Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: Zide Chen <zide.chen@intel.com>
To: Sean Christopherson <seanjc@google.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>
Cc: kvm@vger.kernel.org, Andi Kleen <ak@linux.intel.com>,
	Jim Mattson <jmattson@google.com>,
	Stephane Eranian <eranian@google.com>,
	linux-kernel@vger.kernel.org, Mingwei Zhang <mizhang@google.com>,
	Zide Chen <zide.chen@intel.com>,
	Das Sandipan <Sandipan.Das@amd.com>,
	Shukla Manali <Manali.Shukla@amd.com>,
	Dapeng Mi <dapeng1.mi@linux.intel.com>,
	Xudong Hao <xudong.hao@intel.com>
Subject: [PATCH 14/23] KVM: x86/pmu, perf/x86: Update effective PMU partition mask
Date: Fri, 21 Aug 2026 15:19:53 -0700	[thread overview]
Message-ID: <20260821222002.54907-15-zide.chen@intel.com> (raw)
In-Reply-To: <20260821222002.54907-1-zide.chen@intel.com>

The static system-wide mask x86_pmu.partition_mask defines the global
maximum guest capability, while a guest may have its own mask, which
is a subset of x86_pmu.partition_mask.

The per-guest mask, which on Intel is backed by the PERFMON_MASK VMCS
field, is the effective mask while a vCPU is loaded. Whenever it
changes -- e.g. during kvm_arch_vcpu_{load,put}() -- perf/x86 needs to
be told so it can keep its own per-CPU copy in sync.

Suggested-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
 arch/x86/events/core.c            |  8 ++++++++
 arch/x86/include/asm/perf_event.h |  1 +
 arch/x86/kvm/pmu.c                | 13 +++++++++++++
 arch/x86/kvm/pmu.h                |  3 +++
 arch/x86/kvm/x86.c                |  4 ++++
 5 files changed, 29 insertions(+)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 282170f7c1e1..f485f927967a 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -1883,6 +1883,14 @@ void perf_put_guest_lvtpc(void)
 		apic_write(APIC_LVTPC, APIC_DM_NMI);
 }
 EXPORT_SYMBOL_FOR_KVM(perf_put_guest_lvtpc);
+
+void perf_set_current_partition_mask(u64 mask)
+{
+	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+	cpuc->partition_mask = mask & READ_ONCE(x86_pmu.partition_mask);
+}
+EXPORT_SYMBOL_FOR_KVM(perf_set_current_partition_mask);
 #endif /* CONFIG_PERF_GUEST_MEDIATED_PMU */
 
 static int
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index aaaa34062f8c..5be4f6a93b14 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -794,6 +794,7 @@ static inline void perf_check_microcode(void) { }
 extern void perf_pmu_partition_preload(void);
 extern void perf_load_guest_lvtpc(u32 guest_lvtpc);
 extern void perf_put_guest_lvtpc(void);
+extern void perf_set_current_partition_mask(u64 mask);
 #endif
 
 #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index f944a15160cb..c447f32c1cb1 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -46,6 +46,19 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(enable_mediated_pmu);
 u64 __read_mostly perfmon_mask;
 EXPORT_SYMBOL_FOR_KVM_INTERNAL(perfmon_mask);
 
