From patchwork Wed Aug 30 10:34:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Dyasli X-Patchwork-Id: 9929275 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2B7E460309 for ; Wed, 30 Aug 2017 10:37:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 33A4628421 for ; Wed, 30 Aug 2017 10:37:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 287762847B; Wed, 30 Aug 2017 10:37:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A5E5728421 for ; Wed, 30 Aug 2017 10:37:08 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dn0KZ-00011H-Lj; Wed, 30 Aug 2017 10:34:43 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dn0KY-00010A-0j for xen-devel@lists.xen.org; Wed, 30 Aug 2017 10:34:42 +0000 Received: from [85.158.143.35] by server-5.bemta-6.messagelabs.com id C2/A0-03454-1C496A95; Wed, 30 Aug 2017 10:34:41 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpjkeJIrShJLcpLzFFi42JxWrohUvfAlGW RBm3v9CyWfFzM4sDocXT3b6YAxijWzLyk/IoE1oz7f26xFMw3qtj8dyJLA+N/tS5GTg4JAX+J zb2NbCA2m4CexMbZr5hAbBEBWYnVXXPYuxi5OJgFtjBLzOt8zgySEBawkGi+/hfMZhFQlXiys p0FxOYVsJG4e+o1G8RQeYldbRdZQWxOAVuJY78PMoLYQkA1/a8XsEPYqhKvX+yC6hWUODnzCZ jNLCAhcfDFC+YJjLyzkKRmIUktYGRaxahRnFpUllqka2Shl1SUmZ5RkpuYmaNraGCml5taXJy YnpqTmFSsl5yfu4kRGD4MQLCD8fzawEOMkhxMSqK8MZOWRQrxJeWnVGYkFmfEF5XmpBYfYpTh 4FCS4N02ESgnWJSanlqRlpkDDGSYtAQHj5IIb/hkoDRvcUFibnFmOkTqFKOilDhvGUhCACSRU ZoH1waLnkuMslLCvIxAhwjxFKQW5WaWoMq/YhTnYFQS5l0NMoUnM68EbvoroMVMQItjvZaCLC 5JREhJNTDOZ/yiHfxu/W5BB1bVS6c7CpraxfYy8H9LDWt+ENB8MNot+7R9c7P/hcg/flX+t7b FrVwVeGqx9hOj+hsXTX8oiyi1/xB9lr5hU1qzcMaX8yuqDbxvzv3yTLO/wkptw9XZ7MYOHcE3 ZWyf/xP5PTXqgm7m0qSLd577GGwyVcpSSl7ZyTolklGJpTgj0VCLuag4EQDlR7qbmQIAAA== X-Env-Sender: prvs=408f3fb1e=sergey.dyasli@citrix.com X-Msg-Ref: server-9.tower-21.messagelabs.com!1504089279!80131680!1 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 59189 invoked from network); 30 Aug 2017 10:34:40 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-9.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 30 Aug 2017 10:34:40 -0000 X-IronPort-AV: E=Sophos;i="5.41,448,1498521600"; d="scan'208";a="437433974" From: Sergey Dyasli To: Date: Wed, 30 Aug 2017 11:34:33 +0100 Message-ID: <20170830103433.6605-6-sergey.dyasli@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170830103433.6605-1-sergey.dyasli@citrix.com> References: <20170830103433.6605-1-sergey.dyasli@citrix.com> MIME-Version: 1.0 Cc: Sergey Dyasli , Kevin Tian , Stefano Stabellini , Wei Liu , Jun Nakajima , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Jan Beulich Subject: [Xen-devel] [PATCH v1 5/5] x86/msr: introduce guest_wrmsr() X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 Reviewed-by: Kevin Tian --- 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__ */