# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1273737370 -3600
# Node ID ed3ed9404989e4bbbc18d76c6ec8462e9f646e02
# Parent b8dc98dc6c40f9138339d5bd8aa0e519a8786f1c
VPMU: Enable vpmu for svm
Signed-off-by: Wei Wang <wei.wang2@xxxxxxx>
---
xen/arch/x86/hvm/svm/svm.c | 32 ++++++++++++++++++++++-
xen/arch/x86/hvm/vpmu.c | 51 ++++++++++++++++++++++++++++++++------
xen/include/asm-x86/hvm/svm/svm.h | 1
3 files changed, 74 insertions(+), 10 deletions(-)
diff -r b8dc98dc6c40 -r ed3ed9404989 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Thu May 13 08:55:41 2010 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Thu May 13 08:56:10 2010 +0100
@@ -639,6 +639,7 @@ static void svm_ctxt_switch_from(struct
svm_fpu_leave(v);
svm_save_dr(v);
+ vpmu_save(v);
svm_sync_vmcb(v);
svm_vmload(root_vmcb[cpu]);
@@ -679,6 +680,7 @@ static void svm_ctxt_switch_to(struct vc
svm_vmsave(root_vmcb[cpu]);
svm_vmload(v->arch.hvm_svm.vmcb);
+ vpmu_load(v);
if ( cpu_has_rdtscp )
wrmsrl(MSR_TSC_AUX, hvm_msr_tsc_aux(v));
@@ -742,12 +744,15 @@ static int svm_vcpu_initialise(struct vc
return rc;
}
+ vpmu_initialise(v);
return 0;
}
static void svm_vcpu_destroy(struct vcpu *v)
{
svm_destroy_vmcb(v);
+ vpmu_destroy(v);
+ passive_domain_destroy(v);
}
static void svm_inject_exception(
@@ -810,7 +815,7 @@ static int svm_event_pending(struct vcpu
static int svm_do_pmu_interrupt(struct cpu_user_regs *regs)
{
- return 0;
+ return vpmu_do_interrupt(regs);
}
static int svm_cpu_prepare(unsigned int cpu)
@@ -1071,6 +1076,17 @@ static int svm_msr_read_intercept(struct
msr_content = vmcb->lastinttoip;
break;
+ case MSR_K7_PERFCTR0:
+ case MSR_K7_PERFCTR1:
+ case MSR_K7_PERFCTR2:
+ case MSR_K7_PERFCTR3:
+ case MSR_K7_EVNTSEL0:
+ case MSR_K7_EVNTSEL1:
+ case MSR_K7_EVNTSEL2:
+ case MSR_K7_EVNTSEL3:
+ vpmu_do_rdmsr(regs);
+ goto done;
+
default:
if ( rdmsr_viridian_regs(ecx, &msr_content) ||
@@ -1089,6 +1105,7 @@ static int svm_msr_read_intercept(struct
regs->eax = (uint32_t)msr_content;
regs->edx = (uint32_t)(msr_content >> 32);
+done:
HVMTRACE_3D (MSR_READ, ecx, regs->eax, regs->edx);
HVM_DBG_LOG(DBG_LEVEL_1, "returns: ecx=%x, eax=%lx, edx=%lx",
ecx, (unsigned long)regs->eax, (unsigned long)regs->edx);
@@ -1153,6 +1170,17 @@ static int svm_msr_write_intercept(struc
vmcb->lastinttoip = msr_content;
break;
+ case MSR_K7_PERFCTR0:
+ case MSR_K7_PERFCTR1:
+ case MSR_K7_PERFCTR2:
+ case MSR_K7_PERFCTR3:
+ case MSR_K7_EVNTSEL0:
+ case MSR_K7_EVNTSEL1:
+ case MSR_K7_EVNTSEL2:
+ case MSR_K7_EVNTSEL3:
+ vpmu_do_wrmsr(regs);
+ goto done;
+
default:
if ( wrmsr_viridian_regs(ecx, msr_content) )
break;
@@ -1169,7 +1197,7 @@ static int svm_msr_write_intercept(struc
}
break;
}
-
+done:
return X86EMUL_OKAY;
gpf:
diff -r b8dc98dc6c40 -r ed3ed9404989 xen/arch/x86/hvm/vpmu.c
--- a/xen/arch/x86/hvm/vpmu.c Thu May 13 08:55:41 2010 +0100
+++ b/xen/arch/x86/hvm/vpmu.c Thu May 13 08:56:10 2010 +0100
@@ -30,6 +30,8 @@
#include <public/sched.h>
#include <public/hvm/save.h>
#include <asm/hvm/vpmu.h>
+#include <asm/hvm/svm/svm.h>
+#include <asm/hvm/svm/vmcb.h>
static int __read_mostly opt_vpmu_enabled;
boolean_param("vpmu", opt_vpmu_enabled);
@@ -78,9 +80,14 @@ void vpmu_load(struct vcpu *v)
}
extern struct arch_vpmu_ops core2_vpmu_ops;
+extern struct arch_vpmu_ops amd_vpmu_ops;
+
void vpmu_initialise(struct vcpu *v)
{
struct vpmu_struct *vpmu = vcpu_vpmu(v);
+ __u8 vendor = current_cpu_data.x86_vendor;
+ __u8 family = current_cpu_data.x86;
+ __u8 cpu_model = current_cpu_data.x86_model;
if ( !opt_vpmu_enabled )
return;
@@ -88,17 +95,45 @@ void vpmu_initialise(struct vcpu *v)
if ( vpmu->flags & VPMU_CONTEXT_ALLOCATED )
vpmu_destroy(v);
- if ( current_cpu_data.x86 == 6 )
+ switch ( vendor )
{
- switch ( current_cpu_data.x86_model )
+ case X86_VENDOR_AMD:
{
- case 15:
- case 23:
- case 26:
- case 29:
- vpmu->arch_vpmu_ops = &core2_vpmu_ops;
- break;
+ switch ( family )
+ {
+ case 0x10:
+ vpmu->arch_vpmu_ops = &amd_vpmu_ops;
+ break;
+ default:
+ printk("VMPU: Initialization failed. "
+ "AMD processor family %d has not "
+ "been supported\n", family);
+ return;
+ }
}
+ break;
+
+ case X86_VENDOR_INTEL:
+ {
+ if ( family == 6 )
+ {
+ switch ( cpu_model )
+ {
+ case 15:
+ case 23:
+ case 26:
+ case 29:
+ vpmu->arch_vpmu_ops = &core2_vpmu_ops;
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ printk("VMPU: Initialization failed. "
+ "Unknown CPU vendor %d\n", vendor);
+ return;
}
if ( vpmu->arch_vpmu_ops != NULL )
diff -r b8dc98dc6c40 -r ed3ed9404989 xen/include/asm-x86/hvm/svm/svm.h
--- a/xen/include/asm-x86/hvm/svm/svm.h Thu May 13 08:55:41 2010 +0100
+++ b/xen/include/asm-x86/hvm/svm/svm.h Thu May 13 08:56:10 2010 +0100
@@ -27,6 +27,7 @@
#include <asm/processor.h>
#include <asm/hvm/svm/vmcb.h>
#include <asm/i387.h>
+#include <asm/hvm/vpmu.h>
void svm_dump_vmcb(const char *from, struct vmcb_struct *vmcb);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|