All of lore.kernel.org
 help / color / mirror / Atom feed
From: Like Xu <like.xu.linux@gmail.com>
To: Paolo Bonzini <pbonzini@redhat.com>, Jim Mattson <jmattson@google.com>
Cc: Sean Christopherson <seanjc@google.com>,
	Vitaly Kuznetsov <vkuznets@redhat.com>,
	Wanpeng Li <wanpengli@tencent.com>,
	Joerg Roedel <joro@8bytes.org>,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	Like Xu <likexu@tencent.com>
Subject: [PATCH kvm/queue v2 1/3] KVM: x86/pmu: Replace pmu->available_event_types with a new BITMAP
Date: Mon, 17 Jan 2022 16:53:05 +0800	[thread overview]
Message-ID: <20220117085307.93030-2-likexu@tencent.com> (raw)
In-Reply-To: <20220117085307.93030-1-likexu@tencent.com>

From: Like Xu <likexu@tencent.com>

Currently, KVM refuses to create a perf_event for a counter if its
requested hw event is prompted as unavailable according to the
Intel CPUID CPUID 0x0A.EBX bit vector. We replace the basis for
this validation with the kernel generic and common enum perf_hw_id{}.
This helps to remove the use of static {intel,amd}_arch_events[] later on,
as it is not constant across platforms.

Signed-off-by: Like Xu <likexu@tencent.com>
---
 arch/x86/include/asm/kvm_host.h |  2 +-
 arch/x86/kvm/vmx/pmu_intel.c    | 40 +++++++++++++++++++++++++++------
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 5d97f4adc1cb..03fabf22e167 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -501,7 +501,6 @@ struct kvm_pmc {
 struct kvm_pmu {
 	unsigned nr_arch_gp_counters;
 	unsigned nr_arch_fixed_counters;
-	unsigned available_event_types;
 	u64 fixed_ctr_ctrl;
 	u64 global_ctrl;
 	u64 global_status;
@@ -516,6 +515,7 @@ struct kvm_pmu {
 	DECLARE_BITMAP(reprogram_pmi, X86_PMC_IDX_MAX);
 	DECLARE_BITMAP(all_valid_pmc_idx, X86_PMC_IDX_MAX);
 	DECLARE_BITMAP(pmc_in_use, X86_PMC_IDX_MAX);
+	DECLARE_BITMAP(avail_perf_hw_ids, PERF_COUNT_HW_MAX);
 
 	/*
 	 * The gate to release perf_events not marked in
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index ffccfd9823c0..1ba8f0f0098b 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -74,6 +74,7 @@ static unsigned int intel_pmc_perf_hw_id(struct kvm_pmc *pmc)
 	u8 event_select = pmc->eventsel & ARCH_PERFMON_EVENTSEL_EVENT;
 	u8 unit_mask = (pmc->eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
 	int i;
+	unsigned int event_type = PERF_COUNT_HW_MAX;
 
 	for (i = 0; i < ARRAY_SIZE(intel_arch_events); i++) {
 		if (intel_arch_events[i].eventsel != event_select ||
@@ -81,16 +82,14 @@ static unsigned int intel_pmc_perf_hw_id(struct kvm_pmc *pmc)
 			continue;
 
 		/* disable event that reported as not present by cpuid */
-		if ((i < 7) && !(pmu->available_event_types & (1 << i)))
+		event_type = intel_arch_events[i].event_type;
+		if (!test_bit(event_type, pmu->avail_perf_hw_ids))
 			return PERF_COUNT_HW_MAX + 1;
 
 		break;
 	}
 
-	if (i == ARRAY_SIZE(intel_arch_events))
-		return PERF_COUNT_HW_MAX;
-
-	return intel_arch_events[i].event_type;
+	return event_type;
 }
 
 /* check if a PMC is enabled by comparing it with globl_ctrl bits. */
@@ -469,6 +468,25 @@ static void setup_fixed_pmc_eventsel(struct kvm_pmu *pmu)
 	}
 }
 
+/* Mapping between CPUID 0x0A.EBX bit vector and enum perf_hw_id. */
+static inline int map_unavail_bit_to_perf_hw_id(int bit)
+{
+	switch (bit) {
+	case 0:
+	case 1:
+		return bit;
+	case 2:
+		return PERF_COUNT_HW_BUS_CYCLES;
+	case 3:
+	case 4:
+	case 5:
+	case 6:
+		return --bit;
+	}
+
+	return PERF_COUNT_HW_MAX;
+}
+
 static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
 {
 	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
@@ -478,6 +496,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
 	struct kvm_cpuid_entry2 *entry;
 	union cpuid10_eax eax;
 	union cpuid10_edx edx;
+	unsigned long available_cpuid_events;
+	int bit;
 
 	pmu->nr_arch_gp_counters = 0;
 	pmu->nr_arch_fixed_counters = 0;
@@ -503,8 +523,14 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
 	eax.split.bit_width = min_t(int, eax.split.bit_width, x86_pmu.bit_width_gp);
 	pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << eax.split.bit_width) - 1;
 	eax.split.mask_length = min_t(int, eax.split.mask_length, x86_pmu.events_mask_len);
