Jacob Shin
2011-May-05 00:54 UTC
[Xen-devel] [PATCH 0/3] AMD Family 15h Performance Monitor Counters patches
Hello, The following set of patches are for upcoming hardware changes in performance monitor counters on AMD Family 15h processors. The 4 existing legacy K7 performance monitor counter MSRs have been relocated to new addresses (old registers are still functional as aliases) and 2 new counters have been added. -Jacob Shin Advanced Micro Devices, Inc. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jacob Shin
2011-May-05 01:09 UTC
[Xen-devel] [PATCH 1/3] xenoprof: Update cpu_type to sync with upstream oprofile
# HG changeset patch # User Jacob Shin <jacob.shin@amd.com> # Date 1304461593 18000 # Node ID eeb1bb50ba13c36e44d4994e01d82d294f3c584a # Parent 476b0d68e7d5405babc1182da3b345b1e4cc1bca xenoprof: Update cpu_type to sync with upstream oprofile Update xenoprof''s cpu_type to match upstream oprofile. Currently AMD Family 11h ~ Family 15h are broken due to string mismatches. Signed-off-by: Jacob Shin <jacob.shin@amd.com> diff -r 476b0d68e7d5 -r eeb1bb50ba13 xen/arch/x86/oprofile/nmi_int.c --- a/xen/arch/x86/oprofile/nmi_int.c Sat Apr 30 09:48:16 2011 +0100 +++ b/xen/arch/x86/oprofile/nmi_int.c Tue May 03 17:26:33 2011 -0500 @@ -435,19 +435,19 @@ static int __init nmi_init(void) break; case 0x11: model = &op_athlon_spec; - cpu_type = "x86-64/family11"; + cpu_type = "x86-64/family11h"; break; case 0x12: model = &op_athlon_spec; - cpu_type = "x86-64/family12"; + cpu_type = "x86-64/family12h"; break; case 0x14: model = &op_athlon_spec; - cpu_type = "x86-64/family14"; + cpu_type = "x86-64/family14h"; break; case 0x15: model = &op_athlon_spec; - cpu_type = "x86-64/family15"; + cpu_type = "x86-64/family15h"; break; } break; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jacob Shin
2011-May-05 01:09 UTC
[Xen-devel] [PATCH 2/3] xenoprof: Add support for AMD Family 15h processors
# HG changeset patch # User Jacob Shin <jacob.shin@amd.com> # Date 1304524596 18000 # Node ID 349a9e537940f8bc340a2055cb5068b58809042f # Parent eeb1bb50ba13c36e44d4994e01d82d294f3c584a xenoprof: Add support for AMD Family 15h processors AMD Family 15h CPU mirrors legacy K7 performance monitor counters to a new location, and adds 2 new counters. This patch updates xenoprof to take advantage of the new counters. Signed-off-by: Jacob Shin <jacob.shin@amd.com> diff -r eeb1bb50ba13 -r 349a9e537940 xen/arch/x86/oprofile/nmi_int.c --- a/xen/arch/x86/oprofile/nmi_int.c Tue May 03 17:26:33 2011 -0500 +++ b/xen/arch/x86/oprofile/nmi_int.c Wed May 04 10:56:36 2011 -0500 @@ -30,7 +30,7 @@ struct op_counter_config counter_config[ struct op_counter_config counter_config[OP_MAX_COUNTER]; struct op_ibs_config ibs_config; -static struct op_x86_model_spec const *__read_mostly model; +struct op_x86_model_spec const *__read_mostly model; static struct op_msrs cpu_msrs[NR_CPUS]; static unsigned long saved_lvtpc[NR_CPUS]; @@ -446,7 +446,7 @@ static int __init nmi_init(void) cpu_type = "x86-64/family14h"; break; case 0x15: - model = &op_athlon_spec; + model = &op_fam15h_spec; cpu_type = "x86-64/family15h"; break; } diff -r eeb1bb50ba13 -r 349a9e537940 xen/arch/x86/oprofile/op_model_athlon.c --- a/xen/arch/x86/oprofile/op_model_athlon.c Tue May 03 17:26:33 2011 -0500 +++ b/xen/arch/x86/oprofile/op_model_athlon.c Wed May 04 10:56:36 2011 -0500 @@ -24,8 +24,13 @@ #include "op_x86_model.h" #include "op_counter.h" -#define NUM_COUNTERS 4 -#define NUM_CONTROLS 4 +#define K7_NUM_COUNTERS 4 +#define K7_NUM_CONTROLS 4 + +#define FAM15H_NUM_COUNTERS 6 +#define FAM15H_NUM_CONTROLS 6 + +#define MAX_COUNTERS FAM15H_NUM_COUNTERS #define CTR_READ(msr_content,msrs,c) do {rdmsrl(msrs->counters[(c)].addr, (msr_content));} while (0) #define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1);} while (0) @@ -44,9 +49,10 @@ #define CTRL_SET_HOST_ONLY(val, h) (val |= ((h & 0x1ULL) << 41)) #define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 0x1ULL) << 40)) -static unsigned long reset_value[NUM_COUNTERS]; +static unsigned long reset_value[MAX_COUNTERS]; extern char svm_stgi_label[]; +extern struct op_x86_model_spec const *__read_mostly model; #ifdef CONFIG_X86_64 u32 ibs_caps = 0; @@ -175,26 +181,44 @@ static void athlon_fill_in_addresses(str msrs->controls[3].addr = MSR_K7_EVNTSEL3; } - +static void fam15h_fill_in_addresses(struct op_msrs * const msrs) +{ + msrs->counters[0].addr = MSR_FAM15H_PERFCTR0; + msrs->counters[1].addr = MSR_FAM15H_PERFCTR1; + msrs->counters[2].addr = MSR_FAM15H_PERFCTR2; + msrs->counters[3].addr = MSR_FAM15H_PERFCTR3; + msrs->counters[4].addr = MSR_FAM15H_PERFCTR4; + msrs->counters[5].addr = MSR_FAM15H_PERFCTR5; + + msrs->controls[0].addr = MSR_FAM15H_EVNTSEL0; + msrs->controls[1].addr = MSR_FAM15H_EVNTSEL1; + msrs->controls[2].addr = MSR_FAM15H_EVNTSEL2; + msrs->controls[3].addr = MSR_FAM15H_EVNTSEL3; + msrs->controls[4].addr = MSR_FAM15H_EVNTSEL4; + msrs->controls[5].addr = MSR_FAM15H_EVNTSEL5; +} + static void athlon_setup_ctrs(struct op_msrs const * const msrs) { uint64_t msr_content; int i; + unsigned int const nr_ctrs = model->num_counters; + unsigned int const nr_ctrls = model->num_controls; /* clear all counters */ - for (i = 0 ; i < NUM_CONTROLS; ++i) { + for (i = 0 ; i < nr_ctrls; ++i) { CTRL_READ(msr_content, msrs, i); CTRL_CLEAR(msr_content); CTRL_WRITE(msr_content, msrs, i); } /* avoid a false detection of ctr overflows in NMI handler */ - for (i = 0; i < NUM_COUNTERS; ++i) { + for (i = 0; i < nr_ctrs; ++i) { CTR_WRITE(1, msrs, i); } /* enable active counters */ - for (i = 0; i < NUM_COUNTERS; ++i) { + for (i = 0; i < nr_ctrs; ++i) { if (counter_config[i].enabled) { reset_value[i] = counter_config[i].count; @@ -300,6 +324,7 @@ static int athlon_check_ctrs(unsigned in int mode = 0; struct vcpu *v = current; struct cpu_user_regs *guest_regs = guest_cpu_user_regs(); + unsigned int const nr_ctrs = model->num_counters; if (!guest_mode(regs) && (regs->eip == (unsigned long)svm_stgi_label)) { @@ -312,7 +337,7 @@ static int athlon_check_ctrs(unsigned in mode = xenoprofile_get_mode(v, regs); } - for (i = 0 ; i < NUM_COUNTERS; ++i) { + for (i = 0 ; i < nr_ctrs; ++i) { CTR_READ(msr_content, msrs, i); if (CTR_OVERFLOWED(msr_content)) { xenoprof_log_event(current, regs, eip, mode, i); @@ -373,7 +398,8 @@ static void athlon_start(struct op_msrs { uint64_t msr_content; int i; - for (i = 0 ; i < NUM_COUNTERS ; ++i) { + unsigned int const nr_ctrs = model->num_counters; + for (i = 0 ; i < nr_ctrs ; ++i) { if (reset_value[i]) { CTRL_READ(msr_content, msrs, i); CTRL_SET_ACTIVE(msr_content); @@ -401,10 +427,11 @@ static void athlon_stop(struct op_msrs c { uint64_t msr_content; int i; + unsigned int const nr_ctrs = model->num_counters; /* Subtle: stop on all counters to avoid race with * setting our pm callback */ - for (i = 0 ; i < NUM_COUNTERS ; ++i) { + for (i = 0 ; i < nr_ctrs ; ++i) { CTRL_READ(msr_content, msrs, i); CTRL_SET_INACTIVE(msr_content); CTRL_WRITE(msr_content, msrs, i); @@ -512,11 +539,21 @@ void __init ibs_init(void) #endif /* CONFIG_X86_64 */ struct op_x86_model_spec const op_athlon_spec = { - .num_counters = NUM_COUNTERS, - .num_controls = NUM_CONTROLS, + .num_counters = K7_NUM_COUNTERS, + .num_controls = K7_NUM_CONTROLS, .fill_in_addresses = &athlon_fill_in_addresses, .setup_ctrs = &athlon_setup_ctrs, .check_ctrs = &athlon_check_ctrs, .start = &athlon_start, .stop = &athlon_stop }; + +struct op_x86_model_spec const op_fam15h_spec = { + .num_counters = FAM15H_NUM_COUNTERS, + .num_controls = FAM15H_NUM_CONTROLS, + .fill_in_addresses = &fam15h_fill_in_addresses, + .setup_ctrs = &athlon_setup_ctrs, + .check_ctrs = &athlon_check_ctrs, + .start = &athlon_start, + .stop = &athlon_stop +}; diff -r eeb1bb50ba13 -r 349a9e537940 xen/arch/x86/oprofile/op_x86_model.h --- a/xen/arch/x86/oprofile/op_x86_model.h Tue May 03 17:26:33 2011 -0500 +++ b/xen/arch/x86/oprofile/op_x86_model.h Wed May 04 10:56:36 2011 -0500 @@ -48,6 +48,7 @@ extern struct op_x86_model_spec const op extern struct op_x86_model_spec const op_p4_spec; extern struct op_x86_model_spec const op_p4_ht2_spec; extern struct op_x86_model_spec const op_athlon_spec; +extern struct op_x86_model_spec const op_fam15h_spec; void arch_perfmon_setup_counters(void); #endif /* OP_X86_MODEL_H */ diff -r eeb1bb50ba13 -r 349a9e537940 xen/include/asm-x86/msr-index.h --- a/xen/include/asm-x86/msr-index.h Tue May 03 17:26:33 2011 -0500 +++ b/xen/include/asm-x86/msr-index.h Wed May 04 10:56:36 2011 -0500 @@ -223,6 +223,19 @@ #define MSR_K8_ENABLE_C1E 0xc0010055 #define MSR_K8_VM_CR 0xc0010114 #define MSR_K8_VM_HSAVE_PA 0xc0010117 + +#define MSR_FAM15H_EVNTSEL0 0xc0010200 +#define MSR_FAM15H_PERFCTR0 0xc0010201 +#define MSR_FAM15H_EVNTSEL1 0xc0010202 +#define MSR_FAM15H_PERFCTR1 0xc0010203 +#define MSR_FAM15H_EVNTSEL2 0xc0010204 +#define MSR_FAM15H_PERFCTR2 0xc0010205 +#define MSR_FAM15H_EVNTSEL3 0xc0010206 +#define MSR_FAM15H_PERFCTR3 0xc0010207 +#define MSR_FAM15H_EVNTSEL4 0xc0010208 +#define MSR_FAM15H_PERFCTR4 0xc0010209 +#define MSR_FAM15H_EVNTSEL5 0xc001020a +#define MSR_FAM15H_PERFCTR5 0xc001020b #define MSR_K8_FEATURE_MASK 0xc0011004 #define MSR_K8_EXT_FEATURE_MASK 0xc0011005 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jacob Shin
2011-May-05 01:09 UTC
[Xen-devel] [PATCH 3/3] hvm: vpmu: Add support for AMD Family 15h processors
# HG changeset patch # User Jacob Shin <jacob.shin@amd.com> # Date 1304554679 18000 # Node ID 43a81a05dbf7bbb6e29b283e0cd5f80d8ac04aab # Parent 349a9e537940f8bc340a2055cb5068b58809042f hvm: vpmu: Add support for AMD Family 15h processors AMD Family 15h CPU mirrors legacy K7 performance monitor counters to a new location, and adds 2 new counters. This patch updates HVM VPMU to take advantage of the new counters. Signed-off-by: Jacob Shin <jacob.shin@amd.com> diff -r 349a9e537940 -r 43a81a05dbf7 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Wed May 04 10:56:36 2011 -0500 +++ b/xen/arch/x86/hvm/svm/svm.c Wed May 04 19:17:59 2011 -0500 @@ -1235,6 +1235,18 @@ static int svm_msr_read_intercept(unsign case MSR_K7_EVNTSEL1: case MSR_K7_EVNTSEL2: case MSR_K7_EVNTSEL3: + case MSR_FAM15H_PERFCTR0: + case MSR_FAM15H_PERFCTR1: + case MSR_FAM15H_PERFCTR2: + case MSR_FAM15H_PERFCTR3: + case MSR_FAM15H_PERFCTR4: + case MSR_FAM15H_PERFCTR5: + case MSR_FAM15H_EVNTSEL0: + case MSR_FAM15H_EVNTSEL1: + case MSR_FAM15H_EVNTSEL2: + case MSR_FAM15H_EVNTSEL3: + case MSR_FAM15H_EVNTSEL4: + case MSR_FAM15H_EVNTSEL5: vpmu_do_rdmsr(msr, msr_content); break; @@ -1333,6 +1345,18 @@ static int svm_msr_write_intercept(unsig case MSR_K7_EVNTSEL1: case MSR_K7_EVNTSEL2: case MSR_K7_EVNTSEL3: + case MSR_FAM15H_PERFCTR0: + case MSR_FAM15H_PERFCTR1: + case MSR_FAM15H_PERFCTR2: + case MSR_FAM15H_PERFCTR3: + case MSR_FAM15H_PERFCTR4: + case MSR_FAM15H_PERFCTR5: + case MSR_FAM15H_EVNTSEL0: + case MSR_FAM15H_EVNTSEL1: + case MSR_FAM15H_EVNTSEL2: + case MSR_FAM15H_EVNTSEL3: + case MSR_FAM15H_EVNTSEL4: + case MSR_FAM15H_EVNTSEL5: vpmu_do_wrmsr(msr, msr_content); break; diff -r 349a9e537940 -r 43a81a05dbf7 xen/arch/x86/hvm/svm/vpmu.c --- a/xen/arch/x86/hvm/svm/vpmu.c Wed May 04 10:56:36 2011 -0500 +++ b/xen/arch/x86/hvm/svm/vpmu.c Wed May 04 19:17:59 2011 -0500 @@ -36,7 +36,9 @@ #include <public/hvm/save.h> #include <asm/hvm/vpmu.h> -#define NUM_COUNTERS 4 +#define F10H_NUM_COUNTERS 4 +#define F15H_NUM_COUNTERS 6 +#define MAX_NUM_COUNTERS F15H_NUM_COUNTERS #define MSR_F10H_EVNTSEL_GO_SHIFT 40 #define MSR_F10H_EVNTSEL_EN_SHIFT 22 @@ -46,6 +48,11 @@ #define is_pmu_enabled(msr) ((msr) & (1ULL << MSR_F10H_EVNTSEL_EN_SHIFT)) #define set_guest_mode(msr) (msr |= (1ULL << MSR_F10H_EVNTSEL_GO_SHIFT)) #define is_overflowed(msr) (!((msr) & (1ULL << (MSR_F10H_COUNTER_LENGTH-1)))) + +static int __read_mostly num_counters = 0; +static u32 __read_mostly *counters = NULL; +static u32 __read_mostly *ctrls = NULL; +static bool_t __read_mostly k7_counters_mirrored = 0; /* PMU Counter MSRs. */ u32 AMD_F10H_COUNTERS[] = { @@ -63,10 +70,28 @@ u32 AMD_F10H_CTRLS[] = { MSR_K7_EVNTSEL3 }; +u32 AMD_F15H_COUNTERS[] = { + MSR_FAM15H_PERFCTR0, + MSR_FAM15H_PERFCTR1, + MSR_FAM15H_PERFCTR2, + MSR_FAM15H_PERFCTR3, + MSR_FAM15H_PERFCTR4, + MSR_FAM15H_PERFCTR5 +}; + +u32 AMD_F15H_CTRLS[] = { + MSR_FAM15H_EVNTSEL0, + MSR_FAM15H_EVNTSEL1, + MSR_FAM15H_EVNTSEL2, + MSR_FAM15H_EVNTSEL3, + MSR_FAM15H_EVNTSEL4, + MSR_FAM15H_EVNTSEL5 +}; + /* storage for context switching */ struct amd_vpmu_context { - u64 counters[NUM_COUNTERS]; - u64 ctrls[NUM_COUNTERS]; + u64 counters[MAX_NUM_COUNTERS]; + u64 ctrls[MAX_NUM_COUNTERS]; u32 hw_lapic_lvtpc; }; @@ -78,10 +103,44 @@ static inline int get_pmu_reg_type(u32 a if ( (addr >= MSR_K7_PERFCTR0) && (addr <= MSR_K7_PERFCTR3) ) return MSR_TYPE_COUNTER; + if ( (addr >= MSR_FAM15H_EVNTSEL0) && (addr <= MSR_FAM15H_PERFCTR5 ) ) + { + if (addr & 1) + return MSR_TYPE_COUNTER; + else + return MSR_TYPE_CTRL; + } + /* unsupported registers */ return -1; } +static inline u32 get_fam15h_addr(u32 addr) +{ + switch ( addr ) + { + case MSR_K7_PERFCTR0: + return MSR_FAM15H_PERFCTR0; + case MSR_K7_PERFCTR1: + return MSR_FAM15H_PERFCTR1; + case MSR_K7_PERFCTR2: + return MSR_FAM15H_PERFCTR2; + case MSR_K7_PERFCTR3: + return MSR_FAM15H_PERFCTR3; + case MSR_K7_EVNTSEL0: + return MSR_FAM15H_EVNTSEL0; + case MSR_K7_EVNTSEL1: + return MSR_FAM15H_EVNTSEL1; + case MSR_K7_EVNTSEL2: + return MSR_FAM15H_EVNTSEL2; + case MSR_K7_EVNTSEL3: + return MSR_FAM15H_EVNTSEL3; + default: + break; + } + + return addr; +} static int amd_vpmu_do_interrupt(struct cpu_user_regs *regs) { @@ -110,12 +169,12 @@ static inline void context_restore(struc struct vpmu_struct *vpmu = vcpu_vpmu(v); struct amd_vpmu_context *ctxt = vpmu->context; - for ( i = 0; i < NUM_COUNTERS; i++ ) - wrmsrl(AMD_F10H_CTRLS[i], ctxt->ctrls[i]); + for ( i = 0; i < num_counters; i++ ) + wrmsrl(ctrls[i], ctxt->ctrls[i]); - for ( i = 0; i < NUM_COUNTERS; i++ ) + for ( i = 0; i < num_counters; i++ ) { - wrmsrl(AMD_F10H_COUNTERS[i], ctxt->counters[i]); + wrmsrl(counters[i], ctxt->counters[i]); /* Force an interrupt to allow guest reset the counter, if the value is positive */ @@ -147,11 +206,11 @@ static inline void context_save(struct v struct vpmu_struct *vpmu = vcpu_vpmu(v); struct amd_vpmu_context *ctxt = vpmu->context; - for ( i = 0; i < NUM_COUNTERS; i++ ) - rdmsrl(AMD_F10H_COUNTERS[i], ctxt->counters[i]); + for ( i = 0; i < num_counters; i++ ) + rdmsrl(counters[i], ctxt->counters[i]); - for ( i = 0; i < NUM_COUNTERS; i++ ) - rdmsrl(AMD_F10H_CTRLS[i], ctxt->ctrls[i]); + for ( i = 0; i < num_counters; i++ ) + rdmsrl(ctrls[i], ctxt->ctrls[i]); } static void amd_vpmu_save(struct vcpu *v) @@ -175,12 +234,18 @@ static void context_update(unsigned int struct vpmu_struct *vpmu = vcpu_vpmu(v); struct amd_vpmu_context *ctxt = vpmu->context; - for ( i = 0; i < NUM_COUNTERS; i++ ) - if ( msr == AMD_F10H_COUNTERS[i] ) + if ( k7_counters_mirrored && + ((msr >= MSR_K7_EVNTSEL0) && (msr <= MSR_K7_PERFCTR3)) ) + { + msr = get_fam15h_addr(msr); + } + + for ( i = 0; i < num_counters; i++ ) + if ( msr == counters[i] ) ctxt->counters[i] = msr_content; - for ( i = 0; i < NUM_COUNTERS; i++ ) - if ( msr == AMD_F10H_CTRLS[i] ) + for ( i = 0; i < num_counters; i++ ) + if ( msr == ctrls[i] ) ctxt->ctrls[i] = msr_content; ctxt->hw_lapic_lvtpc = apic_read(APIC_LVTPC); @@ -235,9 +300,30 @@ static void amd_vpmu_initialise(struct v { struct amd_vpmu_context *ctxt = NULL; struct vpmu_struct *vpmu = vcpu_vpmu(v); + __u8 family = current_cpu_data.x86; if ( vpmu->flags & VPMU_CONTEXT_ALLOCATED ) return; + + if ( counters == NULL ) + { + switch ( family ) + { + case 0x15: + num_counters = F15H_NUM_COUNTERS; + counters = AMD_F15H_COUNTERS; + ctrls = AMD_F15H_CTRLS; + k7_counters_mirrored = 1; + break; + case 0x10: + default: + num_counters = F10H_NUM_COUNTERS; + counters = AMD_F10H_COUNTERS; + ctrls = AMD_F10H_CTRLS; + k7_counters_mirrored = 0; + break; + } + } ctxt = xmalloc_bytes(sizeof(struct amd_vpmu_context)); diff -r 349a9e537940 -r 43a81a05dbf7 xen/arch/x86/hvm/vpmu.c --- a/xen/arch/x86/hvm/vpmu.c Wed May 04 10:56:36 2011 -0500 +++ b/xen/arch/x86/hvm/vpmu.c Wed May 04 19:17:59 2011 -0500 @@ -101,6 +101,7 @@ void vpmu_initialise(struct vcpu *v) switch ( family ) { case 0x10: + case 0x15: vpmu->arch_vpmu_ops = &amd_vpmu_ops; break; default: _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jan Beulich
2011-May-05 07:38 UTC
Re: [Xen-devel] [PATCH 2/3] xenoprof: Add support for AMD Family 15h processors
>>> On 05.05.11 at 03:09, Jacob Shin <jacob.shin@amd.com> wrote: > # HG changeset patch > # User Jacob Shin <jacob.shin@amd.com> > # Date 1304524596 18000 > # Node ID 349a9e537940f8bc340a2055cb5068b58809042f > # Parent eeb1bb50ba13c36e44d4994e01d82d294f3c584a > xenoprof: Add support for AMD Family 15h processors > > AMD Family 15h CPU mirrors legacy K7 performance monitor counters to > a new location, and adds 2 new counters. This patch updates xenoprof > to take advantage of the new counters. > > Signed-off-by: Jacob Shin <jacob.shin@amd.com> > > diff -r eeb1bb50ba13 -r 349a9e537940 xen/arch/x86/oprofile/nmi_int.c > --- a/xen/arch/x86/oprofile/nmi_int.c Tue May 03 17:26:33 2011 -0500 > +++ b/xen/arch/x86/oprofile/nmi_int.c Wed May 04 10:56:36 2011 -0500 > @@ -30,7 +30,7 @@ struct op_counter_config counter_config[ > struct op_counter_config counter_config[OP_MAX_COUNTER]; > struct op_ibs_config ibs_config; > > -static struct op_x86_model_spec const *__read_mostly model; > +struct op_x86_model_spec const *__read_mostly model; > static struct op_msrs cpu_msrs[NR_CPUS]; > static unsigned long saved_lvtpc[NR_CPUS]; > > @@ -446,7 +446,7 @@ static int __init nmi_init(void) > cpu_type = "x86-64/family14h"; > break; > case 0x15: > - model = &op_athlon_spec; > + model = &op_fam15h_spec;Let''s please call this op_amd_fam15h_spec. Jan> cpu_type = "x86-64/family15h"; > break; > } > diff -r eeb1bb50ba13 -r 349a9e537940 xen/arch/x86/oprofile/op_model_athlon.c > --- a/xen/arch/x86/oprofile/op_model_athlon.c Tue May 03 17:26:33 2011 -0500 > +++ b/xen/arch/x86/oprofile/op_model_athlon.c Wed May 04 10:56:36 2011 -0500 > @@ -24,8 +24,13 @@ > #include "op_x86_model.h" > #include "op_counter.h" > > -#define NUM_COUNTERS 4 > -#define NUM_CONTROLS 4 > +#define K7_NUM_COUNTERS 4 > +#define K7_NUM_CONTROLS 4 > + > +#define FAM15H_NUM_COUNTERS 6 > +#define FAM15H_NUM_CONTROLS 6 > + > +#define MAX_COUNTERS FAM15H_NUM_COUNTERS > > #define CTR_READ(msr_content,msrs,c) do {rdmsrl(msrs->counters[(c)].addr, > (msr_content));} while (0) > #define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned > int)(l), -1);} while (0) > @@ -44,9 +49,10 @@ > #define CTRL_SET_HOST_ONLY(val, h) (val |= ((h & 0x1ULL) << 41)) > #define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 0x1ULL) << 40)) > > -static unsigned long reset_value[NUM_COUNTERS]; > +static unsigned long reset_value[MAX_COUNTERS]; > > extern char svm_stgi_label[]; > +extern struct op_x86_model_spec const *__read_mostly model; > > #ifdef CONFIG_X86_64 > u32 ibs_caps = 0; > @@ -175,26 +181,44 @@ static void athlon_fill_in_addresses(str > msrs->controls[3].addr = MSR_K7_EVNTSEL3; > } > > - > +static void fam15h_fill_in_addresses(struct op_msrs * const msrs) > +{ > + msrs->counters[0].addr = MSR_FAM15H_PERFCTR0; > + msrs->counters[1].addr = MSR_FAM15H_PERFCTR1; > + msrs->counters[2].addr = MSR_FAM15H_PERFCTR2; > + msrs->counters[3].addr = MSR_FAM15H_PERFCTR3; > + msrs->counters[4].addr = MSR_FAM15H_PERFCTR4; > + msrs->counters[5].addr = MSR_FAM15H_PERFCTR5; > + > + msrs->controls[0].addr = MSR_FAM15H_EVNTSEL0; > + msrs->controls[1].addr = MSR_FAM15H_EVNTSEL1; > + msrs->controls[2].addr = MSR_FAM15H_EVNTSEL2; > + msrs->controls[3].addr = MSR_FAM15H_EVNTSEL3; > + msrs->controls[4].addr = MSR_FAM15H_EVNTSEL4; > + msrs->controls[5].addr = MSR_FAM15H_EVNTSEL5; > +} > + > static void athlon_setup_ctrs(struct op_msrs const * const msrs) > { > uint64_t msr_content; > int i; > + unsigned int const nr_ctrs = model->num_counters; > + unsigned int const nr_ctrls = model->num_controls; > > /* clear all counters */ > - for (i = 0 ; i < NUM_CONTROLS; ++i) { > + for (i = 0 ; i < nr_ctrls; ++i) { > CTRL_READ(msr_content, msrs, i); > CTRL_CLEAR(msr_content); > CTRL_WRITE(msr_content, msrs, i); > } > > /* avoid a false detection of ctr overflows in NMI handler */ > - for (i = 0; i < NUM_COUNTERS; ++i) { > + for (i = 0; i < nr_ctrs; ++i) { > CTR_WRITE(1, msrs, i); > } > > /* enable active counters */ > - for (i = 0; i < NUM_COUNTERS; ++i) { > + for (i = 0; i < nr_ctrs; ++i) { > if (counter_config[i].enabled) { > reset_value[i] = counter_config[i].count; > > @@ -300,6 +324,7 @@ static int athlon_check_ctrs(unsigned in > int mode = 0; > struct vcpu *v = current; > struct cpu_user_regs *guest_regs = guest_cpu_user_regs(); > + unsigned int const nr_ctrs = model->num_counters; > > if (!guest_mode(regs) && > (regs->eip == (unsigned long)svm_stgi_label)) { > @@ -312,7 +337,7 @@ static int athlon_check_ctrs(unsigned in > mode = xenoprofile_get_mode(v, regs); > } > > - for (i = 0 ; i < NUM_COUNTERS; ++i) { > + for (i = 0 ; i < nr_ctrs; ++i) { > CTR_READ(msr_content, msrs, i); > if (CTR_OVERFLOWED(msr_content)) { > xenoprof_log_event(current, regs, eip, mode, i); > @@ -373,7 +398,8 @@ static void athlon_start(struct op_msrs > { > uint64_t msr_content; > int i; > - for (i = 0 ; i < NUM_COUNTERS ; ++i) { > + unsigned int const nr_ctrs = model->num_counters; > + for (i = 0 ; i < nr_ctrs ; ++i) { > if (reset_value[i]) { > CTRL_READ(msr_content, msrs, i); > CTRL_SET_ACTIVE(msr_content); > @@ -401,10 +427,11 @@ static void athlon_stop(struct op_msrs c > { > uint64_t msr_content; > int i; > + unsigned int const nr_ctrs = model->num_counters; > > /* Subtle: stop on all counters to avoid race with > * setting our pm callback */ > - for (i = 0 ; i < NUM_COUNTERS ; ++i) { > + for (i = 0 ; i < nr_ctrs ; ++i) { > CTRL_READ(msr_content, msrs, i); > CTRL_SET_INACTIVE(msr_content); > CTRL_WRITE(msr_content, msrs, i); > @@ -512,11 +539,21 @@ void __init ibs_init(void) > #endif /* CONFIG_X86_64 */ > > struct op_x86_model_spec const op_athlon_spec = { > - .num_counters = NUM_COUNTERS, > - .num_controls = NUM_CONTROLS, > + .num_counters = K7_NUM_COUNTERS, > + .num_controls = K7_NUM_CONTROLS, > .fill_in_addresses = &athlon_fill_in_addresses, > .setup_ctrs = &athlon_setup_ctrs, > .check_ctrs = &athlon_check_ctrs, > .start = &athlon_start, > .stop = &athlon_stop > }; > + > +struct op_x86_model_spec const op_fam15h_spec = { > + .num_counters = FAM15H_NUM_COUNTERS, > + .num_controls = FAM15H_NUM_CONTROLS, > + .fill_in_addresses = &fam15h_fill_in_addresses, > + .setup_ctrs = &athlon_setup_ctrs, > + .check_ctrs = &athlon_check_ctrs, > + .start = &athlon_start, > + .stop = &athlon_stop > +}; > diff -r eeb1bb50ba13 -r 349a9e537940 xen/arch/x86/oprofile/op_x86_model.h > --- a/xen/arch/x86/oprofile/op_x86_model.h Tue May 03 17:26:33 2011 -0500 > +++ b/xen/arch/x86/oprofile/op_x86_model.h Wed May 04 10:56:36 2011 -0500 > @@ -48,6 +48,7 @@ extern struct op_x86_model_spec const op > extern struct op_x86_model_spec const op_p4_spec; > extern struct op_x86_model_spec const op_p4_ht2_spec; > extern struct op_x86_model_spec const op_athlon_spec; > +extern struct op_x86_model_spec const op_fam15h_spec; > > void arch_perfmon_setup_counters(void); > #endif /* OP_X86_MODEL_H */ > diff -r eeb1bb50ba13 -r 349a9e537940 xen/include/asm-x86/msr-index.h > --- a/xen/include/asm-x86/msr-index.h Tue May 03 17:26:33 2011 -0500 > +++ b/xen/include/asm-x86/msr-index.h Wed May 04 10:56:36 2011 -0500 > @@ -223,6 +223,19 @@ > #define MSR_K8_ENABLE_C1E 0xc0010055 > #define MSR_K8_VM_CR 0xc0010114 > #define MSR_K8_VM_HSAVE_PA 0xc0010117 > + > +#define MSR_FAM15H_EVNTSEL0 0xc0010200 > +#define MSR_FAM15H_PERFCTR0 0xc0010201 > +#define MSR_FAM15H_EVNTSEL1 0xc0010202 > +#define MSR_FAM15H_PERFCTR1 0xc0010203 > +#define MSR_FAM15H_EVNTSEL2 0xc0010204 > +#define MSR_FAM15H_PERFCTR2 0xc0010205 > +#define MSR_FAM15H_EVNTSEL3 0xc0010206 > +#define MSR_FAM15H_PERFCTR3 0xc0010207 > +#define MSR_FAM15H_EVNTSEL4 0xc0010208 > +#define MSR_FAM15H_PERFCTR4 0xc0010209 > +#define MSR_FAM15H_EVNTSEL5 0xc001020a > +#define MSR_FAM15H_PERFCTR5 0xc001020b > > #define MSR_K8_FEATURE_MASK 0xc0011004 > #define MSR_K8_EXT_FEATURE_MASK 0xc0011005 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jan Beulich
2011-May-05 07:43 UTC
Re: [Xen-devel] [PATCH 3/3] hvm: vpmu: Add support for AMD Family 15h processors
>>> On 05.05.11 at 03:09, Jacob Shin <jacob.shin@amd.com> wrote: > --- a/xen/arch/x86/hvm/vpmu.c Wed May 04 10:56:36 2011 -0500 > +++ b/xen/arch/x86/hvm/vpmu.c Wed May 04 19:17:59 2011 -0500 > @@ -101,6 +101,7 @@ void vpmu_initialise(struct vcpu *v) > switch ( family ) > { > case 0x10: > + case 0x15: > vpmu->arch_vpmu_ops = &amd_vpmu_ops; > break; > default:How about 0x11, 0x12, and 0x14? Jan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jacob Shin
2011-May-10 17:00 UTC
Re: [Xen-devel] [PATCH 3/3] hvm: vpmu: Add support for AMD Family 15h processors
On 05/05/2011 02:43 AM, Jan Beulich wrote:>>>> On 05.05.11 at 03:09, Jacob Shin<jacob.shin@amd.com> wrote: >> --- a/xen/arch/x86/hvm/vpmu.c Wed May 04 10:56:36 2011 -0500 >> +++ b/xen/arch/x86/hvm/vpmu.c Wed May 04 19:17:59 2011 -0500 >> @@ -101,6 +101,7 @@ void vpmu_initialise(struct vcpu *v) >> switch ( family ) >> { >> case 0x10: >> + case 0x15: >> vpmu->arch_vpmu_ops =&amd_vpmu_ops; >> break; >> default: > > How about 0x11, 0x12, and 0x14? >Family 11h does not have guest only event monitoring .. but yes, we can enable 12h and 14h in the same path as the 10h. I''ll send out a revised patchset later this afternoon. Thanks! _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-May-10 17:20 UTC
Re: [Xen-devel] [PATCH 3/3] hvm: vpmu: Add support for AMD Family 15h processors
On 10/05/2011 18:00, "Jacob Shin" <jacob.shin@amd.com> wrote:> On 05/05/2011 02:43 AM, Jan Beulich wrote: >>>>> On 05.05.11 at 03:09, Jacob Shin<jacob.shin@amd.com> wrote: >>> --- a/xen/arch/x86/hvm/vpmu.c Wed May 04 10:56:36 2011 -0500 >>> +++ b/xen/arch/x86/hvm/vpmu.c Wed May 04 19:17:59 2011 -0500 >>> @@ -101,6 +101,7 @@ void vpmu_initialise(struct vcpu *v) >>> switch ( family ) >>> { >>> case 0x10: >>> + case 0x15: >>> vpmu->arch_vpmu_ops =&amd_vpmu_ops; >>> break; >>> default: >> >> How about 0x11, 0x12, and 0x14? >> > > Family 11h does not have guest only event monitoring .. but yes, we can > enable 12h and 14h in the same path as the 10h. I''ll send out a revised > patchset later this afternoon.I already applied your patch series (with MSRs renamed as Jan recommended). So just send the above as a delta patch please. -- Keir> Thanks! > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/x_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel