+ */
+static int core2_no_vpmu_do_rdmsr(unsigned int msr, uint64_t *msr_content)
+{
+ int type = -1, index = -1;
+ if ( !is_core2_vpmu_msr(msr, &type, &index) )
+ return 0;
+ *msr_content = 0;
+ return 1;
+}
+
+/*
+ * These functions are used in case vpmu is not enabled.
+ */
+struct arch_vpmu_ops core2_no_vpmu_ops = {
+ .do_rdmsr = core2_no_vpmu_do_rdmsr,
+ .do_cpuid = core2_no_vpmu_do_cpuid,
+};
+
int vmx_vpmu_initialise(struct vcpu *v, unsigned int vpmu_flags)
{
struct vpmu_struct *vpmu = vcpu_vpmu(v);
@@ -734,6 +787,10 @@ int vmx_vpmu_initialise(struct vcpu *v,
uint8_t cpu_model = current_cpu_data.x86_model;
int ret = 0;
+ vpmu->arch_vpmu_ops = &core2_no_vpmu_ops;
+ if ( !vpmu_flags )
+ return 0;
+
if ( family == 6 )
{
switch ( cpu_model )
diff -r a6b81234b189 xen/arch/x86/hvm/vpmu.c
--- a/xen/arch/x86/hvm/vpmu.c Mon Mar 11 16:13:42 2013 +0000
+++ b/xen/arch/x86/hvm/vpmu.c Wed Mar 13 09:54:00 2013 +0100
@@ -67,7 +67,7 @@ int vpmu_do_wrmsr(unsigned int msr, uint
{
struct vpmu_struct *vpmu = vcpu_vpmu(current);
- if ( vpmu->arch_vpmu_ops )
+ if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->do_wrmsr )
return vpmu->arch_vpmu_ops->do_wrmsr(msr, msr_content);
return 0;
}
@@ -76,7 +76,7 @@ int vpmu_do_rdmsr(unsigned int msr, uint
{
struct vpmu_struct *vpmu = vcpu_vpmu(current);
- if ( vpmu->arch_vpmu_ops )
+ if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->do_rdmsr )
return vpmu->arch_vpmu_ops->do_rdmsr(msr, msr_content);
return 0;
}
@@ -85,7 +85,7 @@ int vpmu_do_interrupt(struct cpu_user_re
{
struct vpmu_struct *vpmu = vcpu_vpmu(current);
- if ( vpmu->arch_vpmu_ops )
+ if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->do_interrupt )
return vpmu->arch_vpmu_ops->do_interrupt(regs);
return 0;
}
@@ -104,7 +104,7 @@ void vpmu_save(struct vcpu *v)
{
struct vpmu_struct *vpmu = vcpu_vpmu(v);
- if ( vpmu->arch_vpmu_ops )
+ if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->arch_vpmu_save )
vpmu->arch_vpmu_ops->arch_vpmu_save(v);
}
@@ -112,7 +112,7 @@ void vpmu_load(struct vcpu *v)
{
struct vpmu_struct *vpmu = vcpu_vpmu(v);
- if ( vpmu->arch_vpmu_ops )
+ if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->arch_vpmu_load )
vpmu->arch_vpmu_ops->arch_vpmu_load(v);
}
@@ -121,9 +121,6 @@ void vpmu_initialise(struct vcpu *v)
struct vpmu_struct *vpmu = vcpu_vpmu(v);
uint8_t vendor = current_cpu_data.x86_vendor;
- if ( !opt_vpmu_enabled )
- return;
-
if ( vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) )
vpmu_destroy(v);
vpmu_clear(vpmu);
@@ -153,7 +150,7 @@ void vpmu_destroy(struct vcpu *v)
{
struct vpmu_struct *vpmu = vcpu_vpmu(v);
- if ( vpmu->arch_vpmu_ops )
+ if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->arch_vpmu_destroy )
vpmu->arch_vpmu_ops->arch_vpmu_destroy(v);
}