public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Alexandru Elisei <alexandru.elisei@arm.com>
To: Joey Gouly <joey.gouly@arm.com>
Cc: kvm@vger.kernel.org, drjones@redhat.com, kvmarm@lists.linux.dev,
	Marc Zyngier <maz@kernel.org>,
	Oliver Upton <oliver.upton@linux.dev>
Subject: Re: [kvm-unit-tests PATCH v1 6/7] arm64: pmu: count EL2 cycles
Date: Thu, 27 Feb 2025 17:01:03 +0000	[thread overview]
Message-ID: <Z8CaT5Qe5X4t4Kzg@raptor> (raw)
In-Reply-To: <20250220141354.2565567-7-joey.gouly@arm.com>

Hi Joey,

On Thu, Feb 20, 2025 at 02:13:53PM +0000, Joey Gouly wrote:
> 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 --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)

I think you can drop the macro. I was expecting to see an exclude EL2 macro
used in its place when the test is running at EL2, but it seems
PMEVTYPER_EXCLUDE_EL1 is not used anywhere. Unless I'm missing something here.

> -#define PMEVTYPER_EXCLUDE_EL0 BIT(30)
> +#define PMEVTYPER_EXCLUDE_EL0 BIT(30) | BIT(27)

I'm not really sure what that's supposed to achieve - if the test is
running at EL2, and events from both EL0 and EL2 are excluded, what's left
to count?

I also don't understand what PMEVTYPER_EXCLUDE_EL0 does in the non-nested
virt case (when kvm-unit-tests boots at El1). The tests run at EL1, so not
counting events at EL0 shouldn't affect anything. Am I missing something
obvious here?

>  
>  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

It's called twice, so it could be abstracted in a function.

Also, I find it interesting that for PMCCFILTR_EL0 you set the NSH bit
based on current exception level, but for PMEVTYPER you set it
unconditionally. Why the different approaches? For convenience of is there
something more?

Thanks,
Alex

  reply	other threads:[~2025-02-27 17:01 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-20 14:13 [kvm-unit-tests PATCH v1 0/7] arm64: support EL2 Joey Gouly
2025-02-20 14:13 ` [kvm-unit-tests PATCH v1 1/7] arm64: drop to EL1 if booted at EL2 Joey Gouly
2025-02-20 15:23   ` Marc Zyngier
2025-02-27 16:53   ` Alexandru Elisei
2025-03-04 17:02     ` Joey Gouly
2025-03-06 15:52       ` Alexandru Elisei
2025-02-20 14:13 ` [kvm-unit-tests PATCH v1 2/7] arm64: timer: use hypervisor timers when " Joey Gouly
2025-02-27 16:55   ` Alexandru Elisei
2025-03-04 17:05     ` Joey Gouly
2025-03-06 15:52       ` Alexandru Elisei
2025-02-20 14:13 ` [kvm-unit-tests PATCH v1 3/7] arm64: micro-bench: fix timer IRQ Joey Gouly
2025-02-27 16:58   ` Alexandru Elisei
2025-02-20 14:13 ` [kvm-unit-tests PATCH v1 4/7] arm64: micro-bench: use smc when at EL2 Joey Gouly
2025-02-20 14:13 ` [kvm-unit-tests PATCH v1 5/7] arm64: selftest: update test for running " Joey Gouly
2025-02-27 16:58   ` Alexandru Elisei
2025-02-20 14:13 ` [kvm-unit-tests PATCH v1 6/7] arm64: pmu: count EL2 cycles Joey Gouly
2025-02-27 17:01   ` Alexandru Elisei [this message]
2025-03-04 16:56     ` Joey Gouly
2025-03-06 15:58       ` Alexandru Elisei
2025-02-20 14:13 ` [kvm-unit-tests PATCH v1 7/7] arm64: run at EL2 if supported Joey Gouly
2025-02-20 15:34   ` Marc Zyngier

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=Z8CaT5Qe5X4t4Kzg@raptor \
    --to=alexandru.elisei@arm.com \
    --cc=drjones@redhat.com \
    --cc=joey.gouly@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=maz@kernel.org \
    --cc=oliver.upton@linux.dev \
    /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