[prev in list] [next in list] [prev in thread] [next in thread]
List: xen-cvs
Subject: [Xen-changelog] [xen master] VMX/vPMU: fix DebugCtl MSR handling
From: patchbot () xen ! org
Date: 2014-08-24 23:35:37
Message-ID: E1XLhJx-0000Wa-5b () xenbits ! xen ! org
[Download RAW message or body]
commit 2d9b91f1aeaa08a8cc261efae3d9c8dca56edf4d
Author: Jan Beulich <jbeulich@suse.com>
AuthorDate: Fri Aug 22 14:30:27 2014 +0200
Commit: Jan Beulich <jbeulich@suse.com>
CommitDate: Fri Aug 22 14:30:27 2014 +0200
VMX/vPMU: fix DebugCtl MSR handling
- writes with one of the vPMU-supported flags and some unsupported one
set got accepted, leading to a VM entry failure
- writes with one of the vPMU-supported flags set but the Debug Store
feature unavailable produced a #GP (other than other writes to this
MSR with unsupported bits set)
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
---
xen/arch/x86/hvm/svm/svm.c | 2 +-
xen/arch/x86/hvm/svm/vpmu.c | 5 ++++-
xen/arch/x86/hvm/vmx/vmx.c | 4 ++--
xen/arch/x86/hvm/vmx/vpmu_core2.c | 25 ++++++++++++++-----------
xen/arch/x86/hvm/vpmu.c | 4 ++--
xen/include/asm-x86/hvm/vpmu.h | 5 +++--
6 files changed, 26 insertions(+), 19 deletions(-)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 71b8a6a..98b6b13 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1789,7 +1789,7 @@ static int svm_msr_write_intercept(unsigned int msr, uint64_t msr_content)
case MSR_AMD_FAM15H_EVNTSEL3:
case MSR_AMD_FAM15H_EVNTSEL4:
case MSR_AMD_FAM15H_EVNTSEL5:
- vpmu_do_wrmsr(msr, msr_content);
+ vpmu_do_wrmsr(msr, msr_content, 0);
break;
case MSR_IA32_MCx_MISC(4): /* Threshold register */
diff --git a/xen/arch/x86/hvm/svm/vpmu.c b/xen/arch/x86/hvm/svm/vpmu.c
index 3ac7d53..8e07a98 100644
--- a/xen/arch/x86/hvm/svm/vpmu.c
+++ b/xen/arch/x86/hvm/svm/vpmu.c
@@ -278,11 +278,14 @@ static void context_update(unsigned int msr, u64 msr_content)
}
}
-static int amd_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content)
+static int amd_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content,
+ uint64_t supported)
{
struct vcpu *v = current;
struct vpmu_struct *vpmu = vcpu_vpmu(v);
+ ASSERT(!supported);
+
/* For all counters, enable guest only mode for HVM guest */
if ( (get_pmu_reg_type(msr) == MSR_TYPE_CTRL) &&
!(is_guest_mode(msr_content)) )
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 46eeee2..f2496c4 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -2249,7 +2249,7 @@ static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content)
if ( msr_content & ~supported )
{
/* Perhaps some other bits are supported in vpmu. */
- if ( !vpmu_do_wrmsr(msr, msr_content) )
+ if ( !vpmu_do_wrmsr(msr, msr_content, supported) )
break;
}
if ( msr_content & IA32_DEBUGCTLMSR_LBR )
@@ -2278,7 +2278,7 @@ static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content)
goto gp_fault;
break;
default:
- if ( vpmu_do_wrmsr(msr, msr_content) )
+ if ( vpmu_do_wrmsr(msr, msr_content, 0) )
return X86EMUL_OKAY;
if ( passive_domain_do_wrmsr(msr, msr_content) )
return X86EMUL_OKAY;
diff --git a/xen/arch/x86/hvm/vmx/vpmu_core2.c b/xen/arch/x86/hvm/vmx/vpmu_core2.c
index ccd14d9..e4b9d7b 100644
--- a/xen/arch/x86/hvm/vmx/vpmu_core2.c
+++ b/xen/arch/x86/hvm/vmx/vpmu_core2.c
@@ -454,7 +454,8 @@ static int core2_vpmu_msr_common_check(u32 msr_index, int *type, int *index)
return 1;
}
-static int core2_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content)
+static int core2_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content,
+ uint64_t supported)
{
u64 global_ctrl, non_global_ctrl;
char pmu_enable = 0;
@@ -469,24 +470,26 @@ static int core2_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content)
/* Special handling for BTS */
if ( msr == MSR_IA32_DEBUGCTLMSR )
{
- uint64_t supported = IA32_DEBUGCTLMSR_TR | IA32_DEBUGCTLMSR_BTS |
- IA32_DEBUGCTLMSR_BTINT;
+ supported |= IA32_DEBUGCTLMSR_TR | IA32_DEBUGCTLMSR_BTS |
+ IA32_DEBUGCTLMSR_BTINT;
if ( cpu_has(¤t_cpu_data, X86_FEATURE_DSCPL) )
supported |= IA32_DEBUGCTLMSR_BTS_OFF_OS |
IA32_DEBUGCTLMSR_BTS_OFF_USR;
- if ( msr_content & supported )
- {
- if ( vpmu_is_set(vpmu, VPMU_CPU_HAS_BTS) )
- return 1;
- gdprintk(XENLOG_WARNING, "Debug Store is not supported on this cpu\n");
- hvm_inject_hw_exception(TRAP_gp_fault, 0);
- return 0;
- }
+ if ( !(msr_content & ~supported) &&
+ vpmu_is_set(vpmu, VPMU_CPU_HAS_BTS) )
+ return 1;
+ if ( (msr_content & supported) &&
+ !vpmu_is_set(vpmu, VPMU_CPU_HAS_BTS) )
+ printk(XENLOG_G_WARNING
+ "%pv: Debug Store unsupported on this CPU\n",
+ current);
}
return 0;
}
+ ASSERT(!supported);
+
core2_vpmu_cxt = vpmu->context;
switch ( msr )
{
diff --git a/xen/arch/x86/hvm/vpmu.c b/xen/arch/x86/hvm/vpmu.c
index 63765fa..15d5b6f 100644
--- a/xen/arch/x86/hvm/vpmu.c
+++ b/xen/arch/x86/hvm/vpmu.c
@@ -64,12 +64,12 @@ static void __init parse_vpmu_param(char *s)
}
}
-int vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content)
+int vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content, uint64_t supported)
{
struct vpmu_struct *vpmu = vcpu_vpmu(current);
if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->do_wrmsr )
- return vpmu->arch_vpmu_ops->do_wrmsr(msr, msr_content);
+ return vpmu->arch_vpmu_ops->do_wrmsr(msr, msr_content, supported);
return 0;
}
diff --git a/xen/include/asm-x86/hvm/vpmu.h b/xen/include/asm-x86/hvm/vpmu.h
index 40f63fb..9a5ac01 100644
--- a/xen/include/asm-x86/hvm/vpmu.h
+++ b/xen/include/asm-x86/hvm/vpmu.h
@@ -45,7 +45,8 @@
/* Arch specific operations shared by all vpmus */
struct arch_vpmu_ops {
- int (*do_wrmsr)(unsigned int msr, uint64_t msr_content);
+ int (*do_wrmsr)(unsigned int msr, uint64_t msr_content,
+ uint64_t supported);
int (*do_rdmsr)(unsigned int msr, uint64_t *msr_content);
int (*do_interrupt)(struct cpu_user_regs *regs);
void (*do_cpuid)(unsigned int input,
@@ -86,7 +87,7 @@ struct vpmu_struct {
#define vpmu_is_set(_vpmu, _x) ((_vpmu)->flags & (_x))
#define vpmu_clear(_vpmu) ((_vpmu)->flags = 0)
-int vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content);
+int vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content, uint64_t supported);
int vpmu_do_rdmsr(unsigned int msr, uint64_t *msr_content);
int vpmu_do_interrupt(struct cpu_user_regs *regs);
void vpmu_do_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xen.org
http://lists.xensource.com/xen-changelog
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic