Replace mfn_to_page(lXe_get_pfn()) by lXe_get_page(). However, what I got surprised by while looking for all of these is that ptwr_emulated_update() uses gmfn_to_mfn() on the pte loaded from the emulation context, while ptwr_do_page_fault() doesn't on the pte stored into that context. Shouldn't these two be symmetric? Index: 2007-02-20/xen/arch/x86/mm.c =================================================================== --- 2007-02-20.orig/xen/arch/x86/mm.c 2007-02-20 10:55:57.000000000 +0100 +++ 2007-02-20/xen/arch/x86/mm.c 2007-02-20 10:56:12.000000000 +0100 @@ -794,7 +794,7 @@ static void put_page_from_l2e(l2_pgentry { if ( (l2e_get_flags(l2e) & _PAGE_PRESENT) && (l2e_get_pfn(l2e) != pfn) ) - put_page_and_type(mfn_to_page(l2e_get_pfn(l2e))); + put_page_and_type(l2e_get_page(l2e)); } @@ -803,7 +803,7 @@ static void put_page_from_l3e(l3_pgentry { if ( (l3e_get_flags(l3e) & _PAGE_PRESENT) && (l3e_get_pfn(l3e) != pfn) ) - put_page_and_type(mfn_to_page(l3e_get_pfn(l3e))); + put_page_and_type(l3e_get_page(l3e)); } #endif @@ -812,7 +812,7 @@ static void put_page_from_l4e(l4_pgentry { if ( (l4e_get_flags(l4e) & _PAGE_PRESENT) && (l4e_get_pfn(l4e) != pfn) ) - put_page_and_type(mfn_to_page(l4e_get_pfn(l4e))); + put_page_and_type(l4e_get_page(l4e)); } #endif @@ -3369,7 +3369,6 @@ int ptwr_do_page_fault(struct vcpu *v, u struct cpu_user_regs *regs) { struct domain *d = v->domain; - unsigned long pfn; struct page_info *page; l1_pgentry_t pte; struct ptwr_emulate_ctxt ptwr_ctxt; @@ -3383,8 +3382,7 @@ int ptwr_do_page_fault(struct vcpu *v, u guest_get_eff_l1e(v, addr, &pte); if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) ) goto bail; - pfn = l1e_get_pfn(pte); - page = mfn_to_page(pfn); + page = l1e_get_page(pte); /* We are looking only for read-only mappings of p.t. pages. */ if ( ((l1e_get_flags(pte) & (_PAGE_PRESENT|_PAGE_RW)) != _PAGE_PRESENT) ||