Messages in this thread | | | Date | Wed, 27 Sep 2023 14:01:59 +0800 | Subject | Re: [PATCH 07/13] KVM: x86/mmu: Track PRIVATE impact on hugepage mappings for all memslots | From | Binbin Wu <> |
| |
On 9/22/2023 4:33 AM, Sean Christopherson wrote: > Track the effects of private attributes on potential hugepage mappings if > the VM supports private memory, i.e. even if the target memslot can only > ever be mapped shared. If userspace configures a chunk of memory as > private, KVM must not allow that memory to be mapped shared regardless of > whether or not the *current* memslot can be mapped private. E.g. if the > guest accesses a private range using a shared memslot, then KVM must exit > to userspace. How does usersapce handle this case? IIRC, in gmem v12 patch set, it says a memslot can not be convert to private from shared. So, userspace should delete the old memslot and and a new one?
> Fixes: 5bb0b4e162d1 ("KVM: x86: Disallow hugepages when memory attributes are mixed") > Signed-off-by: Sean Christopherson <seanjc@google.com> > --- > arch/x86/kvm/mmu/mmu.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c > index 269d4dc47c98..148931cf9dba 100644 > --- a/arch/x86/kvm/mmu/mmu.c > +++ b/arch/x86/kvm/mmu/mmu.c > @@ -7314,10 +7314,12 @@ bool kvm_arch_post_set_memory_attributes(struct kvm *kvm, > lockdep_assert_held(&kvm->slots_lock); > > /* > - * KVM x86 currently only supports KVM_MEMORY_ATTRIBUTE_PRIVATE, skip > - * the slot if the slot will never consume the PRIVATE attribute. > + * Calculate which ranges can be mapped with hugepages even if the slot > + * can't map memory PRIVATE. KVM mustn't create a SHARED hugepage over > + * a range that has PRIVATE GFNs, and conversely converting a range to > + * SHARED may now allow hugepages. > */ > - if (!kvm_slot_can_be_private(slot)) > + if (WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm))) > return false; > > /* > @@ -7372,7 +7374,7 @@ void kvm_mmu_init_memslot_memory_attributes(struct kvm *kvm, > { > int level; > > - if (!kvm_slot_can_be_private(slot)) > + if (!kvm_arch_has_private_mem(kvm)) > return; > > for (level = PG_LEVEL_2M; level <= KVM_MAX_HUGEPAGE_LEVEL; level++) {
| |