[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN] Work around a Linux PAE issue where it sometimes sets
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 28e9bba0342574ff971d1246f74d24009c897b36 # Parent d40dfbef8e5d37f89de3654843c1aefdc6462bad [XEN] Work around a Linux PAE issue where it sometimes sets the top half of a PTE without first clearing the bottom half (to make the PTE not-present) hence the PTE fails validation checks. Also remove dead revalidation function after shadow2 checkin. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/mm.c | 75 +++++++++++++---------------------------------- xen/include/asm-x86/mm.h | 1 2 files changed, 21 insertions(+), 55 deletions(-) diff -r d40dfbef8e5d -r 28e9bba03425 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Fri Aug 18 15:22:54 2006 +0100 +++ b/xen/arch/x86/mm.c Fri Aug 18 15:24:10 2006 +0100 @@ -3050,56 +3050,6 @@ long arch_memory_op(int op, XEN_GUEST_HA * Writable Pagetables */ -/* Re-validate a given p.t. page, given its prior snapshot */ -int revalidate_l1( - struct domain *d, l1_pgentry_t *l1page, l1_pgentry_t *snapshot) -{ - l1_pgentry_t ol1e, nl1e; - int modified = 0, i; - - for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) - { - ol1e = snapshot[i]; - nl1e = l1page[i]; - - if ( likely(l1e_get_intpte(ol1e) == l1e_get_intpte(nl1e)) ) - continue; - - /* Update number of entries modified. */ - modified++; - - /* - * Fast path for PTEs that have merely been write-protected - * (e.g., during a Unix fork()). A strict reduction in privilege. - */ - if ( likely(l1e_get_intpte(ol1e) == (l1e_get_intpte(nl1e)|_PAGE_RW)) ) - { - if ( likely(l1e_get_flags(nl1e) & _PAGE_PRESENT) ) - put_page_type(mfn_to_page(l1e_get_pfn(nl1e))); - continue; - } - - if ( unlikely(!get_page_from_l1e(nl1e, d)) ) - { - /* - * Make the remaining p.t's consistent before crashing, so the - * reference counts are correct. - */ - memcpy(&l1page[i], &snapshot[i], - (L1_PAGETABLE_ENTRIES - i) * sizeof(l1_pgentry_t)); - - /* Crash the offending domain. */ - MEM_LOG("ptwr: Could not revalidate l1 page"); - domain_crash(d); - break; - } - - put_page_from_l1e(ol1e, d); - } - - return modified; -} - static int ptwr_emulated_update( unsigned long addr, paddr_t old, @@ -3167,10 +3117,27 @@ static int ptwr_emulated_update( nl1e = l1e_from_intpte(val); if ( unlikely(!get_page_from_l1e(nl1e, d)) ) { - MEM_LOG("ptwr_emulate: could not get_page_from_l1e()"); - return X86EMUL_UNHANDLEABLE; - } - + if ( (CONFIG_PAGING_LEVELS == 3) && + (bytes == 4) && + !do_cmpxchg && + (l1e_get_flags(nl1e) & _PAGE_PRESENT) ) + { + /* + * If this is a half-write to a PAE PTE then we assume that the + * guest has simply got the two writes the wrong way round. We + * zap the PRESENT bit on the assumption the bottom half will be + * written immediately after we return to the guest. + */ + MEM_LOG("ptwr_emulate: fixing up invalid PAE PTE %"PRIpte"\n", + l1e_get_intpte(nl1e)); + l1e_remove_flags(nl1e, _PAGE_PRESENT); + } + else + { + MEM_LOG("ptwr_emulate: could not get_page_from_l1e()"); + return X86EMUL_UNHANDLEABLE; + } + } /* Checked successfully: do the update (write or cmpxchg). */ pl1e = map_domain_page(page_to_mfn(page)); diff -r d40dfbef8e5d -r 28e9bba03425 xen/include/asm-x86/mm.h --- a/xen/include/asm-x86/mm.h Fri Aug 18 15:22:54 2006 +0100 +++ b/xen/include/asm-x86/mm.h Fri Aug 18 15:24:10 2006 +0100 @@ -397,7 +397,6 @@ void memguard_guard_stack(void *p); int ptwr_do_page_fault(struct domain *, unsigned long, struct cpu_user_regs *); -int revalidate_l1(struct domain *, l1_pgentry_t *, l1_pgentry_t *); int audit_adjust_pgtables(struct domain *d, int dir, int noisy); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |