KVM: VMX: update live TR selector if it changes in real mode
[pandora-kernel.git] / arch / x86 / kvm / mmu.c
index f02b8ed..b6a9963 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);
 }
@@ -3583,7 +3587,7 @@ static int mmu_shrink(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask)
        if (nr_to_scan == 0)
                goto out;
 
-       spin_lock(&kvm_lock);
+       raw_spin_lock(&kvm_lock);
 
        list_for_each_entry(kvm, &vm_list, vm_list) {
                int idx, freed_pages;
@@ -3606,7 +3610,7 @@ static int mmu_shrink(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask)
        if (kvm_freed)
                list_move_tail(&kvm_freed->vm_list, &vm_list);
 
-       spin_unlock(&kvm_lock);
+       raw_spin_unlock(&kvm_lock);
 
 out:
        return percpu_counter_read_positive(&kvm_total_used_mmu_pages);