Hardware can support more than 8 general or 3 fixed counters, which could lead to inconsistent access to MSRs (thus failure to initialize vPMU in guest) as we don't support accessing more than these limits.
Signed-off-by: Teddy Astie <[email protected]> --- I'm not aware of a processor that have more than that, but the specification tells that this is possible. xen/arch/x86/cpu-policy.c | 6 ++++++ xen/arch/x86/cpu/vpmu_intel.c | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/xen/arch/x86/cpu-policy.c b/xen/arch/x86/cpu-policy.c index 7f4456d5a2..46db7f0726 100644 --- a/xen/arch/x86/cpu-policy.c +++ b/xen/arch/x86/cpu-policy.c @@ -276,6 +276,12 @@ switch ( p->x86_vendor ) if ( p->basic.pmu.version > 2 ) p->basic.pmu.version = 2; + /* Truncate control register count to what we support */ + if ( p->basic.pmu.num_gp_ctrs > 8 ) + p->basic.pmu.num_gp_ctrs = 8; + + if ( p->basic.pmu.num_fixed_ctr > 3 ) + p->basic.pmu.num_fixed_ctr = 3; break; } } diff --git a/xen/arch/x86/cpu/vpmu_intel.c b/xen/arch/x86/cpu/vpmu_intel.c index 85539ce6c5..0871795218 100644 --- a/xen/arch/x86/cpu/vpmu_intel.c +++ b/xen/arch/x86/cpu/vpmu_intel.c @@ -924,7 +924,22 @@ const struct arch_vpmu_ops *__init core2_vpmu_init(void) } arch_pmc_cnt = core2_get_arch_pmc_count(); + if ( arch_pmc_cnt > 8 ) + { + printk(XENLOG_INFO + "VPMU: Too many general counters (%u), emulating 8 registers\n", + arch_pmc_cnt); + arch_pmc_cnt = 8; + } + fixed_pmc_cnt = core2_get_fixed_pmc_count(); + if ( fixed_pmc_cnt > 3 ) + { + printk(XENLOG_INFO + "VPMU: Too many fixed counters (%u), emulating 3 registers\n", + arch_pmc_cnt); + fixed_pmc_cnt = 3; + } if ( cpu_has_pdcm ) { -- 2.53.0 -- Teddy Astie | Vates XCP-ng Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech
