[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 1/4] x86/mm: add optional cache to GLA->GFN translation
The caching isn't actually implemented here, this is just setting the stage. Touching these anyway also - make their return values gfn_t - gva -> gla in their names - name their input arguments gla At the use sites do the conversion to gfn_t as suitable. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- v2: Re-base. --- a/xen/arch/x86/debug.c +++ b/xen/arch/x86/debug.c @@ -51,7 +51,7 @@ dbg_hvm_va2mfn(dbgva_t vaddr, struct dom DBGP2("vaddr:%lx domid:%d\n", vaddr, dp->domain_id); - *gfn = _gfn(paging_gva_to_gfn(dp->vcpu[0], vaddr, &pfec)); + *gfn = paging_gla_to_gfn(dp->vcpu[0], vaddr, &pfec, NULL); if ( gfn_eq(*gfn, INVALID_GFN) ) { DBGP2("kdb:bad gfn from gva_to_gfn\n"); --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -699,7 +699,8 @@ static int hvmemul_linear_to_phys( struct hvm_emulate_ctxt *hvmemul_ctxt) { struct vcpu *curr = current; - unsigned long pfn, npfn, done, todo, i, offset = addr & ~PAGE_MASK; + gfn_t gfn, ngfn; + unsigned long done, todo, i, offset = addr & ~PAGE_MASK; int reverse; /* @@ -721,15 +722,17 @@ static int hvmemul_linear_to_phys( if ( reverse && ((PAGE_SIZE - offset) < bytes_per_rep) ) { /* Do page-straddling first iteration forwards via recursion. */ - paddr_t _paddr; + paddr_t gaddr; unsigned long one_rep = 1; int rc = hvmemul_linear_to_phys( - addr, &_paddr, bytes_per_rep, &one_rep, pfec, hvmemul_ctxt); + addr, &gaddr, bytes_per_rep, &one_rep, pfec, hvmemul_ctxt); + if ( rc != X86EMUL_OKAY ) return rc; - pfn = _paddr >> PAGE_SHIFT; + gfn = gaddr_to_gfn(gaddr); } - else if ( (pfn = paging_gva_to_gfn(curr, addr, &pfec)) == gfn_x(INVALID_GFN) ) + else if ( gfn_eq(gfn = paging_gla_to_gfn(curr, addr, &pfec, NULL), + INVALID_GFN) ) { if ( pfec & (PFEC_page_paged | PFEC_page_shared) ) return X86EMUL_RETRY; @@ -744,11 +747,11 @@ static int hvmemul_linear_to_phys( { /* Get the next PFN in the range. */ addr += reverse ? -PAGE_SIZE : PAGE_SIZE; - npfn = paging_gva_to_gfn(curr, addr, &pfec); + ngfn = paging_gla_to_gfn(curr, addr, &pfec, NULL); /* Is it contiguous with the preceding PFNs? If not then we're done. */ - if ( (npfn == gfn_x(INVALID_GFN)) || - (npfn != (pfn + (reverse ? -i : i))) ) + if ( gfn_eq(ngfn, INVALID_GFN) || + !gfn_eq(ngfn, gfn_add(gfn, reverse ? -i : i)) ) { if ( pfec & (PFEC_page_paged | PFEC_page_shared) ) return X86EMUL_RETRY; @@ -756,7 +759,7 @@ static int hvmemul_linear_to_phys( if ( done == 0 ) { ASSERT(!reverse); - if ( npfn != gfn_x(INVALID_GFN) ) + if ( !gfn_eq(ngfn, INVALID_GFN) ) return X86EMUL_UNHANDLEABLE; *reps = 0; x86_emul_pagefault(pfec, addr & PAGE_MASK, &hvmemul_ctxt->ctxt); @@ -769,7 +772,8 @@ static int hvmemul_linear_to_phys( done += PAGE_SIZE; } - *paddr = ((paddr_t)pfn << PAGE_SHIFT) | offset; + *paddr = gfn_to_gaddr(gfn) | offset; + return X86EMUL_OKAY; } --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2682,7 +2682,7 @@ static void *hvm_map_entry(unsigned long * treat it as a kernel-mode read (i.e. no access checks). */ pfec = PFEC_page_present; - gfn = paging_gva_to_gfn(current, va, &pfec); + gfn = gfn_x(paging_gla_to_gfn(current, va, &pfec, NULL)); if ( pfec & (PFEC_page_paged | PFEC_page_shared) ) goto fail; @@ -3112,7 +3112,7 @@ enum hvm_translation_result hvm_translat if ( linear ) { - gfn = _gfn(paging_gva_to_gfn(v, addr, &pfec)); + gfn = paging_gla_to_gfn(v, addr, &pfec, NULL); if ( gfn_eq(gfn, INVALID_GFN) ) { --- a/xen/arch/x86/hvm/monitor.c +++ b/xen/arch/x86/hvm/monitor.c @@ -130,7 +130,7 @@ static inline unsigned long gfn_of_rip(u hvm_get_segment_register(curr, x86_seg_cs, &sreg); - return paging_gva_to_gfn(curr, sreg.base + rip, &pfec); + return gfn_x(paging_gla_to_gfn(curr, sreg.base + rip, &pfec, NULL)); } int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type, --- a/xen/arch/x86/mm/guest_walk.c +++ b/xen/arch/x86/mm/guest_walk.c @@ -81,8 +81,9 @@ static bool set_ad_bits(guest_intpte_t * */ bool guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m, - unsigned long va, walk_t *gw, - uint32_t walk, mfn_t top_mfn, void *top_map) + unsigned long gla, walk_t *gw, uint32_t walk, + gfn_t top_gfn, mfn_t top_mfn, void *top_map, + struct hvmemul_cache *cache) { struct domain *d = v->domain; p2m_type_t p2mt; @@ -116,7 +117,7 @@ guest_walk_tables(struct vcpu *v, struct perfc_incr(guest_walk); memset(gw, 0, sizeof(*gw)); - gw->va = va; + gw->va = gla; gw->pfec = walk & (PFEC_user_mode | PFEC_write_access); /* @@ -133,7 +134,7 @@ guest_walk_tables(struct vcpu *v, struct /* Get the l4e from the top level table and check its flags*/ gw->l4mfn = top_mfn; l4p = (guest_l4e_t *) top_map; - gw->l4e = l4p[guest_l4_table_offset(va)]; + gw->l4e = l4p[guest_l4_table_offset(gla)]; gflags = guest_l4e_get_flags(gw->l4e); if ( !(gflags & _PAGE_PRESENT) ) goto out; @@ -163,7 +164,7 @@ guest_walk_tables(struct vcpu *v, struct } /* Get the l3e and check its flags*/ - gw->l3e = l3p[guest_l3_table_offset(va)]; + gw->l3e = l3p[guest_l3_table_offset(gla)]; gflags = guest_l3e_get_flags(gw->l3e); if ( !(gflags & _PAGE_PRESENT) ) goto out; @@ -205,7 +206,7 @@ guest_walk_tables(struct vcpu *v, struct /* Increment the pfn by the right number of 4k pages. */ start = _gfn((gfn_x(start) & ~GUEST_L3_GFN_MASK) + - ((va >> PAGE_SHIFT) & GUEST_L3_GFN_MASK)); + ((gla >> PAGE_SHIFT) & GUEST_L3_GFN_MASK)); gw->l1e = guest_l1e_from_gfn(start, flags); gw->l2mfn = gw->l1mfn = INVALID_MFN; leaf_level = 3; @@ -215,7 +216,7 @@ guest_walk_tables(struct vcpu *v, struct #else /* PAE only... */ /* Get the l3e and check its flag */ - gw->l3e = ((guest_l3e_t *) top_map)[guest_l3_table_offset(va)]; + gw->l3e = ((guest_l3e_t *)top_map)[guest_l3_table_offset(gla)]; gflags = guest_l3e_get_flags(gw->l3e); if ( !(gflags & _PAGE_PRESENT) ) goto out; @@ -242,14 +243,14 @@ guest_walk_tables(struct vcpu *v, struct } /* Get the l2e */ - gw->l2e = l2p[guest_l2_table_offset(va)]; + gw->l2e = l2p[guest_l2_table_offset(gla)]; #else /* 32-bit only... */ /* Get l2e from the top level table */ gw->l2mfn = top_mfn; l2p = (guest_l2e_t *) top_map; - gw->l2e = l2p[guest_l2_table_offset(va)]; + gw->l2e = l2p[guest_l2_table_offset(gla)]; #endif /* All levels... */ @@ -310,7 +311,7 @@ guest_walk_tables(struct vcpu *v, struct /* Increment the pfn by the right number of 4k pages. */ start = _gfn((gfn_x(start) & ~GUEST_L2_GFN_MASK) + - guest_l1_table_offset(va)); + guest_l1_table_offset(gla)); #if GUEST_PAGING_LEVELS == 2 /* Wider than 32 bits if PSE36 superpage. */ gw->el1e = (gfn_x(start) << PAGE_SHIFT) | flags; @@ -334,7 +335,7 @@ guest_walk_tables(struct vcpu *v, struct gw->pfec |= rc & PFEC_synth_mask; goto out; } - gw->l1e = l1p[guest_l1_table_offset(va)]; + gw->l1e = l1p[guest_l1_table_offset(gla)]; gflags = guest_l1e_get_flags(gw->l1e); if ( !(gflags & _PAGE_PRESENT) ) goto out; @@ -443,22 +444,22 @@ guest_walk_tables(struct vcpu *v, struct break; case 1: - if ( set_ad_bits(&l1p[guest_l1_table_offset(va)].l1, &gw->l1e.l1, + if ( set_ad_bits(&l1p[guest_l1_table_offset(gla)].l1, &gw->l1e.l1, (walk & PFEC_write_access)) ) paging_mark_dirty(d, gw->l1mfn); /* Fallthrough */ case 2: - if ( set_ad_bits(&l2p[guest_l2_table_offset(va)].l2, &gw->l2e.l2, + if ( set_ad_bits(&l2p[guest_l2_table_offset(gla)].l2, &gw->l2e.l2, (walk & PFEC_write_access) && leaf_level == 2) ) paging_mark_dirty(d, gw->l2mfn); /* Fallthrough */ #if GUEST_PAGING_LEVELS == 4 /* 64-bit only... */ case 3: - if ( set_ad_bits(&l3p[guest_l3_table_offset(va)].l3, &gw->l3e.l3, + if ( set_ad_bits(&l3p[guest_l3_table_offset(gla)].l3, &gw->l3e.l3, (walk & PFEC_write_access) && leaf_level == 3) ) paging_mark_dirty(d, gw->l3mfn); - if ( set_ad_bits(&l4p[guest_l4_table_offset(va)].l4, &gw->l4e.l4, + if ( set_ad_bits(&l4p[guest_l4_table_offset(gla)].l4, &gw->l4e.l4, false) ) paging_mark_dirty(d, gw->l4mfn); #endif --- a/xen/arch/x86/mm/hap/guest_walk.c +++ b/xen/arch/x86/mm/hap/guest_walk.c @@ -26,8 +26,8 @@ asm(".file \"" __OBJECT_FILE__ "\""); #include <xen/sched.h> #include "private.h" /* for hap_gva_to_gfn_* */ -#define _hap_gva_to_gfn(levels) hap_gva_to_gfn_##levels##_levels -#define hap_gva_to_gfn(levels) _hap_gva_to_gfn(levels) +#define _hap_gla_to_gfn(levels) hap_gla_to_gfn_##levels##_levels +#define hap_gla_to_gfn(levels) _hap_gla_to_gfn(levels) #define _hap_p2m_ga_to_gfn(levels) hap_p2m_ga_to_gfn_##levels##_levels #define hap_p2m_ga_to_gfn(levels) _hap_p2m_ga_to_gfn(levels) @@ -39,16 +39,10 @@ asm(".file \"" __OBJECT_FILE__ "\""); #include <asm/guest_pt.h> #include <asm/p2m.h> -unsigned long hap_gva_to_gfn(GUEST_PAGING_LEVELS)( - struct vcpu *v, struct p2m_domain *p2m, unsigned long gva, uint32_t *pfec) -{ - unsigned long cr3 = v->arch.hvm.guest_cr[3]; - return hap_p2m_ga_to_gfn(GUEST_PAGING_LEVELS)(v, p2m, cr3, gva, pfec, NULL); -} - -unsigned long hap_p2m_ga_to_gfn(GUEST_PAGING_LEVELS)( +static unsigned long ga_to_gfn( struct vcpu *v, struct p2m_domain *p2m, unsigned long cr3, - paddr_t ga, uint32_t *pfec, unsigned int *page_order) + paddr_t ga, uint32_t *pfec, unsigned int *page_order, + struct hvmemul_cache *cache) { bool walk_ok; mfn_t top_mfn; @@ -91,7 +85,8 @@ unsigned long hap_p2m_ga_to_gfn(GUEST_PA #if GUEST_PAGING_LEVELS == 3 top_map += (cr3 & ~(PAGE_MASK | 31)); #endif - walk_ok = guest_walk_tables(v, p2m, ga, &gw, *pfec, top_mfn, top_map); + walk_ok = guest_walk_tables(v, p2m, ga, &gw, *pfec, + top_gfn, top_mfn, top_map, cache); unmap_domain_page(top_map); put_page(top_page); @@ -137,6 +132,21 @@ unsigned long hap_p2m_ga_to_gfn(GUEST_PA return gfn_x(INVALID_GFN); } +gfn_t hap_gla_to_gfn(GUEST_PAGING_LEVELS)( + struct vcpu *v, struct p2m_domain *p2m, unsigned long gla, uint32_t *pfec, + struct hvmemul_cache *cache) +{ + unsigned long cr3 = v->arch.hvm.guest_cr[3]; + + return _gfn(ga_to_gfn(v, p2m, cr3, gla, pfec, NULL, cache)); +} + +unsigned long hap_p2m_ga_to_gfn(GUEST_PAGING_LEVELS)( + struct vcpu *v, struct p2m_domain *p2m, unsigned long cr3, + paddr_t ga, uint32_t *pfec, unsigned int *page_order) +{ + return ga_to_gfn(v, p2m, cr3, ga, pfec, page_order, NULL); +} /* * Local variables: --- a/xen/arch/x86/mm/hap/hap.c +++ b/xen/arch/x86/mm/hap/hap.c @@ -744,10 +744,11 @@ hap_write_p2m_entry(struct domain *d, un p2m_flush_nestedp2m(d); } -static unsigned long hap_gva_to_gfn_real_mode( - struct vcpu *v, struct p2m_domain *p2m, unsigned long gva, uint32_t *pfec) +static gfn_t hap_gla_to_gfn_real_mode( + struct vcpu *v, struct p2m_domain *p2m, unsigned long gla, uint32_t *pfec, + struct hvmemul_cache *cache) { - return ((paddr_t)gva >> PAGE_SHIFT); + return gaddr_to_gfn(gla); } static unsigned long hap_p2m_ga_to_gfn_real_mode( @@ -763,7 +764,7 @@ static unsigned long hap_p2m_ga_to_gfn_r static const struct paging_mode hap_paging_real_mode = { .page_fault = hap_page_fault, .invlpg = hap_invlpg, - .gva_to_gfn = hap_gva_to_gfn_real_mode, + .gla_to_gfn = hap_gla_to_gfn_real_mode, .p2m_ga_to_gfn = hap_p2m_ga_to_gfn_real_mode, .update_cr3 = hap_update_cr3, .update_paging_modes = hap_update_paging_modes, @@ -774,7 +775,7 @@ static const struct paging_mode hap_pagi static const struct paging_mode hap_paging_protected_mode = { .page_fault = hap_page_fault, .invlpg = hap_invlpg, - .gva_to_gfn = hap_gva_to_gfn_2_levels, + .gla_to_gfn = hap_gla_to_gfn_2_levels, .p2m_ga_to_gfn = hap_p2m_ga_to_gfn_2_levels, .update_cr3 = hap_update_cr3, .update_paging_modes = hap_update_paging_modes, @@ -785,7 +786,7 @@ static const struct paging_mode hap_pagi static const struct paging_mode hap_paging_pae_mode = { .page_fault = hap_page_fault, .invlpg = hap_invlpg, - .gva_to_gfn = hap_gva_to_gfn_3_levels, + .gla_to_gfn = hap_gla_to_gfn_3_levels, .p2m_ga_to_gfn = hap_p2m_ga_to_gfn_3_levels, .update_cr3 = hap_update_cr3, .update_paging_modes = hap_update_paging_modes, @@ -796,7 +797,7 @@ static const struct paging_mode hap_pagi static const struct paging_mode hap_paging_long_mode = { .page_fault = hap_page_fault, .invlpg = hap_invlpg, - .gva_to_gfn = hap_gva_to_gfn_4_levels, + .gla_to_gfn = hap_gla_to_gfn_4_levels, .p2m_ga_to_gfn = hap_p2m_ga_to_gfn_4_levels, .update_cr3 = hap_update_cr3, .update_paging_modes = hap_update_paging_modes, --- a/xen/arch/x86/mm/hap/private.h +++ b/xen/arch/x86/mm/hap/private.h @@ -24,18 +24,21 @@ /********************************************/ /* GUEST TRANSLATION FUNCS */ /********************************************/ -unsigned long hap_gva_to_gfn_2_levels(struct vcpu *v, - struct p2m_domain *p2m, - unsigned long gva, - uint32_t *pfec); -unsigned long hap_gva_to_gfn_3_levels(struct vcpu *v, - struct p2m_domain *p2m, - unsigned long gva, - uint32_t *pfec); -unsigned long hap_gva_to_gfn_4_levels(struct vcpu *v, - struct p2m_domain *p2m, - unsigned long gva, - uint32_t *pfec); +gfn_t hap_gla_to_gfn_2_levels(struct vcpu *v, + struct p2m_domain *p2m, + unsigned long gla, + uint32_t *pfec, + struct hvmemul_cache *cache); +gfn_t hap_gla_to_gfn_3_levels(struct vcpu *v, + struct p2m_domain *p2m, + unsigned long gla, + uint32_t *pfec, + struct hvmemul_cache *cache); +gfn_t hap_gla_to_gfn_4_levels(struct vcpu *v, + struct p2m_domain *p2m, + unsigned long gla, + uint32_t *pfec, + struct hvmemul_cache *cache); unsigned long hap_p2m_ga_to_gfn_2_levels(struct vcpu *v, struct p2m_domain *p2m, unsigned long cr3, --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1970,16 +1970,16 @@ void np2m_schedule(int dir) } } -unsigned long paging_gva_to_gfn(struct vcpu *v, - unsigned long va, - uint32_t *pfec) +gfn_t paging_gla_to_gfn(struct vcpu *v, unsigned long gla, uint32_t *pfec, + struct hvmemul_cache *cache) { struct p2m_domain *hostp2m = p2m_get_hostp2m(v->domain); const struct paging_mode *hostmode = paging_get_hostmode(v); if ( is_hvm_vcpu(v) && paging_mode_hap(v->domain) && nestedhvm_is_n2(v) ) { - unsigned long l2_gfn, l1_gfn; + gfn_t l2_gfn; + unsigned long l1_gfn; struct p2m_domain *p2m; const struct paging_mode *mode; uint8_t l1_p2ma; @@ -1989,31 +1989,31 @@ unsigned long paging_gva_to_gfn(struct v /* translate l2 guest va into l2 guest gfn */ p2m = p2m_get_nestedp2m(v); mode = paging_get_nestedmode(v); - l2_gfn = mode->gva_to_gfn(v, p2m, va, pfec); + l2_gfn = mode->gla_to_gfn(v, p2m, gla, pfec, cache); - if ( l2_gfn == gfn_x(INVALID_GFN) ) - return gfn_x(INVALID_GFN); + if ( gfn_eq(l2_gfn, INVALID_GFN) ) + return INVALID_GFN; /* translate l2 guest gfn into l1 guest gfn */ - rv = nestedhap_walk_L1_p2m(v, l2_gfn, &l1_gfn, &l1_page_order, &l1_p2ma, - 1, + rv = nestedhap_walk_L1_p2m(v, gfn_x(l2_gfn), &l1_gfn, &l1_page_order, + &l1_p2ma, 1, !!(*pfec & PFEC_write_access), !!(*pfec & PFEC_insn_fetch)); if ( rv != NESTEDHVM_PAGEFAULT_DONE ) - return gfn_x(INVALID_GFN); + return INVALID_GFN; /* * Sanity check that l1_gfn can be used properly as a 4K mapping, even * if it mapped by a nested superpage. */ - ASSERT((l2_gfn & ((1ul << l1_page_order) - 1)) == + ASSERT((gfn_x(l2_gfn) & ((1ul << l1_page_order) - 1)) == (l1_gfn & ((1ul << l1_page_order) - 1))); - return l1_gfn; + return _gfn(l1_gfn); } - return hostmode->gva_to_gfn(v, hostp2m, va, pfec); + return hostmode->gla_to_gfn(v, hostp2m, gla, pfec, cache); } /* --- a/xen/arch/x86/mm/shadow/hvm.c +++ b/xen/arch/x86/mm/shadow/hvm.c @@ -313,15 +313,15 @@ const struct x86_emulate_ops hvm_shadow_ static mfn_t emulate_gva_to_mfn(struct vcpu *v, unsigned long vaddr, struct sh_emulate_ctxt *sh_ctxt) { - unsigned long gfn; + gfn_t gfn; struct page_info *page; mfn_t mfn; p2m_type_t p2mt; uint32_t pfec = PFEC_page_present | PFEC_write_access; /* Translate the VA to a GFN. */ - gfn = paging_get_hostmode(v)->gva_to_gfn(v, NULL, vaddr, &pfec); - if ( gfn == gfn_x(INVALID_GFN) ) + gfn = paging_get_hostmode(v)->gla_to_gfn(v, NULL, vaddr, &pfec, NULL); + if ( gfn_eq(gfn, INVALID_GFN) ) { x86_emul_pagefault(pfec, vaddr, &sh_ctxt->ctxt); @@ -331,7 +331,7 @@ static mfn_t emulate_gva_to_mfn(struct v /* Translate the GFN to an MFN. */ ASSERT(!paging_locked_by_me(v->domain)); - page = get_page_from_gfn(v->domain, gfn, &p2mt, P2M_ALLOC); + page = get_page_from_gfn(v->domain, gfn_x(gfn), &p2mt, P2M_ALLOC); /* Sanity checking. */ if ( page == NULL ) --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -173,17 +173,20 @@ delete_shadow_status(struct domain *d, m static inline bool sh_walk_guest_tables(struct vcpu *v, unsigned long va, walk_t *gw, - uint32_t pfec) + uint32_t pfec, struct hvmemul_cache *cache) { return guest_walk_tables(v, p2m_get_hostp2m(v->domain), va, gw, pfec, + _gfn(paging_mode_external(v->domain) + ? cr3_pa(v->arch.hvm.guest_cr[3]) >> PAGE_SHIFT + : pagetable_get_pfn(v->arch.guest_table)), #if GUEST_PAGING_LEVELS == 3 /* PAE */ INVALID_MFN, - v->arch.paging.shadow.gl3e + v->arch.paging.shadow.gl3e, #else /* 32 or 64 */ pagetable_get_mfn(v->arch.guest_table), - v->arch.paging.shadow.guest_vtable + v->arch.paging.shadow.guest_vtable, #endif - ); + cache); } /* This validation is called with lock held, and after write permission @@ -3032,7 +3035,7 @@ static int sh_page_fault(struct vcpu *v, * shadow page table. */ version = atomic_read(&d->arch.paging.shadow.gtable_dirty_version); smp_rmb(); - walk_ok = sh_walk_guest_tables(v, va, &gw, error_code); + walk_ok = sh_walk_guest_tables(v, va, &gw, error_code, NULL); #if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC) regs->error_code &= ~PFEC_page_present; @@ -3680,9 +3683,9 @@ static bool sh_invlpg(struct vcpu *v, un } -static unsigned long -sh_gva_to_gfn(struct vcpu *v, struct p2m_domain *p2m, - unsigned long va, uint32_t *pfec) +static gfn_t +sh_gla_to_gfn(struct vcpu *v, struct p2m_domain *p2m, + unsigned long gla, uint32_t *pfec, struct hvmemul_cache *cache) /* Called to translate a guest virtual address to what the *guest* * pagetables would map it to. */ { @@ -3692,24 +3695,25 @@ sh_gva_to_gfn(struct vcpu *v, struct p2m #if (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) /* Check the vTLB cache first */ - unsigned long vtlb_gfn = vtlb_lookup(v, va, *pfec); + unsigned long vtlb_gfn = vtlb_lookup(v, gla, *pfec); + if ( vtlb_gfn != gfn_x(INVALID_GFN) ) - return vtlb_gfn; + return _gfn(vtlb_gfn); #endif /* (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) */ - if ( !(walk_ok = sh_walk_guest_tables(v, va, &gw, *pfec)) ) + if ( !(walk_ok = sh_walk_guest_tables(v, gla, &gw, *pfec, cache)) ) { *pfec = gw.pfec; - return gfn_x(INVALID_GFN); + return INVALID_GFN; } gfn = guest_walk_to_gfn(&gw); #if (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) /* Remember this successful VA->GFN translation for later. */ - vtlb_insert(v, va >> PAGE_SHIFT, gfn_x(gfn), *pfec); + vtlb_insert(v, gla >> PAGE_SHIFT, gfn_x(gfn), *pfec); #endif /* (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) */ - return gfn_x(gfn); + return gfn; } @@ -4954,7 +4958,7 @@ int sh_audit_l4_table(struct vcpu *v, mf const struct paging_mode sh_paging_mode = { .page_fault = sh_page_fault, .invlpg = sh_invlpg, - .gva_to_gfn = sh_gva_to_gfn, + .gla_to_gfn = sh_gla_to_gfn, .update_cr3 = sh_update_cr3, .update_paging_modes = shadow_update_paging_modes, .write_p2m_entry = shadow_write_p2m_entry, --- a/xen/arch/x86/mm/shadow/none.c +++ b/xen/arch/x86/mm/shadow/none.c @@ -43,11 +43,12 @@ static bool _invlpg(struct vcpu *v, unsi return true; } -static unsigned long _gva_to_gfn(struct vcpu *v, struct p2m_domain *p2m, - unsigned long va, uint32_t *pfec) +static gfn_t _gla_to_gfn(struct vcpu *v, struct p2m_domain *p2m, + unsigned long gla, uint32_t *pfec, + struct hvmemul_cache *cache) { ASSERT_UNREACHABLE(); - return gfn_x(INVALID_GFN); + return INVALID_GFN; } static void _update_cr3(struct vcpu *v, int do_locking, bool noflush) @@ -70,7 +71,7 @@ static void _write_p2m_entry(struct doma static const struct paging_mode sh_paging_none = { .page_fault = _page_fault, .invlpg = _invlpg, - .gva_to_gfn = _gva_to_gfn, + .gla_to_gfn = _gla_to_gfn, .update_cr3 = _update_cr3, .update_paging_modes = _update_paging_modes, .write_p2m_entry = _write_p2m_entry, --- a/xen/include/asm-x86/guest_pt.h +++ b/xen/include/asm-x86/guest_pt.h @@ -425,7 +425,8 @@ static inline unsigned int guest_walk_to bool guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m, unsigned long va, - walk_t *gw, uint32_t pfec, mfn_t top_mfn, void *top_map); + walk_t *gw, uint32_t pfec, gfn_t top_gfn, mfn_t top_mfn, + void *top_map, struct hvmemul_cache *cache); /* Pretty-print the contents of a guest-walk */ static inline void print_gw(const walk_t *gw) --- a/xen/include/asm-x86/hvm/vcpu.h +++ b/xen/include/asm-x86/hvm/vcpu.h @@ -53,6 +53,8 @@ struct hvm_mmio_cache { uint8_t buffer[32]; }; +struct hvmemul_cache; + struct hvm_vcpu_io { /* I/O request in flight to device model. */ enum hvm_io_completion io_completion; --- a/xen/include/asm-x86/paging.h +++ b/xen/include/asm-x86/paging.h @@ -112,10 +112,11 @@ struct paging_mode { struct cpu_user_regs *regs); bool (*invlpg )(struct vcpu *v, unsigned long linear); - unsigned long (*gva_to_gfn )(struct vcpu *v, + gfn_t (*gla_to_gfn )(struct vcpu *v, struct p2m_domain *p2m, - unsigned long va, - uint32_t *pfec); + unsigned long gla, + uint32_t *pfec, + struct hvmemul_cache *cache); unsigned long (*p2m_ga_to_gfn )(struct vcpu *v, struct p2m_domain *p2m, unsigned long cr3, @@ -251,9 +252,10 @@ void paging_invlpg(struct vcpu *v, unsig * SDM Intel 64 Volume 3, Chapter Paging, PAGE-FAULT EXCEPTIONS: * The PFEC_insn_fetch flag is set only when NX or SMEP are enabled. */ -unsigned long paging_gva_to_gfn(struct vcpu *v, - unsigned long va, - uint32_t *pfec); +gfn_t paging_gla_to_gfn(struct vcpu *v, + unsigned long va, + uint32_t *pfec, + struct hvmemul_cache *cache); /* Translate a guest address using a particular CR3 value. This is used * to by nested HAP code, to walk the guest-supplied NPT tables as if _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |