Skip to content

Commit fb6f779

Browse files
committed
KVM: x86/mmu: Zap shared-only memslots when private attribute changes
Zap all relevant memslots, including shared-only memslots, if the private memory attribute is being changed. If userspace converts a range to private, KVM must zap shared SPTEs to prevent the guest from accessing the memory as shared. If userspace converts a range to shared, zapping SPTEs for shared-only memslots isn't strictly necessary, but doing so ensures that KVM will install a hugepage mapping if possible, e.g. if a 2MiB range that was mixed is converted to be 100% shared. Fixes: dcde045 ("KVM: x86/mmu: Handle page fault for private memory") Link: https://lore.kernel.org/r/20230921203331.3746712-9-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 26cf445 commit fb6f779

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

arch/x86/kvm/mmu/mmu.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7259,10 +7259,17 @@ bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm,
72597259
struct kvm_gfn_range *range)
72607260
{
72617261
/*
7262-
* KVM x86 currently only supports KVM_MEMORY_ATTRIBUTE_PRIVATE, skip
7263-
* the slot if the slot will never consume the PRIVATE attribute.
7262+
* Zap SPTEs even if the slot can't be mapped PRIVATE. KVM x86 only
7263+
* supports KVM_MEMORY_ATTRIBUTE_PRIVATE, and so it *seems* like KVM
7264+
* can simply ignore such slots. But if userspace is making memory
7265+
* PRIVATE, then KVM must prevent the guest from accessing the memory
7266+
* as shared. And if userspace is making memory SHARED and this point
7267+
* is reached, then at least one page within the range was previously
7268+
* PRIVATE, i.e. the slot's possible hugepage ranges are changing.
7269+
* Zapping SPTEs in this case ensures KVM will reassess whether or not
7270+
* a hugepage can be used for affected ranges.
72647271
*/
7265-
if (!kvm_slot_can_be_private(range->slot))
7272+
if (WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm)))
72667273
return false;
72677274

72687275
return kvm_mmu_unmap_gfn_range(kvm, range);

0 commit comments

Comments
 (0)