+void kvm_pmu_vcpu_load(struct kvm_vcpu *vcpu)
+{
+	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+
+	perf_set_current_partition_mask(kvm_vcpu_has_perfmon_mask(vcpu) ?
+					pmu->perfmon_mask : 0);
+}
+
+void kvm_pmu_vcpu_put(struct kvm_vcpu *vcpu)
+{
+	perf_set_current_partition_mask(0);
+}
+
 struct kvm_x86_pmu_event_filter {
 	__u32 action;
 	__u32 nevents;
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index 057e3258e473..c5feeb60bcf6 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -70,6 +70,9 @@ void kvm_pmu_ops_update(const struct kvm_pmu_ops *pmu_ops);
 
 void kvm_handle_guest_mediated_pmi(void);
 
+void kvm_pmu_vcpu_load(struct kvm_vcpu *vcpu);
+void kvm_pmu_vcpu_put(struct kvm_vcpu *vcpu);
+
 static inline bool kvm_pmu_has_perf_global_ctrl(struct kvm_pmu *pmu)
 {
 	/*
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 26a3b7a267b5..07e3fe5b53f8 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2538,6 +2538,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 	kvm_request_l1tf_flush_l1d();
 
+	kvm_pmu_vcpu_load(vcpu);
+
 	if (vcpu->scheduled_out && pmu->version && pmu->event_count) {
 		pmu->need_cleanup = true;
 		kvm_make_request(KVM_REQ_PMU, vcpu);
@@ -2686,6 +2688,8 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 
 	kvm_x86_call(vcpu_put)(vcpu);
 	vcpu->arch.last_host_tsc = rdtsc();
+
+	kvm_pmu_vcpu_put(vcpu);
 }
 
 static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
-- 
2.55.0


  parent reply	other threads:[~2026-08-21 22:31 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-21 22:19 [PATCH 00/23] perf/KVM: Support PMU partitioning for x86 platforms Zide Chen
2026-08-21 22:19 ` [PATCH 01/23] perf/x86/intel: Guard counter masks against zero counters Zide Chen
2026-08-21 22:19 ` [PATCH 02/23] perf, perf/x86: Pass partition mask from KVM to perf/x86 Zide Chen
2026-08-21 22:19 ` [PATCH 03/23] perf/x86: Add GUEST_PMU states for PMU partitioning Zide Chen
2026-08-21 22:19 ` [PATCH 04/23] perf/x86: Split host/guest PMI handling under " Zide Chen
2026-08-21 22:19 ` [PATCH 05/23] perf/x86: Allow exclude_host events to run in non-root mode Zide Chen
2026-08-21 22:19 ` [PATCH 06/23] perf/x86: Restrict !exclude_guest events to host-owned counters Zide Chen
2026-08-21 22:19 ` [PATCH 07/23] perf/x86: Apply PMU partition mask on static constraints Zide Chen
2026-08-21 22:19 ` [PATCH 08/23] perf/x86: Export available PMU counters to sysfs Zide Chen
2026-08-21 22:19 ` [PATCH 09/23] perf: Skip exclude_guest events on PMU partitioned counters Zide Chen
2026-08-21 22:19 ` [PATCH 10/23] perf: Reschedule events across PMU partition transitions Zide Chen
2026-08-21 22:19 ` [PATCH 11/23] perf, perf/x86: Allow host !exclude_guest events in PMU partitioning Zide Chen
2026-08-21 22:19 ` [PATCH 12/23] KVM: x86/pmu: Add the perfmon_mask module parameter Zide Chen
2026-08-21 22:19 ` [PATCH 13/23] KVM: x86/pmu: Set up the PERFMON_MASK VMCS field Zide Chen
2026-08-21 22:19 ` Zide Chen [this message]
2026-08-21 22:19 ` [PATCH 15/23] KVM: x86/pmu: Relax MSR intercept policy under PerfMon masking Zide Chen
2026-08-21 22:19 ` [PATCH 16/23] KVM: x86/pmu: Handle FIXED_CTR_CTRL " Zide Chen
2026-08-21 22:19 ` [PATCH 17/23] KVM: x86/pmu: Handle GLOBAL_CTRL " Zide Chen
2026-08-21 22:19 ` [PATCH 18/23] KVM: x86/pmu: Handle GLOBAL_STATUS MSRs " Zide Chen
2026-08-21 22:19 ` [PATCH 19/23] KVM: x86/pmu: Always intercept GLOBAL_INUSE " Zide Chen
2026-08-21 22:19 ` [PATCH 20/23] KVM: x86/pmu: Request guest PMI for guest-induced PMIs Zide Chen
2026-08-21 22:20 ` [PATCH 21/23] KVM: x86/pmu: Enable PerfMon masking Zide Chen
2026-08-21 22:20 ` [PATCH 22/23] KVM: selftests: Fix PERF_METRICS test by checking FC3 availability Zide Chen
2026-08-21 22:20 ` [PATCH 23/23] KVM: selftests: Allow no general purpose counters on the host Zide Chen

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=20260821222002.54907-15-zide.chen@intel.com \
    --to=zide.chen@intel.com \
    --cc=Manali.Shukla@amd.com \
    --cc=Sandipan.Das@amd.com \
    --cc=ak@linux.intel.com \
    --cc=dapeng1.mi@linux.intel.com \
    --cc=eranian@google.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mizhang@google.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=seanjc@google.com \
    --cc=xudong.hao@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox