[PATCH 1/4] KVM: x86/mmu: Rework gfn_to_memslot_dirty_bitmap() into auto-prefetch helper
From: Sean Christopherson
Date: Wed Oct 28 2026 - 17:25:09 EST
Rework gfn_to_memslot_dirty_bitmap() into a more generic helper that takes
a memslot to check if said a memslot is suitable for auto-prefetch. "auto"
in this case means prefetch that's initiated by KVM without a corresponding
action from either the host or userspace. Taking a memslot will allow
using the helper for other prefetch flows where KVM already has the memslot,
i.e. will allow reusing the dirty logging logic in particular, without
introducing potential TOCTOU bugs.
Return error numbers that align with KVM's uAPI for prefaulting so that KVM
is consistent in the unlikely case prefaulting ever ends up being subject
to the same restrictions (prefaulting isn't "auto" in that it's an explicit
request/command from userspace).
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
arch/x86/kvm/mmu/mmu.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 5a2cc6a17a9b..393feeaddfb1 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -872,19 +872,19 @@ static void unaccount_nx_huge_page(struct kvm *kvm, struct kvm_mmu_page *sp,
untrack_possible_nx_huge_page(kvm, sp, mmu_type);
}
-static struct kvm_memory_slot *gfn_to_memslot_dirty_bitmap(struct kvm_vcpu *vcpu,
- gfn_t gfn,
- bool no_dirty_log)
+static int kvm_check_memslot_usable_for_auto_prefetch(struct kvm_memory_slot *slot,
+ unsigned int access)
{
- struct kvm_memory_slot *slot;
+ if (!slot)
+ return -ENOENT;
- slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
- if (!slot || slot->flags & KVM_MEMSLOT_INVALID)
- return NULL;
- if (no_dirty_log && kvm_slot_dirty_track_enabled(slot))
- return NULL;
+ if (slot->flags & KVM_MEMSLOT_INVALID)
+ return -EAGAIN;
- return slot;
+ if ((access & ACC_WRITE_MASK) && kvm_slot_dirty_track_enabled(slot))
+ return -EACCES;
+
+ return 0;
}
/*
@@ -3231,8 +3231,8 @@ static bool kvm_mmu_prefetch_sptes(struct kvm_vcpu *vcpu, gfn_t gfn, u64 *sptep,
if (WARN_ON_ONCE(nr_pages > PTE_PREFETCH_NUM))
return false;
- slot = gfn_to_memslot_dirty_bitmap(vcpu, gfn, access & ACC_WRITE_MASK);
- if (!slot)
+ slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
+ if (kvm_check_memslot_usable_for_auto_prefetch(slot, access))
return false;
nr_pages = kvm_prefetch_pages(slot, gfn, pages, nr_pages);
--
2.56.0.313.g2479322e68-goog