* [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events
@ 2023-11-10 2:28 Sean Christopherson
2023-11-10 2:28 ` [PATCH 01/10] KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled Sean Christopherson
` (11 more replies)
0 siblings, 12 replies; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 2:28 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
Optimize code used by, or which impacts, kvm_pmu_trigger_event() to try
and make a dent in the overhead of emulating PMU events in software, which
is quite noticeable due to it kicking in anytime the guest has a vPMU and
KVM is skipping an instruction.
Note, Jim has a proposal/idea[*] (that I supported) to make
kvm_pmu_trigger_event() even more performant. I opted not to do that as
it's a bit more invasive, and I started chewing on this not so much because
I care _that_ much about performance, but because it irritates me that the
PMU code makes things way harder than they need to be.
Note #2, this applies on top of my other two PMU series:
https://lore.kernel.org/all/20231103230541.352265-1-seanjc@google.com
https://lore.kernel.org/all/20231110021306.1269082-1-seanjc@google.com
Those series fix actual functional issues, i.e. I'll definitely apply them
first (there's definitely no rush on this one).
[*] https://lore.kernel.org/all/CALMp9eQGqqo66fQGwFJMc3y+9XdUrL7ageE8kvoAOV6NJGfJpw@mail.gmail.com
Sean Christopherson (10):
KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled
KVM: x86/pmu: Add common define to capture fixed counters offset
KVM: x86/pmu: Move pmc_idx => pmc translation helper to common code
KVM: x86/pmu: Snapshot and clear reprogramming bitmap before
reprogramming
KVM: x86/pmu: Add macros to iterate over all PMCs given a bitmap
KVM: x86/pmu: Process only enabled PMCs when emulating events in
software
KVM: x86/pmu: Snapshot event selectors that KVM emulates in software
KVM: x86/pmu: Expand the comment about what bits are check emulating
events
KVM: x86/pmu: Check eventsel first when emulating (branch) insns
retired
KVM: x86/pmu: Avoid CPL lookup if PMC enabline for USER and KERNEL is
the same
arch/x86/include/asm/kvm-x86-pmu-ops.h | 1 -
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/pmu.c | 143 +++++++++++++++----------
arch/x86/kvm/pmu.h | 52 ++++++++-
arch/x86/kvm/svm/pmu.c | 7 +-
arch/x86/kvm/vmx/nested.c | 2 +-
arch/x86/kvm/vmx/pmu_intel.c | 44 ++------
arch/x86/kvm/x86.c | 6 +-
8 files changed, 154 insertions(+), 102 deletions(-)
base-commit: ef1883475d4a24d8eaebb84175ed46206a688103
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 01/10] KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
@ 2023-11-10 2:28 ` Sean Christopherson
2023-11-10 2:28 ` [PATCH 02/10] KVM: x86/pmu: Add common define to capture fixed counters offset Sean Christopherson
` (10 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 2:28 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
Move the purging of common PMU metadata from intel_pmu_refresh() to
kvm_pmu_refresh(), and invoke the vendor refresh() hook if and only if
the VM is supposed to have a vPMU.
KVM already denies access to the PMU based on kvm->arch.enable_pmu, as
get_gp_pmc_amd() returns NULL for all PMCs in that case, i.e. KVM already
violates AMD's architecture by not virtualizing a PMU (kernels have long
since learned to not panic when the PMU is unavailable). But configuring
the PMU as if it were enabled causes unwanted side effects, e.g. calls to
kvm_pmu_trigger_event() waste an absurd number of cycles due to the
all_valid_pmc_idx bitmap being non-zero.
Fixes: b1d66dad65dc ("KVM: x86/svm: Add module param to control PMU virtualization")
Reported-by: Konstantin Khorenko <khorenko@virtuozzo.com>
Closes: https://lore.kernel.org/all/20231109180646.2963718-2-khorenko@virtuozzo.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/pmu.c | 20 ++++++++++++++++++--
arch/x86/kvm/vmx/pmu_intel.c | 16 ++--------------
2 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 1b74a29ed250..b52bab7dc422 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -739,6 +739,8 @@ static void kvm_pmu_reset(struct kvm_vcpu *vcpu)
*/
void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
{
+ struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+
if (KVM_BUG_ON(kvm_vcpu_has_run(vcpu), vcpu->kvm))
return;
@@ -748,8 +750,22 @@ void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
*/
kvm_pmu_reset(vcpu);
- bitmap_zero(vcpu_to_pmu(vcpu)->all_valid_pmc_idx, X86_PMC_IDX_MAX);
- static_call(kvm_x86_pmu_refresh)(vcpu);
+ pmu->version = 0;
+ pmu->nr_arch_gp_counters = 0;
+ pmu->nr_arch_fixed_counters = 0;
+ pmu->counter_bitmask[KVM_PMC_GP] = 0;
+ pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
+ pmu->reserved_bits = 0xffffffff00200000ull;
+ pmu->raw_event_mask = X86_RAW_EVENT_MASK;
+ pmu->global_ctrl_mask = ~0ull;
+ pmu->global_status_mask = ~0ull;
+ pmu->fixed_ctr_ctrl_mask = ~0ull;
+ pmu->pebs_enable_mask = ~0ull;
+ pmu->pebs_data_cfg_mask = ~0ull;
+ bitmap_zero(pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX);
+
+ if (vcpu->kvm->arch.enable_pmu)
+ static_call(kvm_x86_pmu_refresh)(vcpu);
}
void kvm_pmu_init(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index c3a841d8df27..0d2fd9fdcf4b 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -463,19 +463,6 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
u64 counter_mask;
int i;
- pmu->nr_arch_gp_counters = 0;
- pmu->nr_arch_fixed_counters = 0;
- pmu->counter_bitmask[KVM_PMC_GP] = 0;
- pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
- pmu->version = 0;
- pmu->reserved_bits = 0xffffffff00200000ull;
- pmu->raw_event_mask = X86_RAW_EVENT_MASK;
- pmu->global_ctrl_mask = ~0ull;
- pmu->global_status_mask = ~0ull;
- pmu->fixed_ctr_ctrl_mask = ~0ull;
- pmu->pebs_enable_mask = ~0ull;
- pmu->pebs_data_cfg_mask = ~0ull;
-
memset(&lbr_desc->records, 0, sizeof(lbr_desc->records));
/*
@@ -487,8 +474,9 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
return;
entry = kvm_find_cpuid_entry(vcpu, 0xa);
- if (!entry || !vcpu->kvm->arch.enable_pmu)
+ if (!entry)
return;
+
eax.full = entry->eax;
edx.full = entry->edx;
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 02/10] KVM: x86/pmu: Add common define to capture fixed counters offset
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
2023-11-10 2:28 ` [PATCH 01/10] KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled Sean Christopherson
@ 2023-11-10 2:28 ` Sean Christopherson
2023-11-10 2:28 ` [PATCH 03/10] KVM: x86/pmu: Move pmc_idx => pmc translation helper to common code Sean Christopherson
` (9 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 2:28 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
Add a common define to "officially" solidify KVM's split of counters,
i.e. to commit to using bits 31:0 to track general purpose counters and
bits 63:32 to track fixed counters (which only Intel supports). KVM
already bleeds this behavior all over common PMU code, and adding a KVM-
defined macro allows clarifying that the value is a _base_, as oppposed to
the _flag_ that is used to access fixed PMCs via RDPMC (which perf
confusingly calls INTEL_PMC_FIXED_RDPMC_BASE).
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/pmu.c | 8 ++++----
arch/x86/kvm/pmu.h | 4 +++-
arch/x86/kvm/vmx/pmu_intel.c | 12 ++++++------
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index b52bab7dc422..714fa6dd912e 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -67,7 +67,7 @@ static const struct x86_cpu_id vmx_pebs_pdist_cpu[] = {
* all perf counters (both gp and fixed). The mapping relationship
* between pmc and perf counters is as the following:
* * Intel: [0 .. KVM_INTEL_PMC_MAX_GENERIC-1] <=> gp counters
- * [INTEL_PMC_IDX_FIXED .. INTEL_PMC_IDX_FIXED + 2] <=> fixed
+ * [KVM_FIXED_PMC_BASE_IDX .. KVM_FIXED_PMC_BASE_IDX + 2] <=> fixed
* * AMD: [0 .. AMD64_NUM_COUNTERS-1] and, for families 15H
* and later, [0 .. AMD64_NUM_COUNTERS_CORE-1] <=> gp counters
*/
@@ -411,7 +411,7 @@ static bool is_gp_event_allowed(struct kvm_x86_pmu_event_filter *f,
static bool is_fixed_event_allowed(struct kvm_x86_pmu_event_filter *filter,
int idx)
{
- int fixed_idx = idx - INTEL_PMC_IDX_FIXED;
+ int fixed_idx = idx - KVM_FIXED_PMC_BASE_IDX;
if (filter->action == KVM_PMU_EVENT_DENY &&
test_bit(fixed_idx, (ulong *)&filter->fixed_counter_bitmap))
@@ -465,7 +465,7 @@ static void reprogram_counter(struct kvm_pmc *pmc)
if (pmc_is_fixed(pmc)) {
fixed_ctr_ctrl = fixed_ctrl_field(pmu->fixed_ctr_ctrl,
- pmc->idx - INTEL_PMC_IDX_FIXED);
+ pmc->idx - KVM_FIXED_PMC_BASE_IDX);
if (fixed_ctr_ctrl & 0x1)
eventsel |= ARCH_PERFMON_EVENTSEL_OS;
if (fixed_ctr_ctrl & 0x2)
@@ -831,7 +831,7 @@ static inline bool cpl_is_matched(struct kvm_pmc *pmc)
select_user = config & ARCH_PERFMON_EVENTSEL_USR;
} else {
config = fixed_ctrl_field(pmc_to_pmu(pmc)->fixed_ctr_ctrl,
- pmc->idx - INTEL_PMC_IDX_FIXED);
+ pmc->idx - KVM_FIXED_PMC_BASE_IDX);
select_os = config & 0x1;
select_user = config & 0x2;
}
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index 87ecf22f5b25..7ffa4f1dedb0 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -18,6 +18,8 @@
#define VMWARE_BACKDOOR_PMC_REAL_TIME 0x10001
#define VMWARE_BACKDOOR_PMC_APPARENT_TIME 0x10002
+#define KVM_FIXED_PMC_BASE_IDX INTEL_PMC_IDX_FIXED
+
struct kvm_pmu_ops {
struct kvm_pmc *(*pmc_idx_to_pmc)(struct kvm_pmu *pmu, int pmc_idx);
struct kvm_pmc *(*rdpmc_ecx_to_pmc)(struct kvm_vcpu *vcpu,
@@ -130,7 +132,7 @@ static inline bool pmc_speculative_in_use(struct kvm_pmc *pmc)
if (pmc_is_fixed(pmc))
return fixed_ctrl_field(pmu->fixed_ctr_ctrl,
- pmc->idx - INTEL_PMC_IDX_FIXED) & 0x3;
+ pmc->idx - KVM_FIXED_PMC_BASE_IDX) & 0x3;
return pmc->eventsel & ARCH_PERFMON_EVENTSEL_ENABLE;
}
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 0d2fd9fdcf4b..61252bb733c4 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -42,18 +42,18 @@ static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
pmc = get_fixed_pmc(pmu, MSR_CORE_PERF_FIXED_CTR0 + i);
- __set_bit(INTEL_PMC_IDX_FIXED + i, pmu->pmc_in_use);
+ __set_bit(KVM_FIXED_PMC_BASE_IDX + i, pmu->pmc_in_use);
kvm_pmu_request_counter_reprogram(pmc);
}
}
static struct kvm_pmc *intel_pmc_idx_to_pmc(struct kvm_pmu *pmu, int pmc_idx)
{
- if (pmc_idx < INTEL_PMC_IDX_FIXED) {
+ if (pmc_idx < KVM_FIXED_PMC_BASE_IDX) {
return get_gp_pmc(pmu, MSR_P6_EVNTSEL0 + pmc_idx,
MSR_P6_EVNTSEL0);
} else {
- u32 idx = pmc_idx - INTEL_PMC_IDX_FIXED;
+ u32 idx = pmc_idx - KVM_FIXED_PMC_BASE_IDX;
return get_fixed_pmc(pmu, idx + MSR_CORE_PERF_FIXED_CTR0);
}
@@ -508,7 +508,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
for (i = 0; i < pmu->nr_arch_fixed_counters; i++)
pmu->fixed_ctr_ctrl_mask &= ~(0xbull << (i * 4));
counter_mask = ~(((1ull << pmu->nr_arch_gp_counters) - 1) |
- (((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED));
+ (((1ull << pmu->nr_arch_fixed_counters) - 1) << KVM_FIXED_PMC_BASE_IDX));
pmu->global_ctrl_mask = counter_mask;
/*
@@ -552,7 +552,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
pmu->reserved_bits &= ~ICL_EVENTSEL_ADAPTIVE;
for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
pmu->fixed_ctr_ctrl_mask &=
- ~(1ULL << (INTEL_PMC_IDX_FIXED + i * 4));
+ ~(1ULL << (KVM_FIXED_PMC_BASE_IDX + i * 4));
}
pmu->pebs_data_cfg_mask = ~0xff00000full;
} else {
@@ -578,7 +578,7 @@ static void intel_pmu_init(struct kvm_vcpu *vcpu)
for (i = 0; i < KVM_PMC_MAX_FIXED; i++) {
pmu->fixed_counters[i].type = KVM_PMC_FIXED;
pmu->fixed_counters[i].vcpu = vcpu;
- pmu->fixed_counters[i].idx = i + INTEL_PMC_IDX_FIXED;
+ pmu->fixed_counters[i].idx = i + KVM_FIXED_PMC_BASE_IDX;
pmu->fixed_counters[i].current_config = 0;
pmu->fixed_counters[i].eventsel = intel_get_fixed_pmc_eventsel(i);
}
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 03/10] KVM: x86/pmu: Move pmc_idx => pmc translation helper to common code
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
2023-11-10 2:28 ` [PATCH 01/10] KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled Sean Christopherson
2023-11-10 2:28 ` [PATCH 02/10] KVM: x86/pmu: Add common define to capture fixed counters offset Sean Christopherson
@ 2023-11-10 2:28 ` Sean Christopherson
2023-11-10 2:28 ` [PATCH 04/10] KVM: x86/pmu: Snapshot and clear reprogramming bitmap before reprogramming Sean Christopherson
` (8 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 2:28 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
Add a common helper for *internal* PMC lookups, and delete the ops hook
and Intel's implementation. Keep AMD's implementation, but rename it to
amd_pmu_get_pmc() to make it somewhat more obvious that it's suited for
both KVM-internal and guest-initiated lookups.
Because KVM tracks all counters in a single bitmap, getting a counter
when iterating over a bitmap, e.g. of all valid PMCs, requires a small
amount of math, that while simple, isn't super obvious and doesn't use the
same semantics as PMC lookups from RDPMC! Although AMD doesn't support
fixed counters, the common PMU code still behaves as if there a split, the
high half of which just happens to always be empty.
Opportunstically add a comment to explain both what is going on, and why
KVM uses a single bitmap, e.g. the boilerplate for iterating over separate
bitmaps could be done via macros, so it's not (just) about deduplicating
code.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/include/asm/kvm-x86-pmu-ops.h | 1 -
arch/x86/kvm/pmu.c | 8 +++----
arch/x86/kvm/pmu.h | 29 +++++++++++++++++++++++++-
arch/x86/kvm/svm/pmu.c | 7 +++----
arch/x86/kvm/vmx/pmu_intel.c | 15 +------------
5 files changed, 36 insertions(+), 24 deletions(-)
diff --git a/arch/x86/include/asm/kvm-x86-pmu-ops.h b/arch/x86/include/asm/kvm-x86-pmu-ops.h
index d7eebee4450c..e5e7f036587f 100644
--- a/arch/x86/include/asm/kvm-x86-pmu-ops.h
+++ b/arch/x86/include/asm/kvm-x86-pmu-ops.h
@@ -12,7 +12,6 @@ BUILD_BUG_ON(1)
* a NULL definition, for example if "static_call_cond()" will be used
* at the call sites.
*/
-KVM_X86_PMU_OP(pmc_idx_to_pmc)
KVM_X86_PMU_OP(rdpmc_ecx_to_pmc)
KVM_X86_PMU_OP(msr_idx_to_pmc)
KVM_X86_PMU_OP(is_valid_rdpmc_ecx)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 714fa6dd912e..6ee05ad35f55 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -505,7 +505,7 @@ void kvm_pmu_handle_event(struct kvm_vcpu *vcpu)
int bit;
for_each_set_bit(bit, pmu->reprogram_pmi, X86_PMC_IDX_MAX) {
- struct kvm_pmc *pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, bit);
+ struct kvm_pmc *pmc = kvm_pmc_idx_to_pmc(pmu, bit);
if (unlikely(!pmc)) {
clear_bit(bit, pmu->reprogram_pmi);
@@ -715,7 +715,7 @@ static void kvm_pmu_reset(struct kvm_vcpu *vcpu)
bitmap_zero(pmu->reprogram_pmi, X86_PMC_IDX_MAX);
for_each_set_bit(i, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX) {
- pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, i);
+ pmc = kvm_pmc_idx_to_pmc(pmu, i);
if (!pmc)
continue;
@@ -791,7 +791,7 @@ void kvm_pmu_cleanup(struct kvm_vcpu *vcpu)
pmu->pmc_in_use, X86_PMC_IDX_MAX);
for_each_set_bit(i, bitmask, X86_PMC_IDX_MAX) {
- pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, i);
+ pmc = kvm_pmc_idx_to_pmc(pmu, i);
if (pmc && pmc->perf_event && !pmc_speculative_in_use(pmc))
pmc_stop_counter(pmc);
@@ -846,7 +846,7 @@ void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 perf_hw_id)
int i;
for_each_set_bit(i, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX) {
- pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, i);
+ pmc = kvm_pmc_idx_to_pmc(pmu, i);
if (!pmc || !pmc_event_is_allowed(pmc))
continue;
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index 7ffa4f1dedb0..2235772a495b 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -4,6 +4,8 @@
#include <linux/nospec.h>
+#include <asm/kvm_host.h>
+
#define vcpu_to_pmu(vcpu) (&(vcpu)->arch.pmu)
#define pmu_to_vcpu(pmu) (container_of((pmu), struct kvm_vcpu, arch.pmu))
#define pmc_to_pmu(pmc) (&(pmc)->vcpu->arch.pmu)
@@ -21,7 +23,6 @@
#define KVM_FIXED_PMC_BASE_IDX INTEL_PMC_IDX_FIXED
struct kvm_pmu_ops {
- struct kvm_pmc *(*pmc_idx_to_pmc)(struct kvm_pmu *pmu, int pmc_idx);
struct kvm_pmc *(*rdpmc_ecx_to_pmc)(struct kvm_vcpu *vcpu,
unsigned int idx, u64 *mask);
struct kvm_pmc *(*msr_idx_to_pmc)(struct kvm_vcpu *vcpu, u32 msr);
@@ -56,6 +57,32 @@ static inline bool kvm_pmu_has_perf_global_ctrl(struct kvm_pmu *pmu)
return pmu->version > 1;
}
+/*
+ * KVM tracks all counters in 64-bit bitmaps, with general purpose counters
+ * mapped to bits 31:0 and fixed counters mapped to 63:32, e.g. fixed counter 0
+ * is tracked internally via index 32. On Intel, (AMD doesn't support fixed
+ * counters), this mirrors how fixed counters are mapped to PERF_GLOBAL_CTRL
+ * and similar MSRs, i.e. tracking fixed counters at base index 32 reduces the
+ * amounter of boilerplate needed to iterate over PMCs *and* simplifies common
+ * enabling/disable/reset operations.
+ *
+ * WARNING! This helper is only for lookups that are initiated by KVM, it is
+ * NOT safe for guest lookups, e.g. will do the wrong thing if passed a raw
+ * ECX value from RDPMC (fixed counters are accessed by setting bit 30 in ECX
+ * for RDPMC, not by adding 32 to the fixed counter index).
+ */
+static inline struct kvm_pmc *kvm_pmc_idx_to_pmc(struct kvm_pmu *pmu, int idx)
+{
+ if (idx < pmu->nr_arch_gp_counters)
+ return &pmu->gp_counters[idx];
+
+ idx -= KVM_FIXED_PMC_BASE_IDX;
+ if (idx >= 0 && idx < pmu->nr_arch_fixed_counters)
+ return &pmu->fixed_counters[idx];
+
+ return NULL;
+}
+
static inline u64 pmc_bitmask(struct kvm_pmc *pmc)
{
struct kvm_pmu *pmu = pmc_to_pmu(pmc);
diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c
index 1fafc46f61c9..b6c1d1c3f204 100644
--- a/arch/x86/kvm/svm/pmu.c
+++ b/arch/x86/kvm/svm/pmu.c
@@ -25,7 +25,7 @@ enum pmu_type {
PMU_TYPE_EVNTSEL,
};
-static struct kvm_pmc *amd_pmc_idx_to_pmc(struct kvm_pmu *pmu, int pmc_idx)
+static struct kvm_pmc *amd_pmu_get_pmc(struct kvm_pmu *pmu, int pmc_idx)
{
unsigned int num_counters = pmu->nr_arch_gp_counters;
@@ -70,7 +70,7 @@ static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr,
return NULL;
}
- return amd_pmc_idx_to_pmc(pmu, idx);
+ return amd_pmu_get_pmc(pmu, idx);
}
static bool amd_is_valid_rdpmc_ecx(struct kvm_vcpu *vcpu, unsigned int idx)
@@ -84,7 +84,7 @@ static bool amd_is_valid_rdpmc_ecx(struct kvm_vcpu *vcpu, unsigned int idx)
static struct kvm_pmc *amd_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu,
unsigned int idx, u64 *mask)
{
- return amd_pmc_idx_to_pmc(vcpu_to_pmu(vcpu), idx);
+ return amd_pmu_get_pmc(vcpu_to_pmu(vcpu), idx);
}
static struct kvm_pmc *amd_msr_idx_to_pmc(struct kvm_vcpu *vcpu, u32 msr)
@@ -226,7 +226,6 @@ static void amd_pmu_init(struct kvm_vcpu *vcpu)
}
struct kvm_pmu_ops amd_pmu_ops __initdata = {
- .pmc_idx_to_pmc = amd_pmc_idx_to_pmc,
.rdpmc_ecx_to_pmc = amd_rdpmc_ecx_to_pmc,
.msr_idx_to_pmc = amd_msr_idx_to_pmc,
.is_valid_rdpmc_ecx = amd_is_valid_rdpmc_ecx,
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 61252bb733c4..4254411be467 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -47,18 +47,6 @@ static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
}
}
-static struct kvm_pmc *intel_pmc_idx_to_pmc(struct kvm_pmu *pmu, int pmc_idx)
-{
- if (pmc_idx < KVM_FIXED_PMC_BASE_IDX) {
- return get_gp_pmc(pmu, MSR_P6_EVNTSEL0 + pmc_idx,
- MSR_P6_EVNTSEL0);
- } else {
- u32 idx = pmc_idx - KVM_FIXED_PMC_BASE_IDX;
-
- return get_fixed_pmc(pmu, idx + MSR_CORE_PERF_FIXED_CTR0);
- }
-}
-
static u32 intel_rdpmc_get_masked_idx(struct kvm_pmu *pmu, u32 idx)
{
/*
@@ -710,7 +698,7 @@ void intel_pmu_cross_mapped_check(struct kvm_pmu *pmu)
for_each_set_bit(bit, (unsigned long *)&pmu->global_ctrl,
X86_PMC_IDX_MAX) {
- pmc = intel_pmc_idx_to_pmc(pmu, bit);
+ pmc = kvm_pmc_idx_to_pmc(pmu, bit);
if (!pmc || !pmc_speculative_in_use(pmc) ||
!pmc_is_globally_enabled(pmc) || !pmc->perf_event)
@@ -727,7 +715,6 @@ void intel_pmu_cross_mapped_check(struct kvm_pmu *pmu)
}
struct kvm_pmu_ops intel_pmu_ops __initdata = {
- .pmc_idx_to_pmc = intel_pmc_idx_to_pmc,
.rdpmc_ecx_to_pmc = intel_rdpmc_ecx_to_pmc,
.msr_idx_to_pmc = intel_msr_idx_to_pmc,
.is_valid_rdpmc_ecx = intel_is_valid_rdpmc_ecx,
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 04/10] KVM: x86/pmu: Snapshot and clear reprogramming bitmap before reprogramming
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
` (2 preceding siblings ...)
2023-11-10 2:28 ` [PATCH 03/10] KVM: x86/pmu: Move pmc_idx => pmc translation helper to common code Sean Christopherson
@ 2023-11-10 2:28 ` Sean Christopherson
2023-11-10 2:28 ` [PATCH 05/10] KVM: x86/pmu: Add macros to iterate over all PMCs given a bitmap Sean Christopherson
` (7 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 2:28 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
Refactor the handling of the reprogramming bitmap to snapshot and clear
to-be-processed bits before doing the reprogramming, and then explicitly
set bits for PMCs that need to be reprogrammed (again). This will allow
adding a macro to iterate over all valid PMCs without having to add
special handling for the reprogramming bit, which (a) can have bits set
for non-existent PMCs and (b) needs to clear such bits to avoid wasting
cycles in perpetuity.
Note, the existing behavior of clearing bits after reprogramming does NOT
have a race with kvm_vm_ioctl_set_pmu_event_filter(). Setting a new PMU
filter synchronizes SRCU _before_ setting the bitmap, i.e. guarantees that
the vCPU isn't in the middle of reprogramming with a stale filter prior to
setting the bitmap.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/pmu.c | 52 ++++++++++++++++++---------------
2 files changed, 30 insertions(+), 23 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index d8bc9ba88cfc..22ba24d0fd4f 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -535,6 +535,7 @@ struct kvm_pmc {
#define KVM_PMC_MAX_FIXED 3
#define MSR_ARCH_PERFMON_FIXED_CTR_MAX (MSR_ARCH_PERFMON_FIXED_CTR0 + KVM_PMC_MAX_FIXED - 1)
#define KVM_AMD_PMC_MAX_GENERIC 6
+
struct kvm_pmu {
u8 version;
unsigned nr_arch_gp_counters;
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 6ee05ad35f55..ee921b24d9e4 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -444,7 +444,7 @@ static bool pmc_event_is_allowed(struct kvm_pmc *pmc)
check_pmu_event_filter(pmc);
}
-static void reprogram_counter(struct kvm_pmc *pmc)
+static int reprogram_counter(struct kvm_pmc *pmc)
{
struct kvm_pmu *pmu = pmc_to_pmu(pmc);
u64 eventsel = pmc->eventsel;
@@ -455,7 +455,7 @@ static void reprogram_counter(struct kvm_pmc *pmc)
emulate_overflow = pmc_pause_counter(pmc);
if (!pmc_event_is_allowed(pmc))
- goto reprogram_complete;
+ return 0;
if (emulate_overflow)
__kvm_perf_overflow(pmc, false);
@@ -476,43 +476,49 @@ static void reprogram_counter(struct kvm_pmc *pmc)
}
if (pmc->current_config == new_config && pmc_resume_counter(pmc))
- goto reprogram_complete;
+ return 0;
pmc_release_perf_event(pmc);
pmc->current_config = new_config;
- /*
- * If reprogramming fails, e.g. due to contention, leave the counter's
- * regprogram bit set, i.e. opportunistically try again on the next PMU
- * refresh. Don't make a new request as doing so can stall the guest
- * if reprogramming repeatedly fails.
- */
- if (pmc_reprogram_counter(pmc, PERF_TYPE_RAW,
- (eventsel & pmu->raw_event_mask),
- !(eventsel & ARCH_PERFMON_EVENTSEL_USR),
- !(eventsel & ARCH_PERFMON_EVENTSEL_OS),
- eventsel & ARCH_PERFMON_EVENTSEL_INT))
- return;
-
-reprogram_complete:
- clear_bit(pmc->idx, (unsigned long *)&pmc_to_pmu(pmc)->reprogram_pmi);
+ return pmc_reprogram_counter(pmc, PERF_TYPE_RAW,
+ (eventsel & pmu->raw_event_mask),
+ !(eventsel & ARCH_PERFMON_EVENTSEL_USR),
+ !(eventsel & ARCH_PERFMON_EVENTSEL_OS),
+ eventsel & ARCH_PERFMON_EVENTSEL_INT);
}
void kvm_pmu_handle_event(struct kvm_vcpu *vcpu)
{
+ DECLARE_BITMAP(bitmap, X86_PMC_IDX_MAX);
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
int bit;
- for_each_set_bit(bit, pmu->reprogram_pmi, X86_PMC_IDX_MAX) {
+ bitmap_copy(bitmap, pmu->reprogram_pmi, X86_PMC_IDX_MAX);
+
+ /*
+ * The reprogramming bitmap can be written asynchronously by something
+ * other than the task that holds vcpu->mutex, take care to clear only
+ * the bits that will actually processed.
+ */
+ BUILD_BUG_ON(sizeof(bitmap) != sizeof(atomic64_t));
+ atomic64_andnot(*(s64 *)bitmap, &pmu->__reprogram_pmi);
+
+ for_each_set_bit(bit, bitmap, X86_PMC_IDX_MAX) {
struct kvm_pmc *pmc = kvm_pmc_idx_to_pmc(pmu, bit);
- if (unlikely(!pmc)) {
- clear_bit(bit, pmu->reprogram_pmi);
+ if (unlikely(!pmc))
continue;
- }
- reprogram_counter(pmc);
+ /*
+ * If reprogramming fails, e.g. due to contention, re-set the
+ * regprogram bit set, i.e. opportunistically try again on the
+ * next PMU refresh. Don't make a new request as doing so can
+ * stall the guest if reprogramming repeatedly fails.
+ */
+ if (reprogram_counter(pmc))
+ set_bit(pmc->idx, pmu->reprogram_pmi);
}
/*
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 05/10] KVM: x86/pmu: Add macros to iterate over all PMCs given a bitmap
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
` (3 preceding siblings ...)
2023-11-10 2:28 ` [PATCH 04/10] KVM: x86/pmu: Snapshot and clear reprogramming bitmap before reprogramming Sean Christopherson
@ 2023-11-10 2:28 ` Sean Christopherson
2023-11-10 2:28 ` [PATCH 06/10] KVM: x86/pmu: Process only enabled PMCs when emulating events in software Sean Christopherson
` (6 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 2:28 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
Add and use kvm_for_each_pmc() to dedup a variety of open coded for-loops
that iterate over valid PMCs given a bitmap (and because seeing checkpatch
whine about bad macro style is always amusing).
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/pmu.c | 26 +++++++-------------------
arch/x86/kvm/pmu.h | 6 ++++++
arch/x86/kvm/vmx/pmu_intel.c | 7 ++-----
3 files changed, 15 insertions(+), 24 deletions(-)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index ee921b24d9e4..0e2175170038 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -493,6 +493,7 @@ void kvm_pmu_handle_event(struct kvm_vcpu *vcpu)
{
DECLARE_BITMAP(bitmap, X86_PMC_IDX_MAX);
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+ struct kvm_pmc *pmc;
int bit;
bitmap_copy(bitmap, pmu->reprogram_pmi, X86_PMC_IDX_MAX);
@@ -505,12 +506,7 @@ void kvm_pmu_handle_event(struct kvm_vcpu *vcpu)
BUILD_BUG_ON(sizeof(bitmap) != sizeof(atomic64_t));
atomic64_andnot(*(s64 *)bitmap, &pmu->__reprogram_pmi);
- for_each_set_bit(bit, bitmap, X86_PMC_IDX_MAX) {
- struct kvm_pmc *pmc = kvm_pmc_idx_to_pmc(pmu, bit);
-
- if (unlikely(!pmc))
- continue;
-
+ kvm_for_each_pmc(pmu, pmc, bit, bitmap) {
/*
* If reprogramming fails, e.g. due to contention, re-set the
* regprogram bit set, i.e. opportunistically try again on the
@@ -720,11 +716,7 @@ static void kvm_pmu_reset(struct kvm_vcpu *vcpu)
bitmap_zero(pmu->reprogram_pmi, X86_PMC_IDX_MAX);
- for_each_set_bit(i, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX) {
- pmc = kvm_pmc_idx_to_pmc(pmu, i);
- if (!pmc)
- continue;
-
+ kvm_for_each_pmc(pmu, pmc, i, pmu->all_valid_pmc_idx) {
pmc_stop_counter(pmc);
pmc->counter = 0;
pmc->emulated_counter = 0;
@@ -796,10 +788,8 @@ void kvm_pmu_cleanup(struct kvm_vcpu *vcpu)
bitmap_andnot(bitmask, pmu->all_valid_pmc_idx,
pmu->pmc_in_use, X86_PMC_IDX_MAX);
- for_each_set_bit(i, bitmask, X86_PMC_IDX_MAX) {
- pmc = kvm_pmc_idx_to_pmc(pmu, i);
-
- if (pmc && pmc->perf_event && !pmc_speculative_in_use(pmc))
+ kvm_for_each_pmc(pmu, pmc, i, bitmask) {
+ if (pmc->perf_event && !pmc_speculative_in_use(pmc))
pmc_stop_counter(pmc);
}
@@ -851,10 +841,8 @@ void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 perf_hw_id)
struct kvm_pmc *pmc;
int i;
- for_each_set_bit(i, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX) {
- pmc = kvm_pmc_idx_to_pmc(pmu, i);
-
- if (!pmc || !pmc_event_is_allowed(pmc))
+ kvm_for_each_pmc(pmu, pmc, i, pmu->all_valid_pmc_idx) {
+ if (!pmc_event_is_allowed(pmc))
continue;
/* Ignore checks for edge detect, pin control, invert and CMASK bits */
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index 2235772a495b..cb62a4e44849 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -83,6 +83,12 @@ static inline struct kvm_pmc *kvm_pmc_idx_to_pmc(struct kvm_pmu *pmu, int idx)
return NULL;
}
+#define kvm_for_each_pmc(pmu, pmc, i, bitmap) \
+ for_each_set_bit(i, bitmap, X86_PMC_IDX_MAX) \
+ if (!(pmc = kvm_pmc_idx_to_pmc(pmu, i))) \
+ continue; \
+ else \
+
static inline u64 pmc_bitmask(struct kvm_pmc *pmc)
{
struct kvm_pmu *pmu = pmc_to_pmu(pmc);
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 4254411be467..ee3e122d3617 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -696,11 +696,8 @@ void intel_pmu_cross_mapped_check(struct kvm_pmu *pmu)
struct kvm_pmc *pmc = NULL;
int bit, hw_idx;
- for_each_set_bit(bit, (unsigned long *)&pmu->global_ctrl,
- X86_PMC_IDX_MAX) {
- pmc = kvm_pmc_idx_to_pmc(pmu, bit);
-
- if (!pmc || !pmc_speculative_in_use(pmc) ||
+ kvm_for_each_pmc(pmu, pmc, bit, (unsigned long *)&pmu->global_ctrl) {
+ if (!pmc_speculative_in_use(pmc) ||
!pmc_is_globally_enabled(pmc) || !pmc->perf_event)
continue;
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 06/10] KVM: x86/pmu: Process only enabled PMCs when emulating events in software
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
` (4 preceding siblings ...)
2023-11-10 2:28 ` [PATCH 05/10] KVM: x86/pmu: Add macros to iterate over all PMCs given a bitmap Sean Christopherson
@ 2023-11-10 2:28 ` Sean Christopherson
2023-11-10 2:28 ` [PATCH 07/10] KVM: x86/pmu: Snapshot event selectors that KVM emulates " Sean Christopherson
` (5 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 2:28 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
Mask off disabled counters based on PERF_GLOBAL_CTRL *before* iterating
over PMCs to emulate (branch) instruction required events in software. In
the common case where the guest isn't utilizing the PMU, pre-checking for
enabled counters turns a relatively expensive search into a few AND uops
and a Jcc.
Sadly, PMUs without PERF_GLOBAL_CTRL, e.g. most existing AMD CPUs, are out
of luck as there is no way to check that a PMC isn't being used without
checking the PMC's event selector.
Cc: Konstantin Khorenko <khorenko@virtuozzo.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/pmu.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 0e2175170038..488d21024a92 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -837,11 +837,20 @@ static inline bool cpl_is_matched(struct kvm_pmc *pmc)
void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 perf_hw_id)
{
+ DECLARE_BITMAP(bitmap, X86_PMC_IDX_MAX);
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
struct kvm_pmc *pmc;
int i;
- kvm_for_each_pmc(pmu, pmc, i, pmu->all_valid_pmc_idx) {
+ BUILD_BUG_ON(sizeof(pmu->global_ctrl) * BITS_PER_BYTE != X86_PMC_IDX_MAX);
+
+ if (!kvm_pmu_has_perf_global_ctrl(pmu))
+ bitmap_copy(bitmap, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX);
+ else if (!bitmap_and(bitmap, pmu->all_valid_pmc_idx,
+ (unsigned long *)&pmu->global_ctrl, X86_PMC_IDX_MAX))
+ return;
+
+ kvm_for_each_pmc(pmu, pmc, i, bitmap) {
if (!pmc_event_is_allowed(pmc))
continue;
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 07/10] KVM: x86/pmu: Snapshot event selectors that KVM emulates in software
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
` (5 preceding siblings ...)
2023-11-10 2:28 ` [PATCH 06/10] KVM: x86/pmu: Process only enabled PMCs when emulating events in software Sean Christopherson
@ 2023-11-10 2:28 ` Sean Christopherson
2023-11-10 2:28 ` [PATCH 08/10] KVM: x86/pmu: Expand the comment about what bits are check emulating events Sean Christopherson
` (4 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 2:28 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
Snapshot the event selectors for the events that KVM emulates in software,
which is currently instructions retired and branch instructions retired.
The event selectors a tied to the underlying CPU, i.e. are constant for a
given platform even though perf doesn't manage the mappings as such.
Getting the event selectors from perf isn't exactly cheap, especially if
mitigations are enabled, as at least one indirect call is involved.
Snapshot the values in KVM instead of optimizing perf as working with the
raw event selectors will be required if KVM ever wants to emulate events
that aren't part of perf's uABI, i.e. that don't have an "enum perf_hw_id"
entry.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/pmu.c | 17 ++++++++---------
arch/x86/kvm/pmu.h | 13 ++++++++++++-
arch/x86/kvm/vmx/nested.c | 2 +-
arch/x86/kvm/x86.c | 6 +++---
4 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 488d21024a92..45cb8b2a024b 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -29,6 +29,9 @@
struct x86_pmu_capability __read_mostly kvm_pmu_cap;
EXPORT_SYMBOL_GPL(kvm_pmu_cap);
+struct kvm_pmu_emulated_event_selectors __read_mostly kvm_pmu_eventsel;
+EXPORT_SYMBOL_GPL(kvm_pmu_eventsel);
+
/* Precise Distribution of Instructions Retired (PDIR) */
static const struct x86_cpu_id vmx_pebs_pdir_cpu[] = {
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, NULL),
@@ -809,13 +812,6 @@ static void kvm_pmu_incr_counter(struct kvm_pmc *pmc)
kvm_pmu_request_counter_reprogram(pmc);
}
-static inline bool eventsel_match_perf_hw_id(struct kvm_pmc *pmc,
- unsigned int perf_hw_id)
-{
- return !((pmc->eventsel ^ perf_get_hw_event_config(perf_hw_id)) &
- AMD64_RAW_EVENT_MASK_NB);
-}
-
static inline bool cpl_is_matched(struct kvm_pmc *pmc)
{
bool select_os, select_user;
@@ -835,7 +831,7 @@ static inline bool cpl_is_matched(struct kvm_pmc *pmc)
return (static_call(kvm_x86_get_cpl)(pmc->vcpu) == 0) ? select_os : select_user;
}
-void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 perf_hw_id)
+void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 eventsel)
{
DECLARE_BITMAP(bitmap, X86_PMC_IDX_MAX);
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
@@ -855,7 +851,10 @@ void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 perf_hw_id)
continue;
/* Ignore checks for edge detect, pin control, invert and CMASK bits */
- if (eventsel_match_perf_hw_id(pmc, perf_hw_id) && cpl_is_matched(pmc))
+ if ((pmc->eventsel ^ eventsel) & AMD64_RAW_EVENT_MASK_NB)
+ continue;
+
+ if (cpl_is_matched(pmc))
kvm_pmu_incr_counter(pmc);
}
}
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index cb62a4e44849..9dc5f549c98c 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -22,6 +22,11 @@
#define KVM_FIXED_PMC_BASE_IDX INTEL_PMC_IDX_FIXED
+struct kvm_pmu_emulated_event_selectors {
+ u64 INSTRUCTIONS_RETIRED;
+ u64 BRANCH_INSTRUCTIONS_RETIRED;
+};
+
struct kvm_pmu_ops {
struct kvm_pmc *(*rdpmc_ecx_to_pmc)(struct kvm_vcpu *vcpu,
unsigned int idx, u64 *mask);
@@ -171,6 +176,7 @@ static inline bool pmc_speculative_in_use(struct kvm_pmc *pmc)
}
extern struct x86_pmu_capability kvm_pmu_cap;
+extern struct kvm_pmu_emulated_event_selectors kvm_pmu_eventsel;
static inline void kvm_init_pmu_capability(const struct kvm_pmu_ops *pmu_ops)
{
@@ -212,6 +218,11 @@ static inline void kvm_init_pmu_capability(const struct kvm_pmu_ops *pmu_ops)
pmu_ops->MAX_NR_GP_COUNTERS);
kvm_pmu_cap.num_counters_fixed = min(kvm_pmu_cap.num_counters_fixed,
KVM_PMC_MAX_FIXED);
+
+ kvm_pmu_eventsel.INSTRUCTIONS_RETIRED =
+ perf_get_hw_event_config(PERF_COUNT_HW_INSTRUCTIONS);
+ kvm_pmu_eventsel.BRANCH_INSTRUCTIONS_RETIRED =
+ perf_get_hw_event_config(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
}
static inline void kvm_pmu_request_counter_reprogram(struct kvm_pmc *pmc)
@@ -259,7 +270,7 @@ void kvm_pmu_init(struct kvm_vcpu *vcpu);
void kvm_pmu_cleanup(struct kvm_vcpu *vcpu);
void kvm_pmu_destroy(struct kvm_vcpu *vcpu);
int kvm_vm_ioctl_set_pmu_event_filter(struct kvm *kvm, void __user *argp);
-void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 perf_hw_id);
+void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 eventsel);
bool is_vmware_backdoor_pmc(u32 pmc_idx);
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index c5ec0ef51ff7..cf985085467b 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -3564,7 +3564,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
return 1;
}
- kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
+ kvm_pmu_trigger_event(vcpu, kvm_pmu_eventsel.BRANCH_INSTRUCTIONS_RETIRED);
if (CC(evmptrld_status == EVMPTRLD_VMFAIL))
return nested_vmx_failInvalid(vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index efbf52a9dc83..9d9b5f9e4b28 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8839,7 +8839,7 @@ int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu)
if (unlikely(!r))
return 0;
- kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_INSTRUCTIONS);
+ kvm_pmu_trigger_event(vcpu, kvm_pmu_eventsel.INSTRUCTIONS_RETIRED);
/*
* rflags is the old, "raw" value of the flags. The new value has
@@ -9152,9 +9152,9 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
*/
if (!ctxt->have_exception ||
exception_type(ctxt->exception.vector) == EXCPT_TRAP) {
- kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_INSTRUCTIONS);
+ kvm_pmu_trigger_event(vcpu, kvm_pmu_eventsel.INSTRUCTIONS_RETIRED);
if (ctxt->is_branch)
- kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
+ kvm_pmu_trigger_event(vcpu, kvm_pmu_eventsel.BRANCH_INSTRUCTIONS_RETIRED);
kvm_rip_write(vcpu, ctxt->eip);
if (r && (ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
r = kvm_vcpu_do_singlestep(vcpu);
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 08/10] KVM: x86/pmu: Expand the comment about what bits are check emulating events
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
` (6 preceding siblings ...)
2023-11-10 2:28 ` [PATCH 07/10] KVM: x86/pmu: Snapshot event selectors that KVM emulates " Sean Christopherson
@ 2023-11-10 2:28 ` Sean Christopherson
2023-11-10 2:28 ` [PATCH 09/10] KVM: x86/pmu: Check eventsel first when emulating (branch) insns retired Sean Christopherson
` (3 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 2:28 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
Expand the comment about what bits are and aren't checked when emulating
PMC events in software. As pointed out by Jim, AMD's mask includes bits
35:32, which on Intel overlap with the IN_TX and IN_TXCP bits (32 and 33)
as well as reserved bits (34 and 45).
Checking The IN_TX* bits is actually correct, as it's safe to assert that
the vCPU can't be in an HLE/RTM transaction if KVM is emulating an
instruction, i.e. KVM *shouldn't count if either of those bits is set.
For the reserved bits, KVM is has equal odds of being right if Intel adds
new behavior, i.e. ignoring them is just as likely to be correct as
checking them.
Opportunistically explain *why* the other flags aren't checked.
Suggested-by: Jim Mattson <jmattson@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/pmu.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 45cb8b2a024b..ba561849fd3e 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -850,7 +850,20 @@ void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 eventsel)
if (!pmc_event_is_allowed(pmc))
continue;
- /* Ignore checks for edge detect, pin control, invert and CMASK bits */
+ /*
+ * Ignore checks for edge detect (all events currently emulated
+ * but KVM are always rising edges), pin control (unsupported
+ * by modern CPUs), and counter mask and its invert flag (KVM
+ * doesn't emulate multiple events in a single clock cycle).
+ *
+ * Note, the uppermost nibble of AMD's mask overlaps Intel's
+ * IN_TX (bit 32) and IN_TXCP (bit 33), as well as two reserved
+ * bits (bits 35:34). Checking the "in HLE/RTM transaction"
+ * flags is correct as the vCPU can't be in a transaction if
+ * KVM is emulating an instruction. Checking the reserved bits
+ * might be wrong if they are defined in the future, but so
+ * could ignoring them, so do the simple thing for now.
+ */
if ((pmc->eventsel ^ eventsel) & AMD64_RAW_EVENT_MASK_NB)
continue;
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 09/10] KVM: x86/pmu: Check eventsel first when emulating (branch) insns retired
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
` (7 preceding siblings ...)
2023-11-10 2:28 ` [PATCH 08/10] KVM: x86/pmu: Expand the comment about what bits are check emulating events Sean Christopherson
@ 2023-11-10 2:28 ` Sean Christopherson
2023-11-10 2:28 ` [PATCH 10/10] KVM: x86/pmu: Avoid CPL lookup if PMC enabline for USER and KERNEL is the same Sean Christopherson
` (2 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 2:28 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
When triggering events, i.e. emulating PMC events in software, check for
a matching event selector before checking the event is allowed. The "is
allowed" check *might* be cheap, but it could also be very costly, e.g. if
userspace has defined a large PMU event filter. The event selector check
on the other hand is all but guaranteed to be <10 uops, e.g. looks
something like:
0xffffffff8105e615 <+5>: movabs $0xf0000ffff,%rax
0xffffffff8105e61f <+15>: xor %rdi,%rsi
0xffffffff8105e622 <+18>: test %rax,%rsi
0xffffffff8105e625 <+21>: sete %al
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/pmu.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index ba561849fd3e..a5ea729b16f2 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -847,9 +847,6 @@ void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 eventsel)
return;
kvm_for_each_pmc(pmu, pmc, i, bitmap) {
- if (!pmc_event_is_allowed(pmc))
- continue;
-
/*
* Ignore checks for edge detect (all events currently emulated
* but KVM are always rising edges), pin control (unsupported
@@ -864,11 +861,11 @@ void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 eventsel)
* might be wrong if they are defined in the future, but so
* could ignoring them, so do the simple thing for now.
*/
- if ((pmc->eventsel ^ eventsel) & AMD64_RAW_EVENT_MASK_NB)
+ if (((pmc->eventsel ^ eventsel) & AMD64_RAW_EVENT_MASK_NB) ||
+ !pmc_event_is_allowed(pmc) || !cpl_is_matched(pmc))
continue;
- if (cpl_is_matched(pmc))
- kvm_pmu_incr_counter(pmc);
+ kvm_pmu_incr_counter(pmc);
}
}
EXPORT_SYMBOL_GPL(kvm_pmu_trigger_event);
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 10/10] KVM: x86/pmu: Avoid CPL lookup if PMC enabline for USER and KERNEL is the same
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
` (8 preceding siblings ...)
2023-11-10 2:28 ` [PATCH 09/10] KVM: x86/pmu: Check eventsel first when emulating (branch) insns retired Sean Christopherson
@ 2023-11-10 2:28 ` Sean Christopherson
2023-11-10 6:37 ` [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Dongli Zhang
2024-02-03 0:11 ` Sean Christopherson
11 siblings, 0 replies; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 2:28 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
Don't bother querying the CPL if a PMC is (not) counting for both USER and
KERNEL, i.e. if the end result is guaranteed to be the same regardless of
the CPL. Querying the CPL on Intel requires a VMREAD, i.e. isn't free,
and a single CMP+Jcc is cheap.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/pmu.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index a5ea729b16f2..231604d6dc86 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -828,6 +828,13 @@ static inline bool cpl_is_matched(struct kvm_pmc *pmc)
select_user = config & 0x2;
}
+ /*
+ * Skip the CPL lookup, which isn't free on Intel, if the result will
+ * be the same regardless of the CPL.
+ */
+ if (select_os == select_user)
+ return select_os;
+
return (static_call(kvm_x86_get_cpl)(pmc->vcpu) == 0) ? select_os : select_user;
}
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
` (9 preceding siblings ...)
2023-11-10 2:28 ` [PATCH 10/10] KVM: x86/pmu: Avoid CPL lookup if PMC enabline for USER and KERNEL is the same Sean Christopherson
@ 2023-11-10 6:37 ` Dongli Zhang
2023-11-10 14:56 ` Sean Christopherson
2024-02-03 0:11 ` Sean Christopherson
11 siblings, 1 reply; 15+ messages in thread
From: Dongli Zhang @ 2023-11-10 6:37 UTC (permalink / raw)
To: Sean Christopherson
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson,
Paolo Bonzini
Hi Sean,
On 11/9/23 18:28, Sean Christopherson wrote:
>
> base-commit: ef1883475d4a24d8eaebb84175ed46206a688103
May I have a silly question?
May I have the tree that the commit is the base? I do not find it in kvm-x86.
https://github.com/kvm-x86/linux/commit/ef1883475d4a24d8eaebb84175ed46206a688103
Thank you very much!
Dongli Zhang
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events
2023-11-10 6:37 ` [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Dongli Zhang
@ 2023-11-10 14:56 ` Sean Christopherson
2023-11-16 16:37 ` Konstantin Khorenko
0 siblings, 1 reply; 15+ messages in thread
From: Sean Christopherson @ 2023-11-10 14:56 UTC (permalink / raw)
To: Dongli Zhang
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson,
Paolo Bonzini
On Thu, Nov 09, 2023, Dongli Zhang wrote:
> Hi Sean,
>
> On 11/9/23 18:28, Sean Christopherson wrote:
> >
> > base-commit: ef1883475d4a24d8eaebb84175ed46206a688103
>
> May I have a silly question?
>
> May I have the tree that the commit is the base? I do not find it in kvm-x86.
>
> https://github.com/kvm-x86/linux/commit/ef1883475d4a24d8eaebb84175ed46206a688103
It's kvm-x86/next (which I failed to explicitly call out), plus two PMU series
as mentioned in the cover letter.
https://lore.kernel.org/all/20231103230541.352265-1-seanjc@google.com
https://lore.kernel.org/all/20231110021306.1269082-1-seanjc@google.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events
2023-11-10 14:56 ` Sean Christopherson
@ 2023-11-16 16:37 ` Konstantin Khorenko
0 siblings, 0 replies; 15+ messages in thread
From: Konstantin Khorenko @ 2023-11-16 16:37 UTC (permalink / raw)
To: Sean Christopherson, Dongli Zhang
Cc: kvm, linux-kernel, Jim Mattson, Paolo Bonzini
On 10.11.2023 15:56, Sean Christopherson wrote:
> On Thu, Nov 09, 2023, Dongli Zhang wrote:
>> Hi Sean,
>>
>> On 11/9/23 18:28, Sean Christopherson wrote:
>>> base-commit: ef1883475d4a24d8eaebb84175ed46206a688103
>> May I have a silly question?
>>
>> May I have the tree that the commit is the base? I do not find it in kvm-x86.
>>
>> https://github.com/kvm-x86/linux/commit/ef1883475d4a24d8eaebb84175ed46206a688103
> It's kvm-x86/next (which I failed to explicitly call out), plus two PMU series
> as mentioned in the cover letter.
>
> https://lore.kernel.org/all/20231103230541.352265-1-seanjc@google.com
> https://lore.kernel.org/all/20231110021306.1269082-1-seanjc@google.com
Hi Sean,
i have tested my testcase on your patchset, results look impressive, thank you for your work!
Note, for AMD node PMU totally disabled case gave a bit worse results on kvm-next kernel vs stock
latest mainstream.
The difference is tiny though.
*AMD node*: CPU: AMD Zen 3 (three!): AMD EPYC 7443P 24-Core Processor
-----------------------------------------------------------------------------------------
| Kernel | CPUID rate |
-----------------------------------------------------------------------------------------
| stock ms 6.6.0+ (commit 305230142ae0) | 1360250 |
| stock ms 6.6.0+ + kvm.enable_pmu=0 | 1542894 (+13.4%) |
| kvm-next ms 6.6.0+ + patches from Sean + kvm.enable_pmu=1 | 1498864 |
| kvm-next ms 6.6.0+ + patches from Sean + kvm.enable_pmu=0 | 1526396 (+1.84%) |
-----------------------------------------------------------------------------------------
*Intel node*: CPU: Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz
-----------------------------------------------------------------------------------------
| Kernel | CPUID rate |
-----------------------------------------------------------------------------------------
| stock ms 6.6.0+ | 1431608 |
| stock ms 6.6.0+ + kvm.enable_pmu=0 | 1553839 (+8.5%) |
| kvm-next ms 6.6.0+ + patches from Sean + kvm.enable_pmu=1 | 1559365 |
| kvm-next ms 6.6.0+ + patches from Sean + kvm.enable_pmu=0 | 1582281 (+1.5%) |
-----------------------------------------------------------------------------------------
Note: in order to disable PMU completely i used "kvm" module "enable_pmu=0" option
(not used KVM_PMU_CAP_DISABLEthis time).
Hope that helps.
--
Best regards,
Konstantin Khorenko,
Virtuozzo Linux Kernel Team
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
` (10 preceding siblings ...)
2023-11-10 6:37 ` [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Dongli Zhang
@ 2024-02-03 0:11 ` Sean Christopherson
11 siblings, 0 replies; 15+ messages in thread
From: Sean Christopherson @ 2024-02-03 0:11 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini
Cc: kvm, linux-kernel, Konstantin Khorenko, Jim Mattson
On Thu, 09 Nov 2023 18:28:47 -0800, Sean Christopherson wrote:
> Optimize code used by, or which impacts, kvm_pmu_trigger_event() to try
> and make a dent in the overhead of emulating PMU events in software, which
> is quite noticeable due to it kicking in anytime the guest has a vPMU and
> KVM is skipping an instruction.
>
> Note, Jim has a proposal/idea[*] (that I supported) to make
> kvm_pmu_trigger_event() even more performant. I opted not to do that as
> it's a bit more invasive, and I started chewing on this not so much because
> I care _that_ much about performance, but because it irritates me that the
> PMU code makes things way harder than they need to be.
>
> [...]
Applied to kvm-x86 pmu, thanks!
[01/10] KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled
https://github.com/kvm-x86/linux/commit/f933b88e2015
[02/10] KVM: x86/pmu: Add common define to capture fixed counters offset
https://github.com/kvm-x86/linux/commit/be6b067dae15
[03/10] KVM: x86/pmu: Move pmc_idx => pmc translation helper to common code
https://github.com/kvm-x86/linux/commit/b31880ca2f41
[04/10] KVM: x86/pmu: Snapshot and clear reprogramming bitmap before reprogramming
https://github.com/kvm-x86/linux/commit/004a0aa56ede
[05/10] KVM: x86/pmu: Add macros to iterate over all PMCs given a bitmap
https://github.com/kvm-x86/linux/commit/e5a65d4f723a
[06/10] KVM: x86/pmu: Process only enabled PMCs when emulating events in software
https://github.com/kvm-x86/linux/commit/d2b321ea9380
[07/10] KVM: x86/pmu: Snapshot event selectors that KVM emulates in software
https://github.com/kvm-x86/linux/commit/f19063b1ca05
[08/10] KVM: x86/pmu: Expand the comment about what bits are check emulating events
https://github.com/kvm-x86/linux/commit/afda2d7666f8
[09/10] KVM: x86/pmu: Check eventsel first when emulating (branch) insns retired
https://github.com/kvm-x86/linux/commit/e35529fb4ac9
[10/10] KVM: x86/pmu: Avoid CPL lookup if PMC enabline for USER and KERNEL is the same
https://github.com/kvm-x86/linux/commit/83bdfe04c968
--
https://github.com/kvm-x86/linux/tree/next
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2024-02-03 0:13 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-10 2:28 [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Sean Christopherson
2023-11-10 2:28 ` [PATCH 01/10] KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled Sean Christopherson
2023-11-10 2:28 ` [PATCH 02/10] KVM: x86/pmu: Add common define to capture fixed counters offset Sean Christopherson
2023-11-10 2:28 ` [PATCH 03/10] KVM: x86/pmu: Move pmc_idx => pmc translation helper to common code Sean Christopherson
2023-11-10 2:28 ` [PATCH 04/10] KVM: x86/pmu: Snapshot and clear reprogramming bitmap before reprogramming Sean Christopherson
2023-11-10 2:28 ` [PATCH 05/10] KVM: x86/pmu: Add macros to iterate over all PMCs given a bitmap Sean Christopherson
2023-11-10 2:28 ` [PATCH 06/10] KVM: x86/pmu: Process only enabled PMCs when emulating events in software Sean Christopherson
2023-11-10 2:28 ` [PATCH 07/10] KVM: x86/pmu: Snapshot event selectors that KVM emulates " Sean Christopherson
2023-11-10 2:28 ` [PATCH 08/10] KVM: x86/pmu: Expand the comment about what bits are check emulating events Sean Christopherson
2023-11-10 2:28 ` [PATCH 09/10] KVM: x86/pmu: Check eventsel first when emulating (branch) insns retired Sean Christopherson
2023-11-10 2:28 ` [PATCH 10/10] KVM: x86/pmu: Avoid CPL lookup if PMC enabline for USER and KERNEL is the same Sean Christopherson
2023-11-10 6:37 ` [PATCH 00/10] KVM: x86/pmu: Optimize triggering of emulated events Dongli Zhang
2023-11-10 14:56 ` Sean Christopherson
2023-11-16 16:37 ` Konstantin Khorenko
2024-02-03 0:11 ` Sean Christopherson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox