]> www.infradead.org Git - users/willy/xarray.git/commitdiff
KVM: x86/mmu: Add a field to control memslot rmap allocation
authorBen Gardon <bgardon@google.com>
Tue, 18 May 2021 17:34:12 +0000 (10:34 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 17 Jun 2021 17:09:26 +0000 (13:09 -0400)
Add a field to control whether new memslots should have rmaps allocated
for them. As of this change, it's not safe to skip allocating rmaps, so
the field is always set to allocate rmaps. Future changes will make it
safe to operate without rmaps, using the TDP MMU. Then further changes
will allow the rmaps to be allocated lazily when needed for nested
oprtation.

No functional change expected.

Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Ben Gardon <bgardon@google.com>
Message-Id: <20210518173414.450044-6-bgardon@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/x86.c

index 9c7ced0e31718976c5744ea6c8d366a7a9c7882a..11798a9ff3e9df2c1336f485cbccb27491273734 100644 (file)
@@ -1124,6 +1124,12 @@ struct kvm_arch {
         */
        spinlock_t tdp_mmu_pages_lock;
 #endif /* CONFIG_X86_64 */
+
+       /*
+        * If set, rmaps have been allocated for all memslots and should be
+        * allocated for any newly created or modified memslots.
+        */
+       bool memslots_have_rmaps;
 };
 
 struct kvm_vm_stat {
index 66e4d096fe05a10c1edeee06f78176c1eae27154..64b3ee7ea4672eff660a4294cab3f75992032211 100644 (file)
@@ -5511,6 +5511,8 @@ void kvm_mmu_init_vm(struct kvm *kvm)
 
        kvm_mmu_init_tdp_mmu(kvm);
 
+       kvm->arch.memslots_have_rmaps = true;
+
        node->track_write = kvm_mmu_pte_write;
        node->track_flush_slot = kvm_mmu_invalidate_zap_pages_in_memslot;
        kvm_page_track_register_notifier(kvm, node);
index 5f66a5972d8295a6419432dadfe3e5004d27afd8..11637fb10360895acce0bd23e0f679fb1bcf6cf9 100644 (file)
@@ -10962,7 +10962,8 @@ static int memslot_rmap_alloc(struct kvm_memory_slot *slot,
        return 0;
 }
 
-static int kvm_alloc_memslot_metadata(struct kvm_memory_slot *slot,
+static int kvm_alloc_memslot_metadata(struct kvm *kvm,
+                                     struct kvm_memory_slot *slot,
                                      unsigned long npages)
 {
        int i, r;
@@ -10974,9 +10975,11 @@ static int kvm_alloc_memslot_metadata(struct kvm_memory_slot *slot,
         */
        memset(&slot->arch, 0, sizeof(slot->arch));
 
-       r = memslot_rmap_alloc(slot, npages);
-       if (r)
-               return r;
+       if (kvm->arch.memslots_have_rmaps) {
+               r = memslot_rmap_alloc(slot, npages);
+               if (r)
+                       return r;
+       }
 
        for (i = 1; i < KVM_NR_PAGE_SIZES; ++i) {
                struct kvm_lpage_info *linfo;
@@ -11047,7 +11050,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
                                enum kvm_mr_change change)
 {
        if (change == KVM_MR_CREATE || change == KVM_MR_MOVE)
-               return kvm_alloc_memslot_metadata(memslot,
+               return kvm_alloc_memslot_metadata(kvm, memslot,
                                                  mem->memory_size >> PAGE_SHIFT);
        return 0;
 }