diff -r 3e3048cab2ae -r ad3bc452a6f8 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Tue Aug 9 04:24:42 2005 +++ b/xen/arch/x86/mm.c Tue Aug 9 04:38:09 2005 @@ -2692,7 +2692,6 @@ unsigned int modified; #if defined(__x86_64__) struct vcpu *v = current; - /* If in user mode, switch to kernel mode just to read LDT mapping. */ extern void toggle_guest_mode(struct vcpu *); int user_mode = !(v->arch.flags & TF_kernel_mode); #endif @@ -2700,7 +2699,17 @@ ASSERT(!shadow_mode_enabled(d)); if ( unlikely(d->arch.ptwr[which].vcpu != current) ) +#if defined(__x86_64__) + /* + * The processor must have been running in kernel mode at + * ptwr_do_fault(). Don't use write_ptbase() because it will + * affect monitor_table of the (other) processor. + */ + write_cr3(pagetable_get_paddr( + d->arch.ptwr[which].vcpu->arch.guest_table)); +#else write_ptbase(d->arch.ptwr[which].vcpu); +#endif else TOGGLE_MODE(); @@ -2922,6 +2931,11 @@ page &= PAGE_MASK; page = ((unsigned long *) __va(page))[l2_table_offset((unsigned long)pl2e)]; + if ( !(page & _PAGE_PRESENT) ) + return -1; + + page &= PAGE_MASK; + page = ((unsigned long *) __va(page))[l1_table_offset((unsigned long)pl2e)]; if ( !(page & _PAGE_PRESENT) ) return -1;