Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp1053356pxb; Wed, 3 Nov 2021 17:29:29 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy18S5ZqNSUBI+U7FBBI15iIb8Xn4HnSVDalXQPnaVnT0WZmZPfz6EVVuJZd+vHq48Zek+m X-Received: by 2002:a05:6e02:1a85:: with SMTP id k5mr13803985ilv.27.1635985769362; Wed, 03 Nov 2021 17:29:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1635985769; cv=none; d=google.com; s=arc-20160816; b=LJT6rOFcUc52KStVkKlhKYJ2GtQ3GlzJ8a2QpKzLUHFGOgfnAP5qWix0CYSzWnYU7O pDoSdQBNlO3WFcGOCQxED0I0yHLM67LXeYvM1fLSpvIzJ65vNDPitrQ0L+QL9Qj6ot3f ryJAFUWnSttz/b8FeonLCw2frzuafszkopeIiRXx7bzZ8m1i+hf6QSUdfiNPC9P22Fs4 tPNZLQuYPYM3sr1uP89O7h8PP06ltEo/WGAvorRcooah7mCjTP/x+03hV+C9z1YvjGal 5s9vXRiXWsLWfNBYY2/x/yK9jzxI3A6CJ4O2GjuMDtnRfbGUCliyWuCliFt4HiEaJ4n9 Xo0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:reply-to:dkim-signature; bh=uUiF2cCeyvLcomA71gNb8UtnumiDOcYwDfMiXjWen6E=; b=KTPKf7GFsmqyhVN0fJWv4VrtNN01xmyCklHzpeol2WII1Qk6aeUpOyjlCf/rGvdoC7 5SufQim3BBWfImjWO1H+Uss4HxQu78Ce2SPXjfpBEoJhWciZSZgRMjx/YDM78h4gYAE3 HsqdEbem0LnajI9Xc8HQlLSDp/8IGYjkOElhjIXueZvMXk8dR4XU10/Vx5PxknK38FRz ovze/g3MGGKysd8jK/w6RR5KbaySy4ju0zIpG2B7MktswL0qgg62zvpHdJ9FOlbVq3wm ahoj+xJW1VnGL9Tl+o7x7i0XO2l+TzXYRqCdp1q63Rg/kWjzaDSLJhZQ0ABAyDY8uIyo olPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=oTQ7zxZO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p10si1691945ile.38.2021.11.03.17.29.14; Wed, 03 Nov 2021 17:29:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=oTQ7zxZO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233217AbhKDAaK (ORCPT + 99 others); Wed, 3 Nov 2021 20:30:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233142AbhKDA2k (ORCPT ); Wed, 3 Nov 2021 20:28:40 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8BBC4C06127A for ; Wed, 3 Nov 2021 17:26:03 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id l7-20020a622507000000b00494608c84a4so262382pfl.6 for ; Wed, 03 Nov 2021 17:26:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=uUiF2cCeyvLcomA71gNb8UtnumiDOcYwDfMiXjWen6E=; b=oTQ7zxZOtJdIWwrRYuqPf1zjANoRXpGs4d18yx/1uFcULOqfGSPv/eGnnTHt2OaFXl Fw2Ja9jpx42JTWA+4xQHXaSDJzaLjB39qn72mpFaq/+8Pgyy1WE+Sui5ukzf7K0T1tch WQUzSIOcUqQ4RYGuYqINyp9t2Du3YpUpxuubgXkNzI9EfzqleZjWAUTMgOc4YeGCZQie KXx3n4rodQ4x96mmNgtB9r6T1WA9dTicsSrUIx+if+mPJuWUWAF+djp3CD78xEHLczgf /8ph947YIr/9EVIDN0A2sn1MabQLXDCtd3nrNdsi57mxIxM3VfxgHreQqgiovSN/aw02 N1Uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=uUiF2cCeyvLcomA71gNb8UtnumiDOcYwDfMiXjWen6E=; b=s3a2FIoLWlMZ6KMlTdqS8VDpp7A2RjttJGBBVlWnXiJLw9rNQ5oj2RvjJjo1AVXlnc tB41ck+V4IpEG+SiyZxWMsDRrkc7Zq59hn32xC6mEEVHww4PaW2SQrtSQs0olCGyWuso cOICiAuvcBcZALsVcunQc0lXpDClRRS2ZD30nK71ukhVRm5BhHI14WOC6QmVhzmOR+OQ 6ii/0R+Rb7ZMltMOA34e9UVJ+TlW8z6pXqMUqe49a0NiMP0wTNgjS+10DlVZWIAU/1Eh hpc2YgtCGxKpdSTO2GSHoSLB4cZNrE7DTNix8d981qZ1X6P9YhOiFNzAy9GB4mb2y1sv Fm0Q== X-Gm-Message-State: AOAM533Ld/oXfDD20ZHTsZV6kmSGvRr8nqh9lK4VIQxCeZUe3UG7uVyw qAChIlTFhkeK3A+zUyVjwQDECJzohTs= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a05:6a00:2181:b0:44c:f4bc:2f74 with SMTP id h1-20020a056a00218100b0044cf4bc2f74mr47622932pfi.68.1635985562987; Wed, 03 Nov 2021 17:26:02 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 4 Nov 2021 00:25:04 +0000 In-Reply-To: <20211104002531.1176691-1-seanjc@google.com> Message-Id: <20211104002531.1176691-4-seanjc@google.com> Mime-Version: 1.0 References: <20211104002531.1176691-1-seanjc@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [PATCH v5.5 03/30] KVM: Require total number of memslot pages to fit in an unsigned long From: Sean Christopherson To: Marc Zyngier , Huacai Chen , Aleksandar Markovic , Paul Mackerras , Anup Patel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Christian Borntraeger , Janosch Frank , Paolo Bonzini Cc: James Morse , Alexandru Elisei , Suzuki K Poulose , Atish Patra , David Hildenbrand , Cornelia Huck , Claudio Imbrenda , Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-mips@vger.kernel.org, kvm@vger.kernel.org, kvm-ppc@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Ben Gardon , "Maciej S . Szmigiero" Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Explicitly disallow creating more memslot pages than can fit in an unsigned long, KVM doesn't correctly handle a total number of memslot pages that doesn't fit in an unsigned long and remedying that would be a waste of time. For a 64-bit kernel, this is a nop as memslots are not allowed to overlap in the gfn address space. With a 32-bit kernel, userspace can at most address 3gb of virtual memory, whereas wrapping the total number of pages would require 4tb+ of guest physical memory. Even with x86's second address space for SMM, userspace would need to alias all of guest memory more than one _thousand_ times. And on older x86 hardware with MAXPHYADDR < 43, the guest couldn't actually access any of those aliases even if userspace lied about guest.MAXPHYADDR. On 390 and arm64, this is a nop as they don't support 32-bit hosts. On x86, practically speaking this is simply acknowledging reality as the existing kvm_mmu_calculate_default_mmu_pages() assumes the total number of pages fits in an "unsigned long". On PPC, this is likely a nop as every flavor of PPC KVM assumes gfns (and gpas!) fit in unsigned long. arch/powerpc/kvm/book3s_32_mmu_host.c goes a step further and fails the build if CONFIG_PTE_64BIT=y, which presumably means that it does't support 64-bit physical addresses. On MIPS, this is also likely a nop as the core MMU helpers assume gpas fit in unsigned long, e.g. see kvm_mips_##name##_pte. And finally, RISC-V is a "don't care" as it doesn't exist in any release, i.e. there is no established ABI to break. Signed-off-by: Sean Christopherson --- include/linux/kvm_host.h | 1 + virt/kvm/kvm_main.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 60a35d9fe259..d8e92d4a78d8 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -551,6 +551,7 @@ struct kvm { */ struct mutex slots_arch_lock; struct mm_struct *mm; /* userspace tied to this vm */ + unsigned long nr_memslot_pages; struct kvm_memslots __rcu *memslots[KVM_ADDRESS_SPACE_NUM]; struct kvm_vcpu *vcpus[KVM_MAX_VCPUS]; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 83287730389f..264c4b16520b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1623,6 +1623,15 @@ static int kvm_set_memslot(struct kvm *kvm, update_memslots(slots, new, change); slots = install_new_memslots(kvm, as_id, slots); + /* + * Update the total number of memslot pages before calling the arch + * hook so that architectures can consume the result directly. + */ + if (change == KVM_MR_DELETE) + kvm->nr_memslot_pages -= old.npages; + else if (change == KVM_MR_CREATE) + kvm->nr_memslot_pages += new->npages; + kvm_arch_commit_memory_region(kvm, mem, &old, new, change); /* Free the old memslot's metadata. Note, this is the full copy!!! */ @@ -1653,6 +1662,9 @@ static int kvm_delete_memslot(struct kvm *kvm, if (!old->npages) return -EINVAL; + if (WARN_ON_ONCE(kvm->nr_memslot_pages < old->npages)) + return -EIO; + memset(&new, 0, sizeof(new)); new.id = old->id; /* @@ -1736,6 +1748,13 @@ int __kvm_set_memory_region(struct kvm *kvm, if (!old.npages) { change = KVM_MR_CREATE; new.dirty_bitmap = NULL; + + /* + * To simplify KVM internals, the total number of pages across + * all memslots must fit in an unsigned long. + */ + if ((kvm->nr_memslot_pages + new.npages) < kvm->nr_memslot_pages) + return -EINVAL; } else { /* Modify an existing slot. */ if ((new.userspace_addr != old.userspace_addr) || (new.npages != old.npages) || -- 2.33.1.1089.g2158813163f-goog