@@ -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
@@ -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,
@@ -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,
@@ -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)
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@suse.com> --- 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.