From: Jan Beulich <jbeulich@suse.com>
To: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
"Wei Liu" <wl@xen.org>, "Roger Pau Monné" <roger.pau@citrix.com>,
"Tim Deegan" <tim@xen.org>,
"George Dunlap" <george.dunlap@citrix.com>
Subject: [PATCH 07/11] x86/shadow: L2H shadow type is PV32-only
Date: Thu, 5 Jan 2023 17:05:00 +0100 [thread overview]
Message-ID: <2743393d-852d-b385-9eba-e22806b1c4af@suse.com> (raw)
In-Reply-To: <074dc3bb-6057-4f61-d516-d0fe3551165c@suse.com>
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.
--- 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)
next prev parent reply other threads:[~2023-01-05 16:05 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-05 15:57 [PATCH 00/11] x86/shadow: misc tidying Jan Beulich
2023-01-05 15:59 ` [PATCH 01/11] x86/shadow: replace sh_reset_l3_up_pointers() Jan Beulich
2023-01-06 0:55 ` Andrew Cooper
2023-01-09 8:35 ` Jan Beulich
2023-01-05 15:59 ` [PATCH 02/11] x86/shadow: convert sh_audit_flags()'es 1st parameter to domain Jan Beulich
2023-01-05 15:59 ` [PATCH 03/11] x86/shadow: drop hash_vcpu_foreach() Jan Beulich
2023-01-05 16:00 ` [PATCH 04/11] x86/shadow: rename hash_domain_foreach() Jan Beulich
2023-01-05 16:04 ` [PATCH 05/11] x86/shadow: move bogus HVM checks in sh_pagetable_dying() Jan Beulich
2023-01-06 1:00 ` Andrew Cooper
2023-01-09 8:39 ` Jan Beulich
2023-01-05 16:04 ` [PATCH 06/11] x86/shadow: drop a few uses of mfn_valid() Jan Beulich
2023-01-06 1:02 ` Andrew Cooper
2023-01-09 8:42 ` Jan Beulich
2023-01-05 16:05 ` Jan Beulich [this message]
2023-01-06 1:31 ` [PATCH 07/11] x86/shadow: L2H shadow type is PV32-only Andrew Cooper
2023-01-09 9:12 ` Jan Beulich
2023-01-05 16:05 ` [PATCH 08/11] x86/shadow: reduce effort of hash calculation Jan Beulich
2023-01-06 2:03 ` Andrew Cooper
2023-01-09 9:48 ` Jan Beulich
2023-01-05 16:06 ` [PATCH 09/11] x86/shadow: simplify conditionals in sh_{get,put}_ref() Jan Beulich
2023-01-05 16:07 ` [PATCH 10/11] x86/shadow: correct shadow type bounds checks Jan Beulich
2023-01-05 16:07 ` [PATCH 11/11] x86/shadow: sh_remove_all_mappings() is HVM-only Jan Beulich
2023-01-06 2:03 ` [PATCH 00/11] x86/shadow: misc tidying Andrew Cooper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2743393d-852d-b385-9eba-e22806b1c4af@suse.com \
--to=jbeulich@suse.com \
--cc=andrew.cooper3@citrix.com \
--cc=george.dunlap@citrix.com \
--cc=roger.pau@citrix.com \
--cc=tim@xen.org \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.