[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 |