* [PATCH v3] KVM: Skip gfn-based MMU notifier invalidations for guest_memfd-only memslots
@ 2026-11-13 16:40 Sean Christopherson
2026-11-13 17:10 ` sashiko-bot
2026-11-13 17:25 ` Lorenzo Stoakes (ARM)
0 siblings, 2 replies; 5+ messages in thread
From: Sean Christopherson @ 2026-11-13 16:40 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Sean Christopherson, kvm, linux-kernel, Lorenzo Stoakes,
Naveen N Rao, Alexandru Elisei
From: Alexandru Elisei <alexandru.elisei@arm.com>
Don't invalidate gmem-only memslots when responding to MMU notifier
invalidations, as the entire point of gmem-only memslots is so that KVM
doesn't need a VMA to install mappings into KVM's MMU. Specifically,
page faults are resolved by going straight to guest_memfd, using the gfn
and the associated memslot's gmem.file. I.e. whether or not userspace
happens to have valid mappings to the same gmem instance is irrelevant,
as are any invalidations for those mappings.
Note! The exception is KVM's gfn_to_pfn_cache implementation which isn't
yet wired up to pull pfns directly from guest_memfd, i.e. still relies on
userspace mappings/VMAs and thus need to be invalidated, e.g. to ensure KVM
doesn't retain a kernel mapping+pointer to PRIVATE memory. However, as of
commit da260bcb56fe ("KVM: pfncache: use a dedicated invalidation sequence
for cache refresh"), GPC invalidation no longer relies on memslot lookups,
because GPCs also support HVA-based mappings. I.e. KVM *must* be able to
detect and handle relevant MMU notifier invalidations even if there is *no*
memslot whatsoever.
In addition to the obvious performance benefits, avoiding unnecessary and
spurious SPTE zaps and TLB flushes will allow KVM to support features like
ARM's Statistical Profiling Extension (SPE)[1] and x86's Secure AVIC[2],
both of which rely on the pages *never* being unmapped from the stage-2
page tables.
Link: https://lore.kernel.org/all/20260903160623.315525-1-alexandru.elisei@arm.com [1]
Link: https://lore.kernel.org/all/cover.1783490022.git.naveen@kernel.org [2]
Cc: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Cc: Naveen N Rao (AMD) <naveen@kernel.org>
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
[sean: rewrite changelog to capture the new gpc behavior]
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
v3: v1, but with a different changelog.
v2: https://lore.kernel.org/all/20260714160411.302386-1-alexandru.elisei@arm.com
v1: https://lore.kernel.org/all/20260615155244.183044-1-alexandru.elisei@arm.com
virt/kvm/kvm_main.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index cf4cb586f140..599dea22afb8 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -601,6 +601,10 @@ static __always_inline kvm_mn_ret_t kvm_handle_hva_range(struct kvm *kvm,
unsigned long hva_start, hva_end;
slot = container_of(node, struct kvm_memory_slot, hva_node[slots->node_idx]);
+
+ if (kvm_slot_has_gmem(slot) && kvm_memslot_is_gmem_only(slot))
+ continue;
+
hva_start = max_t(unsigned long, range->start, slot->userspace_addr);
hva_end = min_t(unsigned long, range->end,
slot->userspace_addr + (slot->npages << PAGE_SHIFT));
base-commit: d21eef2084a9af87ac2a783bc7c2b175ba114e4e
--
2.56.1.703.gf848ed807c-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v3] KVM: Skip gfn-based MMU notifier invalidations for guest_memfd-only memslots
2026-11-13 16:40 [PATCH v3] KVM: Skip gfn-based MMU notifier invalidations for guest_memfd-only memslots Sean Christopherson
@ 2026-11-13 17:10 ` sashiko-bot
2026-11-13 17:17 ` Sean Christopherson
2026-11-13 17:25 ` Lorenzo Stoakes (ARM)
1 sibling, 1 reply; 5+ messages in thread
From: sashiko-bot @ 2026-11-13 17:10 UTC (permalink / raw)
To: Sean Christopherson; +Cc: kvm
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Critical] KVM: x86/mmu: host page UAF via kvm_mmu_prefetch_sptes() on
gmem-only memslots
--
commit 8fb2cb0acca2cbb14c599c1c5881381eb579d79c
Author: Alexandru Elisei <alexandru.elisei@arm.com>
KVM: Skip gfn-based MMU notifier invalidations for guest_memfd-only memslots
This commit skips guest_memfd-only memslots in kvm_handle_hva_range() when
handling MMU notifier invalidations.
Link: https://lore.kernel.org/all/20260903160623.315525-1-alexandru.elisei@arm.com
Link: https://lore.kernel.org/all/cover.1783490022.git.naveen@kernel.org
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index cf4cb586f1407..599dea22afb81 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -601,6 +601,10 @@ static __always_inline kvm_mn_ret_t kvm_handle_hva_range(struct kvm *kvm,
> unsigned long hva_start, hva_end;
>
> slot = container_of(node, struct kvm_memory_slot, hva_node[slots->node_idx]);
> +
> + if (kvm_slot_has_gmem(slot) && kvm_memslot_is_gmem_only(slot))
> + continue;
[Severity: Critical]
Can skipping guest_memfd-only memslots here leave writable SPTEs installed by
x86's kvm_mmu_prefetch_sptes() unzapped when the VMA at slot->userspace_addr
is unmapped?
While __kvm_mmu_faultin_pfn() resolves the primary fault from guest_memfd for
gmem-only memslots, the post-fault PTE prefetch paths (such as FNAME(fetch)()
-> FNAME(pte_prefetch)() for nested EPT/NPT or shadow paging) call
kvm_mmu_prefetch_sptes() for neighboring GFNs without checking
kvm_memslot_is_gmem_only():
arch/x86/kvm/mmu/mmu.c:kvm_mmu_prefetch_sptes() {
slot = gfn_to_memslot_dirty_bitmap(vcpu, gfn, access & ACC_WRITE_MASK);
if (!slot)
return false;
nr_pages = kvm_prefetch_pages(slot, gfn, pages, nr_pages);
if (nr_pages <= 0)
return false;
for (i = 0; i < nr_pages; i++, gfn++, sptep++) {
mmu_set_spte(vcpu, slot, sptep, access, gfn,
page_to_pfn(pages[i]), NULL);
...
kvm_release_page_dirty(pages[i]);
}
}
kvm_prefetch_pages() resolves PFNs from slot->userspace_addr via
get_user_pages_fast_only(), and kvm_mmu_prefetch_sptes() installs writable
SPTEs and drops the page references. With kvm_handle_hva_range() ignoring
gmem-only memslots, unmapping or reclaiming the VMA at slot->userspace_addr
will not zap those prefetched SPTEs, giving the guest a host page
use-after-free.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261113164000.467175-1-seanjc@google.com?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH v3] KVM: Skip gfn-based MMU notifier invalidations for guest_memfd-only memslots
2026-11-13 17:10 ` sashiko-bot
@ 2026-11-13 17:17 ` Sean Christopherson
2026-11-13 17:36 ` sashiko-bot
0 siblings, 1 reply; 5+ messages in thread
From: Sean Christopherson @ 2026-11-13 17:17 UTC (permalink / raw)
To: sashiko-reviews; +Cc: kvm
On Fri, Nov 13, 2026, sashiko-bot@kernel.org wrote:
> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > index cf4cb586f1407..599dea22afb81 100644
> > --- a/virt/kvm/kvm_main.c
> > +++ b/virt/kvm/kvm_main.c
> > @@ -601,6 +601,10 @@ static __always_inline kvm_mn_ret_t kvm_handle_hva_range(struct kvm *kvm,
> > unsigned long hva_start, hva_end;
> >
> > slot = container_of(node, struct kvm_memory_slot, hva_node[slots->node_idx]);
> > +
> > + if (kvm_slot_has_gmem(slot) && kvm_memslot_is_gmem_only(slot))
> > + continue;
>
> [Severity: Critical]
> Can skipping guest_memfd-only memslots here leave writable SPTEs installed by
> x86's kvm_mmu_prefetch_sptes() unzapped when the VMA at slot->userspace_addr
> is unmapped?
>
> While __kvm_mmu_faultin_pfn() resolves the primary fault from guest_memfd for
> gmem-only memslots, the post-fault PTE prefetch paths (such as FNAME(fetch)()
> -> FNAME(pte_prefetch)() for nested EPT/NPT or shadow paging) call
> kvm_mmu_prefetch_sptes() for neighboring GFNs without checking
> kvm_memslot_is_gmem_only():
>
> arch/x86/kvm/mmu/mmu.c:kvm_mmu_prefetch_sptes() {
> slot = gfn_to_memslot_dirty_bitmap(vcpu, gfn, access & ACC_WRITE_MASK);
> if (!slot)
> return false;
>
> nr_pages = kvm_prefetch_pages(slot, gfn, pages, nr_pages);
> if (nr_pages <= 0)
> return false;
>
> for (i = 0; i < nr_pages; i++, gfn++, sptep++) {
> mmu_set_spte(vcpu, slot, sptep, access, gfn,
> page_to_pfn(pages[i]), NULL);
> ...
> kvm_release_page_dirty(pages[i]);
> }
> }
>
> kvm_prefetch_pages() resolves PFNs from slot->userspace_addr via
> get_user_pages_fast_only(), and kvm_mmu_prefetch_sptes() installs writable
> SPTEs and drops the page references. With kvm_handle_hva_range() ignoring
> gmem-only memslots, unmapping or reclaiming the VMA at slot->userspace_addr
> will not zap those prefetched SPTEs, giving the guest a host page
> use-after-free.
Well fudge. That's a bug that needs to be fixed irrespective of this patch,
though it obviously needs to land first.
The TDP MMU doesn't support automatic prefetching, yet[*], and I'm planning on
using the "normal" fault flow for that support, so I think we can just disable
prefetching for gmem-only slots without negatively impacting any real-world
workload, and punt on proper support until someone cares, e.g.
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index f4b12d6aef55..a54196587235 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -3245,6 +3245,9 @@ static bool kvm_mmu_prefetch_sptes(struct kvm_vcpu *vcpu, gfn_t gfn, u64 *sptep,
if (!slot)
return false;
+ if (kvm_memslot_is_gmem_only(slot))
+ return false;
+
nr_pages = kvm_prefetch_pages(slot, gfn, pages, nr_pages);
if (nr_pages <= 0)
return false;
[*] https://lore.kernel.org/all/20261028202607.1844883-4-seanjc@google.com
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v3] KVM: Skip gfn-based MMU notifier invalidations for guest_memfd-only memslots
2026-11-13 17:17 ` Sean Christopherson
@ 2026-11-13 17:36 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-11-13 17:36 UTC (permalink / raw)
To: Sean Christopherson; +Cc: kvm
Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [High] KVM: x86/mmu: missing Signed-off-by trailer in commit message
- [Medium] KVM: x86/mmu: commit title and message do not match change in
kvm_mmu_prefetch_sptes()
- [Low] KVM: x86/mmu: missing Fixes trailer for commit f029f04ddbec
--
commit 0029f5853016e6378c3fb60ef0b654f4ef090476
Author: Sean Christopherson <seanjc@google.com>
> KVM: Skip gfn-based MMU notifier invalidations for guest_memfd-only memslots
>
> On Fri, Nov 13, 2026, sashiko-bot@kernel.org wrote:
> > > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > > index cf4cb586f1407..599dea22afb81 100644
> > > --- a/virt/kvm/kvm_main.c
> > > +++ b/virt/kvm/kvm_main.c
> > > @@ -601,6 +601,10 @@ static __always_inline kvm_mn_ret_t kvm_handle_hva_range(struct kvm *kvm,
> > > unsigned long hva_start, hva_end;
> > >
> > > slot = container_of(node, struct kvm_memory_slot, hva_node[slots->node_idx]);
> > > +
> > > + if (kvm_slot_has_gmem(slot) && kvm_memslot_is_gmem_only(slot))
> > > + continue;
> >
> > [Severity: Critical]
> > Can skipping guest_memfd-only memslots here leave writable SPTEs installed by
> > x86's kvm_mmu_prefetch_sptes() unzapped when the VMA at slot->userspace_addr
> > is unmapped?
> >
> > While __kvm_mmu_faultin_pfn() resolves the primary fault from guest_memfd for
> > gmem-only memslots, the post-fault PTE prefetch paths (such as FNAME(fetch)()
> > -> FNAME(pte_prefetch)() for nested EPT/NPT or shadow paging) call
> > kvm_mmu_prefetch_sptes() for neighboring GFNs without checking
> > kvm_memslot_is_gmem_only():
> >
> > arch/x86/kvm/mmu/mmu.c:kvm_mmu_prefetch_sptes() {
> > slot = gfn_to_memslot_dirty_bitmap(vcpu, gfn, access & ACC_WRITE_MASK);
> > if (!slot)
> > return false;
> >
> > nr_pages = kvm_prefetch_pages(slot, gfn, pages, nr_pages);
> > if (nr_pages <= 0)
> > return false;
> >
> > for (i = 0; i < nr_pages; i++, gfn++, sptep++) {
> > mmu_set_spte(vcpu, slot, sptep, access, gfn,
> > page_to_pfn(pages[i]), NULL);
> > ...
> > kvm_release_page_dirty(pages[i]);
> > }
> > }
> >
> > kvm_prefetch_pages() resolves PFNs from slot->userspace_addr via
> > get_user_pages_fast_only(), and kvm_mmu_prefetch_sptes() installs writable
> > SPTEs and drops the page references. With kvm_handle_hva_range() ignoring
> > gmem-only memslots, unmapping or reclaiming the VMA at slot->userspace_addr
> > will not zap those prefetched SPTEs, giving the guest a host page
> > use-after-free.
>
> Well fudge. That's a bug that needs to be fixed irrespective of this patch,
> though it obviously needs to land first.
>
> The TDP MMU doesn't support automatic prefetching, yet[*], and I'm planning on
> using the "normal" fault flow for that support, so I think we can just disable
> prefetching for gmem-only slots without negatively impacting any real-world
> workload, and punt on proper support until someone cares, e.g.
[Severity: High]
The commit message is missing a Signed-off-by trailer.
[Severity: Medium]
The commit subject and message are an unedited email reply to a different
patch and end mid-sentence, rather than describing the change in
kvm_mmu_prefetch_sptes() to skip SPTE prefetching for guest_memfd-only
memslots.
[Severity: Low]
Since commit f029f04ddbec ("KVM: x86/mmu: Handle guest page faults for
guest_memfd with shared memory") updated __kvm_mmu_faultin_pfn() to fault
in pages from guest_memfd for gmem-only memslots while leaving
kvm_mmu_prefetch_sptes() resolving PFNs from slot->userspace_addr, should
this include:
Fixes: f029f04ddbec ("KVM: x86/mmu: Handle guest page faults for guest_memfd with shared memory")
--
Sashiko AI review · https://sashiko.dev/#/patchset/avdGNbOO4562tk10@google.com?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3] KVM: Skip gfn-based MMU notifier invalidations for guest_memfd-only memslots
2026-11-13 16:40 [PATCH v3] KVM: Skip gfn-based MMU notifier invalidations for guest_memfd-only memslots Sean Christopherson
2026-11-13 17:10 ` sashiko-bot
@ 2026-11-13 17:25 ` Lorenzo Stoakes (ARM)
1 sibling, 0 replies; 5+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-11-13 17:25 UTC (permalink / raw)
To: Sean Christopherson
Cc: Paolo Bonzini, kvm, linux-kernel, Naveen N Rao, Alexandru Elisei
On Fri, Nov 13, 2026 at 08:40:00AM -0800, Sean Christopherson wrote:
> From: Alexandru Elisei <alexandru.elisei@arm.com>
>
> Don't invalidate gmem-only memslots when responding to MMU notifier
> invalidations, as the entire point of gmem-only memslots is so that KVM
> doesn't need a VMA to install mappings into KVM's MMU. Specifically,
> page faults are resolved by going straight to guest_memfd, using the gfn
> and the associated memslot's gmem.file. I.e. whether or not userspace
> happens to have valid mappings to the same gmem instance is irrelevant,
> as are any invalidations for those mappings.
>
> Note! The exception is KVM's gfn_to_pfn_cache implementation which isn't
> yet wired up to pull pfns directly from guest_memfd, i.e. still relies on
> userspace mappings/VMAs and thus need to be invalidated, e.g. to ensure KVM
> doesn't retain a kernel mapping+pointer to PRIVATE memory. However, as of
> commit da260bcb56fe ("KVM: pfncache: use a dedicated invalidation sequence
> for cache refresh"), GPC invalidation no longer relies on memslot lookups,
> because GPCs also support HVA-based mappings. I.e. KVM *must* be able to
> detect and handle relevant MMU notifier invalidations even if there is *no*
> memslot whatsoever.
>
> In addition to the obvious performance benefits, avoiding unnecessary and
> spurious SPTE zaps and TLB flushes will allow KVM to support features like
> ARM's Statistical Profiling Extension (SPE)[1] and x86's Secure AVIC[2],
> both of which rely on the pages *never* being unmapped from the stage-2
> page tables.
>
> Link: https://lore.kernel.org/all/20260903160623.315525-1-alexandru.elisei@arm.com [1]
> Link: https://lore.kernel.org/all/cover.1783490022.git.naveen@kernel.org [2]
> Cc: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> Cc: Naveen N Rao (AMD) <naveen@kernel.org>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> [sean: rewrite changelog to capture the new gpc behavior]
> Signed-off-by: Sean Christopherson <seanjc@google.com>
Thanks a lot for this Sean + Alex! :)
Though, having local AI do a review pass on it flagged an issue (don't worry my
own analysis - not pasting some slop here :).
I think actually this might need an additional change for x86, since it doesn't
have a gmem-only check for the shadow MMU PTE prefetch:
direct_map()
-> direct_pte_prefetch()
-> __direct_pte_prefetch()
-> direct_pte_prefetch_many()
-> kvm_mmu_prefetch_sptes()
-> kvm_prefetch_pages()
-> get_user_pages_fast_only()
And a VMM that's doing something broken (i.e. trying to take advantage of this
as a vulnerability), could then intentionally set up a gmem-only slot to point
at ordinary anon memory, munmap(), and have a UAF on the underlying folio due to
no MMU notifier invalidation.
Fix would be something like:
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index cf4cb586f140..76350dc55d8f 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3172,6 +3172,9 @@ int kvm_prefetch_pages(struct kvm_memory_slot *slot, gfn_t gfn,
unsigned long addr;
gfn_t entry = 0;
+ if (kvm_memslot_is_gmem_only(slot))
+ return 0;
+
addr = gfn_to_hva_many(slot, gfn, &entry);
if (kvm_is_error_hva(addr))
return -1;
> ---
>
> v3: v1, but with a different changelog.
>
> v2: https://lore.kernel.org/all/20260714160411.302386-1-alexandru.elisei@arm.com
>
> v1: https://lore.kernel.org/all/20260615155244.183044-1-alexandru.elisei@arm.com
>
> virt/kvm/kvm_main.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index cf4cb586f140..599dea22afb8 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -601,6 +601,10 @@ static __always_inline kvm_mn_ret_t kvm_handle_hva_range(struct kvm *kvm,
> unsigned long hva_start, hva_end;
>
> slot = container_of(node, struct kvm_memory_slot, hva_node[slots->node_idx]);
> +
> + if (kvm_slot_has_gmem(slot) && kvm_memslot_is_gmem_only(slot))
> + continue;
> +
> hva_start = max_t(unsigned long, range->start, slot->userspace_addr);
> hva_end = min_t(unsigned long, range->end,
> slot->userspace_addr + (slot->npages << PAGE_SHIFT));
>
> base-commit: d21eef2084a9af87ac2a783bc7c2b175ba114e4e
> --
> 2.56.1.703.gf848ed807c-goog
>
--
Cheers, Lorenzo
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-13 17:36 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-13 16:40 [PATCH v3] KVM: Skip gfn-based MMU notifier invalidations for guest_memfd-only memslots Sean Christopherson
2026-11-13 17:10 ` sashiko-bot
2026-11-13 17:17 ` Sean Christopherson
2026-11-13 17:36 ` sashiko-bot
2026-11-13 17:25 ` Lorenzo Stoakes (ARM)
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.