[XEN] Fix early-unshadow detection for 3- or 4-level guest pagetables.
authorGeorge Dunlap <dunlapg@umich.edu>
Tue, 16 Jan 2007 19:04:12 +0000 (14:04 -0500)
committerGeorge Dunlap <dunlapg@umich.edu>
Tue, 16 Jan 2007 19:04:12 +0000 (14:04 -0500)
Early-unshadow will unshadow whenever 2 zero values are written
to the same page; for PAE, one PTE takes 2 writes.  Only check
for the early unshadow when writing the low half of the PTE.

xen/arch/x86/mm/shadow/multi.c
xen/arch/x86/mm/shadow/private.h

index e040e60e7145f13d8df6fb0227dd567d8fdad543..0546cb1a66eae796f26a4e3f534d46c380b2f23a 100644 (file)
@@ -3944,7 +3944,7 @@ sh_x86_emulate_write(struct vcpu *v, unsigned long vaddr, void *src,
     if ( !skip ) sh_validate_guest_pt_write(v, mfn, addr, bytes);
 
     /* If we are writing zeros to this page, might want to unshadow */
-    if ( likely(bytes >= 4) && (*(u32 *)addr == 0) )
+    if ( likely(bytes >= 4) && (*(u32 *)addr == 0) && is_lo_pte(vaddr) )
         check_for_early_unshadow(v, mfn);
 
     sh_unmap_domain_page(addr);
@@ -3996,7 +3996,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, unsigned long vaddr,
                   vaddr, prev, old, new, *(unsigned long *)addr, bytes);
 
     /* If we are writing zeros to this page, might want to unshadow */
-    if ( likely(bytes >= 4) && (*(u32 *)addr == 0) )
+    if ( likely(bytes >= 4) && (*(u32 *)addr == 0) && is_lo_pte(vaddr) )
         check_for_early_unshadow(v, mfn);
 
     sh_unmap_domain_page(addr);
index 913fa437705f6aa0983793378b8f9a53a44ceae7..21d78eb2dec698208cfd453a8da910b0220adb7b 100644 (file)
@@ -427,6 +427,11 @@ extern int sh_remove_write_access(struct vcpu *v, mfn_t readonly_mfn,
 #undef mfn_valid
 #define mfn_valid(_mfn) (mfn_x(_mfn) < max_page)
 
+#if GUEST_PAGING_LEVELS >= 3
+# define is_lo_pte(_vaddr) (((_vaddr)&0x4)==0)
+#else
+# define is_lo_pte(_vaddr) (1)
+#endif
 
 static inline int
 sh_mfn_is_a_page_table(mfn_t gmfn)