From: George Dunlap Date: Tue, 16 Jan 2007 19:04:12 +0000 (-0500) Subject: [XEN] Fix early-unshadow detection for 3- or 4-level guest pagetables. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15396^2~14 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=a086d29d0e360e83eafed55959c3e4e2a1340a38;p=xen.git [XEN] Fix early-unshadow detection for 3- or 4-level guest pagetables. 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. --- diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index e040e60e71..0546cb1a66 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -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); diff --git a/xen/arch/x86/mm/shadow/private.h b/xen/arch/x86/mm/shadow/private.h index 913fa43770..21d78eb2de 100644 --- a/xen/arch/x86/mm/shadow/private.h +++ b/xen/arch/x86/mm/shadow/private.h @@ -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)