|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v25 05/15] x86/VPMU: Initialize VPMUs with __initcall
Am Freitag 19 Juni 2015, 14:44:36 schrieb Boris Ostrovsky:
> Move some VPMU initilization operations into __initcalls to avoid performing
> same tests and calculations for each vcpu.
>
> Signed-off-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
> Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
For the Intel/VMX part:
Reviewed-by: Dietmar Hahn <dietmar.hahn@xxxxxxxxxxxxxx>
> ---
> xen/arch/x86/hvm/svm/vpmu.c | 106 ++++++++++++--------------
> xen/arch/x86/hvm/vmx/vpmu_core2.c | 151
> +++++++++++++++++++-------------------
> xen/arch/x86/hvm/vpmu.c | 32 ++++++++
> xen/include/asm-x86/hvm/vpmu.h | 2 +
> 4 files changed, 156 insertions(+), 135 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/svm/vpmu.c b/xen/arch/x86/hvm/svm/vpmu.c
> index 481ea7b..b60ca40 100644
> --- a/xen/arch/x86/hvm/svm/vpmu.c
> +++ b/xen/arch/x86/hvm/svm/vpmu.c
> @@ -356,54 +356,6 @@ static int amd_vpmu_do_rdmsr(unsigned int msr, uint64_t
> *msr_content)
> return 1;
> }
>
> -static int amd_vpmu_initialise(struct vcpu *v)
> -{
> - struct xen_pmu_amd_ctxt *ctxt;
> - struct vpmu_struct *vpmu = vcpu_vpmu(v);
> - uint8_t family = current_cpu_data.x86;
> -
> - 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:
> - case 0x12:
> - case 0x14:
> - case 0x16:
> - default:
> - num_counters = F10H_NUM_COUNTERS;
> - counters = AMD_F10H_COUNTERS;
> - ctrls = AMD_F10H_CTRLS;
> - k7_counters_mirrored = 0;
> - break;
> - }
> - }
> -
> - ctxt = xzalloc_bytes(sizeof(*ctxt) +
> - 2 * sizeof(uint64_t) * num_counters);
> - if ( !ctxt )
> - {
> - gdprintk(XENLOG_WARNING, "Insufficient memory for PMU, "
> - " PMU feature is unavailable on domain %d vcpu %d.\n",
> - v->vcpu_id, v->domain->domain_id);
> - return -ENOMEM;
> - }
> -
> - ctxt->counters = sizeof(*ctxt);
> - ctxt->ctrls = ctxt->counters + sizeof(uint64_t) * num_counters;
> -
> - vpmu->context = ctxt;
> - vpmu->priv_context = NULL;
> - vpmu_set(vpmu, VPMU_CONTEXT_ALLOCATED);
> - return 0;
> -}
> -
> static void amd_vpmu_destroy(struct vcpu *v)
> {
> struct vpmu_struct *vpmu = vcpu_vpmu(v);
> @@ -474,30 +426,62 @@ struct arch_vpmu_ops amd_vpmu_ops = {
>
> int svm_vpmu_initialise(struct vcpu *v)
> {
> + struct xen_pmu_amd_ctxt *ctxt;
> struct vpmu_struct *vpmu = vcpu_vpmu(v);
> - uint8_t family = current_cpu_data.x86;
> - int ret = 0;
>
> - /* vpmu enabled? */
> if ( vpmu_mode == XENPMU_MODE_OFF )
> return 0;
>
> - switch ( family )
> + if ( !counters )
> + return -EINVAL;
> +
> + ctxt = xzalloc_bytes(sizeof(*ctxt) +
> + 2 * sizeof(uint64_t) * num_counters);
> + if ( !ctxt )
> {
> + printk(XENLOG_G_WARNING "Insufficient memory for PMU, "
> + " PMU feature is unavailable on domain %d vcpu %d.\n",
> + v->vcpu_id, v->domain->domain_id);
> + return -ENOMEM;
> + }
> +
> + ctxt->counters = sizeof(*ctxt);
> + ctxt->ctrls = ctxt->counters + sizeof(uint64_t) * num_counters;
> +
> + vpmu->context = ctxt;
> + vpmu->priv_context = NULL;
> +
> + vpmu->arch_vpmu_ops = &amd_vpmu_ops;
> +
> + vpmu_set(vpmu, VPMU_CONTEXT_ALLOCATED);
> + return 0;
> +}
> +
> +int __init amd_vpmu_init(void)
> +{
> + switch ( current_cpu_data.x86 )
> + {
> + case 0x15:
> + num_counters = F15H_NUM_COUNTERS;
> + counters = AMD_F15H_COUNTERS;
> + ctrls = AMD_F15H_CTRLS;
> + k7_counters_mirrored = 1;
> + break;
> case 0x10:
> case 0x12:
> case 0x14:
> - case 0x15:
> case 0x16:
> - ret = amd_vpmu_initialise(v);
> - if ( !ret )
> - vpmu->arch_vpmu_ops = &amd_vpmu_ops;
> - return ret;
> + num_counters = F10H_NUM_COUNTERS;
> + counters = AMD_F10H_COUNTERS;
> + ctrls = AMD_F10H_CTRLS;
> + k7_counters_mirrored = 0;
> + break;
> + default:
> + printk(XENLOG_WARNING "VPMU: Unsupported CPU family %#x\n",
> + current_cpu_data.x86);
> + return -EINVAL;
> }
>
> - printk("VPMU: Initialization failed. "
> - "AMD processor family %d has not "
> - "been supported\n", family);
> - return -EINVAL;
> + return 0;
> }
>
> diff --git a/xen/arch/x86/hvm/vmx/vpmu_core2.c
> b/xen/arch/x86/hvm/vmx/vpmu_core2.c
> index cfcdf42..025c970 100644
> --- a/xen/arch/x86/hvm/vmx/vpmu_core2.c
> +++ b/xen/arch/x86/hvm/vmx/vpmu_core2.c
> @@ -708,62 +708,6 @@ static int core2_vpmu_do_interrupt(struct cpu_user_regs
> *regs)
> return 1;
> }
>
> -static int core2_vpmu_initialise(struct vcpu *v)
> -{
> - struct vpmu_struct *vpmu = vcpu_vpmu(v);
> - u64 msr_content;
> - static bool_t ds_warned;
> -
> - if ( !(vpmu_features & XENPMU_FEATURE_INTEL_BTS) )
> - goto func_out;
> - /* Check the 'Debug Store' feature in the CPUID.EAX[1]:EDX[21] */
> - while ( boot_cpu_has(X86_FEATURE_DS) )
> - {
> - if ( !boot_cpu_has(X86_FEATURE_DTES64) )
> - {
> - if ( !ds_warned )
> - printk(XENLOG_G_WARNING "CPU doesn't support 64-bit DS Area"
> - " - Debug Store disabled for guests\n");
> - break;
> - }
> - vpmu_set(vpmu, VPMU_CPU_HAS_DS);
> - rdmsrl(MSR_IA32_MISC_ENABLE, msr_content);
> - if ( msr_content & MSR_IA32_MISC_ENABLE_BTS_UNAVAIL )
> - {
> - /* If BTS_UNAVAIL is set reset the DS feature. */
> - vpmu_reset(vpmu, VPMU_CPU_HAS_DS);
> - if ( !ds_warned )
> - printk(XENLOG_G_WARNING "CPU has set BTS_UNAVAIL"
> - " - Debug Store disabled for guests\n");
> - break;
> - }
> -
> - vpmu_set(vpmu, VPMU_CPU_HAS_BTS);
> - if ( !ds_warned )
> - {
> - if ( !boot_cpu_has(X86_FEATURE_DSCPL) )
> - printk(XENLOG_G_INFO
> - "vpmu: CPU doesn't support CPL-Qualified BTS\n");
> -
> printk("******************************************************\n");
> - printk("** WARNING: Emulation of BTS Feature is switched on
> **\n");
> - printk("** Using this processor feature in a virtualized
> **\n");
> - printk("** environment is not 100%% safe.
> **\n");
> - printk("** Setting the DS buffer address with wrong values
> **\n");
> - printk("** may lead to hypervisor hangs or crashes.
> **\n");
> - printk("** It is NOT recommended for production use!
> **\n");
> -
> printk("******************************************************\n");
> - }
> - break;
> - }
> - ds_warned = 1;
> - func_out:
> -
> - arch_pmc_cnt = core2_get_arch_pmc_count();
> - fixed_pmc_cnt = core2_get_fixed_pmc_count();
> - check_pmc_quirk();
> - return 0;
> -}
> -
> static void core2_vpmu_destroy(struct vcpu *v)
> {
> struct vpmu_struct *vpmu = vcpu_vpmu(v);
> @@ -829,23 +773,77 @@ struct arch_vpmu_ops core2_no_vpmu_ops = {
> int vmx_vpmu_initialise(struct vcpu *v)
> {
> struct vpmu_struct *vpmu = vcpu_vpmu(v);
> - uint8_t family = current_cpu_data.x86;
> - uint8_t cpu_model = current_cpu_data.x86_model;
> - int ret = 0;
> + u64 msr_content;
> + static bool_t ds_warned;
>
> vpmu->arch_vpmu_ops = &core2_no_vpmu_ops;
> if ( vpmu_mode == XENPMU_MODE_OFF )
> return 0;
>
> - if ( family == 6 )
> - {
> - u64 caps;
> + if ( (arch_pmc_cnt + fixed_pmc_cnt) == 0 )
> + return -EINVAL;
>
> - rdmsrl(MSR_IA32_PERF_CAPABILITIES, caps);
> - full_width_write = (caps >> 13) & 1;
> + if ( !(vpmu_features & XENPMU_FEATURE_INTEL_BTS) )
> + goto func_out;
> + /* Check the 'Debug Store' feature in the CPUID.EAX[1]:EDX[21] */
> + while ( boot_cpu_has(X86_FEATURE_DS) )
> + {
> + if ( !boot_cpu_has(X86_FEATURE_DTES64) )
> + {
> + if ( !ds_warned )
> + printk(XENLOG_G_WARNING "CPU doesn't support 64-bit DS Area"
> + " - Debug Store disabled for guests\n");
> + break;
> + }
> + vpmu_set(vpmu, VPMU_CPU_HAS_DS);
> + rdmsrl(MSR_IA32_MISC_ENABLE, msr_content);
> + if ( msr_content & MSR_IA32_MISC_ENABLE_BTS_UNAVAIL )
> + {
> + /* If BTS_UNAVAIL is set reset the DS feature. */
> + vpmu_reset(vpmu, VPMU_CPU_HAS_DS);
> + if ( !ds_warned )
> + printk(XENLOG_G_WARNING "CPU has set BTS_UNAVAIL"
> + " - Debug Store disabled for guests\n");
> + break;
> + }
>
> - switch ( cpu_model )
> + vpmu_set(vpmu, VPMU_CPU_HAS_BTS);
> + if ( !ds_warned )
> {
> + if ( !boot_cpu_has(X86_FEATURE_DSCPL) )
> + printk(XENLOG_G_INFO
> + "vpmu: CPU doesn't support CPL-Qualified BTS\n");
> +
> printk("******************************************************\n");
> + printk("** WARNING: Emulation of BTS Feature is switched on
> **\n");
> + printk("** Using this processor feature in a virtualized
> **\n");
> + printk("** environment is not 100%% safe.
> **\n");
> + printk("** Setting the DS buffer address with wrong values
> **\n");
> + printk("** may lead to hypervisor hangs or crashes.
> **\n");
> + printk("** It is NOT recommended for production use!
> **\n");
> +
> printk("******************************************************\n");
> + }
> + break;
> + }
> + ds_warned = 1;
> + func_out:
> +
> + vpmu->arch_vpmu_ops = &core2_vpmu_ops;
> +
> + return 0;
> +}
> +
> +int __init core2_vpmu_init(void)
> +{
> + u64 caps;
> +
> + if ( current_cpu_data.x86 != 6 )
> + {
> + printk(XENLOG_WARNING "VPMU: only family 6 is supported\n");
> + return -EINVAL;
> + }
> +
> + switch ( current_cpu_data.x86_model )
> + {
> /* Core2: */
> case 0x0f: /* original 65 nm celeron/pentium/core2/xeon,
> "Merom"/"Conroe" */
> case 0x16: /* single-core 65 nm celeron/core2solo
> "Merom-L"/"Conroe-L" */
> @@ -884,16 +882,21 @@ int vmx_vpmu_initialise(struct vcpu *v)
>
> /* next gen Xeon Phi */
> case 0x57:
> - ret = core2_vpmu_initialise(v);
> - if ( !ret )
> - vpmu->arch_vpmu_ops = &core2_vpmu_ops;
> - return ret;
> - }
> + break;
> +
> + default:
> + printk(XENLOG_WARNING "VPMU: Unsupported CPU model %#x\n",
> + current_cpu_data.x86_model);
> + return -EINVAL;
> }
>
> - printk("VPMU: Initialization failed. "
> - "Intel processor family %d model %d has not "
> - "been supported\n", family, cpu_model);
> - return -EINVAL;
> + arch_pmc_cnt = core2_get_arch_pmc_count();
> + fixed_pmc_cnt = core2_get_fixed_pmc_count();
> + rdmsrl(MSR_IA32_PERF_CAPABILITIES, caps);
> + full_width_write = (caps >> 13) & 1;
> +
> + check_pmc_quirk();
> +
> + return 0;
> }
>
> diff --git a/xen/arch/x86/hvm/vpmu.c b/xen/arch/x86/hvm/vpmu.c
> index 3e65c9b..e7e552e 100644
> --- a/xen/arch/x86/hvm/vpmu.c
> +++ b/xen/arch/x86/hvm/vpmu.c
> @@ -453,14 +453,46 @@ long do_xenpmu_op(unsigned int op,
> XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg)
>
> static int __init vpmu_init(void)
> {
> + int vendor = current_cpu_data.x86_vendor;
> +
> + if ( !opt_vpmu_enabled )
> + {
> + printk(XENLOG_INFO "VPMU: disabled\n");
> + return 0;
> + }
> +
> /* NMI watchdog uses LVTPC and HW counter */
> if ( opt_watchdog && opt_vpmu_enabled )
> {
> printk(XENLOG_WARNING "NMI watchdog is enabled. Turning VPMU
> off.\n");
> opt_vpmu_enabled = 0;
> vpmu_mode = XENPMU_MODE_OFF;
> + return 0;
> + }
> +
> + switch ( vendor )
> + {
> + case X86_VENDOR_AMD:
> + if ( amd_vpmu_init() )
> + vpmu_mode = XENPMU_MODE_OFF;
> + break;
> + case X86_VENDOR_INTEL:
> + if ( core2_vpmu_init() )
> + vpmu_mode = XENPMU_MODE_OFF;
> + break;
> + default:
> + printk(XENLOG_WARNING "VPMU: Unknown CPU vendor: %d. "
> + "Turning VPMU off.\n", vendor);
> + vpmu_mode = XENPMU_MODE_OFF;
> + break;
> }
>
> + if ( vpmu_mode != XENPMU_MODE_OFF )
> + printk(XENLOG_INFO "VPMU: version " __stringify(XENPMU_VER_MAJ) "."
> + __stringify(XENPMU_VER_MIN) "\n");
> + else
> + opt_vpmu_enabled = 0;
> +
> return 0;
> }
> __initcall(vpmu_init);
> diff --git a/xen/include/asm-x86/hvm/vpmu.h b/xen/include/asm-x86/hvm/vpmu.h
> index 88ffc19..96f7666 100644
> --- a/xen/include/asm-x86/hvm/vpmu.h
> +++ b/xen/include/asm-x86/hvm/vpmu.h
> @@ -52,7 +52,9 @@ struct arch_vpmu_ops {
> void (*arch_vpmu_dump)(const struct vcpu *);
> };
>
> +int core2_vpmu_init(void);
> int vmx_vpmu_initialise(struct vcpu *);
> +int amd_vpmu_init(void);
> int svm_vpmu_initialise(struct vcpu *);
>
> struct vpmu_struct {
>
--
Company details: http://ts.fujitsu.com/imprint.html
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |