KVM: Minor memory slot optimization
[linux-3.10.git] / virt / kvm / kvm_main.c
index 9a56ca2..4c8c065 100644 (file)
@@ -716,7 +716,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
        unsigned long npages;
        struct kvm_memory_slot *memslot, *slot;
        struct kvm_memory_slot old, new;
-       struct kvm_memslots *slots, *old_memslots;
+       struct kvm_memslots *slots = NULL, *old_memslots;
 
        r = check_memory_region_flags(mem);
        if (r)
@@ -832,18 +832,25 @@ int __kvm_set_memory_region(struct kvm *kvm,
                 *      - kvm_is_visible_gfn (mmu_check_roots)
                 */
                kvm_arch_flush_shadow_memslot(kvm, slot);
-               kfree(old_memslots);
+               slots = old_memslots;
        }
 
        r = kvm_arch_prepare_memory_region(kvm, &new, old, mem, user_alloc);
        if (r)
-               goto out_free;
+               goto out_slots;
 
        r = -ENOMEM;
-       slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots),
-                       GFP_KERNEL);
-       if (!slots)
-               goto out_free;
+       /*
+        * We can re-use the old_memslots from above, the only difference
+        * from the currently installed memslots is the invalid flag.  This
+        * will get overwritten by update_memslots anyway.
+        */
+       if (!slots) {
+               slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots),
+                               GFP_KERNEL);
+               if (!slots)
+                       goto out_free;
+       }
 
        /* map new memory slot into the iommu */
        if (npages) {