[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v1 5/5] x86/msr: introduce guest_wrmsr()
The new function is responsible for handling WRMSR from both HVM and PV guests. Currently it handles only 2 MSRs: MSR_INTEL_PLATFORM_INFO MSR_INTEL_MISC_FEATURES_ENABLES It has a different behaviour compared to the old MSR handlers: if MSR is being handled by guest_wrmsr() then WRMSR will either succeed (if a guest is allowed to access it and provided a correct value based on its MSR policy) or produce a GP fault. A guest will never see a successful WRMSR of some MSR unknown to this function. guest_wrmsr() unifies and replaces the handling code from vmx_msr_write_intercept() and priv_op_write_msr(). Signed-off-by: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 7 ++++++- xen/arch/x86/hvm/vmx/vmx.c | 23 ---------------------- xen/arch/x86/msr.c | 44 ++++++++++++++++++++++++++++++++++++++++++ xen/arch/x86/pv/emul-priv-op.c | 22 ++++----------------- xen/include/asm-x86/msr.h | 1 + 5 files changed, 55 insertions(+), 42 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index ec7205ee32..524f9a37c0 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3465,7 +3465,7 @@ int hvm_msr_write_intercept(unsigned int msr, uint64_t msr_content, { struct vcpu *v = current; struct domain *d = v->domain; - int ret = X86EMUL_OKAY; + int ret; HVMTRACE_3D(MSR_WRITE, msr, (uint32_t)msr_content, (uint32_t)(msr_content >> 32)); @@ -3483,6 +3483,11 @@ int hvm_msr_write_intercept(unsigned int msr, uint64_t msr_content, return X86EMUL_OKAY; } + if ( (ret = guest_wrmsr(v, msr, msr_content)) != X86EMUL_UNHANDLEABLE ) + return ret; + else + ret = X86EMUL_OKAY; + switch ( msr ) { unsigned int index; diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index ac34383658..cea2a1ae55 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -3116,29 +3116,6 @@ static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content) goto gp_fault; break; - case MSR_INTEL_PLATFORM_INFO: - if ( msr_content || - rdmsr_safe(MSR_INTEL_PLATFORM_INFO, msr_content) ) - goto gp_fault; - break; - - case MSR_INTEL_MISC_FEATURES_ENABLES: - { - struct msr_vcpu_policy *vp = v->arch.msr; - bool old_cpuid_faulting = vp->misc_features_enables.cpuid_faulting; - - if ( msr_content & ~MSR_MISC_FEATURES_CPUID_FAULTING ) - goto gp_fault; - - vp->misc_features_enables.cpuid_faulting = - msr_content & MSR_MISC_FEATURES_CPUID_FAULTING; - - if ( cpu_has_cpuid_faulting && - (old_cpuid_faulting ^ vp->misc_features_enables.cpuid_faulting) ) - ctxt_switch_levelling(v); - break; - } - default: if ( passive_domain_do_wrmsr(msr, msr_content) ) return X86EMUL_OKAY; diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c index a822a132ad..9202a4a476 100644 --- a/xen/arch/x86/msr.c +++ b/xen/arch/x86/msr.c @@ -148,6 +148,50 @@ int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val) return X86EMUL_EXCEPTION; } +int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val) +{ + struct domain *d = v->domain; + struct msr_domain_policy *dp = d->arch.msr; + struct msr_vcpu_policy *vp = v->arch.msr; + + switch ( msr ) + { + case MSR_INTEL_PLATFORM_INFO: + goto gp_fault; + + case MSR_INTEL_MISC_FEATURES_ENABLES: + { + uint64_t rsvd = ~0ull; + bool old_cpuid_faulting = vp->misc_features_enables.cpuid_faulting; + + if ( !vp->misc_features_enables.available ) + goto gp_fault; + + if ( dp->plaform_info.cpuid_faulting ) + rsvd &= ~MSR_MISC_FEATURES_CPUID_FAULTING; + + if ( val & rsvd ) + goto gp_fault; + + vp->misc_features_enables.cpuid_faulting = + val & MSR_MISC_FEATURES_CPUID_FAULTING; + + if ( is_hvm_domain(d) && cpu_has_cpuid_faulting && + (old_cpuid_faulting ^ vp->misc_features_enables.cpuid_faulting) ) + ctxt_switch_levelling(v); + break; + } + + default: + return X86EMUL_UNHANDLEABLE; + } + + return X86EMUL_OKAY; + + gp_fault: + return X86EMUL_EXCEPTION; +} + /* * Local variables: * mode: C diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c index d563214fc4..d32af7d45d 100644 --- a/xen/arch/x86/pv/emul-priv-op.c +++ b/xen/arch/x86/pv/emul-priv-op.c @@ -983,6 +983,10 @@ static int priv_op_write_msr(unsigned int reg, uint64_t val, struct vcpu *curr = current; const struct domain *currd = curr->domain; bool vpmu_msr = false; + int ret; + + if ( (ret = guest_wrmsr(curr, reg, val)) != X86EMUL_UNHANDLEABLE ) + return ret; switch ( reg ) { @@ -1126,24 +1130,6 @@ static int priv_op_write_msr(unsigned int reg, uint64_t val, wrmsrl(reg, val); return X86EMUL_OKAY; - case MSR_INTEL_PLATFORM_INFO: - if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL || - val || rdmsr_safe(MSR_INTEL_PLATFORM_INFO, val) ) - break; - return X86EMUL_OKAY; - - case MSR_INTEL_MISC_FEATURES_ENABLES: - if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL || - (val & ~MSR_MISC_FEATURES_CPUID_FAULTING) || - rdmsr_safe(MSR_INTEL_MISC_FEATURES_ENABLES, temp) ) - break; - if ( (val & MSR_MISC_FEATURES_CPUID_FAULTING) && - !this_cpu(cpuid_faulting_enabled) ) - break; - curr->arch.msr->misc_features_enables.cpuid_faulting = - !!(val & MSR_MISC_FEATURES_CPUID_FAULTING); - return X86EMUL_OKAY; - case MSR_P6_PERFCTR(0) ... MSR_P6_PERFCTR(7): case MSR_P6_EVNTSEL(0) ... MSR_P6_EVNTSEL(3): case MSR_CORE_PERF_FIXED_CTR0 ... MSR_CORE_PERF_FIXED_CTR2: diff --git a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h index 9cc505cb40..751fa25a36 100644 --- a/xen/include/asm-x86/msr.h +++ b/xen/include/asm-x86/msr.h @@ -233,6 +233,7 @@ int init_vcpu_msr_policy(struct vcpu *v); * by the new MSR infrastructure. */ int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val); +int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val); #endif /* !__ASSEMBLY__ */ -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |