From: Ricardo Koller <ricarkol@google.com>
To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu,
andrew.jones@linux.dev
Cc: maz@kernel.org
Subject: [kvm-unit-tests PATCH v2 1/4] arm: pmu: Fix overflow checks for PMUv3p5 long counters
Date: Tue, 20 Dec 2022 03:10:29 +0000 [thread overview]
Message-ID: <20221220031032.2648701-2-ricarkol@google.com> (raw)
In-Reply-To: <20221220031032.2648701-1-ricarkol@google.com>
PMUv3p5 uses 64-bit counters irrespective of whether the PMU is configured
for overflowing at 32 or 64-bits. The consequence is that tests that check
the counter values after overflowing should not assume that values will be
wrapped around 32-bits: they overflow into the other half of the 64-bit
counters on PMUv3p5.
Fix tests by correctly checking overflowing-counters against the expected
64-bit value.
Signed-off-by: Ricardo Koller <ricarkol@google.com>
---
arm/pmu.c | 37 +++++++++++++++++++++++++------------
1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/arm/pmu.c b/arm/pmu.c
index cd47b14..1b55e20 100644
--- a/arm/pmu.c
+++ b/arm/pmu.c
@@ -54,10 +54,13 @@
#define EXT_COMMON_EVENTS_LOW 0x4000
#define EXT_COMMON_EVENTS_HIGH 0x403F
-#define ALL_SET 0xFFFFFFFF
-#define ALL_CLEAR 0x0
-#define PRE_OVERFLOW 0xFFFFFFF0
-#define PRE_OVERFLOW2 0xFFFFFFDC
+#define ALL_SET 0x00000000FFFFFFFFULL
+#define ALL_SET_64 0xFFFFFFFFFFFFFFFFULL
+#define ALL_CLEAR 0x0000000000000000ULL
+#define PRE_OVERFLOW 0x00000000FFFFFFF0ULL
+#define PRE_OVERFLOW2 0x00000000FFFFFFDCULL
+
+#define ALL_SET_AT(_64b) (_64b ? ALL_SET_64 : ALL_SET)
#define PMU_PPI 23
@@ -538,6 +541,7 @@ static void test_mem_access(void)
static void test_sw_incr(void)
{
uint32_t events[] = {SW_INCR, SW_INCR};
+ uint64_t cntr0;
int i;
if (!satisfy_prerequisites(events, ARRAY_SIZE(events)))
@@ -572,9 +576,11 @@ static void test_sw_incr(void)
write_sysreg(0x3, pmswinc_el0);
isb();
- report(read_regn_el0(pmevcntr, 0) == 84, "counter #1 after + 100 SW_INCR");
- report(read_regn_el0(pmevcntr, 1) == 100,
- "counter #0 after + 100 SW_INCR");
+ cntr0 = (pmu.version < ID_DFR0_PMU_V3_8_5) ?
+ (uint32_t)PRE_OVERFLOW + 100 :
+ (uint64_t)PRE_OVERFLOW + 100;
+ report(read_regn_el0(pmevcntr, 0) == cntr0, "counter #0 after + 100 SW_INCR");
+ report(read_regn_el0(pmevcntr, 1) == 100, "counter #1 after + 100 SW_INCR");
report_info("counter values after 100 SW_INCR #0=%ld #1=%ld",
read_regn_el0(pmevcntr, 0), read_regn_el0(pmevcntr, 1));
report(read_sysreg(pmovsclr_el0) == 0x1,
@@ -584,6 +590,7 @@ static void test_sw_incr(void)
static void test_chained_counters(void)
{
uint32_t events[] = {CPU_CYCLES, CHAIN};
+ uint64_t all_set = ALL_SET_AT(pmu.version >= ID_DFR0_PMU_V3_8_5);
if (!satisfy_prerequisites(events, ARRAY_SIZE(events)))
return;
@@ -614,17 +621,19 @@ static void test_chained_counters(void)
report(read_sysreg(pmovsclr_el0) == 0x1, "overflow recorded for chained incr #2");
write_regn_el0(pmevcntr, 0, PRE_OVERFLOW);
- write_regn_el0(pmevcntr, 1, ALL_SET);
+ write_regn_el0(pmevcntr, 1, all_set);
precise_instrs_loop(22, pmu.pmcr_ro | PMU_PMCR_E);
report_info("overflow reg = 0x%lx", read_sysreg(pmovsclr_el0));
- report(!read_regn_el0(pmevcntr, 1), "CHAIN counter #1 wrapped");
+ report(read_regn_el0(pmevcntr, 1) == 0, "CHAIN counter #1 wrapped");
+
report(read_sysreg(pmovsclr_el0) == 0x3, "overflow on even and odd counters");
}
static void test_chained_sw_incr(void)
{
uint32_t events[] = {SW_INCR, CHAIN};
+ uint64_t cntr0, cntr1;
int i;
if (!satisfy_prerequisites(events, ARRAY_SIZE(events)))
@@ -665,10 +674,14 @@ static void test_chained_sw_incr(void)
write_sysreg(0x1, pmswinc_el0);
isb();
+ cntr0 = (pmu.version < ID_DFR0_PMU_V3_8_5) ?
+ (uint32_t)PRE_OVERFLOW + 100 :
+ (uint64_t)PRE_OVERFLOW + 100;
+ cntr1 = (pmu.version < ID_DFR0_PMU_V3_8_5) ? 0 : ALL_SET + 1;
report((read_sysreg(pmovsclr_el0) == 0x3) &&
- (read_regn_el0(pmevcntr, 1) == 0) &&
- (read_regn_el0(pmevcntr, 0) == 84),
- "expected overflows and values after 100 SW_INCR/CHAIN");
+ (read_regn_el0(pmevcntr, 0) == cntr0) &&
+ (read_regn_el0(pmevcntr, 1) == cntr1),
+ "expected overflows and values after 100 SW_INCR/CHAIN");
report_info("overflow=0x%lx, #0=%ld #1=%ld", read_sysreg(pmovsclr_el0),
read_regn_el0(pmevcntr, 0), read_regn_el0(pmevcntr, 1));
}
--
2.39.0.314.g84b9a713c41-goog
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
WARNING: multiple messages have this Message-ID (diff)
From: Ricardo Koller <ricarkol@google.com>
To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu,
andrew.jones@linux.dev
Cc: maz@kernel.org, alexandru.elisei@arm.com, eric.auger@redhat.com,
oliver.upton@linux.dev, reijiw@google.com,
Ricardo Koller <ricarkol@google.com>
Subject: [kvm-unit-tests PATCH v2 1/4] arm: pmu: Fix overflow checks for PMUv3p5 long counters
Date: Tue, 20 Dec 2022 03:10:29 +0000 [thread overview]
Message-ID: <20221220031032.2648701-2-ricarkol@google.com> (raw)
In-Reply-To: <20221220031032.2648701-1-ricarkol@google.com>
PMUv3p5 uses 64-bit counters irrespective of whether the PMU is configured
for overflowing at 32 or 64-bits. The consequence is that tests that check
the counter values after overflowing should not assume that values will be
wrapped around 32-bits: they overflow into the other half of the 64-bit
counters on PMUv3p5.
Fix tests by correctly checking overflowing-counters against the expected
64-bit value.
Signed-off-by: Ricardo Koller <ricarkol@google.com>
---
arm/pmu.c | 37 +++++++++++++++++++++++++------------
1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/arm/pmu.c b/arm/pmu.c
index cd47b14..1b55e20 100644
--- a/arm/pmu.c
+++ b/arm/pmu.c
@@ -54,10 +54,13 @@
#define EXT_COMMON_EVENTS_LOW 0x4000
#define EXT_COMMON_EVENTS_HIGH 0x403F
-#define ALL_SET 0xFFFFFFFF
-#define ALL_CLEAR 0x0
-#define PRE_OVERFLOW 0xFFFFFFF0
-#define PRE_OVERFLOW2 0xFFFFFFDC
+#define ALL_SET 0x00000000FFFFFFFFULL
+#define ALL_SET_64 0xFFFFFFFFFFFFFFFFULL
+#define ALL_CLEAR 0x0000000000000000ULL
+#define PRE_OVERFLOW 0x00000000FFFFFFF0ULL
+#define PRE_OVERFLOW2 0x00000000FFFFFFDCULL
+
+#define ALL_SET_AT(_64b) (_64b ? ALL_SET_64 : ALL_SET)
#define PMU_PPI 23
@@ -538,6 +541,7 @@ static void test_mem_access(void)
static void test_sw_incr(void)
{
uint32_t events[] = {SW_INCR, SW_INCR};
+ uint64_t cntr0;
int i;
if (!satisfy_prerequisites(events, ARRAY_SIZE(events)))
@@ -572,9 +576,11 @@ static void test_sw_incr(void)
write_sysreg(0x3, pmswinc_el0);
isb();
- report(read_regn_el0(pmevcntr, 0) == 84, "counter #1 after + 100 SW_INCR");
- report(read_regn_el0(pmevcntr, 1) == 100,
- "counter #0 after + 100 SW_INCR");
+ cntr0 = (pmu.version < ID_DFR0_PMU_V3_8_5) ?
+ (uint32_t)PRE_OVERFLOW + 100 :
+ (uint64_t)PRE_OVERFLOW + 100;
+ report(read_regn_el0(pmevcntr, 0) == cntr0, "counter #0 after + 100 SW_INCR");
+ report(read_regn_el0(pmevcntr, 1) == 100, "counter #1 after + 100 SW_INCR");
report_info("counter values after 100 SW_INCR #0=%ld #1=%ld",
read_regn_el0(pmevcntr, 0), read_regn_el0(pmevcntr, 1));
report(read_sysreg(pmovsclr_el0) == 0x1,
@@ -584,6 +590,7 @@ static void test_sw_incr(void)
static void test_chained_counters(void)
{
uint32_t events[] = {CPU_CYCLES, CHAIN};
+ uint64_t all_set = ALL_SET_AT(pmu.version >= ID_DFR0_PMU_V3_8_5);
if (!satisfy_prerequisites(events, ARRAY_SIZE(events)))
return;
@@ -614,17 +621,19 @@ static void test_chained_counters(void)
report(read_sysreg(pmovsclr_el0) == 0x1, "overflow recorded for chained incr #2");
write_regn_el0(pmevcntr, 0, PRE_OVERFLOW);
- write_regn_el0(pmevcntr, 1, ALL_SET);
+ write_regn_el0(pmevcntr, 1, all_set);
precise_instrs_loop(22, pmu.pmcr_ro | PMU_PMCR_E);
report_info("overflow reg = 0x%lx", read_sysreg(pmovsclr_el0));
- report(!read_regn_el0(pmevcntr, 1), "CHAIN counter #1 wrapped");
+ report(read_regn_el0(pmevcntr, 1) == 0, "CHAIN counter #1 wrapped");
+
report(read_sysreg(pmovsclr_el0) == 0x3, "overflow on even and odd counters");
}
static void test_chained_sw_incr(void)
{
uint32_t events[] = {SW_INCR, CHAIN};
+ uint64_t cntr0, cntr1;
int i;
if (!satisfy_prerequisites(events, ARRAY_SIZE(events)))
@@ -665,10 +674,14 @@ static void test_chained_sw_incr(void)
write_sysreg(0x1, pmswinc_el0);
isb();
+ cntr0 = (pmu.version < ID_DFR0_PMU_V3_8_5) ?
+ (uint32_t)PRE_OVERFLOW + 100 :
+ (uint64_t)PRE_OVERFLOW + 100;
+ cntr1 = (pmu.version < ID_DFR0_PMU_V3_8_5) ? 0 : ALL_SET + 1;
report((read_sysreg(pmovsclr_el0) == 0x3) &&
- (read_regn_el0(pmevcntr, 1) == 0) &&
- (read_regn_el0(pmevcntr, 0) == 84),
- "expected overflows and values after 100 SW_INCR/CHAIN");
+ (read_regn_el0(pmevcntr, 0) == cntr0) &&
+ (read_regn_el0(pmevcntr, 1) == cntr1),
+ "expected overflows and values after 100 SW_INCR/CHAIN");
report_info("overflow=0x%lx, #0=%ld #1=%ld", read_sysreg(pmovsclr_el0),
read_regn_el0(pmevcntr, 0), read_regn_el0(pmevcntr, 1));
}
--
2.39.0.314.g84b9a713c41-goog
next prev parent reply other threads:[~2022-12-20 3:10 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-20 3:10 [kvm-unit-tests PATCH v2 0/4] arm: pmu: Add support for PMUv3p5 Ricardo Koller
2022-12-20 3:10 ` Ricardo Koller
2022-12-20 3:10 ` Ricardo Koller [this message]
2022-12-20 3:10 ` [kvm-unit-tests PATCH v2 1/4] arm: pmu: Fix overflow checks for PMUv3p5 long counters Ricardo Koller
2023-01-06 19:28 ` Oliver Upton
2023-01-09 16:10 ` Ricardo Koller
2023-01-09 20:32 ` Ricardo Koller
2022-12-20 3:10 ` [kvm-unit-tests PATCH v2 2/4] arm: pmu: Prepare for testing 64-bit overflows Ricardo Koller
2022-12-20 3:10 ` Ricardo Koller
2022-12-20 3:10 ` [kvm-unit-tests PATCH v2 3/4] arm: pmu: Add tests for " Ricardo Koller
2022-12-20 3:10 ` Ricardo Koller
2022-12-20 3:10 ` [kvm-unit-tests PATCH v2 4/4] arm: pmu: Print counter values as hexadecimals Ricardo Koller
2022-12-20 3:10 ` Ricardo Koller
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=20221220031032.2648701-2-ricarkol@google.com \
--to=ricarkol@google.com \
--cc=andrew.jones@linux.dev \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=maz@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.