[PATCH RFC 5/8] KVM: x86/pmu: Add kernel-defined slots event to enable Fixed Counter3

From: Like Xu
Date: Mon Dec 12 2022 - 08:00:08 EST


From: Like Xu <likexu@xxxxxxxxxxx>

The Topdown Slots event can be enabled on gp counter or fixed counter3 and
it does not differ from other fixed counters in terms of the use of count
and sampling modes (except for the hardware logic for event accumulation).

According to commit 6017608936c1 ("perf/x86/intel: Add Icelake support"),
KVM or any perf in-kernel user needs to reprogram fixed counter3 via the
kernel-defined Topdown Slots event for real fixed counter3 on the host.

Opportunistically fix a typo, s/msrs_to_saved_all/msrs_to_save_all/.

Signed-off-by: Like Xu <likexu@xxxxxxxxxxx>
---
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/kvm/vmx/pmu_intel.c | 4 +++-
arch/x86/kvm/x86.c | 6 +++---
3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index aa4eb8cfcd7e..413f2e104543 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -513,7 +513,7 @@ struct kvm_pmc {
#define KVM_INTEL_PMC_MAX_GENERIC 8
#define MSR_ARCH_PERFMON_PERFCTR_MAX (MSR_ARCH_PERFMON_PERFCTR0 + KVM_INTEL_PMC_MAX_GENERIC - 1)
#define MSR_ARCH_PERFMON_EVENTSEL_MAX (MSR_ARCH_PERFMON_EVENTSEL0 + KVM_INTEL_PMC_MAX_GENERIC - 1)
-#define KVM_PMC_MAX_FIXED 3
+#define KVM_PMC_MAX_FIXED 4
#define KVM_AMD_PMC_MAX_GENERIC 6
struct kvm_pmu {
unsigned nr_arch_gp_counters;
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index d86a6ba8c3f9..637fd709f5f4 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -36,6 +36,7 @@
* the second part of hw_events is defined by the generic kernel perf:
*
* 8 - PERF_COUNT_HW_REF_CPU_CYCLES
+ * 9 - Kernel-defined Topdown Slots event (available on fixed counter 3)
*/
static struct kvm_pmu_hw_event intel_arch_events[] = {
[0] = { 0x3c, 0x00 },
@@ -48,10 +49,11 @@ static struct kvm_pmu_hw_event intel_arch_events[] = {
[7] = { 0xa4, 0x01 },
/* The above index must match CPUID 0x0A.EBX bit vector */
[8] = { 0x00, 0x03 },
+ [9] = { 0x00, 0x04 },
};

/* mapping between fixed pmc index and intel_arch_events array */
-static int fixed_pmc_events[] = {1, 0, 8};
+static int fixed_pmc_events[] = {1, 0, 8, 9};

static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
{
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 312aea1854ae..0b61cb58c877 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1435,7 +1435,7 @@ static const u32 msrs_to_save_all[] = {
MSR_IA32_UMWAIT_CONTROL,

MSR_ARCH_PERFMON_FIXED_CTR0, MSR_ARCH_PERFMON_FIXED_CTR1,
- MSR_ARCH_PERFMON_FIXED_CTR0 + 2,
+ MSR_ARCH_PERFMON_FIXED_CTR0 + 2, MSR_ARCH_PERFMON_FIXED_CTR0 + 3,
MSR_CORE_PERF_FIXED_CTR_CTRL, MSR_CORE_PERF_GLOBAL_STATUS,
MSR_CORE_PERF_GLOBAL_CTRL, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
MSR_IA32_PEBS_ENABLE, MSR_IA32_DS_AREA, MSR_PEBS_DATA_CFG,
@@ -7001,8 +7001,8 @@ static void kvm_init_msr_list(void)
u32 dummy[2];
unsigned i;

- BUILD_BUG_ON_MSG(KVM_PMC_MAX_FIXED != 3,
- "Please update the fixed PMCs in msrs_to_saved_all[]");
+ BUILD_BUG_ON_MSG(KVM_PMC_MAX_FIXED != 4,
+ "Please update the fixed PMCs in msrs_to_save_all[]");

num_msrs_to_save = 0;
num_emulated_msrs = 0;
--
2.38.2