[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v5 07/17] x86/VPMU: Add public xenpmu.h
Add pmu.h header files, move various macros and structures that will be shared between hypervisor and PV guests to it. Move MSR banks out of architectural PMU structures to allow for larger sizes in the future. The banks are allocated immediately after the context and PMU structures store offsets to them. Signed-off-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> --- xen/arch/x86/hvm/svm/vpmu.c | 71 ++++++++++++++------------ xen/arch/x86/hvm/vmx/vpmu_core2.c | 87 +++++++++++++++++--------------- xen/arch/x86/hvm/vpmu.c | 1 + xen/arch/x86/oprofile/op_model_ppro.c | 6 ++- xen/include/asm-x86/hvm/vmx/vpmu_core2.h | 32 ------------ xen/include/asm-x86/hvm/vpmu.h | 13 ++--- xen/include/public/arch-arm.h | 3 ++ xen/include/public/arch-x86/pmu.h | 63 +++++++++++++++++++++++ xen/include/public/pmu.h | 38 ++++++++++++++ 9 files changed, 199 insertions(+), 115 deletions(-) delete mode 100644 xen/include/asm-x86/hvm/vmx/vpmu_core2.h create mode 100644 xen/include/public/arch-x86/pmu.h create mode 100644 xen/include/public/pmu.h diff --git a/xen/arch/x86/hvm/svm/vpmu.c b/xen/arch/x86/hvm/svm/vpmu.c index 2fbe2c1..d199f08 100644 --- a/xen/arch/x86/hvm/svm/vpmu.c +++ b/xen/arch/x86/hvm/svm/vpmu.c @@ -30,10 +30,7 @@ #include <asm/apic.h> #include <asm/hvm/vlapic.h> #include <asm/hvm/vpmu.h> - -#define F10H_NUM_COUNTERS 4 -#define F15H_NUM_COUNTERS 6 -#define MAX_NUM_COUNTERS F15H_NUM_COUNTERS +#include <public/pmu.h> #define MSR_F10H_EVNTSEL_GO_SHIFT 40 #define MSR_F10H_EVNTSEL_EN_SHIFT 22 @@ -49,6 +46,10 @@ static const u32 __read_mostly *counters; static const u32 __read_mostly *ctrls; static bool_t __read_mostly k7_counters_mirrored; +#define F10H_NUM_COUNTERS 4 +#define F15H_NUM_COUNTERS 6 +#define AMD_MAX_COUNTERS 6 + /* PMU Counter MSRs. */ static const u32 AMD_F10H_COUNTERS[] = { MSR_K7_PERFCTR0, @@ -83,13 +84,6 @@ static const u32 AMD_F15H_CTRLS[] = { MSR_AMD_FAM15H_EVNTSEL5 }; -/* storage for context switching */ -struct amd_vpmu_context { - u64 counters[MAX_NUM_COUNTERS]; - u64 ctrls[MAX_NUM_COUNTERS]; - bool_t msr_bitmap_set; -}; - static inline int get_pmu_reg_type(u32 addr) { if ( (addr >= MSR_K7_EVNTSEL0) && (addr <= MSR_K7_EVNTSEL3) ) @@ -142,7 +136,7 @@ static void amd_vpmu_set_msr_bitmap(struct vcpu *v) { unsigned int i; struct vpmu_struct *vpmu = vcpu_vpmu(v); - struct amd_vpmu_context *ctxt = vpmu->context; + struct xen_pmu_amd_ctxt *ctxt = vpmu->context; for ( i = 0; i < num_counters; i++ ) { @@ -157,7 +151,7 @@ static void amd_vpmu_unset_msr_bitmap(struct vcpu *v) { unsigned int i; struct vpmu_struct *vpmu = vcpu_vpmu(v); - struct amd_vpmu_context *ctxt = vpmu->context; + struct xen_pmu_amd_ctxt *ctxt = vpmu->context; for ( i = 0; i < num_counters; i++ ) { @@ -177,19 +171,22 @@ static inline void context_load(struct vcpu *v) { unsigned int i; struct vpmu_struct *vpmu = vcpu_vpmu(v); - struct amd_vpmu_context *ctxt = vpmu->context; + struct xen_pmu_amd_ctxt *ctxt = vpmu->context; + uint64_t *counter_regs = vpmu_reg_pointer(ctxt, counters); + uint64_t *ctrl_regs = vpmu_reg_pointer(ctxt, ctrls); for ( i = 0; i < num_counters; i++ ) { - wrmsrl(counters[i], ctxt->counters[i]); - wrmsrl(ctrls[i], ctxt->ctrls[i]); + wrmsrl(counters[i], counter_regs[i]); + wrmsrl(ctrls[i], ctrl_regs[i]); } } static void amd_vpmu_load(struct vcpu *v) { struct vpmu_struct *vpmu = vcpu_vpmu(v); - struct amd_vpmu_context *ctxt = vpmu->context; + struct xen_pmu_amd_ctxt *ctxt = vpmu->context; + uint64_t *ctrl_regs = vpmu_reg_pointer(ctxt, ctrls); vpmu_reset(vpmu, VPMU_FROZEN); @@ -198,7 +195,7 @@ static void amd_vpmu_load(struct vcpu *v) unsigned int i; for ( i = 0; i < num_counters; i++ ) - wrmsrl(ctrls[i], ctxt->ctrls[i]); + wrmsrl(ctrls[i], ctrl_regs[i]); return; } @@ -212,17 +209,18 @@ static inline void context_save(struct vcpu *v) { unsigned int i; struct vpmu_struct *vpmu = vcpu_vpmu(v); - struct amd_vpmu_context *ctxt = vpmu->context; + struct xen_pmu_amd_ctxt *ctxt = vpmu->context; + uint64_t *counter_regs = vpmu_reg_pointer(ctxt, counters); /* No need to save controls -- they are saved in amd_vpmu_do_wrmsr */ for ( i = 0; i < num_counters; i++ ) - rdmsrl(counters[i], ctxt->counters[i]); + rdmsrl(counters[i], counter_regs[i]); } static int amd_vpmu_save(struct vcpu *v) { struct vpmu_struct *vpmu = vcpu_vpmu(v); - struct amd_vpmu_context *ctx = vpmu->context; + struct xen_pmu_amd_ctxt *ctx = vpmu->context; unsigned int i; /* @@ -256,7 +254,9 @@ static void context_update(unsigned int msr, u64 msr_content) unsigned int i; struct vcpu *v = current; struct vpmu_struct *vpmu = vcpu_vpmu(v); - struct amd_vpmu_context *ctxt = vpmu->context; + struct xen_pmu_amd_ctxt *ctxt = vpmu->context; + uint64_t *counter_regs = vpmu_reg_pointer(ctxt, counters); + uint64_t *ctrl_regs = vpmu_reg_pointer(ctxt, ctrls); if ( k7_counters_mirrored && ((msr >= MSR_K7_EVNTSEL0) && (msr <= MSR_K7_PERFCTR3)) ) @@ -268,12 +268,12 @@ static void context_update(unsigned int msr, u64 msr_content) { if ( msr == ctrls[i] ) { - ctxt->ctrls[i] = msr_content; + ctrl_regs[i] = msr_content; return; } else if (msr == counters[i] ) { - ctxt->counters[i] = msr_content; + counter_regs[i] = msr_content; return; } } @@ -300,7 +300,7 @@ static int amd_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content) vpmu_set(vpmu, VPMU_RUNNING); if ( is_hvm_domain(v->domain) && - !((struct amd_vpmu_context *)vpmu->context)->msr_bitmap_set ) + !((struct xen_pmu_amd_ctxt *)vpmu->context)->msr_bitmap_set ) amd_vpmu_set_msr_bitmap(v); } @@ -310,7 +310,7 @@ static int amd_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content) { vpmu_reset(vpmu, VPMU_RUNNING); if ( is_hvm_domain(v->domain) && - ((struct amd_vpmu_context *)vpmu->context)->msr_bitmap_set ) + ((struct xen_pmu_amd_ctxt *)vpmu->context)->msr_bitmap_set ) amd_vpmu_unset_msr_bitmap(v); release_pmu_ownship(PMU_OWNER_HVM); } @@ -351,7 +351,7 @@ static int amd_vpmu_do_rdmsr(unsigned int msr, uint64_t *msr_content) static int amd_vpmu_initialise(struct vcpu *v) { - struct amd_vpmu_context *ctxt; + struct xen_pmu_amd_ctxt *ctxt; struct vpmu_struct *vpmu = vcpu_vpmu(v); uint8_t family = current_cpu_data.x86; @@ -381,7 +381,9 @@ static int amd_vpmu_initialise(struct vcpu *v) } } - ctxt = xzalloc(struct amd_vpmu_context); + ctxt = xzalloc_bytes(sizeof(struct xen_pmu_amd_ctxt) + + sizeof(uint64_t) * AMD_MAX_COUNTERS + + sizeof(uint64_t) * AMD_MAX_COUNTERS); if ( !ctxt ) { gdprintk(XENLOG_WARNING, "Insufficient memory for PMU, " @@ -390,6 +392,9 @@ static int amd_vpmu_initialise(struct vcpu *v) return -ENOMEM; } + ctxt->counters = sizeof(struct xen_pmu_amd_ctxt); + ctxt->ctrls = ctxt->counters + sizeof(uint64_t) * AMD_MAX_COUNTERS; + vpmu->context = ctxt; vpmu_set(vpmu, VPMU_CONTEXT_ALLOCATED); return 0; @@ -403,7 +408,7 @@ static void amd_vpmu_destroy(struct vcpu *v) return; if ( is_hvm_domain(v->domain) && - ((struct amd_vpmu_context *)vpmu->context)->msr_bitmap_set ) + ((struct xen_pmu_amd_ctxt *)vpmu->context)->msr_bitmap_set ) amd_vpmu_unset_msr_bitmap(v); xfree(vpmu->context); @@ -420,7 +425,9 @@ static void amd_vpmu_destroy(struct vcpu *v) static void amd_vpmu_dump(const struct vcpu *v) { const struct vpmu_struct *vpmu = vcpu_vpmu(v); - const struct amd_vpmu_context *ctxt = vpmu->context; + const struct xen_pmu_amd_ctxt *ctxt = vpmu->context; + uint64_t *counter_regs = vpmu_reg_pointer(ctxt, counters); + uint64_t *ctrl_regs = vpmu_reg_pointer(ctxt, ctrls); unsigned int i; printk(" VPMU state: 0x%x ", vpmu->flags); @@ -450,8 +457,8 @@ static void amd_vpmu_dump(const struct vcpu *v) rdmsrl(ctrls[i], ctrl); rdmsrl(counters[i], cntr); printk(" %#x: %#lx (%#lx in HW) %#x: %#lx (%#lx in HW)\n", - ctrls[i], ctxt->ctrls[i], ctrl, - counters[i], ctxt->counters[i], cntr); + ctrls[i], ctrl_regs[i], ctrl, + counters[i], counter_regs[i], cntr); } } diff --git a/xen/arch/x86/hvm/vmx/vpmu_core2.c b/xen/arch/x86/hvm/vmx/vpmu_core2.c index c66289a..856281d 100644 --- a/xen/arch/x86/hvm/vmx/vpmu_core2.c +++ b/xen/arch/x86/hvm/vmx/vpmu_core2.c @@ -35,8 +35,8 @@ #include <asm/hvm/vmx/vmcs.h> #include <public/sched.h> #include <public/hvm/save.h> +#include <public/pmu.h> #include <asm/hvm/vpmu.h> -#include <asm/hvm/vmx/vpmu_core2.h> /* * See Intel SDM Vol 2a Instruction Set Reference chapter 3 for CPUID @@ -68,6 +68,10 @@ #define MSR_PMC_ALIAS_MASK (~(MSR_IA32_PERFCTR0 ^ MSR_IA32_A_PERFCTR0)) static bool_t __read_mostly full_width_write; +/* Intel-specific VPMU features */ +#define VPMU_CPU_HAS_DS 0x100 /* Has Debug Store */ +#define VPMU_CPU_HAS_BTS 0x200 /* Has Branch Trace Store */ + /* * MSR_CORE_PERF_FIXED_CTR_CTRL contains the configuration of all fixed * counters. 4 bits for every counter. @@ -75,16 +79,6 @@ static bool_t __read_mostly full_width_write; #define FIXED_CTR_CTRL_BITS 4 #define FIXED_CTR_CTRL_MASK ((1 << FIXED_CTR_CTRL_BITS) - 1) -#define VPMU_CORE2_MAX_FIXED_PMCS 4 -struct core2_vpmu_context { - u64 fixed_ctrl; - u64 ds_area; - u64 pebs_enable; - u64 global_ovf_status; - u64 fix_counters[VPMU_CORE2_MAX_FIXED_PMCS]; - struct arch_msr_pair arch_msr_pair[1]; -}; - /* Number of general-purpose and fixed performance counters */ static unsigned int __read_mostly arch_pmc_cnt, fixed_pmc_cnt; @@ -224,6 +218,7 @@ static int is_core2_vpmu_msr(u32 msr_index, int *type, int *index) return 0; } +#define msraddr_to_bitpos(x) (((x)&0xffff) + ((x)>>31)*0x2000) static void core2_vpmu_set_msr_bitmap(unsigned long *msr_bitmap) { int i; @@ -293,12 +288,15 @@ static void core2_vpmu_unset_msr_bitmap(unsigned long *msr_bitmap) static inline void __core2_vpmu_save(struct vcpu *v) { int i; - struct core2_vpmu_context *core2_vpmu_cxt = vcpu_vpmu(v)->context; + struct xen_pmu_intel_ctxt *core2_vpmu_cxt = vcpu_vpmu(v)->context; + uint64_t *fixed_counters = vpmu_reg_pointer(core2_vpmu_cxt, fixed_counters); + struct xen_pmu_cntr_pair *xen_pmu_cntr_pair = + vpmu_reg_pointer(core2_vpmu_cxt, arch_counters); for ( i = 0; i < fixed_pmc_cnt; i++ ) - rdmsrl(MSR_CORE_PERF_FIXED_CTR0 + i, core2_vpmu_cxt->fix_counters[i]); + rdmsrl(MSR_CORE_PERF_FIXED_CTR0 + i, fixed_counters[i]); for ( i = 0; i < arch_pmc_cnt; i++ ) - rdmsrl(MSR_IA32_PERFCTR0 + i, core2_vpmu_cxt->arch_msr_pair[i].counter); + rdmsrl(MSR_IA32_PERFCTR0 + i, xen_pmu_cntr_pair[i].counter); } static int core2_vpmu_save(struct vcpu *v) @@ -320,10 +318,13 @@ static int core2_vpmu_save(struct vcpu *v) static inline void __core2_vpmu_load(struct vcpu *v) { unsigned int i, pmc_start; - struct core2_vpmu_context *core2_vpmu_cxt = vcpu_vpmu(v)->context; + struct xen_pmu_intel_ctxt *core2_vpmu_cxt = vcpu_vpmu(v)->context; + uint64_t *fixed_counters = vpmu_reg_pointer(core2_vpmu_cxt, fixed_counters); + struct xen_pmu_cntr_pair *xen_pmu_cntr_pair = + vpmu_reg_pointer(core2_vpmu_cxt, arch_counters); for ( i = 0; i < fixed_pmc_cnt; i++ ) - wrmsrl(MSR_CORE_PERF_FIXED_CTR0 + i, core2_vpmu_cxt->fix_counters[i]); + wrmsrl(MSR_CORE_PERF_FIXED_CTR0 + i, fixed_counters[i]); if ( full_width_write ) pmc_start = MSR_IA32_A_PERFCTR0; @@ -331,8 +332,8 @@ static inline void __core2_vpmu_load(struct vcpu *v) pmc_start = MSR_IA32_PERFCTR0; for ( i = 0; i < arch_pmc_cnt; i++ ) { - wrmsrl(pmc_start + i, core2_vpmu_cxt->arch_msr_pair[i].counter); - wrmsrl(MSR_P6_EVNTSEL0 + i, core2_vpmu_cxt->arch_msr_pair[i].control); + wrmsrl(pmc_start + i, xen_pmu_cntr_pair[i].counter); + wrmsrl(MSR_P6_EVNTSEL0 + i, xen_pmu_cntr_pair[i].control); } wrmsrl(MSR_CORE_PERF_FIXED_CTR_CTRL, core2_vpmu_cxt->fixed_ctrl); @@ -355,7 +356,7 @@ static void core2_vpmu_load(struct vcpu *v) static int core2_vpmu_alloc_resource(struct vcpu *v) { struct vpmu_struct *vpmu = vcpu_vpmu(v); - struct core2_vpmu_context *core2_vpmu_cxt; + struct xen_pmu_intel_ctxt *core2_vpmu_cxt; if ( !acquire_pmu_ownership(PMU_OWNER_HVM) ) return 0; @@ -368,11 +369,16 @@ static int core2_vpmu_alloc_resource(struct vcpu *v) goto out_err; vmx_write_guest_msr(MSR_CORE_PERF_GLOBAL_CTRL, 0); - core2_vpmu_cxt = xzalloc_bytes(sizeof(struct core2_vpmu_context) + - (arch_pmc_cnt-1)*sizeof(struct arch_msr_pair)); + core2_vpmu_cxt = xzalloc_bytes(sizeof(struct xen_pmu_intel_ctxt) + + sizeof(uint64_t) * fixed_pmc_cnt + + sizeof(struct xen_pmu_cntr_pair) * arch_pmc_cnt); if ( !core2_vpmu_cxt ) goto out_err; + core2_vpmu_cxt->fixed_counters = sizeof(struct xen_pmu_intel_ctxt); + core2_vpmu_cxt->arch_counters = core2_vpmu_cxt->fixed_counters + + sizeof(uint64_t) * fixed_pmc_cnt; + vpmu->context = (void *)core2_vpmu_cxt; vpmu_set(vpmu, VPMU_CONTEXT_ALLOCATED); @@ -420,7 +426,7 @@ static int core2_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content) int type = -1, index = -1; struct vcpu *v = current; struct vpmu_struct *vpmu = vcpu_vpmu(v); - struct core2_vpmu_context *core2_vpmu_cxt = NULL; + struct xen_pmu_intel_ctxt *core2_vpmu_cxt = NULL; if ( !core2_vpmu_msr_common_check(msr, &type, &index) ) { @@ -449,7 +455,7 @@ static int core2_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content) switch ( msr ) { case MSR_CORE_PERF_GLOBAL_OVF_CTRL: - core2_vpmu_cxt->global_ovf_status &= ~msr_content; + core2_vpmu_cxt->global_status &= ~msr_content; return 1; case MSR_CORE_PERF_GLOBAL_STATUS: gdprintk(XENLOG_INFO, "Can not write readonly MSR: " @@ -512,11 +518,14 @@ static int core2_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content) tmp = msr - MSR_P6_EVNTSEL0; if ( tmp >= 0 && tmp < arch_pmc_cnt ) { + struct xen_pmu_cntr_pair *xen_pmu_cntr_pair = + vpmu_reg_pointer(core2_vpmu_cxt, arch_counters); + vmx_read_guest_msr(MSR_CORE_PERF_GLOBAL_CTRL, &global_ctrl); - core2_vpmu_cxt->arch_msr_pair[tmp].control = msr_content; + xen_pmu_cntr_pair[tmp].control = msr_content; for ( i = 0; i < arch_pmc_cnt && !pmu_enable; i++ ) pmu_enable += (global_ctrl >> i) & - (core2_vpmu_cxt->arch_msr_pair[i].control >> 22) & 1; + (xen_pmu_cntr_pair[i].control >> 22) & 1; } } @@ -567,7 +576,7 @@ static int core2_vpmu_do_rdmsr(unsigned int msr, uint64_t *msr_content) int type = -1, index = -1; struct vcpu *v = current; struct vpmu_struct *vpmu = vcpu_vpmu(v); - struct core2_vpmu_context *core2_vpmu_cxt = NULL; + struct xen_pmu_intel_ctxt *core2_vpmu_cxt = NULL; if ( core2_vpmu_msr_common_check(msr, &type, &index) ) { @@ -578,7 +587,7 @@ static int core2_vpmu_do_rdmsr(unsigned int msr, uint64_t *msr_content) *msr_content = 0; break; case MSR_CORE_PERF_GLOBAL_STATUS: - *msr_content = core2_vpmu_cxt->global_ovf_status; + *msr_content = core2_vpmu_cxt->global_status; break; case MSR_CORE_PERF_GLOBAL_CTRL: vmx_read_guest_msr(MSR_CORE_PERF_GLOBAL_CTRL, msr_content); @@ -627,8 +636,11 @@ static void core2_vpmu_dump(const struct vcpu *v) { const struct vpmu_struct *vpmu = vcpu_vpmu(v); int i; - const struct core2_vpmu_context *core2_vpmu_cxt = NULL; + const struct xen_pmu_intel_ctxt *core2_vpmu_cxt = NULL; u64 val; + uint64_t *fixed_counters = vpmu_reg_pointer(core2_vpmu_cxt, fixed_counters); + struct xen_pmu_cntr_pair *xen_pmu_cntr_pair = + vpmu_reg_pointer(core2_vpmu_cxt, arch_counters); if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) ) return; @@ -647,12 +659,9 @@ static void core2_vpmu_dump(const struct vcpu *v) /* Print the contents of the counter and its configuration msr. */ for ( i = 0; i < arch_pmc_cnt; i++ ) - { - const struct arch_msr_pair *msr_pair = core2_vpmu_cxt->arch_msr_pair; - printk(" general_%d: 0x%016lx ctrl: 0x%016lx\n", - i, msr_pair[i].counter, msr_pair[i].control); - } + i, xen_pmu_cntr_pair[i].counter, xen_pmu_cntr_pair[i].control); + /* * The configuration of the fixed counter is 4 bits each in the * MSR_CORE_PERF_FIXED_CTR_CTRL. @@ -661,7 +670,7 @@ static void core2_vpmu_dump(const struct vcpu *v) for ( i = 0; i < fixed_pmc_cnt; i++ ) { printk(" fixed_%d: 0x%016lx ctrl: %#lx\n", - i, core2_vpmu_cxt->fix_counters[i], + i, fixed_counters[i], val & FIXED_CTR_CTRL_MASK); val >>= FIXED_CTR_CTRL_BITS; } @@ -672,14 +681,14 @@ static int core2_vpmu_do_interrupt(struct cpu_user_regs *regs) struct vcpu *v = current; u64 msr_content; struct vpmu_struct *vpmu = vcpu_vpmu(v); - struct core2_vpmu_context *core2_vpmu_cxt = vpmu->context; + struct xen_pmu_intel_ctxt *core2_vpmu_cxt = vpmu->context; rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, msr_content); if ( msr_content ) { if ( is_pmc_quirk ) handle_pmc_quirk(msr_content); - core2_vpmu_cxt->global_ovf_status |= msr_content; + core2_vpmu_cxt->global_status |= msr_content; msr_content = 0xC000000700000000 | ((1 << arch_pmc_cnt) - 1); wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, msr_content); } @@ -742,12 +751,6 @@ func_out: arch_pmc_cnt = core2_get_arch_pmc_count(); fixed_pmc_cnt = core2_get_fixed_pmc_count(); - if ( fixed_pmc_cnt > VPMU_CORE2_MAX_FIXED_PMCS ) - { - fixed_pmc_cnt = VPMU_CORE2_MAX_FIXED_PMCS; - printk(XENLOG_G_WARNING "Limiting number of fixed counters to %d\n", - fixed_pmc_cnt); - } check_pmc_quirk(); return 0; diff --git a/xen/arch/x86/hvm/vpmu.c b/xen/arch/x86/hvm/vpmu.c index 979bd33..a6e933a 100644 --- a/xen/arch/x86/hvm/vpmu.c +++ b/xen/arch/x86/hvm/vpmu.c @@ -31,6 +31,7 @@ #include <asm/hvm/svm/svm.h> #include <asm/hvm/svm/vmcb.h> #include <asm/apic.h> +#include <public/pmu.h> /* * "vpmu" : vpmu generally enabled diff --git a/xen/arch/x86/oprofile/op_model_ppro.c b/xen/arch/x86/oprofile/op_model_ppro.c index 3225937..5aae2e7 100644 --- a/xen/arch/x86/oprofile/op_model_ppro.c +++ b/xen/arch/x86/oprofile/op_model_ppro.c @@ -20,11 +20,15 @@ #include <asm/regs.h> #include <asm/current.h> #include <asm/hvm/vpmu.h> -#include <asm/hvm/vmx/vpmu_core2.h> #include "op_x86_model.h" #include "op_counter.h" +struct arch_msr_pair { + u64 counter; + u64 control; +}; + /* * Intel "Architectural Performance Monitoring" CPUID * detection/enumeration details: diff --git a/xen/include/asm-x86/hvm/vmx/vpmu_core2.h b/xen/include/asm-x86/hvm/vmx/vpmu_core2.h deleted file mode 100644 index 410372d..0000000 --- a/xen/include/asm-x86/hvm/vmx/vpmu_core2.h +++ /dev/null @@ -1,32 +0,0 @@ - -/* - * vpmu_core2.h: CORE 2 specific PMU virtualization for HVM domain. - * - * Copyright (c) 2007, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Author: Haitao Shan <haitao.shan@xxxxxxxxx> - */ - -#ifndef __ASM_X86_HVM_VPMU_CORE_H_ -#define __ASM_X86_HVM_VPMU_CORE_H_ - -struct arch_msr_pair { - u64 counter; - u64 control; -}; - -#endif /* __ASM_X86_HVM_VPMU_CORE_H_ */ - diff --git a/xen/include/asm-x86/hvm/vpmu.h b/xen/include/asm-x86/hvm/vpmu.h index 7ee0f01..87a72ce 100644 --- a/xen/include/asm-x86/hvm/vpmu.h +++ b/xen/include/asm-x86/hvm/vpmu.h @@ -22,6 +22,8 @@ #ifndef __ASM_X86_HVM_VPMU_H_ #define __ASM_X86_HVM_VPMU_H_ +#include <public/pmu.h> + /* * Flag bits given as a string on the hypervisor boot parameter 'vpmu'. * See arch/x86/hvm/vpmu.c. @@ -29,12 +31,9 @@ #define VPMU_BOOT_ENABLED 0x1 /* vpmu generally enabled. */ #define VPMU_BOOT_BTS 0x2 /* Intel BTS feature wanted. */ - -#define msraddr_to_bitpos(x) (((x)&0xffff) + ((x)>>31)*0x2000) #define vcpu_vpmu(vcpu) (&((vcpu)->arch.hvm_vcpu.vpmu)) #define vpmu_vcpu(vpmu) (container_of((vpmu), struct vcpu, \ arch.hvm_vcpu.vpmu)) -#define vpmu_domain(vpmu) (vpmu_vcpu(vpmu)->domain) #define MSR_TYPE_COUNTER 0 #define MSR_TYPE_CTRL 1 @@ -42,6 +41,9 @@ #define MSR_TYPE_ARCH_COUNTER 3 #define MSR_TYPE_ARCH_CTRL 4 +/* Start of PMU register bank */ +#define vpmu_reg_pointer(ctxt, offset) ((void *)((uintptr_t)ctxt + \ + (uintptr_t)ctxt->offset)) /* Arch specific operations shared by all vpmus */ struct arch_vpmu_ops { @@ -76,11 +78,6 @@ struct vpmu_struct { #define VPMU_FROZEN 0x10 /* Stop counters while VCPU is not running */ #define VPMU_PASSIVE_DOMAIN_ALLOCATED 0x20 -/* VPMU features */ -#define VPMU_CPU_HAS_DS 0x100 /* Has Debug Store */ -#define VPMU_CPU_HAS_BTS 0x200 /* Has Branch Trace Store */ - - #define vpmu_set(_vpmu, _x) ((_vpmu)->flags |= (_x)) #define vpmu_reset(_vpmu, _x) ((_vpmu)->flags &= ~(_x)) #define vpmu_is_set(_vpmu, _x) ((_vpmu)->flags & (_x)) diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h index 7496556..e982b53 100644 --- a/xen/include/public/arch-arm.h +++ b/xen/include/public/arch-arm.h @@ -388,6 +388,9 @@ typedef uint64_t xen_callback_t; #endif +/* Stub definition of PMU structure */ +typedef struct xen_arch_pmu {} xen_arch_pmu_t; + #endif /* __XEN_PUBLIC_ARCH_ARM_H__ */ /* diff --git a/xen/include/public/arch-x86/pmu.h b/xen/include/public/arch-x86/pmu.h new file mode 100644 index 0000000..fc022e2 --- /dev/null +++ b/xen/include/public/arch-x86/pmu.h @@ -0,0 +1,63 @@ +#ifndef __XEN_PUBLIC_ARCH_X86_PMU_H__ +#define __XEN_PUBLIC_ARCH_X86_PMU_H__ + +/* x86-specific PMU definitions */ + +/* AMD PMU registers and structures */ +struct xen_pmu_amd_ctxt { + uint32_t counters; /* Offset to counter MSRs */ + uint32_t ctrls; /* Offset to control MSRs */ + uint32_t msr_bitmap_set; /* Used by HVM only */ +}; + +/* Intel PMU registers and structures */ +struct xen_pmu_cntr_pair { + uint64_t counter; + uint64_t control; +}; + +struct xen_pmu_intel_ctxt { + uint64_t global_ctrl; + uint64_t global_ovf_ctrl; + uint64_t global_status; + uint64_t fixed_ctrl; + uint64_t ds_area; + uint64_t pebs_enable; + uint64_t debugctl; + uint32_t fixed_counters; /* Offset to fixed counter MSRs */ + uint32_t arch_counters; /* Offset to architectural counter MSRs */ +}; + +#define XENPMU_MAX_CTXT_SZ (sizeof(struct xen_pmu_amd_ctxt) > \ + sizeof(struct xen_pmu_intel_ctxt) ? \ + sizeof(struct xen_pmu_amd_ctxt) : \ + sizeof(struct xen_pmu_intel_ctxt)) +#define XENPMU_CTXT_PAD_SZ (((XENPMU_MAX_CTXT_SZ + 64) & ~63) + 128) +struct xen_arch_pmu { + union { + struct cpu_user_regs regs; + uint8_t pad1[256]; + } r; + union { + uint32_t lapic_lvtpc; + uint64_t pad2; + } l; + union { + struct xen_pmu_amd_ctxt amd; + struct xen_pmu_intel_ctxt intel; + uint8_t pad3[XENPMU_CTXT_PAD_SZ]; + } c; +}; +typedef struct xen_arch_pmu xen_arch_pmu_t; + +#endif /* __XEN_PUBLIC_ARCH_X86_PMU_H__ */ +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ + diff --git a/xen/include/public/pmu.h b/xen/include/public/pmu.h new file mode 100644 index 0000000..3ffd2cf --- /dev/null +++ b/xen/include/public/pmu.h @@ -0,0 +1,38 @@ +#ifndef __XEN_PUBLIC_PMU_H__ +#define __XEN_PUBLIC_PMU_H__ + +#include "xen.h" +#if defined(__i386__) || defined(__x86_64__) +#include "arch-x86/pmu.h" +#elif defined (__arm__) || defined (__aarch64__) +#include "arch-arm.h" +#else +#error "Unsupported architecture" +#endif + +#define XENPMU_VER_MAJ 0 +#define XENPMU_VER_MIN 0 + + +/* Shared between hypervisor and PV domain */ +struct xen_pmu_data { + uint32_t domain_id; + uint32_t vcpu_id; + uint32_t pcpu_id; + uint32_t pmu_flags; + + xen_arch_pmu_t pmu; +}; +typedef struct xen_pmu_data xen_pmu_data_t; + +#endif /* __XEN_PUBLIC_PMU_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ -- 1.8.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |