KVM: MMU: fix kvm_mmu_slot_remove_write_access dropping intermediate W bits
authorXiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Fri, 4 Mar 2011 10:56:41 +0000 (18:56 +0800)
committerMarcelo Tosatti <mtosatti@redhat.com>
Thu, 17 Mar 2011 16:08:32 +0000 (13:08 -0300)
Only remove write access in the last sptes.

Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/x86/kvm/mmu.c

index b6a9963400a7416db07e13c285c005f8cc4d6a2b..b9bf016d7f0fdc351b4b736c997b6a7cae435463 100644 (file)
@@ -3540,12 +3540,17 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
 
                pt = sp->spt;
                for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
-                       if (sp->role.level != PT_PAGE_TABLE_LEVEL
-                           && is_large_pte(pt[i])) {
+                       if (!is_shadow_present_pte(pt[i]) ||
+                             !is_last_spte(pt[i], sp->role.level))
+                               continue;
+
+                       if (is_large_pte(pt[i])) {
                                drop_spte(kvm, &pt[i],
                                          shadow_trap_nonpresent_pte);
                                --kvm->stat.lpages;
+                               continue;
                        }
+
                        /* avoid RMW */
                        if (is_writable_pte(pt[i]))
                                update_spte(&pt[i], pt[i] & ~PT_WRITABLE_MASK);