diff mbox series

[kvm-unit-tests,v1,6/7] arm64: pmu: count EL2 cycles

Message ID 20250220141354.2565567-7-joey.gouly@arm.com (mailing list archive)
State New
Headers show
Series arm64: support EL2 | expand

Commit Message

Joey Gouly Feb. 20, 2025, 2:13 p.m. UTC
Count EL2 cycles if that's the EL kvm-unit-tests is running at!

Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
 arm/pmu.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/arm/pmu.c b/arm/pmu.c
index 2dc0822b..238e4628 100644
--- a/arm/pmu.c
+++ b/arm/pmu.c
@@ -206,6 +206,8 @@  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)
+
 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); }
@@ -247,7 +249,7 @@  static inline void precise_instrs_loop(int loop, uint32_t pmcr)
 #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) | BIT(27)
 
 static bool is_event_supported(uint32_t n, bool warn)
 {
@@ -1059,11 +1061,18 @@  static void test_overflow_interrupt(bool overflow_at_64bits)
 static bool check_cycles_increase(void)
 {
 	bool success = true;
+	u64 pmccfiltr = 0;
 
 	/* 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 */
+
+#if defined(__aarch64__)
+	if (current_level() == CurrentEL_EL2)
+		// include EL2 cycle counts
+		pmccfiltr |= PMCCFILTR_EL0_NSH;
+#endif
+	set_pmccfiltr(pmccfiltr);
 
 	set_pmcr(get_pmcr() | PMU_PMCR_LC | PMU_PMCR_C | PMU_PMCR_E);
 	isb();
@@ -1114,11 +1123,17 @@  static void measure_instrs(int num, uint32_t pmcr)
 static bool check_cpi(int cpi)
 {
 	uint32_t pmcr = get_pmcr() | PMU_PMCR_LC | PMU_PMCR_C | PMU_PMCR_E;
+	u64 pmccfiltr = 0;
 
 	/* 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 */
+#if defined(__aarch64__)
+	if (current_level() == CurrentEL_EL2)
+		// include EL2 cycle counts
+		pmccfiltr |= PMCCFILTR_EL0_NSH;
+#endif
+	set_pmccfiltr(pmccfiltr);
 
 	if (cpi > 0)
 		printf("Checking for CPI=%d.\n", cpi);