[kvm-unit-tests PATCH v6 10/14] arm64: pmu: count EL2 cycles
Joey Gouly
joey.gouly at arm.com
Fri Jan 23 08:50:49 PST 2026
Count EL2 cycles if that's the EL kvm-unit-tests is running at!
Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Acked-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Eric Auger <eric.auger at redhat.com>
---
arm/pmu.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/arm/pmu.c b/arm/pmu.c
index 2dc0822b..2fcec71a 100644
--- a/arm/pmu.c
+++ b/arm/pmu.c
@@ -121,6 +121,8 @@ static struct pmu pmu;
#define PMINTENCLR __ACCESS_CP15(c9, 0, c14, 2)
#define PMCCNTR64 __ACCESS_CP15_64(0, c9)
+#define PMCCFILTR_EL0_DEFAULT 0
+
static inline uint32_t get_id_dfr0(void) { return read_sysreg(ID_DFR0); }
static inline uint32_t get_pmcr(void) { return read_sysreg(PMCR); }
static inline void set_pmcr(uint32_t v) { write_sysreg(v, PMCR); }
@@ -206,6 +208,9 @@ static void test_overflow_interrupt(bool overflow_at_64bits) {}
#define ID_DFR0_PMU_V3_8_5 0b0110
#define ID_DFR0_PMU_IMPDEF 0b1111
+#define PMCCFILTR_EL0_NSH BIT(27)
+#define PMCCFILTR_EL0_DEFAULT (current_level() == CurrentEL_EL2 ? PMCCFILTR_EL0_NSH : 0)
+
static inline uint32_t get_id_aa64dfr0(void) { return read_sysreg(id_aa64dfr0_el1); }
static inline uint32_t get_pmcr(void) { return read_sysreg(pmcr_el0); }
static inline void set_pmcr(uint32_t v) { write_sysreg(v, pmcr_el0); }
@@ -246,8 +251,7 @@ static inline void precise_instrs_loop(int loop, uint32_t pmcr)
#define PMCNTENSET_EL0 sys_reg(3, 3, 9, 12, 1)
#define PMCNTENCLR_EL0 sys_reg(3, 3, 9, 12, 2)
-#define PMEVTYPER_EXCLUDE_EL1 BIT(31)
-#define PMEVTYPER_EXCLUDE_EL0 BIT(30)
+#define PMEVTYPER_EXCLUDE_EL0 (BIT(30) | (current_level() == CurrentEL_EL2 ? BIT(27) : 0))
static bool is_event_supported(uint32_t n, bool warn)
{
@@ -1063,7 +1067,8 @@ static bool check_cycles_increase(void)
/* init before event access, this test only cares about cycle count */
pmu_reset();
set_pmcntenset(1 << PMU_CYCLE_IDX);
- set_pmccfiltr(0); /* count cycles in EL0, EL1, but not EL2 */
+
+ set_pmccfiltr(PMCCFILTR_EL0_DEFAULT);
set_pmcr(get_pmcr() | PMU_PMCR_LC | PMU_PMCR_C | PMU_PMCR_E);
isb();
@@ -1118,7 +1123,7 @@ static bool check_cpi(int cpi)
/* init before event access, this test only cares about cycle count */
pmu_reset();
set_pmcntenset(1 << PMU_CYCLE_IDX);
- set_pmccfiltr(0); /* count cycles in EL0, EL1, but not EL2 */
+ set_pmccfiltr(PMCCFILTR_EL0_DEFAULT);
if (cpi > 0)
printf("Checking for CPI=%d.\n", cpi);
--
2.25.1
More information about the linux-arm-kernel
mailing list