diff -r 65c24b33082a xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Wed Dec 17 12:59:28 2008 +0000 +++ b/xen/arch/x86/hvm/svm/svm.c Wed Dec 17 12:59:50 2008 +0000 @@ -888,7 +888,7 @@ * If this GFN is emulated MMIO or marked as read-only, pass the fault * to the mmio handler. */ - mfn = gfn_to_mfn_current(gfn, &p2mt); + mfn = gfn_to_mfn_type_current(gfn, &p2mt, p2m_guest); if ( (p2mt == p2m_mmio_dm) || (p2mt == p2m_ram_ro) ) { if ( !handle_mmio() ) diff -r 65c24b33082a xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Wed Dec 17 12:59:28 2008 +0000 +++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Dec 17 12:59:50 2008 +0000 @@ -2099,9 +2099,9 @@ mfn_t mfn; p2m_type_t t; - mfn = gfn_to_mfn(d, gfn, &t); + mfn = gfn_to_mfn_guest(d, gfn, &t); - /* There are two legitimate reasons for taking an EPT violation. + /* There are three legitimate reasons for taking an EPT violation. * One is a guest access to MMIO space. */ if ( gla_validity == EPT_GLA_VALIDITY_MATCH && p2m_is_mmio(t) ) { @@ -2109,15 +2109,18 @@ return; } - /* The other is log-dirty mode, writing to a read-only page */ - if ( paging_mode_log_dirty(d) - && (gla_validity == EPT_GLA_VALIDITY_MATCH - || gla_validity == EPT_GLA_VALIDITY_GPT_WALK) + /* The second is log-dirty mode, writing to a read-only page; + * The third is populating a populate-on-demand page. */ + if ( (gla_validity == EPT_GLA_VALIDITY_MATCH + || gla_validity == EPT_GLA_VALIDITY_GPT_WALK) && p2m_is_ram(t) && (t != p2m_ram_ro) ) { - paging_mark_dirty(d, mfn_x(mfn)); - p2m_change_type(d, gfn, p2m_ram_logdirty, p2m_ram_rw); - flush_tlb_mask(d->domain_dirty_cpumask); + if ( paging_mode_log_dirty(d) ) + { + paging_mark_dirty(d, mfn_x(mfn)); + p2m_change_type(d, gfn, p2m_ram_logdirty, p2m_ram_rw); + flush_tlb_mask(d->domain_dirty_cpumask); + } return; } diff -r 65c24b33082a xen/arch/x86/mm/p2m.c --- a/xen/arch/x86/mm/p2m.c Wed Dec 17 12:59:28 2008 +0000 +++ b/xen/arch/x86/mm/p2m.c Wed Dec 17 12:59:50 2008 +0000 @@ -734,7 +734,7 @@ continue; } - p2mfn = gfn_to_mfn_foreign(d, gfn, &type); + p2mfn = gfn_to_mfn_type_foreign(d, gfn, &type, p2m_query); if ( mfn_x(p2mfn) != mfn ) { mpbad++; @@ -752,7 +752,7 @@ if ( test_linear && (gfn <= d->arch.p2m->max_mapped_pfn) ) { - lp2mfn = mfn_x(gfn_to_mfn(d, gfn, &type)); + lp2mfn = mfn_x(gfn_to_mfn_query(d, gfn, &type)); if ( lp2mfn != mfn_x(p2mfn) ) { P2M_PRINTK("linear mismatch gfn %#lx -> mfn %#lx " @@ -963,7 +963,7 @@ /* First, remove m->p mappings for existing p->m mappings */ for ( i = 0; i < (1UL << page_order); i++ ) { - omfn = gfn_to_mfn(d, gfn + i, &ot); + omfn = gfn_to_mfn_query(d, gfn + i, &ot); if ( p2m_is_ram(ot) ) { ASSERT(mfn_valid(omfn)); @@ -988,7 +988,7 @@ * address */ P2M_DEBUG("aliased! mfn=%#lx, old gfn=%#lx, new gfn=%#lx\n", mfn + i, ogfn, gfn + i); - omfn = gfn_to_mfn(d, ogfn, &ot); + omfn = gfn_to_mfn_query(d, ogfn, &ot); if ( p2m_is_ram(ot) ) { ASSERT(mfn_valid(omfn)); @@ -1157,7 +1157,7 @@ if ( !paging_mode_translate(d) ) return 0; - omfn = gfn_to_mfn(d, gfn, &ot); + omfn = gfn_to_mfn_query(d, gfn, &ot); if ( p2m_is_ram(ot) ) { ASSERT(mfn_valid(omfn)); diff -r 65c24b33082a xen/arch/x86/mm/shadow/multi.c --- a/xen/arch/x86/mm/shadow/multi.c Wed Dec 17 12:59:28 2008 +0000 +++ b/xen/arch/x86/mm/shadow/multi.c Wed Dec 17 12:59:50 2008 +0000 @@ -2170,7 +2170,7 @@ if ( guest_l4e_get_flags(new_gl4e) & _PAGE_PRESENT ) { gfn_t gl3gfn = guest_l4e_get_gfn(new_gl4e); - mfn_t gl3mfn = gfn_to_mfn(d, gl3gfn, &p2mt); + mfn_t gl3mfn = gfn_to_mfn_query(d, gl3gfn, &p2mt); if ( p2m_is_ram(p2mt) ) sl3mfn = get_shadow_status(v, gl3mfn, SH_type_l3_shadow); else @@ -2227,7 +2227,7 @@ if ( guest_l3e_get_flags(new_gl3e) & _PAGE_PRESENT ) { gfn_t gl2gfn = guest_l3e_get_gfn(new_gl3e); - mfn_t gl2mfn = gfn_to_mfn(v->domain, gl2gfn, &p2mt); + mfn_t gl2mfn = gfn_to_mfn_query(v->domain, gl2gfn, &p2mt); if ( p2m_is_ram(p2mt) ) sl2mfn = get_shadow_status(v, gl2mfn, SH_type_l2_shadow); else @@ -2276,7 +2276,7 @@ } else { - mfn_t gl1mfn = gfn_to_mfn(v->domain, gl1gfn, &p2mt); + mfn_t gl1mfn = gfn_to_mfn_query(v->domain, gl1gfn, &p2mt); if ( p2m_is_ram(p2mt) ) sl1mfn = get_shadow_status(v, gl1mfn, SH_type_l1_shadow); else @@ -2346,7 +2346,7 @@ perfc_incr(shadow_validate_gl1e_calls); gfn = guest_l1e_get_gfn(new_gl1e); - gmfn = gfn_to_mfn(v->domain, gfn, &p2mt); + gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt); l1e_propagate_from_guest(v, new_gl1e, gmfn, &new_sl1e, ft_prefetch, p2mt); result |= shadow_set_l1e(v, sl1p, new_sl1e, sl1mfn); @@ -2406,7 +2406,7 @@ shadow_l1e_t nsl1e; gfn = guest_l1e_get_gfn(gl1e); - gmfn = gfn_to_mfn(v->domain, gfn, &p2mt); + gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt); l1e_propagate_from_guest(v, gl1e, gmfn, &nsl1e, ft_prefetch, p2mt); rc |= shadow_set_l1e(v, sl1p, nsl1e, sl1mfn); @@ -2723,7 +2723,7 @@ /* Look at the gfn that the l1e is pointing at */ gfn = guest_l1e_get_gfn(gl1e); - gmfn = gfn_to_mfn(v->domain, gfn, &p2mt); + gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt); /* Propagate the entry. */ l1e_propagate_from_guest(v, gl1e, gmfn, &sl1e, ft_prefetch, p2mt); @@ -3079,7 +3079,7 @@ /* What mfn is the guest trying to access? */ gfn = guest_l1e_get_gfn(gw.l1e); - gmfn = gfn_to_mfn(d, gfn, &p2mt); + gmfn = gfn_to_mfn_guest(d, gfn, &p2mt); if ( shadow_mode_refcounts(d) && (!p2m_is_valid(p2mt) || (!p2m_is_mmio(p2mt) && !mfn_valid(gmfn))) ) @@ -4126,7 +4126,7 @@ if ( guest_l3e_get_flags(gl3e[i]) & _PAGE_PRESENT ) { gl2gfn = guest_l3e_get_gfn(gl3e[i]); - gl2mfn = gfn_to_mfn(d, gl2gfn, &p2mt); + gl2mfn = gfn_to_mfn_query(d, gl2gfn, &p2mt); if ( p2m_is_ram(p2mt) ) flush |= sh_remove_write_access(v, gl2mfn, 2, 0); } @@ -4139,7 +4139,7 @@ if ( guest_l3e_get_flags(gl3e[i]) & _PAGE_PRESENT ) { gl2gfn = guest_l3e_get_gfn(gl3e[i]); - gl2mfn = gfn_to_mfn(d, gl2gfn, &p2mt); + gl2mfn = gfn_to_mfn_query(d, gl2gfn, &p2mt); if ( p2m_is_ram(p2mt) ) sh_set_toplevel_shadow(v, i, gl2mfn, (i == 3) ? SH_type_l2h_shadow @@ -4525,7 +4525,12 @@ } /* Translate the GFN to an MFN */ - mfn = gfn_to_mfn(v->domain, _gfn(gfn), &p2mt); + /* PoD: query only if shadow lock is held (to avoid deadlock) */ + if ( shadow_locked_by_me(v->domain) ) + mfn = gfn_to_mfn_query(v->domain, _gfn(gfn), &p2mt); + else + mfn = gfn_to_mfn(v->domain, _gfn(gfn), &p2mt); + if ( p2mt == p2m_ram_ro ) return _mfn(READONLY_GFN); if ( !p2m_is_ram(p2mt) ) @@ -4929,7 +4934,7 @@ { gfn = guest_l1e_get_gfn(*gl1e); mfn = shadow_l1e_get_mfn(*sl1e); - gmfn = gfn_to_mfn(v->domain, gfn, &p2mt); + gmfn = gfn_to_mfn_query(v->domain, gfn, &p2mt); if ( mfn_x(gmfn) != mfn_x(mfn) ) AUDIT_FAIL(1, "bad translation: gfn %" SH_PRI_gfn " --> %" PRI_mfn " != mfn %" PRI_mfn, @@ -4996,7 +5001,7 @@ mfn = shadow_l2e_get_mfn(*sl2e); gmfn = (guest_l2e_get_flags(*gl2e) & _PAGE_PSE) ? get_fl1_shadow_status(v, gfn) - : get_shadow_status(v, gfn_to_mfn(v->domain, gfn, &p2mt), + : get_shadow_status(v, gfn_to_mfn_query(v->domain, gfn, &p2mt), SH_type_l1_shadow); if ( mfn_x(gmfn) != mfn_x(mfn) ) AUDIT_FAIL(2, "bad translation: gfn %" SH_PRI_gfn @@ -5004,7 +5009,7 @@ " --> %" PRI_mfn " != mfn %" PRI_mfn, gfn_x(gfn), (guest_l2e_get_flags(*gl2e) & _PAGE_PSE) ? 0 - : mfn_x(gfn_to_mfn(v->domain, gfn, &p2mt)), + : mfn_x(gfn_to_mfn_query(v->domain, gfn, &p2mt)), mfn_x(gmfn), mfn_x(mfn)); } }); @@ -5043,7 +5048,7 @@ { gfn = guest_l3e_get_gfn(*gl3e); mfn = shadow_l3e_get_mfn(*sl3e); - gmfn = get_shadow_status(v, gfn_to_mfn(v->domain, gfn, &p2mt), + gmfn = get_shadow_status(v, gfn_to_mfn_query(v->domain, gfn, &p2mt), ((GUEST_PAGING_LEVELS == 3 || is_pv_32on64_vcpu(v)) && !shadow_mode_external(v->domain) @@ -5090,7 +5095,7 @@ { gfn = guest_l4e_get_gfn(*gl4e); mfn = shadow_l4e_get_mfn(*sl4e); - gmfn = get_shadow_status(v, gfn_to_mfn(v->domain, gfn, &p2mt), + gmfn = get_shadow_status(v, gfn_to_mfn_query(v->domain, gfn, &p2mt), SH_type_l3_shadow); if ( mfn_x(gmfn) != mfn_x(mfn) ) AUDIT_FAIL(4, "bad translation: gfn %" SH_PRI_gfn diff -r 65c24b33082a xen/arch/x86/mm/shadow/types.h --- a/xen/arch/x86/mm/shadow/types.h Wed Dec 17 12:59:28 2008 +0000 +++ b/xen/arch/x86/mm/shadow/types.h Wed Dec 17 12:59:50 2008 +0000 @@ -191,6 +191,12 @@ }) #endif + /* Override gfn_to_mfn to work with gfn_t */ +#undef gfn_to_mfn_query +#define gfn_to_mfn_query(d, g, t) _gfn_to_mfn_type((d), gfn_x(g), (t), p2m_query) +#undef gfn_to_mfn_guest +#define gfn_to_mfn_guest(d, g, t) _gfn_to_mfn_type((d), gfn_x(g), (t), p2m_guest) + /* The shadow types needed for the various levels. */ #if GUEST_PAGING_LEVELS == 2