diff -r 81d41461e030 xen/arch/x86/mm/shadow/common.c --- a/xen/arch/x86/mm/shadow/common.c Fri Jan 18 13:54:44 2008 +0000 +++ b/xen/arch/x86/mm/shadow/common.c Tue Jan 22 09:40:05 2008 +0000 @@ -662,11 +662,14 @@ int shadow_write_guest_entry(struct vcpu * appropriately. Returns 0 if we page-faulted, 1 for success. */ { int failed; - shadow_lock(v->domain); + struct domain *d = v->domain; + shadow_lock(d); failed = __copy_to_user(p, &new, sizeof(new)); if ( failed != sizeof(new) ) - sh_validate_guest_entry(v, gmfn, p, sizeof(new)); - shadow_unlock(v->domain); + if ( sh_validate_guest_entry(v, gmfn, p, sizeof(new)) + & SHADOW_SET_FLUSH ) + flush_tlb_mask(d->domain_dirty_cpumask); + shadow_unlock(d); return (failed == 0); } @@ -678,13 +681,16 @@ int shadow_cmpxchg_guest_entry(struct vc * cmpxchg itself was successful. */ { int failed; + struct domain *d = v->domain; intpte_t t = *old; - shadow_lock(v->domain); + shadow_lock(d); failed = cmpxchg_user(p, t, new); if ( t == *old ) - sh_validate_guest_entry(v, gmfn, p, sizeof(new)); + if ( sh_validate_guest_entry(v, gmfn, p, sizeof(new)) + & SHADOW_SET_FLUSH ) + flush_tlb_mask(d->domain_dirty_cpumask); *old = t; - shadow_unlock(v->domain); + shadow_unlock(d); return (failed == 0); } diff -r 81d41461e030 xen/arch/x86/mm/shadow/multi.c --- a/xen/arch/x86/mm/shadow/multi.c Fri Jan 18 13:54:44 2008 +0000 +++ b/xen/arch/x86/mm/shadow/multi.c Tue Jan 22 09:42:20 2008 +0000 @@ -1888,11 +1888,28 @@ static shadow_l1e_t * shadow_get_and_cre fetch_type_t ft) { mfn_t sl2mfn; - shadow_l2e_t *sl2e; + shadow_l2e_t *sl2e, tmp; /* Get the l2e */ sl2e = shadow_get_and_create_l2e(v, gw, &sl2mfn, ft); if ( sl2e == NULL ) return NULL; + + if ( __copy_from_user(&tmp, sl2e, sizeof(tmp)) != 0 ) + { + local_flush_tlb(); + if ( __copy_from_user(&tmp, sl2e, sizeof(tmp)) != 0 ) + SHADOW_ERROR("Can't see the l2e, even with TLB flush"); + else + SHADOW_ERROR("TLB flush made the l2e readable!"); + show_page_walk((unsigned long) sl2e); + print_gw(gw); + show_page_walk(gw->va); + printk("v->arch.shadow_table[0] == %#lx\n", + pagetable_get_pfn(v->arch.shadow_table[0])); + printk("CR3 = %#lx\n", read_cr3()); + WARN(); + } + /* Install the sl1 in the l2e if it wasn't there or if we need to * re-do it to fix a PSE dirty bit. */ if ( shadow_l2e_get_flags(*sl2e) & _PAGE_PRESENT @@ -2835,6 +2852,25 @@ static int sh_page_fault(struct vcpu *v, return 0; } + { + shadow_l1e_t tmp; + if ( __copy_from_user(&tmp, ptr_sl1e, sizeof(tmp)) != 0 ) + { + local_flush_tlb(); + if ( __copy_from_user(&tmp, ptr_sl1e, sizeof(tmp)) != 0 ) + SHADOW_ERROR("Can't see the l1e, even with TLB flush"); + else + SHADOW_ERROR("TLB flush made the l1e readable!"); + show_page_walk((unsigned long) ptr_sl1e); + print_gw(&gw); + show_page_walk(gw.va); + printk("v->arch.shadow_table[0] == %#lx\n", + pagetable_get_pfn(v->arch.shadow_table[0])); + printk("CR3 = %#lx\n", read_cr3()); + WARN(); + } + } + /* Calculate the shadow entry and write it */ l1e_propagate_from_guest(v, (gw.l1e) ? gw.l1e : &gw.eff_l1e, gw.l1mfn, gmfn, &sl1e, ft, mmio);