From: Wei Huang <wei@redhat.com> To: cov@codeaurora.org Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, shannon.zhao@linaro.org, alistair.francis@xilinx.com, croberts@codeaurora.org, alindsay@codeaurora.org, drjones@redhat.com Subject: [kvm-unit-tests PATCH v8 2/3] arm: pmu: Check cycle count increases Date: Tue, 8 Nov 2016 12:17:14 -0600 [thread overview] Message-ID: <1478629035-12938-3-git-send-email-wei@redhat.com> (raw) In-Reply-To: <1478629035-12938-1-git-send-email-wei@redhat.com> From: Christopher Covington <cov@codeaurora.org> Ensure that reads of the PMCCNTR_EL0 are monotonically increasing, even for the smallest delta of two subsequent reads. Signed-off-by: Christopher Covington <cov@codeaurora.org> Signed-off-by: Wei Huang <wei@redhat.com> --- arm/pmu.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/arm/pmu.c b/arm/pmu.c index 0b29088..d5e3ac3 100644 --- a/arm/pmu.c +++ b/arm/pmu.c @@ -14,6 +14,7 @@ */ #include "libcflat.h" +#define PMU_PMCR_E (1 << 0) #define PMU_PMCR_N_SHIFT 11 #define PMU_PMCR_N_MASK 0x1f #define PMU_PMCR_ID_SHIFT 16 @@ -21,6 +22,10 @@ #define PMU_PMCR_IMP_SHIFT 24 #define PMU_PMCR_IMP_MASK 0xff +#define PMU_CYCLE_IDX 31 + +#define NR_SAMPLES 10 + #if defined(__arm__) static inline uint32_t pmcr_read(void) { @@ -29,6 +34,47 @@ static inline uint32_t pmcr_read(void) asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (ret)); return ret; } + +static inline void pmcr_write(uint32_t value) +{ + asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (value)); +} + +static inline void pmselr_write(uint32_t value) +{ + asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (value)); +} + +static inline void pmxevtyper_write(uint32_t value) +{ + asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (value)); +} + +/* + * While PMCCNTR can be accessed as a 64 bit coprocessor register, returning 64 + * bits doesn't seem worth the trouble when differential usage of the result is + * expected (with differences that can easily fit in 32 bits). So just return + * the lower 32 bits of the cycle count in AArch32. + */ +static inline uint32_t pmccntr_read(void) +{ + uint32_t cycles; + + asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (cycles)); + return cycles; +} + +static inline void pmcntenset_write(uint32_t value) +{ + asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (value)); +} + +/* PMCCFILTR is an obsolete name for PMXEVTYPER31 in ARMv7 */ +static inline void pmccfiltr_write(uint32_t value) +{ + pmselr_write(PMU_CYCLE_IDX); + pmxevtyper_write(value); +} #elif defined(__aarch64__) static inline uint32_t pmcr_read(void) { @@ -37,6 +83,29 @@ static inline uint32_t pmcr_read(void) asm volatile("mrs %0, pmcr_el0" : "=r" (ret)); return ret; } + +static inline void pmcr_write(uint32_t value) +{ + asm volatile("msr pmcr_el0, %0" : : "r" (value)); +} + +static inline uint32_t pmccntr_read(void) +{ + uint32_t cycles; + + asm volatile("mrs %0, pmccntr_el0" : "=r" (cycles)); + return cycles; +} + +static inline void pmcntenset_write(uint32_t value) +{ + asm volatile("msr pmcntenset_el0, %0" : : "r" (value)); +} + +static inline void pmccfiltr_write(uint32_t value) +{ + asm volatile("msr pmccfiltr_el0, %0" : : "r" (value)); +} #endif /* @@ -63,11 +132,40 @@ static bool check_pmcr(void) return ((pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK) != 0; } +/* + * Ensure that the cycle counter progresses between back-to-back reads. + */ +static bool check_cycles_increase(void) +{ + pmcr_write(pmcr_read() | PMU_PMCR_E); + + for (int i = 0; i < NR_SAMPLES; i++) { + unsigned long a, b; + + a = pmccntr_read(); + b = pmccntr_read(); + + if (a >= b) { + printf("Read %ld then %ld.\n", a, b); + return false; + } + } + + pmcr_write(pmcr_read() & ~PMU_PMCR_E); + + return true; +} + int main(void) { report_prefix_push("pmu"); + /* init for PMU event access, right now only care about cycle count */ + pmcntenset_write(1 << PMU_CYCLE_IDX); + pmccfiltr_write(0); /* count cycles in EL0, EL1, but not EL2 */ + report("Control register", check_pmcr()); + report("Monotonically increasing cycle count", check_cycles_increase()); return report_summary(); } -- 1.8.3.1
WARNING: multiple messages have this Message-ID (diff)
From: Wei Huang <wei@redhat.com> To: cov@codeaurora.org Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, shannon.zhao@linaro.org, alistair.francis@xilinx.com, croberts@codeaurora.org, alindsay@codeaurora.org, drjones@redhat.com Subject: [Qemu-devel] [kvm-unit-tests PATCH v8 2/3] arm: pmu: Check cycle count increases Date: Tue, 8 Nov 2016 12:17:14 -0600 [thread overview] Message-ID: <1478629035-12938-3-git-send-email-wei@redhat.com> (raw) In-Reply-To: <1478629035-12938-1-git-send-email-wei@redhat.com> From: Christopher Covington <cov@codeaurora.org> Ensure that reads of the PMCCNTR_EL0 are monotonically increasing, even for the smallest delta of two subsequent reads. Signed-off-by: Christopher Covington <cov@codeaurora.org> Signed-off-by: Wei Huang <wei@redhat.com> --- arm/pmu.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/arm/pmu.c b/arm/pmu.c index 0b29088..d5e3ac3 100644 --- a/arm/pmu.c +++ b/arm/pmu.c @@ -14,6 +14,7 @@ */ #include "libcflat.h" +#define PMU_PMCR_E (1 << 0) #define PMU_PMCR_N_SHIFT 11 #define PMU_PMCR_N_MASK 0x1f #define PMU_PMCR_ID_SHIFT 16 @@ -21,6 +22,10 @@ #define PMU_PMCR_IMP_SHIFT 24 #define PMU_PMCR_IMP_MASK 0xff +#define PMU_CYCLE_IDX 31 + +#define NR_SAMPLES 10 + #if defined(__arm__) static inline uint32_t pmcr_read(void) { @@ -29,6 +34,47 @@ static inline uint32_t pmcr_read(void) asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (ret)); return ret; } + +static inline void pmcr_write(uint32_t value) +{ + asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (value)); +} + +static inline void pmselr_write(uint32_t value) +{ + asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (value)); +} + +static inline void pmxevtyper_write(uint32_t value) +{ + asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (value)); +} + +/* + * While PMCCNTR can be accessed as a 64 bit coprocessor register, returning 64 + * bits doesn't seem worth the trouble when differential usage of the result is + * expected (with differences that can easily fit in 32 bits). So just return + * the lower 32 bits of the cycle count in AArch32. + */ +static inline uint32_t pmccntr_read(void) +{ + uint32_t cycles; + + asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (cycles)); + return cycles; +} + +static inline void pmcntenset_write(uint32_t value) +{ + asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (value)); +} + +/* PMCCFILTR is an obsolete name for PMXEVTYPER31 in ARMv7 */ +static inline void pmccfiltr_write(uint32_t value) +{ + pmselr_write(PMU_CYCLE_IDX); + pmxevtyper_write(value); +} #elif defined(__aarch64__) static inline uint32_t pmcr_read(void) { @@ -37,6 +83,29 @@ static inline uint32_t pmcr_read(void) asm volatile("mrs %0, pmcr_el0" : "=r" (ret)); return ret; } + +static inline void pmcr_write(uint32_t value) +{ + asm volatile("msr pmcr_el0, %0" : : "r" (value)); +} + +static inline uint32_t pmccntr_read(void) +{ + uint32_t cycles; + + asm volatile("mrs %0, pmccntr_el0" : "=r" (cycles)); + return cycles; +} + +static inline void pmcntenset_write(uint32_t value) +{ + asm volatile("msr pmcntenset_el0, %0" : : "r" (value)); +} + +static inline void pmccfiltr_write(uint32_t value) +{ + asm volatile("msr pmccfiltr_el0, %0" : : "r" (value)); +} #endif /* @@ -63,11 +132,40 @@ static bool check_pmcr(void) return ((pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK) != 0; } +/* + * Ensure that the cycle counter progresses between back-to-back reads. + */ +static bool check_cycles_increase(void) +{ + pmcr_write(pmcr_read() | PMU_PMCR_E); + + for (int i = 0; i < NR_SAMPLES; i++) { + unsigned long a, b; + + a = pmccntr_read(); + b = pmccntr_read(); + + if (a >= b) { + printf("Read %ld then %ld.\n", a, b); + return false; + } + } + + pmcr_write(pmcr_read() & ~PMU_PMCR_E); + + return true; +} + int main(void) { report_prefix_push("pmu"); + /* init for PMU event access, right now only care about cycle count */ + pmcntenset_write(1 << PMU_CYCLE_IDX); + pmccfiltr_write(0); /* count cycles in EL0, EL1, but not EL2 */ + report("Control register", check_pmcr()); + report("Monotonically increasing cycle count", check_cycles_increase()); return report_summary(); } -- 1.8.3.1
next prev parent reply other threads:[~2016-11-08 18:17 UTC|newest] Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-11-08 18:17 [kvm-unit-tests PATCH v8 0/3] ARM PMU tests Wei Huang 2016-11-08 18:17 ` [Qemu-devel] " Wei Huang 2016-11-08 18:17 ` [kvm-unit-tests PATCH v8 1/3] arm: Add PMU test Wei Huang 2016-11-08 18:17 ` [Qemu-devel] " Wei Huang 2016-11-11 7:37 ` Andrew Jones 2016-11-08 18:17 ` Wei Huang [this message] 2016-11-08 18:17 ` [Qemu-devel] [kvm-unit-tests PATCH v8 2/3] arm: pmu: Check cycle count increases Wei Huang 2016-11-11 7:43 ` Andrew Jones 2016-11-11 19:55 ` Wei Huang 2016-11-14 10:05 ` Andrew Jones 2016-11-14 15:12 ` Christopher Covington 2016-11-15 22:50 ` Wei Huang 2016-11-16 13:01 ` Andrew Jones 2016-11-16 16:08 ` Christopher Covington 2016-11-16 16:25 ` Andrew Jones 2016-11-16 16:41 ` Christopher Covington 2016-11-16 16:41 ` Christopher Covington 2016-11-16 15:40 ` Andrew Jones 2016-11-08 18:17 ` [kvm-unit-tests PATCH v8 3/3] arm: pmu: Add CPI checking Wei Huang 2016-11-08 18:17 ` [Qemu-devel] " Wei Huang 2016-11-11 8:08 ` Andrew Jones 2016-11-11 16:10 ` Wei Huang 2016-11-16 15:45 ` Andrew Jones
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=1478629035-12938-3-git-send-email-wei@redhat.com \ --to=wei@redhat.com \ --cc=alindsay@codeaurora.org \ --cc=alistair.francis@xilinx.com \ --cc=cov@codeaurora.org \ --cc=croberts@codeaurora.org \ --cc=drjones@redhat.com \ --cc=kvm@vger.kernel.org \ --cc=kvmarm@lists.cs.columbia.edu \ --cc=qemu-devel@nongnu.org \ --cc=shannon.zhao@linaro.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: linkBe 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.