KVM: MMU: Don't flush shadow when enabling dirty tracking
authorAvi Kivity <avi@redhat.com>
Mon, 27 Dec 2010 10:08:45 +0000 (12:08 +0200)
committerMarcelo Tosatti <mtosatti@redhat.com>
Thu, 17 Mar 2011 16:08:24 +0000 (13:08 -0300)
Instead, drop large mappings, which were the reason we dropped shadow.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
arch/x86/kvm/mmu.c
virt/kvm/kvm_main.c

index f02b8ed..ccacf0b 100644 (file)
@@ -3538,14 +3538,18 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
                if (!test_bit(slot, sp->slot_bitmap))
                        continue;
 
-               if (sp->role.level != PT_PAGE_TABLE_LEVEL)
-                       continue;
-
                pt = sp->spt;
-               for (i = 0; i < PT64_ENT_PER_PAGE; ++i)
+               for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
+                       if (sp->role.level != PT_PAGE_TABLE_LEVEL
+                           && is_large_pte(pt[i])) {
+                               drop_spte(kvm, &pt[i],
+                                         shadow_trap_nonpresent_pte);
+                               --kvm->stat.lpages;
+                       }
                        /* avoid RMW */
                        if (is_writable_pte(pt[i]))
                                update_spte(&pt[i], pt[i] & ~PT_WRITABLE_MASK);
+               }
        }
        kvm_flush_remote_tlbs(kvm);
 }
index f29abeb..a3a8f5f 100644 (file)
@@ -621,7 +621,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
                            struct kvm_userspace_memory_region *mem,
                            int user_alloc)
 {
-       int r, flush_shadow = 0;
+       int r;
        gfn_t base_gfn;
        unsigned long npages;
        unsigned long i;
@@ -741,8 +741,6 @@ skip_lpage:
                if (kvm_create_dirty_bitmap(&new) < 0)
                        goto out_free;
                /* destroy any largepage mappings for dirty tracking */
-               if (old.npages)
-                       flush_shadow = 1;
        }
 #else  /* not defined CONFIG_S390 */
        new.user_alloc = user_alloc;
@@ -813,9 +811,6 @@ skip_lpage:
        kvm_free_physmem_slot(&old, &new);
        kfree(old_memslots);
 
-       if (flush_shadow)
-               kvm_arch_flush_shadow(kvm);
-
        return 0;
 
 out_free: