Linux Kernel Selftest development
 help / color / mirror / Atom feed
From: Colton Lewis <coltonlewis@google.com>
To: kvm@vger.kernel.org
Cc: Alexandru Elisei <alexandru.elisei@arm.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	 Jonathan Corbet <corbet@lwn.net>,
	Russell King <linux@armlinux.org.uk>,
	 Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>, Marc Zyngier <maz@kernel.org>,
	 Oliver Upton <oliver.upton@linux.dev>,
	Mingwei Zhang <mizhang@google.com>,
	 Joey Gouly <joey.gouly@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	 Zenghui Yu <yuzenghui@huawei.com>,
	Mark Rutland <mark.rutland@arm.com>,
	 Shuah Khan <shuah@kernel.org>,
	Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com>,
	 linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	 linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
	 linux-perf-users@vger.kernel.org,
	linux-kselftest@vger.kernel.org,
	 Colton Lewis <coltonlewis@google.com>
Subject: [PATCH v6 14/19] perf: arm_pmuv3: Handle IRQs for Partitioned PMU guest counters
Date: Mon,  9 Feb 2026 22:14:09 +0000	[thread overview]
Message-ID: <20260209221414.2169465-15-coltonlewis@google.com> (raw)
In-Reply-To: <20260209221414.2169465-1-coltonlewis@google.com>

Because ARM hardware is not yet capable of direct PPI injection into
guests, guest counters will still trigger interrupts that need to be
handled by the host PMU interrupt handler. Clear the overflow flags in
hardware to handle the interrupt as normal, but the virtual overflow
register for later injecting the interrupt into the guest.

Signed-off-by: Colton Lewis <coltonlewis@google.com>
---
 arch/arm/include/asm/arm_pmuv3.h   |  6 ++++++
 arch/arm64/include/asm/arm_pmuv3.h |  5 +++++
 arch/arm64/kvm/pmu-direct.c        | 22 ++++++++++++++++++++++
 drivers/perf/arm_pmuv3.c           | 24 +++++++++++++++++-------
 include/kvm/arm_pmu.h              |  2 ++
 5 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/arm_pmuv3.h b/arch/arm/include/asm/arm_pmuv3.h
index bed4dfa755681..d2ed4f2f02b25 100644
--- a/arch/arm/include/asm/arm_pmuv3.h
+++ b/arch/arm/include/asm/arm_pmuv3.h
@@ -180,6 +180,11 @@ static inline void write_pmintenset(u32 val)
 	write_sysreg(val, PMINTENSET);
 }
 
+static inline u32 read_pmintenset(void)
+{
+	return read_sysreg(PMINTENSET);
+}
+
 static inline void write_pmintenclr(u32 val)
 {
 	write_sysreg(val, PMINTENCLR);
@@ -249,6 +254,7 @@ static inline u64 kvm_pmu_guest_counter_mask(struct arm_pmu *pmu)
 	return ~0;
 }
 
+static inline void kvm_pmu_handle_guest_irq(struct arm_pmu *pmu, u64 pmovsr) {}
 
 /* PMU Version in DFR Register */
 #define ARMV8_PMU_DFR_VER_NI        0
diff --git a/arch/arm64/include/asm/arm_pmuv3.h b/arch/arm64/include/asm/arm_pmuv3.h
index 27c4d6d47da31..69ff4d014bf39 100644
--- a/arch/arm64/include/asm/arm_pmuv3.h
+++ b/arch/arm64/include/asm/arm_pmuv3.h
@@ -110,6 +110,11 @@ static inline void write_pmintenset(u64 val)
 	write_sysreg(val, pmintenset_el1);
 }
 
+static inline u64 read_pmintenset(void)
+{
+	return read_sysreg(pmintenset_el1);
+}
+
 static inline void write_pmintenclr(u64 val)
 {
 	write_sysreg(val, pmintenclr_el1);
diff --git a/arch/arm64/kvm/pmu-direct.c b/arch/arm64/kvm/pmu-direct.c
index 11fae54cd6534..79d13a0aa2fd6 100644
--- a/arch/arm64/kvm/pmu-direct.c
+++ b/arch/arm64/kvm/pmu-direct.c
@@ -356,3 +356,25 @@ void kvm_pmu_put(struct kvm_vcpu *vcpu)
 
 	preempt_enable();
 }
+
+/**
+ * kvm_pmu_handle_guest_irq() - Record IRQs in guest counters
+ * @pmu: PMU to check for overflows
+ * @pmovsr: Overflow flags reported by driver
+ *
+ * Set overflow flags in guest-reserved counters in the VCPU register
+ * for the guest to clear later.
+ */
+void kvm_pmu_handle_guest_irq(struct arm_pmu *pmu, u64 pmovsr)
+{
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
+	u64 mask = kvm_pmu_guest_counter_mask(pmu);
+	u64 govf = pmovsr & mask;
+
+	write_pmovsclr(govf);
+
+	if (!vcpu)
+		return;
+
+	__vcpu_rmw_sys_reg(vcpu, PMOVSSET_EL0, |=, govf);
+}
diff --git a/drivers/perf/arm_pmuv3.c b/drivers/perf/arm_pmuv3.c
index 6395b6deb78c2..9520634991305 100644
--- a/drivers/perf/arm_pmuv3.c
+++ b/drivers/perf/arm_pmuv3.c
@@ -774,16 +774,15 @@ static void armv8pmu_disable_event_irq(struct perf_event *event)
 	armv8pmu_disable_intens(BIT(event->hw.idx));
 }
 
-static u64 armv8pmu_getreset_flags(void)
+static u64 armv8pmu_getovf_flags(void)
 {
 	u64 value;
 
 	/* Read */
 	value = read_pmovsclr();
 
-	/* Write to clear flags */
-	value &= ARMV8_PMU_CNT_MASK_ALL;
-	write_pmovsclr(value);
+	/* Only report interrupt enabled counters. */
+	value &= read_pmintenset();
 
 	return value;
 }
@@ -903,16 +902,17 @@ static void read_branch_records(struct pmu_hw_events *cpuc,
 
 static irqreturn_t armv8pmu_handle_irq(struct arm_pmu *cpu_pmu)
 {
-	u64 pmovsr;
 	struct perf_sample_data data;
 	struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
 	struct pt_regs *regs;
+	u64 host_set = kvm_pmu_host_counter_mask(cpu_pmu);
+	u64 pmovsr;
 	int idx;
 
 	/*
-	 * Get and reset the IRQ flags
+	 * Get the IRQ flags
 	 */
-	pmovsr = armv8pmu_getreset_flags();
+	pmovsr = armv8pmu_getovf_flags();
 
 	/*
 	 * Did an overflow occur?
@@ -920,6 +920,12 @@ static irqreturn_t armv8pmu_handle_irq(struct arm_pmu *cpu_pmu)
 	if (!armv8pmu_has_overflowed(pmovsr))
 		return IRQ_NONE;
 
+	/*
+	 * Guest flag reset is handled the kvm hook at the bottom of
+	 * this function.
+	 */
+	write_pmovsclr(pmovsr & host_set);
+
 	/*
 	 * Handle the counter(s) overflow(s)
 	 */
@@ -961,6 +967,10 @@ static irqreturn_t armv8pmu_handle_irq(struct arm_pmu *cpu_pmu)
 		 */
 		perf_event_overflow(event, &data, regs);
 	}
+
+	if (kvm_pmu_is_partitioned(cpu_pmu))
+		kvm_pmu_handle_guest_irq(cpu_pmu, pmovsr);
+
 	armv8pmu_start(cpu_pmu);
 
 	return IRQ_HANDLED;
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index 82665d54258df..3d922bd145d4e 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -99,6 +99,7 @@ u64 kvm_pmu_host_counter_mask(struct arm_pmu *pmu);
 u64 kvm_pmu_guest_counter_mask(struct arm_pmu *pmu);
 void kvm_pmu_host_counters_enable(void);
 void kvm_pmu_host_counters_disable(void);
+void kvm_pmu_handle_guest_irq(struct arm_pmu *pmu, u64 pmovsr);
 
 u8 kvm_pmu_guest_num_counters(struct kvm_vcpu *vcpu);
 u8 kvm_pmu_hpmn(struct kvm_vcpu *vcpu);
@@ -306,6 +307,7 @@ static inline u64 kvm_pmu_guest_counter_mask(void *pmu)
 
 static inline void kvm_pmu_host_counters_enable(void) {}
 static inline void kvm_pmu_host_counters_disable(void) {}
+static inline void kvm_pmu_handle_guest_irq(struct arm_pmu *pmu, u64 pmovsr) {}
 
 #endif
 
-- 
2.53.0.rc2.204.g2597b5adb4-goog


  parent reply	other threads:[~2026-02-09 22:41 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-09 22:13 [PATCH v6 00/19] ARM64 PMU Partitioning Colton Lewis
2026-02-09 22:13 ` [PATCH v6 01/19] arm64: cpufeature: Add cpucap for HPMN0 Colton Lewis
2026-02-09 22:13 ` [PATCH v6 02/19] KVM: arm64: Reorganize PMU includes Colton Lewis
2026-02-09 22:13 ` [PATCH v6 03/19] KVM: arm64: Reorganize PMU functions Colton Lewis
2026-02-09 22:13 ` [PATCH v6 04/19] perf: arm_pmuv3: Introduce method to partition the PMU Colton Lewis
2026-03-11 11:59   ` James Clark
2026-03-12 22:37     ` Colton Lewis
2026-03-11 17:45   ` James Clark
2026-03-12 22:37     ` Colton Lewis
2026-02-09 22:14 ` [PATCH v6 05/19] perf: arm_pmuv3: Generalize counter bitmasks Colton Lewis
2026-02-09 22:14 ` [PATCH v6 06/19] perf: arm_pmuv3: Keep out of guest counter partition Colton Lewis
2026-02-25 17:53   ` Colton Lewis
2026-03-11 12:00   ` James Clark
2026-03-12 22:39     ` Colton Lewis
2026-02-09 22:14 ` [PATCH v6 07/19] KVM: arm64: Set up FGT for Partitioned PMU Colton Lewis
2026-02-09 22:14 ` [PATCH v6 08/19] KVM: arm64: Define access helpers for PMUSERENR and PMSELR Colton Lewis
2026-02-10  4:30   ` kernel test robot
2026-02-10  5:20   ` kernel test robot
2026-02-09 22:14 ` [PATCH v6 09/19] KVM: arm64: Write fast path PMU register handlers Colton Lewis
2026-02-12  9:07   ` Marc Zyngier
2026-02-25 17:45     ` Colton Lewis
2026-02-09 22:14 ` [PATCH v6 10/19] KVM: arm64: Setup MDCR_EL2 to handle a partitioned PMU Colton Lewis
2026-02-09 22:14 ` [PATCH v6 11/19] KVM: arm64: Context swap Partitioned PMU guest registers Colton Lewis
2026-03-11 12:01   ` James Clark
2026-03-12 22:39     ` Colton Lewis
2026-02-09 22:14 ` [PATCH v6 12/19] KVM: arm64: Enforce PMU event filter at vcpu_load() Colton Lewis
2026-02-09 22:14 ` [PATCH v6 13/19] KVM: arm64: Implement lazy PMU context swaps Colton Lewis
2026-02-09 22:14 ` Colton Lewis [this message]
2026-02-10  4:51   ` [PATCH v6 14/19] perf: arm_pmuv3: Handle IRQs for Partitioned PMU guest counters kernel test robot
2026-02-10  7:32   ` kernel test robot
2026-02-09 22:14 ` [PATCH v6 15/19] KVM: arm64: Detect overflows for the Partitioned PMU Colton Lewis
2026-02-09 22:14 ` [PATCH v6 16/19] KVM: arm64: Add vCPU device attr to partition the PMU Colton Lewis
2026-02-10  5:55   ` kernel test robot
2026-03-05 10:16   ` James Clark
2026-03-12 22:13     ` Colton Lewis
2026-02-09 22:14 ` [PATCH v6 17/19] KVM: selftests: Add find_bit to KVM library Colton Lewis
2026-02-09 22:14 ` [PATCH v6 18/19] KVM: arm64: selftests: Add test case for partitioned PMU Colton Lewis
2026-02-09 22:14 ` [PATCH v6 19/19] KVM: arm64: selftests: Relax testing for exceptions when partitioned Colton Lewis
2026-02-10  8:49 ` [PATCH v6 00/19] ARM64 PMU Partitioning Marc Zyngier
2026-02-12 21:08   ` Colton Lewis
2026-02-13  8:11     ` Marc Zyngier
2026-02-25 17:40       ` Colton Lewis

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=20260209221414.2169465-15-coltonlewis@google.com \
    --to=coltonlewis@google.com \
    --cc=alexandru.elisei@arm.com \
    --cc=catalin.marinas@arm.com \
    --cc=corbet@lwn.net \
    --cc=gankulkarni@os.amperecomputing.com \
    --cc=joey.gouly@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=mizhang@google.com \
    --cc=oliver.upton@linux.dev \
    --cc=pbonzini@redhat.com \
    --cc=shuah@kernel.org \
    --cc=suzuki.poulose@arm.com \
    --cc=will@kernel.org \
    --cc=yuzenghui@huawei.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