[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 07/11] x86/shadow: L2H shadow type is PV32-only
Like for the various HVM-only types, save a little bit of code by suitably "masking" this type out when !PV32. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- I wasn't really sure whether it would be worthwhile to also update the "#else" part of shadow_size(). Doing so would be a little tricky, as the type to return 0 for has no name right now; I'd need to move down the #undef to allow for that. Thoughts? In the 4-level variant of SHADOW_FOREACH_L2E() I was heavily inclined to also pull out of the loop the entire loop invariant part of the condition (part of which needs touching here anyway). But in the end I guess this would better be a separate change. --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -1740,9 +1740,11 @@ void sh_destroy_shadow(struct domain *d, case SH_type_fl1_64_shadow: SHADOW_INTERNAL_NAME(sh_destroy_l1_shadow, 4)(d, smfn); break; +#ifdef CONFIG_PV32 case SH_type_l2h_64_shadow: ASSERT(is_pv_32bit_domain(d)); /* Fall through... */ +#endif case SH_type_l2_64_shadow: SHADOW_INTERNAL_NAME(sh_destroy_l2_shadow, 4)(d, smfn); break; @@ -2099,7 +2101,9 @@ static int sh_remove_shadow_via_pointer( #endif case SH_type_l1_64_shadow: case SH_type_l2_64_shadow: +#ifdef CONFIG_PV32 case SH_type_l2h_64_shadow: +#endif case SH_type_l3_64_shadow: case SH_type_l4_64_shadow: SHADOW_INTERNAL_NAME(sh_clear_shadow_entry, 4)(d, vaddr, pmfn); @@ -2137,7 +2141,9 @@ void sh_remove_shadows(struct domain *d, [SH_type_l2_pae_shadow] = SHADOW_INTERNAL_NAME(sh_remove_l1_shadow, 3), #endif [SH_type_l2_64_shadow] = SHADOW_INTERNAL_NAME(sh_remove_l1_shadow, 4), +#ifdef CONFIG_PV32 [SH_type_l2h_64_shadow] = SHADOW_INTERNAL_NAME(sh_remove_l1_shadow, 4), +#endif [SH_type_l3_64_shadow] = SHADOW_INTERNAL_NAME(sh_remove_l2_shadow, 4), [SH_type_l4_64_shadow] = SHADOW_INTERNAL_NAME(sh_remove_l3_shadow, 4), }; @@ -2150,7 +2156,9 @@ void sh_remove_shadows(struct domain *d, #endif [SH_type_l1_64_shadow] = SHF_L2H_64 | SHF_L2_64, [SH_type_l2_64_shadow] = SHF_L3_64, +#ifdef CONFIG_PV32 [SH_type_l2h_64_shadow] = SHF_L3_64, +#endif [SH_type_l3_64_shadow] = SHF_L4_64, }; @@ -2214,7 +2222,9 @@ void sh_remove_shadows(struct domain *d, #endif DO_UNSHADOW(SH_type_l4_64_shadow); DO_UNSHADOW(SH_type_l3_64_shadow); +#ifdef CONFIG_PV32 DO_UNSHADOW(SH_type_l2h_64_shadow); +#endif DO_UNSHADOW(SH_type_l2_64_shadow); DO_UNSHADOW(SH_type_l1_64_shadow); @@ -3179,7 +3189,9 @@ void shadow_audit_tables(struct vcpu *v) [SH_type_l1_64_shadow] = SHADOW_INTERNAL_NAME(sh_audit_l1_table, 4), [SH_type_fl1_64_shadow] = SHADOW_INTERNAL_NAME(sh_audit_fl1_table, 4), [SH_type_l2_64_shadow] = SHADOW_INTERNAL_NAME(sh_audit_l2_table, 4), +# ifdef CONFIG_PV32 [SH_type_l2h_64_shadow] = SHADOW_INTERNAL_NAME(sh_audit_l2_table, 4), +# endif [SH_type_l3_64_shadow] = SHADOW_INTERNAL_NAME(sh_audit_l3_table, 4), [SH_type_l4_64_shadow] = SHADOW_INTERNAL_NAME(sh_audit_l4_table, 4), #endif --- a/xen/arch/x86/mm/shadow/hvm.c +++ b/xen/arch/x86/mm/shadow/hvm.c @@ -56,7 +56,6 @@ const uint8_t sh_type_to_size[] = { [SH_type_l1_64_shadow] = 1, [SH_type_fl1_64_shadow] = 1, [SH_type_l2_64_shadow] = 1, - [SH_type_l2h_64_shadow] = 1, [SH_type_l3_64_shadow] = 1, [SH_type_l4_64_shadow] = 1, [SH_type_p2m_table] = 1, --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -97,6 +97,13 @@ static void sh_flush_local(const struct flush_local(guest_flush_tlb_flags(d)); } +#if GUEST_PAGING_LEVELS >= 4 && defined(CONFIG_PV32) +#define ASSERT_VALID_L2(t) \ + ASSERT((t) == SH_type_l2_shadow || (t) == SH_type_l2h_shadow) +#else +#define ASSERT_VALID_L2(t) ASSERT((t) == SH_type_l2_shadow) +#endif + /**************************************************************************/ /* Hash table mapping from guest pagetables to shadows * @@ -337,7 +344,7 @@ static void sh_audit_gw(struct vcpu *v, if ( mfn_valid((smfn = get_shadow_status(d, gw->l2mfn, SH_type_l2_shadow))) ) sh_audit_l2_table(d, smfn, INVALID_MFN); -#if GUEST_PAGING_LEVELS >= 4 /* 32-bit PV only */ +#if GUEST_PAGING_LEVELS >= 4 && defined(CONFIG_PV32) if ( mfn_valid((smfn = get_shadow_status(d, gw->l2mfn, SH_type_l2h_shadow))) ) sh_audit_l2_table(d, smfn, INVALID_MFN); @@ -859,13 +866,12 @@ do { int _i; \ int _xen = !shadow_mode_external(_dom); \ shadow_l2e_t *_sp = map_domain_page((_sl2mfn)); \ - ASSERT(mfn_to_page(_sl2mfn)->u.sh.type == SH_type_l2_64_shadow ||\ - mfn_to_page(_sl2mfn)->u.sh.type == SH_type_l2h_64_shadow);\ + ASSERT_VALID_L2(mfn_to_page(_sl2mfn)->u.sh.type); \ for ( _i = 0; _i < SHADOW_L2_PAGETABLE_ENTRIES; _i++ ) \ { \ if ( (!(_xen)) \ || !is_pv_32bit_domain(_dom) \ - || mfn_to_page(_sl2mfn)->u.sh.type != SH_type_l2h_64_shadow \ + || mfn_to_page(_sl2mfn)->u.sh.type == SH_type_l2_64_shadow \ || (_i < COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(_dom)) ) \ { \ (_sl2e) = _sp + _i; \ @@ -992,6 +998,7 @@ sh_make_shadow(struct vcpu *v, mfn_t gmf } break; +#ifdef CONFIG_PV32 case SH_type_l2h_shadow: BUILD_BUG_ON(sizeof(l2_pgentry_t) != sizeof(shadow_l2e_t)); if ( is_pv_32bit_domain(d) ) @@ -1002,6 +1009,8 @@ sh_make_shadow(struct vcpu *v, mfn_t gmf unmap_domain_page(l2t); } break; +#endif + default: /* Do nothing */ break; } } @@ -1123,11 +1132,13 @@ static shadow_l2e_t * shadow_get_and_cre shadow_l3e_t new_sl3e; unsigned int t = SH_type_l2_shadow; +#ifdef CONFIG_PV32 /* Tag compat L2 containing hypervisor (m2p) mappings */ if ( is_pv_32bit_domain(d) && guest_l4_table_offset(gw->va) == 0 && guest_l3_table_offset(gw->va) == 3 ) t = SH_type_l2h_shadow; +#endif /* No l2 shadow installed: find and install it. */ *sl2mfn = get_shadow_status(d, gw->l2mfn, t); @@ -1337,11 +1348,7 @@ void sh_destroy_l2_shadow(struct domain SHADOW_DEBUG(DESTROY_SHADOW, "%"PRI_mfn"\n", mfn_x(smfn)); -#if GUEST_PAGING_LEVELS >= 4 - ASSERT(t == SH_type_l2_shadow || t == SH_type_l2h_shadow); -#else - ASSERT(t == SH_type_l2_shadow); -#endif + ASSERT_VALID_L2(t); ASSERT(sp->u.sh.head); /* Record that the guest page isn't shadowed any more (in this type) */ @@ -1865,7 +1872,7 @@ int sh_map_and_validate_gl2he(struct vcpu *v, mfn_t gl2mfn, void *new_gl2p, u32 size) { -#if GUEST_PAGING_LEVELS >= 4 +#if GUEST_PAGING_LEVELS >= 4 && defined(CONFIG_PV32) return sh_map_and_validate(v, gl2mfn, new_gl2p, size, SH_type_l2h_shadow, shadow_l2_index, @@ -3674,7 +3681,7 @@ void sh_clear_shadow_entry(struct domain shadow_set_l1e(d, ep, shadow_l1e_empty(), p2m_invalid, smfn); break; case SH_type_l2_shadow: -#if GUEST_PAGING_LEVELS >= 4 +#if GUEST_PAGING_LEVELS >= 4 && defined(CONFIG_PV32) case SH_type_l2h_shadow: #endif shadow_set_l2e(d, ep, shadow_l2e_empty(), smfn); @@ -4124,14 +4131,16 @@ int cf_check sh_audit_l3_table(struct do if ( SHADOW_AUDIT & SHADOW_AUDIT_ENTRIES_MFNS ) { + unsigned int t = SH_type_l2_shadow; + gfn = guest_l3e_get_gfn(*gl3e); mfn = shadow_l3e_get_mfn(*sl3e); - gmfn = get_shadow_status(d, get_gfn_query_unlocked( - d, gfn_x(gfn), &p2mt), - (is_pv_32bit_domain(d) && - guest_index(gl3e) == 3) - ? SH_type_l2h_shadow - : SH_type_l2_shadow); +#ifdef CONFIG_PV32 + if ( guest_index(gl3e) == 3 && is_pv_32bit_domain(d) ) + t = SH_type_l2h_shadow; +#endif + gmfn = get_shadow_status( + d, get_gfn_query_unlocked(d, gfn_x(gfn), &p2mt), t); if ( !mfn_eq(gmfn, mfn) ) AUDIT_FAIL(3, "bad translation: gfn %" SH_PRI_gfn " --> %" PRI_mfn " != mfn %" PRI_mfn, --- a/xen/arch/x86/mm/shadow/private.h +++ b/xen/arch/x86/mm/shadow/private.h @@ -209,6 +209,10 @@ extern void shadow_audit_tables(struct v #define SH_type_unused 10U #endif +#ifndef CONFIG_PV32 /* Unused (but uglier to #ifdef above): */ +#undef SH_type_l2h_64_shadow +#endif + /* * What counts as a pinnable shadow? */ @@ -286,7 +290,11 @@ static inline void sh_terminate_list(str #define SHF_L1_64 (1u << SH_type_l1_64_shadow) #define SHF_FL1_64 (1u << SH_type_fl1_64_shadow) #define SHF_L2_64 (1u << SH_type_l2_64_shadow) +#ifdef CONFIG_PV32 #define SHF_L2H_64 (1u << SH_type_l2h_64_shadow) +#else +#define SHF_L2H_64 0 +#endif #define SHF_L3_64 (1u << SH_type_l3_64_shadow) #define SHF_L4_64 (1u << SH_type_l4_64_shadow)
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |