|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 5/5] x86/pv: Simplify emulation for the 64bit base MSRs
is_pv_32bit_domain() is an expensive predicate, but isn't used for speculative
safety in this case. Swap to checking the Long Mode bit in the CPUID policy,
which is the architecturally correct behaviour.
is_canonical_address() isn't a trivial predicate, but it will become more
complicated when 5-level support is added. Rearrange write_msr() to collapse
the common checks.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>
For reference, the diff is:
add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-152 (-152)
Function old new delta
read_msr 1075 1030 -45
write_msr 1537 1430 -107
but this isn't the point of the change.
---
xen/arch/x86/pv/emul-priv-op.c | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
index 9dd1d59423..0fd95fe9fa 100644
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -848,6 +848,7 @@ static int read_msr(unsigned int reg, uint64_t *val,
{
struct vcpu *curr = current;
const struct domain *currd = curr->domain;
+ const struct cpuid_policy *cp = currd->arch.cpuid;
bool vpmu_msr = false;
int ret;
@@ -869,19 +870,19 @@ static int read_msr(unsigned int reg, uint64_t *val,
return X86EMUL_OKAY;
case MSR_FS_BASE:
- if ( is_pv_32bit_domain(currd) )
+ if ( !cp->extd.lm )
break;
*val = read_fs_base();
return X86EMUL_OKAY;
case MSR_GS_BASE:
- if ( is_pv_32bit_domain(currd) )
+ if ( !cp->extd.lm )
break;
*val = read_gs_base();
return X86EMUL_OKAY;
case MSR_SHADOW_GS_BASE:
- if ( is_pv_32bit_domain(currd) )
+ if ( !cp->extd.lm )
break;
*val = curr->arch.pv.gs_base_user;
return X86EMUL_OKAY;
@@ -975,6 +976,7 @@ static int write_msr(unsigned int reg, uint64_t val,
{
struct vcpu *curr = current;
const struct domain *currd = curr->domain;
+ const struct cpuid_policy *cp = currd->arch.cpuid;
bool vpmu_msr = false;
int ret;
@@ -991,22 +993,22 @@ static int write_msr(unsigned int reg, uint64_t val,
uint64_t temp;
case MSR_FS_BASE:
- if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) )
- break;
- write_fs_base(val);
- return X86EMUL_OKAY;
-
case MSR_GS_BASE:
- if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) )
- break;
- write_gs_base(val);
- return X86EMUL_OKAY;
-
case MSR_SHADOW_GS_BASE:
- if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) )
+ if ( !cp->extd.lm || !is_canonical_address(val) )
break;
- write_gs_shadow(val);
- curr->arch.pv.gs_base_user = val;
+
+ if ( reg == MSR_FS_BASE )
+ write_fs_base(val);
+ else if ( reg == MSR_GS_BASE )
+ write_gs_base(val);
+ else if ( reg == MSR_SHADOW_GS_BASE )
+ {
+ write_gs_shadow(val);
+ curr->arch.pv.gs_base_user = val;
+ }
+ else
+ ASSERT_UNREACHABLE();
return X86EMUL_OKAY;
case MSR_EFER:
--
2.11.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |