From nobody Mon Feb 9 17:56:14 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0425AC77B62 for ; Thu, 30 Mar 2023 08:58:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230205AbjC3I6Z (ORCPT ); Thu, 30 Mar 2023 04:58:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230114AbjC3I6U (ORCPT ); Thu, 30 Mar 2023 04:58:20 -0400 Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB75E7A8B for ; Thu, 30 Mar 2023 01:58:15 -0700 (PDT) Received: by mail-pl1-x62f.google.com with SMTP id kc4so17440935plb.10 for ; Thu, 30 Mar 2023 01:58:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1680166695; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BG1wtweCRp2yLKIQJrZsbcG2DCCs4VdZ6zbbPPJNRdk=; b=T94hQX0kZBz/CdZCP5ycbTmHKRaEFgSE7kVBYecmLALA9exK+oCTOJrxbI+hIzD6hb W7+6L1AMRc1lBk3/hGte25vuDaT3q0QKDeDkJnHx0kSz4PNqzuhUPXY3ARjk+dDKky4b exdeTDukFKSSg7FAp6mO+twCNdDegcjlxSP7o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680166695; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BG1wtweCRp2yLKIQJrZsbcG2DCCs4VdZ6zbbPPJNRdk=; b=Z2EuFtj1Nd5Aylq28dDUxiHPd048eg0N0EmF/Fe/Y9IvDRlJp4suO2voM1IV0Ldg1I 9UEghBR87WXlDrC3wgYKsxYPpd1zRxe7Gwm5Ydqu/uyd9l9pun7buW+98vA4SmY7Gxq5 SNMeZ5XrxOAkj/lFvObYh/bW2dhsQWGJdmPwazMTfqWCdFe65kB4Tte8LwKyDfV9x/t5 aMUpBeDTCNLTLCyavTmATtIQSPvR31/2hK5LkpbwiZ9w7h7qGbb6T13T30Ti9BG3sfjM tSRznvnXHE48Z9x/MhE/kgF6Vapiaoieo09VopVddp3JGcSJ4mfqHe88z69enm0jG4JW au4A== X-Gm-Message-State: AO0yUKU3XrHi+bgw5CtzeSoPQS95k0P8RbQ9bytTWLqWO9qh7lQCcLOA 9PboNQxqSqOgSEJ9jpbtCEbcgQ== X-Google-Smtp-Source: AK7set+2kV6ovFOne/RSG/JuSnGk/aMOvo6fWoUNisnqe6hnWZg9TLcPl5GMn7BN3NTDcJIfpWdL+A== X-Received: by 2002:a05:6a20:3f0c:b0:db:4c00:7918 with SMTP id az12-20020a056a203f0c00b000db4c007918mr18322352pzb.0.1680166695264; Thu, 30 Mar 2023 01:58:15 -0700 (PDT) Received: from localhost ([2401:fa00:8f:203:1320:eef8:d0bb:b161]) by smtp.gmail.com with UTF8SMTPSA id i12-20020aa787cc000000b00580e3917af7sm17437668pfo.117.2023.03.30.01.58.12 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 30 Mar 2023 01:58:14 -0700 (PDT) From: David Stevens X-Google-Original-From: David Stevens To: Marc Zyngier , Sean Christopherson Cc: Oliver Upton , Paolo Bonzini , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, David Stevens Subject: [PATCH v6 1/4] KVM: mmu: introduce new gfn_to_pfn_noref functions Date: Thu, 30 Mar 2023 17:57:59 +0900 Message-Id: <20230330085802.2414466-2-stevensd@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog In-Reply-To: <20230330085802.2414466-1-stevensd@google.com> References: <20230330085802.2414466-1-stevensd@google.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: David Stevens Introduce new gfn_to_pfn_noref functions that parallel existing gfn_to_pfn functions. These functions can be used when the caller does not need to maintain a reference to the returned pfn (i.e. when usage is guarded by a mmu_notifier). The noref functions take an out parameter that is used to return the struct page if the hva was resolved via gup. The caller needs to drop its reference such a returned page. Signed-off-by: David Stevens --- include/linux/kvm_host.h | 18 ++++ virt/kvm/kvm_main.c | 209 ++++++++++++++++++++++++++++----------- virt/kvm/kvm_mm.h | 6 +- virt/kvm/pfncache.c | 12 ++- 4 files changed, 188 insertions(+), 57 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 90edc16d37e5..146f220cc25b 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1162,8 +1162,22 @@ kvm_pfn_t __gfn_to_pfn_memslot(const struct kvm_memo= ry_slot *slot, gfn_t gfn, bool atomic, bool interruptible, bool *async, bool write_fault, bool *writable, hva_t *hva); =20 +kvm_pfn_t gfn_to_pfn_noref(struct kvm *kvm, gfn_t gfn, struct page **page); +kvm_pfn_t gfn_to_pfn_noref_prot(struct kvm *kvm, gfn_t gfn, + bool write_fault, bool *writable, + struct page **page); +kvm_pfn_t gfn_to_pfn_noref_memslot(const struct kvm_memory_slot *slot, + gfn_t gfn, struct page **page); +kvm_pfn_t gfn_to_pfn_noref_memslot_atomic(const struct kvm_memory_slot *sl= ot, + gfn_t gfn, struct page **page); +kvm_pfn_t __gfn_to_pfn_noref_memslot(const struct kvm_memory_slot *slot, + gfn_t gfn, bool atomic, bool interruptible, + bool *async, bool write_fault, bool *writable, + hva_t *hva, struct page **page); + void kvm_release_pfn_clean(kvm_pfn_t pfn); void kvm_release_pfn_dirty(kvm_pfn_t pfn); +void kvm_release_pfn_noref_clean(kvm_pfn_t pfn, struct page *page); void kvm_set_pfn_dirty(kvm_pfn_t pfn); void kvm_set_pfn_accessed(kvm_pfn_t pfn); =20 @@ -1242,6 +1256,10 @@ struct kvm_memslots *kvm_vcpu_memslots(struct kvm_vc= pu *vcpu); struct kvm_memory_slot *kvm_vcpu_gfn_to_memslot(struct kvm_vcpu *vcpu, gfn= _t gfn); kvm_pfn_t kvm_vcpu_gfn_to_pfn_atomic(struct kvm_vcpu *vcpu, gfn_t gfn); kvm_pfn_t kvm_vcpu_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn); +kvm_pfn_t kvm_vcpu_gfn_to_pfn_noref_atomic(struct kvm_vcpu *vcpu, gfn_t gf= n, + struct page **page); +kvm_pfn_t kvm_vcpu_gfn_to_pfn_noref(struct kvm_vcpu *vcpu, gfn_t gfn, + struct page **page); int kvm_vcpu_map(struct kvm_vcpu *vcpu, gpa_t gpa, struct kvm_host_map *ma= p); void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map, bool = dirty); unsigned long kvm_vcpu_gfn_to_hva(struct kvm_vcpu *vcpu, gfn_t gfn); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f40b72eb0e7b..007dd984eeea 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2484,9 +2484,9 @@ static inline int check_user_page_hwpoison(unsigned l= ong addr) * only part that runs if we can in atomic context. */ static bool hva_to_pfn_fast(unsigned long addr, bool write_fault, - bool *writable, kvm_pfn_t *pfn) + bool *writable, kvm_pfn_t *pfn, + struct page **page) { - struct page *page[1]; =20 /* * Fast pin a writable pfn only if it is a write fault request @@ -2497,7 +2497,7 @@ static bool hva_to_pfn_fast(unsigned long addr, bool = write_fault, return false; =20 if (get_user_page_fast_only(addr, FOLL_WRITE, page)) { - *pfn =3D page_to_pfn(page[0]); + *pfn =3D page_to_pfn(*page); =20 if (writable) *writable =3D true; @@ -2512,10 +2512,10 @@ static bool hva_to_pfn_fast(unsigned long addr, boo= l write_fault, * 1 indicates success, -errno is returned if error is detected. */ static int hva_to_pfn_slow(unsigned long addr, bool *async, bool write_fau= lt, - bool interruptible, bool *writable, kvm_pfn_t *pfn) + bool interruptible, bool *writable, kvm_pfn_t *pfn, + struct page **page) { unsigned int flags =3D FOLL_HWPOISON; - struct page *page; int npages; =20 might_sleep(); @@ -2530,7 +2530,7 @@ static int hva_to_pfn_slow(unsigned long addr, bool *= async, bool write_fault, if (interruptible) flags |=3D FOLL_INTERRUPTIBLE; =20 - npages =3D get_user_pages_unlocked(addr, 1, &page, flags); + npages =3D get_user_pages_unlocked(addr, 1, page, flags); if (npages !=3D 1) return npages; =20 @@ -2540,11 +2540,11 @@ static int hva_to_pfn_slow(unsigned long addr, bool= *async, bool write_fault, =20 if (get_user_page_fast_only(addr, FOLL_WRITE, &wpage)) { *writable =3D true; - put_page(page); - page =3D wpage; + put_page(*page); + *page =3D wpage; } } - *pfn =3D page_to_pfn(page); + *pfn =3D page_to_pfn(*page); return npages; } =20 @@ -2559,16 +2559,6 @@ static bool vma_is_valid(struct vm_area_struct *vma,= bool write_fault) return true; } =20 -static int kvm_try_get_pfn(kvm_pfn_t pfn) -{ - struct page *page =3D kvm_pfn_to_refcounted_page(pfn); - - if (!page) - return 1; - - return get_page_unless_zero(page); -} - static int hva_to_pfn_remapped(struct vm_area_struct *vma, unsigned long addr, bool write_fault, bool *writable, kvm_pfn_t *p_pfn) @@ -2607,26 +2597,6 @@ static int hva_to_pfn_remapped(struct vm_area_struct= *vma, *writable =3D pte_write(*ptep); pfn =3D pte_pfn(*ptep); =20 - /* - * Get a reference here because callers of *hva_to_pfn* and - * *gfn_to_pfn* ultimately call kvm_release_pfn_clean on the - * returned pfn. This is only needed if the VMA has VM_MIXEDMAP - * set, but the kvm_try_get_pfn/kvm_release_pfn_clean pair will - * simply do nothing for reserved pfns. - * - * Whoever called remap_pfn_range is also going to call e.g. - * unmap_mapping_range before the underlying pages are freed, - * causing a call to our MMU notifier. - * - * Certain IO or PFNMAP mappings can be backed with valid - * struct pages, but be allocated without refcounting e.g., - * tail pages of non-compound higher order allocations, which - * would then underflow the refcount when the caller does the - * required put_page. Don't allow those pages here. - */=20 - if (!kvm_try_get_pfn(pfn)) - r =3D -EFAULT; - out: pte_unmap_unlock(ptep, ptl); *p_pfn =3D pfn; @@ -2643,6 +2613,7 @@ static int hva_to_pfn_remapped(struct vm_area_struct = *vma, * host page is not in the memory * @write_fault: whether we should get a writable host page * @writable: whether it allows to map a writable host page for !@write_fa= ult + * @page: outparam for the refcounted page assicated with the pfn, if any * * The function will map a writable host page for these two cases: * 1): @write_fault =3D true @@ -2650,23 +2621,25 @@ static int hva_to_pfn_remapped(struct vm_area_struc= t *vma, * whether the mapping is writable. */ kvm_pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool interruptible, - bool *async, bool write_fault, bool *writable) + bool *async, bool write_fault, bool *writable, + struct page **page) { struct vm_area_struct *vma; kvm_pfn_t pfn; int npages, r; + *page =3D NULL; =20 /* we can do it either atomically or asynchronously, not both */ BUG_ON(atomic && async); =20 - if (hva_to_pfn_fast(addr, write_fault, writable, &pfn)) + if (hva_to_pfn_fast(addr, write_fault, writable, &pfn, page)) return pfn; =20 if (atomic) return KVM_PFN_ERR_FAULT; =20 npages =3D hva_to_pfn_slow(addr, async, write_fault, interruptible, - writable, &pfn); + writable, &pfn, page); if (npages =3D=3D 1) return pfn; if (npages =3D=3D -EINTR) @@ -2700,9 +2673,37 @@ kvm_pfn_t hva_to_pfn(unsigned long addr, bool atomic= , bool interruptible, return pfn; } =20 -kvm_pfn_t __gfn_to_pfn_memslot(const struct kvm_memory_slot *slot, gfn_t g= fn, - bool atomic, bool interruptible, bool *async, - bool write_fault, bool *writable, hva_t *hva) +/* + * Helper function for managing refcounts of pfn returned by hva_to_pfn. + * @pfn: pfn returned by hva_to_pfn + * @page: page outparam from hva_to_pfn + * + * In cases where access to the pfn resolved by hva_to_pfn isn't protected= by + * our MMU notifier, if the pfn was resolved by hva_to_pfn_remapped instea= d of + * gup, then its refcount needs to be bumped. + * + * Certain IO or PFNMAP mappings can be backed with valid struct pages, bu= t be + * allocated without refcounting e.g., tail pages of non-compound higher o= rder + * allocations, which would then underflow the refcount when the caller do= es the + * required put_page. Don't allow those pages here. + */ +kvm_pfn_t kvm_try_get_refcounted_page_ref(kvm_pfn_t pfn, struct page *page) +{ + /* If @page is valid, KVM already has a reference to the pfn/page. */ + if (page || is_error_pfn(pfn)) + return pfn; + + page =3D kvm_pfn_to_refcounted_page(pfn); + if (!page || get_page_unless_zero(page)) + return pfn; + + return KVM_PFN_ERR_FAULT; +} + +kvm_pfn_t __gfn_to_pfn_noref_memslot(const struct kvm_memory_slot *slot, g= fn_t gfn, + bool atomic, bool interruptible, bool *async, + bool write_fault, bool *writable, hva_t *hva, + struct page **page) { unsigned long addr =3D __gfn_to_hva_many(slot, gfn, NULL, write_fault); =20 @@ -2728,47 +2729,134 @@ kvm_pfn_t __gfn_to_pfn_memslot(const struct kvm_me= mory_slot *slot, gfn_t gfn, } =20 return hva_to_pfn(addr, atomic, interruptible, async, write_fault, - writable); + writable, page); +} +EXPORT_SYMBOL_GPL(__gfn_to_pfn_noref_memslot); + +kvm_pfn_t gfn_to_pfn_noref_prot(struct kvm *kvm, gfn_t gfn, bool write_fau= lt, + bool *writable, struct page **page) +{ + return __gfn_to_pfn_noref_memslot(gfn_to_memslot(kvm, gfn), gfn, false, f= alse, + NULL, write_fault, writable, NULL, page); +} +EXPORT_SYMBOL_GPL(gfn_to_pfn_noref_prot); + +kvm_pfn_t gfn_to_pfn_noref_memslot(const struct kvm_memory_slot *slot, gfn= _t gfn, + struct page **page) +{ + return __gfn_to_pfn_noref_memslot(slot, gfn, false, false, NULL, true, + NULL, NULL, page); +} +EXPORT_SYMBOL_GPL(gfn_to_pfn_noref_memslot); + +kvm_pfn_t gfn_to_pfn_noref_memslot_atomic(const struct kvm_memory_slot *sl= ot, + gfn_t gfn, struct page **page) +{ + return __gfn_to_pfn_noref_memslot(slot, gfn, true, false, NULL, true, NUL= L, + NULL, page); +} +EXPORT_SYMBOL_GPL(gfn_to_pfn_noref_memslot_atomic); + +kvm_pfn_t kvm_vcpu_gfn_to_pfn_noref_atomic(struct kvm_vcpu *vcpu, gfn_t gf= n, + struct page **page) +{ + return gfn_to_pfn_noref_memslot_atomic( + kvm_vcpu_gfn_to_memslot(vcpu, gfn), gfn, page); +} +EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_pfn_noref_atomic); + +kvm_pfn_t gfn_to_pfn_noref(struct kvm *kvm, gfn_t gfn, struct page **page) +{ + return gfn_to_pfn_noref_memslot(gfn_to_memslot(kvm, gfn), gfn, page); +} +EXPORT_SYMBOL_GPL(gfn_to_pfn_noref); + +kvm_pfn_t kvm_vcpu_gfn_to_pfn_noref(struct kvm_vcpu *vcpu, gfn_t gfn, + struct page **page) +{ + return gfn_to_pfn_noref_memslot(kvm_vcpu_gfn_to_memslot(vcpu, gfn), + gfn, page); +} +EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_pfn_noref); + +kvm_pfn_t __gfn_to_pfn_memslot(const struct kvm_memory_slot *slot, gfn_t g= fn, + bool atomic, bool interruptible, bool *async, + bool write_fault, bool *writable, hva_t *hva) +{ + struct page *page; + kvm_pfn_t pfn; + + pfn =3D __gfn_to_pfn_noref_memslot(slot, gfn, atomic, interruptible, asyn= c, + write_fault, writable, hva, &page); + + return kvm_try_get_refcounted_page_ref(pfn, page); } EXPORT_SYMBOL_GPL(__gfn_to_pfn_memslot); =20 kvm_pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault, bool *writable) { - return __gfn_to_pfn_memslot(gfn_to_memslot(kvm, gfn), gfn, false, false, - NULL, write_fault, writable, NULL); + struct page *page; + kvm_pfn_t pfn; + + pfn =3D gfn_to_pfn_noref_prot(kvm, gfn, write_fault, writable, &page); + + return kvm_try_get_refcounted_page_ref(pfn, page); } EXPORT_SYMBOL_GPL(gfn_to_pfn_prot); =20 kvm_pfn_t gfn_to_pfn_memslot(const struct kvm_memory_slot *slot, gfn_t gfn) { - return __gfn_to_pfn_memslot(slot, gfn, false, false, NULL, true, - NULL, NULL); + struct page *page; + kvm_pfn_t pfn; + + pfn =3D gfn_to_pfn_noref_memslot(slot, gfn, &page); + + return kvm_try_get_refcounted_page_ref(pfn, page); } EXPORT_SYMBOL_GPL(gfn_to_pfn_memslot); =20 kvm_pfn_t gfn_to_pfn_memslot_atomic(const struct kvm_memory_slot *slot, gf= n_t gfn) { - return __gfn_to_pfn_memslot(slot, gfn, true, false, NULL, true, - NULL, NULL); + struct page *page; + kvm_pfn_t pfn; + + pfn =3D gfn_to_pfn_noref_memslot_atomic(slot, gfn, &page); + + return kvm_try_get_refcounted_page_ref(pfn, page); } EXPORT_SYMBOL_GPL(gfn_to_pfn_memslot_atomic); =20 kvm_pfn_t kvm_vcpu_gfn_to_pfn_atomic(struct kvm_vcpu *vcpu, gfn_t gfn) { - return gfn_to_pfn_memslot_atomic(kvm_vcpu_gfn_to_memslot(vcpu, gfn), gfn); + struct page *page; + kvm_pfn_t pfn; + + pfn =3D kvm_vcpu_gfn_to_pfn_noref_atomic(vcpu, gfn, &page); + + return kvm_try_get_refcounted_page_ref(pfn, page); } EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_pfn_atomic); =20 kvm_pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn) { - return gfn_to_pfn_memslot(gfn_to_memslot(kvm, gfn), gfn); + struct page *page; + kvm_pfn_t pfn; + + pfn =3D gfn_to_pfn_noref(kvm, gfn, &page); + + return kvm_try_get_refcounted_page_ref(pfn, page); } EXPORT_SYMBOL_GPL(gfn_to_pfn); =20 kvm_pfn_t kvm_vcpu_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn) { - return gfn_to_pfn_memslot(kvm_vcpu_gfn_to_memslot(vcpu, gfn), gfn); + struct page *page; + kvm_pfn_t pfn; + + pfn =3D kvm_vcpu_gfn_to_pfn_noref(vcpu, gfn, &page); + + return kvm_try_get_refcounted_page_ref(pfn, page); } EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_pfn); =20 @@ -2925,6 +3013,17 @@ void kvm_release_pfn_clean(kvm_pfn_t pfn) } EXPORT_SYMBOL_GPL(kvm_release_pfn_clean); =20 +void kvm_release_pfn_noref_clean(kvm_pfn_t pfn, struct page *page) +{ + if (is_error_noslot_pfn(pfn)) + return; + + kvm_set_pfn_accessed(pfn); + if (page) + put_page(page); +} +EXPORT_SYMBOL_GPL(kvm_release_pfn_noref_clean); + void kvm_release_page_dirty(struct page *page) { WARN_ON(is_error_page(page)); diff --git a/virt/kvm/kvm_mm.h b/virt/kvm/kvm_mm.h index 180f1a09e6ba..a4072cc5a189 100644 --- a/virt/kvm/kvm_mm.h +++ b/virt/kvm/kvm_mm.h @@ -3,6 +3,8 @@ #ifndef __KVM_MM_H__ #define __KVM_MM_H__ 1 =20 +#include + /* * Architectures can choose whether to use an rwlock or spinlock * for the mmu_lock. These macros, for use in common code @@ -21,7 +23,9 @@ #endif /* KVM_HAVE_MMU_RWLOCK */ =20 kvm_pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool interruptible, - bool *async, bool write_fault, bool *writable); + bool *async, bool write_fault, bool *writable, + struct page **page); +kvm_pfn_t kvm_try_get_refcounted_page_ref(kvm_pfn_t pfn, struct page *page= ); =20 #ifdef CONFIG_HAVE_KVM_PFNCACHE void gfn_to_pfn_cache_invalidate_start(struct kvm *kvm, diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c index 2d6aba677830..e25d3af969f4 100644 --- a/virt/kvm/pfncache.c +++ b/virt/kvm/pfncache.c @@ -144,6 +144,7 @@ static kvm_pfn_t hva_to_pfn_retry(struct gfn_to_pfn_cac= he *gpc) kvm_pfn_t new_pfn =3D KVM_PFN_ERR_FAULT; void *new_khva =3D NULL; unsigned long mmu_seq; + struct page *page; =20 lockdep_assert_held(&gpc->refresh_lock); =20 @@ -183,10 +184,19 @@ static kvm_pfn_t hva_to_pfn_retry(struct gfn_to_pfn_c= ache *gpc) } =20 /* We always request a writeable mapping */ - new_pfn =3D hva_to_pfn(gpc->uhva, false, false, NULL, true, NULL); + new_pfn =3D hva_to_pfn(gpc->uhva, false, false, NULL, true, NULL, &page); if (is_error_noslot_pfn(new_pfn)) goto out_error; =20 + /* + * Filter out pages that support refcounting but which aren't + * currently being refcounted. Some KVM MMUs support such pages, but + * although we could support them here, kvm internals more generally + * don't. Reject them here for consistency. + */ + if (kvm_try_get_refcounted_page_ref(new_pfn, page) !=3D new_pfn) + goto out_error; + /* * Obtain a new kernel mapping if KVM itself will access the * pfn. Note, kmap() and memremap() can both sleep, so this --=20 2.40.0.348.gf938b09366-goog From nobody Mon Feb 9 17:56:14 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 95E29C6FD1D for ; Thu, 30 Mar 2023 08:58:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230214AbjC3I62 (ORCPT ); Thu, 30 Mar 2023 04:58:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58964 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230051AbjC3I6V (ORCPT ); Thu, 30 Mar 2023 04:58:21 -0400 Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 60B8B6EAD for ; Thu, 30 Mar 2023 01:58:20 -0700 (PDT) Received: by mail-pl1-x62f.google.com with SMTP id kc4so17441074plb.10 for ; Thu, 30 Mar 2023 01:58:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1680166700; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5uuafki+29cUKaQO0uBXDUvz3IdimYT6pah8riQ/iK4=; b=XWRGFBVjmIZuyZ3Ya48quyoPniEx9j7UWv6hygUlARVxXnsydbG7vAKY/q29p8rYQ3 mRfqICN98s7dHIVZcDAO9RmXf+rxtWc5XaqCouT8GxFxwoPkBWKJkthWVTfwW4z2XTO4 nVjOM6P2+oqctx4yIpaqFnrI8m0o6OOakHDPE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680166700; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5uuafki+29cUKaQO0uBXDUvz3IdimYT6pah8riQ/iK4=; b=zon2qvhVFu3Q8xXso32E4xPK54hD2giq7saDClts4xwzDVhBbc3Y35kOItpnE3nHfM HyP8AZ5szFniI3MdJrgVXQbRoUhVztuqjIGNNVQmhq7rwef2oPcWwfkpoNZaJb+jIaBc 2WWC8WQTZWuXCl8oJZowRBXKyeyBHLULLPvj/oYL0MZzopbLRzNj+T+FGV0QBUYdQdCb +5AlLYyMgnlwR5w9ukW3wBuuyj+apq3LkRPs0zGr42LLVvefpVnah+O4OF7Wl/w9T6cl ghW9qqH/pn8wEhy6poZVM9VFjaX5jF/ckmqHC43eTVhJcaf0flxV6lTTy8x7OMyP80Sx xCNQ== X-Gm-Message-State: AAQBX9fsXHtSF7vkGhUcs5/D0kDM5O4JlzNTOvpYEkSmi1/DjqeA9ddl XIqVAOXLr5bLzWwmI+B0oFEpRA== X-Google-Smtp-Source: AKy350YvPl5vVV29XJXPQ2Tc3Qx4pyJcTRMviqLTjFxIdm3DnqKJCl1Uv0CFsVTX1vk0V4Ml679diA== X-Received: by 2002:a17:90a:190f:b0:233:c301:32b3 with SMTP id 15-20020a17090a190f00b00233c30132b3mr24295355pjg.3.1680166699779; Thu, 30 Mar 2023 01:58:19 -0700 (PDT) Received: from localhost ([2401:fa00:8f:203:1320:eef8:d0bb:b161]) by smtp.gmail.com with UTF8SMTPSA id g10-20020a17090a7d0a00b00234115a2221sm2718564pjl.39.2023.03.30.01.58.17 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 30 Mar 2023 01:58:19 -0700 (PDT) From: David Stevens X-Google-Original-From: David Stevens To: Marc Zyngier , Sean Christopherson Cc: Oliver Upton , Paolo Bonzini , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, David Stevens Subject: [PATCH v6 2/4] KVM: x86/mmu: use gfn_to_pfn_noref Date: Thu, 30 Mar 2023 17:58:00 +0900 Message-Id: <20230330085802.2414466-3-stevensd@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog In-Reply-To: <20230330085802.2414466-1-stevensd@google.com> References: <20230330085802.2414466-1-stevensd@google.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: David Stevens Switch the x86 mmu to the new gfn_to_pfn_noref functions. This allows IO and PFNMAP mappings backed with valid struct pages but without refcounting (e.g. tail pages of non-compound higher order allocations) to be mapped into the guest. Signed-off-by: David Stevens --- arch/x86/kvm/mmu/mmu.c | 19 ++++++++++--------- arch/x86/kvm/mmu/mmu_internal.h | 1 + arch/x86/kvm/mmu/paging_tmpl.h | 7 ++++--- arch/x86/kvm/x86.c | 5 +++-- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 144c5a01cd77..86b74e7bccfa 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -3114,7 +3114,7 @@ void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, s= truct kvm_page_fault *fault if (unlikely(fault->max_level =3D=3D PG_LEVEL_4K)) return; =20 - if (is_error_noslot_pfn(fault->pfn)) + if (!fault->page) return; =20 if (kvm_slot_dirty_track_enabled(slot)) @@ -4224,6 +4224,7 @@ static int __kvm_faultin_pfn(struct kvm_vcpu *vcpu, s= truct kvm_page_fault *fault if (is_guest_mode(vcpu)) { fault->slot =3D NULL; fault->pfn =3D KVM_PFN_NOSLOT; + fault->page =3D NULL; fault->map_writable =3D false; return RET_PF_CONTINUE; } @@ -4239,9 +4240,9 @@ static int __kvm_faultin_pfn(struct kvm_vcpu *vcpu, s= truct kvm_page_fault *fault } =20 async =3D false; - fault->pfn =3D __gfn_to_pfn_memslot(slot, fault->gfn, false, false, &asyn= c, - fault->write, &fault->map_writable, - &fault->hva); + fault->pfn =3D __gfn_to_pfn_noref_memslot(slot, fault->gfn, false, false,= &async, + fault->write, &fault->map_writable, + &fault->hva, &fault->page); if (!async) return RET_PF_CONTINUE; /* *pfn has correct page already */ =20 @@ -4261,9 +4262,9 @@ static int __kvm_faultin_pfn(struct kvm_vcpu *vcpu, s= truct kvm_page_fault *fault * to wait for IO. Note, gup always bails if it is unable to quickly * get a page and a fatal signal, i.e. SIGKILL, is pending. */ - fault->pfn =3D __gfn_to_pfn_memslot(slot, fault->gfn, false, true, NULL, - fault->write, &fault->map_writable, - &fault->hva); + fault->pfn =3D __gfn_to_pfn_noref_memslot(slot, fault->gfn, false, true, = NULL, + fault->write, &fault->map_writable, + &fault->hva, &fault->page); return RET_PF_CONTINUE; } =20 @@ -4349,7 +4350,7 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, s= truct kvm_page_fault *fault =20 out_unlock: write_unlock(&vcpu->kvm->mmu_lock); - kvm_release_pfn_clean(fault->pfn); + kvm_release_pfn_noref_clean(fault->pfn, fault->page); return r; } =20 @@ -4427,7 +4428,7 @@ static int kvm_tdp_mmu_page_fault(struct kvm_vcpu *vc= pu, =20 out_unlock: read_unlock(&vcpu->kvm->mmu_lock); - kvm_release_pfn_clean(fault->pfn); + kvm_release_pfn_noref_clean(fault->pfn, fault->page); return r; } #endif diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_interna= l.h index 2cbb155c686c..6ee34a2d0e13 100644 --- a/arch/x86/kvm/mmu/mmu_internal.h +++ b/arch/x86/kvm/mmu/mmu_internal.h @@ -239,6 +239,7 @@ struct kvm_page_fault { unsigned long mmu_seq; kvm_pfn_t pfn; hva_t hva; + struct page *page; bool map_writable; =20 /* diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index a056f2773dd9..e4e54e372721 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -525,6 +525,7 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_= mmu_page *sp, unsigned pte_access; gfn_t gfn; kvm_pfn_t pfn; + struct page *page; =20 if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte)) return false; @@ -540,12 +541,12 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kv= m_mmu_page *sp, if (!slot) return false; =20 - pfn =3D gfn_to_pfn_memslot_atomic(slot, gfn); + pfn =3D gfn_to_pfn_noref_memslot_atomic(slot, gfn, &page); if (is_error_pfn(pfn)) return false; =20 mmu_set_spte(vcpu, slot, spte, pte_access, gfn, pfn, NULL); - kvm_release_pfn_clean(pfn); + kvm_release_pfn_noref_clean(pfn, page); return true; } =20 @@ -830,7 +831,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, str= uct kvm_page_fault *fault =20 out_unlock: write_unlock(&vcpu->kvm->mmu_lock); - kvm_release_pfn_clean(fault->pfn); + kvm_release_pfn_noref_clean(fault->pfn, fault->page); return r; } =20 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 237c483b1230..53a8c9e776e5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8458,6 +8458,7 @@ static bool reexecute_instruction(struct kvm_vcpu *vc= pu, gpa_t cr2_or_gpa, { gpa_t gpa =3D cr2_or_gpa; kvm_pfn_t pfn; + struct page *page; =20 if (!(emulation_type & EMULTYPE_ALLOW_RETRY_PF)) return false; @@ -8487,7 +8488,7 @@ static bool reexecute_instruction(struct kvm_vcpu *vc= pu, gpa_t cr2_or_gpa, * retry instruction -> write #PF -> emulation fail -> retry * instruction -> ... */ - pfn =3D gfn_to_pfn(vcpu->kvm, gpa_to_gfn(gpa)); + pfn =3D gfn_to_pfn_noref(vcpu->kvm, gpa_to_gfn(gpa), &page); =20 /* * If the instruction failed on the error pfn, it can not be fixed, @@ -8496,7 +8497,7 @@ static bool reexecute_instruction(struct kvm_vcpu *vc= pu, gpa_t cr2_or_gpa, if (is_error_noslot_pfn(pfn)) return false; =20 - kvm_release_pfn_clean(pfn); + kvm_release_pfn_noref_clean(pfn, page); =20 /* The instructions are well-emulated on direct mmu. */ if (vcpu->arch.mmu->root_role.direct) { --=20 2.40.0.348.gf938b09366-goog From nobody Mon Feb 9 17:56:14 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2BE1FC6FD1D for ; Thu, 30 Mar 2023 08:58:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230176AbjC3I6n (ORCPT ); Thu, 30 Mar 2023 04:58:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59422 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230282AbjC3I6a (ORCPT ); Thu, 30 Mar 2023 04:58:30 -0400 Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D4B0F7682 for ; Thu, 30 Mar 2023 01:58:24 -0700 (PDT) Received: by mail-pl1-x62a.google.com with SMTP id ix20so17473673plb.3 for ; Thu, 30 Mar 2023 01:58:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1680166704; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RprU1FQJyxxcIHKiSPrHpqU5Norly3mnaXVCeZUl59M=; b=QDHkG5g+mhdDG+FzgKVq7FS5dKNc0YNfht7PzrIPGup07HPZi96FiixkgwPtKVIYGG YvA5YfJDQPGG3571GI68xmqSNKdRgYDNHzSXM1UF4Q6IX2GZf6W5zqMvZt/sbbPzmznM kDgvKePhP/3e133fLy2oCD4sa564mWqMu9USM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680166704; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RprU1FQJyxxcIHKiSPrHpqU5Norly3mnaXVCeZUl59M=; b=wa5OZ2EVHLzh9utsdLPo/v9JslnBHos0JH07syKKrsx/fM/ru2pR/VbcOoie54boMt dHt2SpO0xbIjHUk14jMhgp9eCr7W6wZOFgFpry52RR/PIQvMLStDk1CYncV6nAE+m79N LAmPMZdWY6oZuQcj9nIo2zSFD4f7FiBn/kR+Winod79Dy4rflTJqqg7Z5Nh315XNnRn+ MRgRxMhgKPnq8PSn5bY8anduiB4rd2lSQz9HmDS1tiOzJF1uI5cAFIdSxTf9yuJd96D3 rm/h385p9eYA7fn6Dc8V8ZJQXekS1ae2/pEEz3Sccr7z6FlA4/KKgUiC6rgPYpo1gAlS Yheg== X-Gm-Message-State: AAQBX9c0P+PaHXoXPVV/RBF77LSgOgzMLHfB+jpoo5c9ujgZliHUo3wA JtyvCN/oZQ3hUJWSRSPNDdeybg== X-Google-Smtp-Source: AKy350b5AnG4pGNdCaiDN/aoj+xwtATD8wEB5ynusbMELHN8Cc/7Z1ktbP31uXiprAlWbm9qTDcdLw== X-Received: by 2002:a17:902:c44c:b0:1a1:8edc:c5f8 with SMTP id m12-20020a170902c44c00b001a18edcc5f8mr18986019plm.56.1680166703992; Thu, 30 Mar 2023 01:58:23 -0700 (PDT) Received: from localhost ([2401:fa00:8f:203:1320:eef8:d0bb:b161]) by smtp.gmail.com with UTF8SMTPSA id bi11-20020a170902bf0b00b0019f11caf11asm24358430plb.166.2023.03.30.01.58.21 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 30 Mar 2023 01:58:23 -0700 (PDT) From: David Stevens X-Google-Original-From: David Stevens To: Marc Zyngier , Sean Christopherson Cc: Oliver Upton , Paolo Bonzini , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, David Stevens Subject: [PATCH v6 3/4] KVM: arm64/mmu: use gfn_to_pfn_noref Date: Thu, 30 Mar 2023 17:58:01 +0900 Message-Id: <20230330085802.2414466-4-stevensd@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog In-Reply-To: <20230330085802.2414466-1-stevensd@google.com> References: <20230330085802.2414466-1-stevensd@google.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: David Stevens Switch the arm64 mmu to the new gfn_to_pfn_noref functions. This allows IO and PFNMAP mappings backed with valid struct pages but without refcounting (e.g. tail pages of non-compound higher order allocations) to be mapped into the guest. Signed-off-by: David Stevens --- arch/arm64/kvm/mmu.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 7113587222ff..0fd726e82a19 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1082,7 +1082,7 @@ static bool fault_supports_stage2_huge_mapping(struct= kvm_memory_slot *memslot, static unsigned long transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memsl= ot, unsigned long hva, kvm_pfn_t *pfnp, - phys_addr_t *ipap) + struct page **page, phys_addr_t *ipap) { kvm_pfn_t pfn =3D *pfnp; =20 @@ -1091,7 +1091,8 @@ transparent_hugepage_adjust(struct kvm *kvm, struct k= vm_memory_slot *memslot, * sure that the HVA and IPA are sufficiently aligned and that the * block map is contained within the memslot. */ - if (fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE) && + if (*page && + fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE) && get_user_mapping_size(kvm, hva) >=3D PMD_SIZE) { /* * The address we faulted on is backed by a transparent huge @@ -1112,10 +1113,11 @@ transparent_hugepage_adjust(struct kvm *kvm, struct= kvm_memory_slot *memslot, * page accordingly. */ *ipap &=3D PMD_MASK; - kvm_release_pfn_clean(pfn); + kvm_release_page_clean(*page); pfn &=3D ~(PTRS_PER_PMD - 1); - get_page(pfn_to_page(pfn)); *pfnp =3D pfn; + *page =3D pfn_to_page(pfn); + get_page(*page); =20 return PMD_SIZE; } @@ -1201,6 +1203,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys= _addr_t fault_ipa, short vma_shift; gfn_t gfn; kvm_pfn_t pfn; + struct page *page; bool logging_active =3D memslot_is_logging(memslot); unsigned long fault_level =3D kvm_vcpu_trap_get_fault_level(vcpu); unsigned long vma_pagesize, fault_granule; @@ -1301,8 +1304,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys= _addr_t fault_ipa, */ smp_rmb(); =20 - pfn =3D __gfn_to_pfn_memslot(memslot, gfn, false, false, NULL, - write_fault, &writable, NULL); + pfn =3D __gfn_to_pfn_noref_memslot(memslot, gfn, false, false, NULL, + write_fault, &writable, NULL, &page); if (pfn =3D=3D KVM_PFN_ERR_HWPOISON) { kvm_send_hwpoison_signal(hva, vma_shift); return 0; @@ -1348,7 +1351,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys= _addr_t fault_ipa, vma_pagesize =3D fault_granule; else vma_pagesize =3D transparent_hugepage_adjust(kvm, memslot, - hva, &pfn, + hva, + &pfn, &page, &fault_ipa); } =20 @@ -1395,8 +1399,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys= _addr_t fault_ipa, =20 out_unlock: read_unlock(&kvm->mmu_lock); - kvm_set_pfn_accessed(pfn); - kvm_release_pfn_clean(pfn); + kvm_release_pfn_noref_clean(pfn, page); return ret !=3D -EAGAIN ? ret : 0; } =20 --=20 2.40.0.348.gf938b09366-goog From nobody Mon Feb 9 17:56:14 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4A505C6FD1D for ; Thu, 30 Mar 2023 08:58:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230384AbjC3I6x (ORCPT ); Thu, 30 Mar 2023 04:58:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230370AbjC3I6k (ORCPT ); Thu, 30 Mar 2023 04:58:40 -0400 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C625983E8 for ; Thu, 30 Mar 2023 01:58:29 -0700 (PDT) Received: by mail-pj1-x102e.google.com with SMTP id lr16-20020a17090b4b9000b0023f187954acso18907777pjb.2 for ; Thu, 30 Mar 2023 01:58:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1680166709; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=DARmMfXxqHb2Ls37OggPINW15nuQ84yCV7KESHjLY2s=; b=OXoX2NCxtPATlq8jnBH3sThb7ycsR+0Oe6TcPImZJi9tCnRpIHfnfMjFvh2OLeHSO7 M7F63PjkEBkJdxcACVhouJSazYLSPB0gy7jVYsu0xN+szgvXnNWoZ7Oh0kFFo4CWOLgC d+rHEFtEcJ4GCWJzO34ClqYb+5IULO9O4L5x8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680166709; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DARmMfXxqHb2Ls37OggPINW15nuQ84yCV7KESHjLY2s=; b=hAXdlrP7JemcxZ1ioJbxRq0yjRhi3XJMOR9lU2QErTfHiqTNHfw9YaItx5Uh32uE0S ASyTMvEldTcAElHQtq+6XKh90vDis+ix9/b5JdipcLkR6VW1jEB3p8RWtDL72062BKlK 3BSXtHx1kG6u7Jc9FJ4tvxSVfRzXUICHmo3zA+AmPWRGEkDJ8hNKHsQL/OIDcWi0YsLK NC440GMzlxa2nHIbqw+luygGebqYRza4nkQ864Efq3v9GOScnP82FjqrvbjEMsgvTHBK iUEn972clgAva0mKd4jq/3c7qsLtW6/zX03xJD85EGcPtPqBIz4XFVCYGcDZIYOS3VkH nRRg== X-Gm-Message-State: AAQBX9cdZ5QKFCYT+SgkvMhNZdx4RE7WUdbH4tYjGG3vthZOvBx/suvU Vjh4pjtljTZ7Dm2arfOshmemlw== X-Google-Smtp-Source: AKy350YitOtGSTe/IC945dOZxknelnREFOYZr+go4eGipagCeEp7bTT+/hLXchLclFceYZl0IfvvWw== X-Received: by 2002:a17:902:fb85:b0:19e:b088:5900 with SMTP id lg5-20020a170902fb8500b0019eb0885900mr19155304plb.38.1680166709092; Thu, 30 Mar 2023 01:58:29 -0700 (PDT) Received: from localhost ([2401:fa00:8f:203:1320:eef8:d0bb:b161]) by smtp.gmail.com with UTF8SMTPSA id s5-20020a63e805000000b00502f1256674sm23134697pgh.41.2023.03.30.01.58.26 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 30 Mar 2023 01:58:28 -0700 (PDT) From: David Stevens X-Google-Original-From: David Stevens To: Marc Zyngier , Sean Christopherson Cc: Oliver Upton , Paolo Bonzini , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, David Stevens Subject: [PATCH v6 4/4] KVM: mmu: remove over-aggressive warnings Date: Thu, 30 Mar 2023 17:58:02 +0900 Message-Id: <20230330085802.2414466-5-stevensd@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog In-Reply-To: <20230330085802.2414466-1-stevensd@google.com> References: <20230330085802.2414466-1-stevensd@google.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: David Stevens Remove two warnings that require ref counts for pages to be non-zero, as mapped pfns from follow_pfn may not have an initialized ref count. Signed-off-by: David Stevens --- arch/x86/kvm/mmu/mmu.c | 10 ---------- virt/kvm/kvm_main.c | 5 ++--- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 86b74e7bccfa..46b3d6c0ff27 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -555,7 +555,6 @@ static u64 mmu_spte_clear_track_bits(struct kvm *kvm, u= 64 *sptep) kvm_pfn_t pfn; u64 old_spte =3D *sptep; int level =3D sptep_to_sp(sptep)->role.level; - struct page *page; =20 if (!is_shadow_present_pte(old_spte) || !spte_has_volatile_bits(old_spte)) @@ -570,15 +569,6 @@ static u64 mmu_spte_clear_track_bits(struct kvm *kvm, = u64 *sptep) =20 pfn =3D spte_to_pfn(old_spte); =20 - /* - * KVM doesn't hold a reference to any pages mapped into the guest, and - * instead uses the mmu_notifier to ensure that KVM unmaps any pages - * before they are reclaimed. Sanity check that, if the pfn is backed - * by a refcounted page, the refcount is elevated. - */ - page =3D kvm_pfn_to_refcounted_page(pfn); - WARN_ON(page && !page_count(page)); - if (is_accessed_spte(old_spte)) kvm_set_pfn_accessed(pfn); =20 diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 007dd984eeea..a80070cb04d7 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -165,10 +165,9 @@ bool kvm_is_zone_device_page(struct page *page) /* * The metadata used by is_zone_device_page() to determine whether or * not a page is ZONE_DEVICE is guaranteed to be valid if and only if - * the device has been pinned, e.g. by get_user_pages(). WARN if the - * page_count() is zero to help detect bad usage of this helper. + * the device has been pinned, e.g. by get_user_pages(). */ - if (WARN_ON_ONCE(!page_count(page))) + if (!page_count(page)) return false; =20 return is_zone_device_page(page); --=20 2.40.0.348.gf938b09366-goog