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


Reply via email to