-	pmu->available_event_types = ~entry->ebx &
-					((1ull << eax.split.mask_length) - 1);
+	/*
+	 * The number of valid EBX bits should be less than the number of valid perf_hw_ids.
+	 * Otherwise, we need to additionally determine if the event is rejected by KVM.
+	 */
+	available_cpuid_events = ~entry->ebx & ((1ull << eax.split.mask_length) - 1);
+	bitmap_fill(pmu->avail_perf_hw_ids, PERF_COUNT_HW_MAX);
+	for_each_clear_bit(bit, (unsigned long *)&available_cpuid_events, eax.split.mask_length)
+		__clear_bit(map_unavail_bit_to_perf_hw_id(bit), pmu->avail_perf_hw_ids);
 
 	if (pmu->version == 1) {
 		pmu->nr_arch_fixed_counters = 0;
-- 
2.33.1


  reply	other threads:[~2022-01-17  8:53 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-17  8:53 [PATCH kvm/queue v2 0/3] KVM: x86/pmu: Fix out-of-date AMD amd_event_mapping[] Like Xu
2022-01-17  8:53 ` Like Xu [this message]
2022-02-01 12:26   ` [PATCH kvm/queue v2 1/3] KVM: x86/pmu: Replace pmu->available_event_types with a new BITMAP Paolo Bonzini
2022-01-17  8:53 ` [PATCH kvm/queue v2 2/3] perf: x86/core: Add interface to query perfmon_event_map[] directly Like Xu
2022-02-01 12:27   ` Paolo Bonzini
2022-02-02 14:43   ` Peter Zijlstra
2022-02-02 22:35     ` Jim Mattson
2022-02-03 17:33       ` David Dunn
2022-02-09  8:10       ` KVM: x86: Reconsider the current approach of vPMU Like Xu
2022-02-09 13:33         ` Peter Zijlstra
2022-02-09 21:00           ` Sean Christopherson
2022-02-10 12:08             ` Like Xu
2022-02-10 17:12               ` Sean Christopherson
2022-02-16  3:33                 ` Like Xu
2022-02-16 17:53                   ` Jim Mattson
2022-02-09 13:21       ` [PATCH kvm/queue v2 2/3] perf: x86/core: Add interface to query perfmon_event_map[] directly Peter Zijlstra
2022-02-09 15:40         ` Dave Hansen
2022-02-09 18:47           ` Jim Mattson
2022-02-09 18:57             ` Dave Hansen
2022-02-09 19:24               ` David Dunn
2022-02-10 13:29                 ` Like Xu
2022-02-10 15:34                 ` Liang, Kan
2022-02-10 16:34                   ` Jim Mattson
2022-02-10 18:30                     ` Liang, Kan
2022-02-10 19:16                       ` Jim Mattson
2022-02-10 19:46                         ` Liang, Kan
2022-02-10 19:55                           ` David Dunn
2022-02-11 14:11                             ` Liang, Kan
2022-02-11 18:08                               ` Jim Mattson
2022-02-11 21:47                                 ` Liang, Kan
2022-02-12 23:31                                   ` Jim Mattson
2022-02-14 21:55                                     ` Liang, Kan
2022-02-14 22:55                                       ` Jim Mattson
2022-02-16  7:36                                         ` Like Xu
2022-02-16 18:10                                           ` Jim Mattson
2022-02-16  7:30                           ` Like Xu
2022-02-16  5:08                   ` Like Xu
2022-02-10 12:55               ` Like Xu
2022-02-12 23:32               ` Jim Mattson
2022-02-08 11:52     ` Like Xu
2022-01-17  8:53 ` [PATCH kvm/queue v2 3/3] KVM: x86/pmu: Setup the {inte|amd}_event_mapping[] when hardware_setup Like Xu
2022-02-01 12:28   ` Paolo Bonzini
2022-02-08 10:10     ` Like Xu
2022-01-26 11:22 ` [PATCH kvm/queue v2 0/3] KVM: x86/pmu: Fix out-of-date AMD amd_event_mapping[] Like Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220117085307.93030-2-likexu@tencent.com \
    --to=like.xu.linux@gmail.com \
    --cc=jmattson@google.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=likexu@tencent.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=vkuznets@redhat.com \
    --cc=wanpengli@tencent.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.