mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/2] coresight: Allow guests to be traced when FEAT_TRF and VHE are present
@ 2023-09-04 14:07 James Clark
  2023-09-04 14:07 ` [PATCH v2 1/2] arm64/sysreg: Move TRFCR definitions to sysreg James Clark
  2023-09-04 14:07 ` [PATCH v2 2/2] coresight: Allow guests to be traced when FEAT_TRF and VHE are present James Clark
  0 siblings, 2 replies; 6+ messages in thread
From: James Clark @ 2023-09-04 14:07 UTC (permalink / raw)
  To: coresight, linux-arm-kernel, kvmarm, broonie
  Cc: maz, James Clark, Catalin Marinas, Will Deacon, Suzuki K Poulose,
	Mike Leach, Leo Yan, Alexander Shishkin, James Morse,
	Kristina Martsenko, Anshuman Khandual, Rob Herring, Jintack Lim,
	Joey Gouly, linux-kernel

FEAT_TRF is a Coresight feature that allows trace capture to be
completely filtered at different exception levels, unlike the existing
TRCVICTLR controls which may still emit target addresses of branches,
even if the following trace is filtered.

Without FEAT_TRF, it was possible to start a trace session on a host and
also collect trace from the guest as TRCVICTLR was never programmed to
exclude guests (and it could still emit target addresses even if it
was). Now when FEAT_TRF is present, because we don't write to
TRFCR_EL1, guest trace will be completely disabled.

This change fixes this issue, and also adds the ability to control it
with the Perf exclude_host and exclude_guest flags.

The first commit moves the register to sysreg because I add the EL12
version in the second commit.

The test results have some single spurious EL2 addresses, but I don't
think this is an issue with this patchset because it happens in the
host-userspace case which maintains the existing programming of
TRFCR. It's likely an issue with the model but I will follow it up
separately.

The corresponding change for nVHE is here [1]. With nVHE the behaviour
is reversed, currently guest trace is always generated because the host
already writes to TRFCR_EL1. This is the same both with and without
FEAT_TRF.

[1]: https://lore.kernel.org/kvmarm/20230804101317.460697-1-james.clark@arm.com/

---

Changes since v1:

 * Split new sysreg definitions into TRFCR_EL2 and TRFCR_ELx so that
   TRFCR_ELx doesn't include CX which TRFCR_EL1 doesn't have.
 * Mask out TS and CX before writing to TRFCR_EL1 because it doesn't
   have CX and TS has no effect.
 * Expand cover letter

James Clark (2):
  arm64/sysreg: Move TRFCR definitions to sysreg
  coresight: Allow guests to be traced when FEAT_TRF and VHE are present

 arch/arm64/include/asm/sysreg.h               | 12 -----
 arch/arm64/tools/sysreg                       | 40 +++++++++++++++
 .../coresight/coresight-etm4x-core.c          | 51 ++++++++++++++++---
 drivers/hwtracing/coresight/coresight-etm4x.h |  2 +-
 drivers/hwtracing/coresight/coresight-priv.h  |  3 ++
 5 files changed, 89 insertions(+), 19 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/2] arm64/sysreg: Move TRFCR definitions to sysreg
  2023-09-04 14:07 [PATCH v2 0/2] coresight: Allow guests to be traced when FEAT_TRF and VHE are present James Clark
@ 2023-09-04 14:07 ` James Clark
  2023-09-04 16:03   ` Mark Brown
  2023-09-04 14:07 ` [PATCH v2 2/2] coresight: Allow guests to be traced when FEAT_TRF and VHE are present James Clark
  1 sibling, 1 reply; 6+ messages in thread
From: James Clark @ 2023-09-04 14:07 UTC (permalink / raw)
  To: coresight, linux-arm-kernel, kvmarm, broonie
  Cc: maz, James Clark, Catalin Marinas, Will Deacon, Suzuki K Poulose,
	Mike Leach, Leo Yan, Alexander Shishkin, James Morse,
	Kristina Martsenko, Anshuman Khandual, Rob Herring, Jintack Lim,
	Joey Gouly, linux-kernel

Add separate definitions for ELx and EL2 as TRFCR_EL1 doesn't have CX.
This also mirrors the previous definition so no code change is required.

Signed-off-by: James Clark <james.clark@arm.com>
---
 arch/arm64/include/asm/sysreg.h | 12 -----------
 arch/arm64/tools/sysreg         | 36 +++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index b481935e9314..fc9a5a09fa04 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -171,8 +171,6 @@
 #define SYS_RGSR_EL1			sys_reg(3, 0, 1, 0, 5)
 #define SYS_GCR_EL1			sys_reg(3, 0, 1, 0, 6)
 
-#define SYS_TRFCR_EL1			sys_reg(3, 0, 1, 2, 1)
-
 #define SYS_TCR_EL1			sys_reg(3, 0, 2, 0, 2)
 
 #define SYS_APIAKEYLO_EL1		sys_reg(3, 0, 2, 1, 0)
@@ -382,7 +380,6 @@
 #define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
 #define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
 
-#define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
 #define SYS_HDFGRTR_EL2			sys_reg(3, 4, 3, 1, 4)
 #define SYS_HDFGWTR_EL2			sys_reg(3, 4, 3, 1, 5)
 #define SYS_HAFGRTR_EL2			sys_reg(3, 4, 3, 1, 6)
@@ -640,15 +637,6 @@
 /* Safe value for MPIDR_EL1: Bit31:RES1, Bit30:U:0, Bit24:MT:0 */
 #define SYS_MPIDR_SAFE_VAL	(BIT(31))
 
-#define TRFCR_ELx_TS_SHIFT		5
-#define TRFCR_ELx_TS_MASK		((0x3UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_VIRTUAL		((0x1UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_GUEST_PHYSICAL	((0x2UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_ELx_TS_PHYSICAL		((0x3UL) << TRFCR_ELx_TS_SHIFT)
-#define TRFCR_EL2_CX			BIT(3)
-#define TRFCR_ELx_ExTRE			BIT(1)
-#define TRFCR_ELx_E0TRE			BIT(0)
-
 /* GIC Hypervisor interface registers */
 /* ICH_MISR_EL2 bit definitions */
 #define ICH_MISR_EOI		(1 << 0)
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 65866bf819c3..6ca7db69d6c9 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2495,3 +2495,39 @@ Field	5	F
 Field	4	P
 Field	3:0	Align
 EndSysreg
+
+SysregFields TRFCR_EL2
+Res0	63:7
+UnsignedEnum	6:5	TS
+	0b0001	VIRTUAL
+	0b0010	GUEST_PHYSICAL
+	0b0011	PHYSICAL
+EndEnum
+Res0	4
+Field	3	CX
+Res0	2
+Field	1	E2TRE
+Field	0	E0TRE
+EndSysregFields
+
+# TRFCR_EL1 doesn't have the CX bit so redefine it without CX instead of
+# using a shared definition between TRFCR_EL2 and TRFCR_EL1
+SysregFields TRFCR_ELx
+Res0	63:7
+UnsignedEnum	6:5	TS
+	0b0001	VIRTUAL
+	0b0010	GUEST_PHYSICAL
+	0b0011	PHYSICAL
+EndEnum
+Res0	4:2
+Field	1	ExTRE
+Field	0	E0TRE
+EndSysregFields
+
+Sysreg	TRFCR_EL1	3	0	1	2	1
+Fields	TRFCR_ELx
+EndSysreg
+
+Sysreg	TRFCR_EL2	3	4	1	2	1
+Fields	TRFCR_EL2
+EndSysreg
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] coresight: Allow guests to be traced when FEAT_TRF and VHE are present
  2023-09-04 14:07 [PATCH v2 0/2] coresight: Allow guests to be traced when FEAT_TRF and VHE are present James Clark
  2023-09-04 14:07 ` [PATCH v2 1/2] arm64/sysreg: Move TRFCR definitions to sysreg James Clark
@ 2023-09-04 14:07 ` James Clark
  2023-09-12 17:37   ` Suzuki K Poulose
  1 sibling, 1 reply; 6+ messages in thread
From: James Clark @ 2023-09-04 14:07 UTC (permalink / raw)
  To: coresight, linux-arm-kernel, kvmarm, broonie
  Cc: maz, James Clark, Catalin Marinas, Will Deacon, Suzuki K Poulose,
	Mike Leach, Leo Yan, Alexander Shishkin, James Morse,
	Kristina Martsenko, Anshuman Khandual, Rob Herring, Jintack Lim,
	Joey Gouly, linux-kernel

Currently the userspace and kernel filters for guests are never set, so
no trace will be generated for them. Add it by writing to the guest
filters when exclude_guest isn't set. By writing either E1TRE or E0TRE,
filtering on either guest kernel or guest userspace is also supported.

Since TRFCR_EL1 access is trapped, this can't be  modified by the guest.

This change also brings exclude_host support which is difficult to add
as a separate commit without excess churn and resulting in no trace at
all.

Testing
=======

The addresses were counted with the following:

  $ perf report -D | grep -Eo 'EL2|EL1|EL0' | sort | uniq -c

Guest kernel only:

  $ perf record -e cs_etm//Gk -a -- true
    535 EL1
      1 EL2

Guest user only (0 addresses expected because the guest OS hasn't reached
userspace yet):

  $ perf record -e cs_etm//Gu -a -- true

Host kernel only:

  $  perf record -e cs_etm//Hk -a -- true
   3501 EL2

Host userspace only:

  $  perf record -e cs_etm//Hu -a -- true
    408 EL0
      1 EL2

Reviewed-by: Mark Brown <broonie@kernel.org> (sysreg)
Signed-off-by: James Clark <james.clark@arm.com>
---
 arch/arm64/tools/sysreg                       |  4 ++
 .../coresight/coresight-etm4x-core.c          | 51 ++++++++++++++++---
 drivers/hwtracing/coresight/coresight-etm4x.h |  2 +-
 drivers/hwtracing/coresight/coresight-priv.h  |  3 ++
 4 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 6ca7db69d6c9..cae9139b6c05 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -2531,3 +2531,7 @@ EndSysreg
 Sysreg	TRFCR_EL2	3	4	1	2	1
 Fields	TRFCR_EL2
 EndSysreg
+
+Sysreg TRFCR_EL12	3	5	1	2	1
+Fields	TRFCR_ELx
+EndSysreg
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 77b0271ce6eb..6c16a14d6fbe 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -274,6 +274,18 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata)
 	cpu_prohibit_trace();
 }
 
+static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
+{
+	u64 trfcr = drvdata->trfcr;
+
+	if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
+		trfcr &= ~TRFCR_ELx_ExTRE;
+	if (drvdata->config.mode & ETM_MODE_EXCL_USER)
+		trfcr &= ~TRFCR_ELx_E0TRE;
+
+	return trfcr;
+}
+
 /*
  * etm4x_allow_trace - Allow CPU tracing in the respective ELs,
  * as configured by the drvdata->config.mode for the current
@@ -286,18 +298,39 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata)
  */
 static void etm4x_allow_trace(struct etmv4_drvdata *drvdata)
 {
-	u64 trfcr = drvdata->trfcr;
+	u64 trfcr;
 
 	/* If the CPU doesn't support FEAT_TRF, nothing to do */
-	if (!trfcr)
+	if (!drvdata->trfcr)
 		return;
 
-	if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
-		trfcr &= ~TRFCR_ELx_ExTRE;
-	if (drvdata->config.mode & ETM_MODE_EXCL_USER)
-		trfcr &= ~TRFCR_ELx_E0TRE;
+	if (drvdata->config.mode & ETM_MODE_EXCL_HOST)
+		trfcr = drvdata->trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE);
+	else
+		trfcr = etm4x_get_kern_user_filter(drvdata);
 
 	write_trfcr(trfcr);
+
+	/*
+	 * Filters for EL1 and EL0 (when running a guest) are stored in
+	 * TRFCR_EL1 so write it there for VHE. For nVHE, the filters in
+	 * have to be re-applied when switching to the guest instead.
+	 */
+	if (!is_kernel_in_hyp_mode())
+		return;
+
+	if (drvdata->config.mode & ETM_MODE_EXCL_GUEST)
+		trfcr = drvdata->trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE);
+	else
+		trfcr = etm4x_get_kern_user_filter(drvdata);
+
+	/*
+	 * TRFCR_EL1 doesn't have CX and TRFCR_EL1.TS has no effect when TS is
+	 * set in EL2 so mask them out.
+	 */
+	trfcr &= ~(TRFCR_ELx_TS_MASK | TRFCR_EL2_CX);
+
+	write_sysreg_s(trfcr, SYS_TRFCR_EL12);
 }
 
 #ifdef CONFIG_ETM4X_IMPDEF_FEATURE
@@ -655,6 +688,12 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
 	if (attr->exclude_user)
 		config->mode = ETM_MODE_EXCL_USER;
 
+	if (attr->exclude_host)
+		config->mode |= ETM_MODE_EXCL_HOST;
+
+	if (attr->exclude_guest)
+		config->mode |= ETM_MODE_EXCL_GUEST;
+
 	/* Always start from the default config */
 	etm4_set_default_config(config);
 
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 20e2e4cb7614..3f170599822f 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -841,7 +841,7 @@ enum etm_impdef_type {
  * @s_ex_level: Secure ELs where tracing is supported.
  */
 struct etmv4_config {
-	u32				mode;
+	u64				mode;
 	u32				pe_sel;
 	u32				cfg;
 	u32				eventctrl0;
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 767076e07970..727dd27ba800 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -39,6 +39,9 @@
 
 #define ETM_MODE_EXCL_KERN	BIT(30)
 #define ETM_MODE_EXCL_USER	BIT(31)
+#define ETM_MODE_EXCL_HOST	BIT(32)
+#define ETM_MODE_EXCL_GUEST	BIT(33)
+
 struct cs_pair_attribute {
 	struct device_attribute attr;
 	u32 lo_off;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 1/2] arm64/sysreg: Move TRFCR definitions to sysreg
  2023-09-04 14:07 ` [PATCH v2 1/2] arm64/sysreg: Move TRFCR definitions to sysreg James Clark
@ 2023-09-04 16:03   ` Mark Brown
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2023-09-04 16:03 UTC (permalink / raw)
  To: James Clark
  Cc: coresight, linux-arm-kernel, kvmarm, maz, Catalin Marinas,
	Will Deacon, Suzuki K Poulose, Mike Leach, Leo Yan,
	Alexander Shishkin, James Morse, Kristina Martsenko,
	Anshuman Khandual, Rob Herring, Jintack Lim, Joey Gouly,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 409 bytes --]

On Mon, Sep 04, 2023 at 03:07:02PM +0100, James Clark wrote:

> +SysregFields TRFCR_EL2
> +Res0	63:7
> +UnsignedEnum	6:5	TS
> +	0b0001	VIRTUAL
> +	0b0010	GUEST_PHYSICAL
> +	0b0011	PHYSICAL
> +EndEnum

DDO0601 2023-06 also defines the value 0b0000 as "Timestamp controlled
by TRFCR_EL1.TS or TRFCR.TS".  

> +Field	0	E0TRE

DDO0601 2023-06 calls this bit EH0HTRE.

Otherwise this looks good.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] coresight: Allow guests to be traced when FEAT_TRF and VHE are present
  2023-09-04 14:07 ` [PATCH v2 2/2] coresight: Allow guests to be traced when FEAT_TRF and VHE are present James Clark
@ 2023-09-12 17:37   ` Suzuki K Poulose
  2023-09-15 12:51     ` James Clark
  0 siblings, 1 reply; 6+ messages in thread
From: Suzuki K Poulose @ 2023-09-12 17:37 UTC (permalink / raw)
  To: James Clark, coresight, linux-arm-kernel, kvmarm, broonie, Marc Zyngier
  Cc: maz, Catalin Marinas, Will Deacon, Mike Leach, Leo Yan,
	Alexander Shishkin, James Morse, Kristina Martsenko,
	Anshuman Khandual, Rob Herring, Jintack Lim, Joey Gouly,
	linux-kernel

Hi James


On 04/09/2023 15:07, James Clark wrote:
> Currently the userspace and kernel filters for guests are never set, so
> no trace will be generated for them. Add it by writing to the guest
> filters when exclude_guest isn't set. By writing either E1TRE or E0TRE,
> filtering on either guest kernel or guest userspace is also supported.
> 
> Since TRFCR_EL1 access is trapped, this can't be  modified by the guest.
> 
> This change also brings exclude_host support which is difficult to add
> as a separate commit without excess churn and resulting in no trace at
> all.
> 
> Testing
> =======
> 
> The addresses were counted with the following:
> 
>    $ perf report -D | grep -Eo 'EL2|EL1|EL0' | sort | uniq -c
> 
> Guest kernel only:
> 
>    $ perf record -e cs_etm//Gk -a -- true
>      535 EL1
>        1 EL2
> 
> Guest user only (0 addresses expected because the guest OS hasn't reached
> userspace yet):
> 
>    $ perf record -e cs_etm//Gu -a -- true
> 
> Host kernel only:
> 
>    $  perf record -e cs_etm//Hk -a -- true
>     3501 EL2
> 
> Host userspace only:
> 
>    $  perf record -e cs_etm//Hu -a -- true
>      408 EL0
>        1 EL2
> 
> Reviewed-by: Mark Brown <broonie@kernel.org> (sysreg)
> Signed-off-by: James Clark <james.clark@arm.com>
> ---
>   arch/arm64/tools/sysreg                       |  4 ++
>   .../coresight/coresight-etm4x-core.c          | 51 ++++++++++++++++---
>   drivers/hwtracing/coresight/coresight-etm4x.h |  2 +-
>   drivers/hwtracing/coresight/coresight-priv.h  |  3 ++
>   4 files changed, 53 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
> index 6ca7db69d6c9..cae9139b6c05 100644
> --- a/arch/arm64/tools/sysreg
> +++ b/arch/arm64/tools/sysreg
> @@ -2531,3 +2531,7 @@ EndSysreg
>   Sysreg	TRFCR_EL2	3	4	1	2	1
>   Fields	TRFCR_EL2
>   EndSysreg
> +
> +Sysreg TRFCR_EL12	3	5	1	2	1
> +Fields	TRFCR_ELx
> +EndSysreg
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 77b0271ce6eb..6c16a14d6fbe 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -274,6 +274,18 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata)
>   	cpu_prohibit_trace();
>   }
>   
> +static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
> +{
> +	u64 trfcr = drvdata->trfcr;
> +
> +	if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
> +		trfcr &= ~TRFCR_ELx_ExTRE;
> +	if (drvdata->config.mode & ETM_MODE_EXCL_USER)
> +		trfcr &= ~TRFCR_ELx_E0TRE;
> +
> +	return trfcr;
> +}
> +
>   /*
>    * etm4x_allow_trace - Allow CPU tracing in the respective ELs,
>    * as configured by the drvdata->config.mode for the current
> @@ -286,18 +298,39 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata)
>    */
>   static void etm4x_allow_trace(struct etmv4_drvdata *drvdata)
>   {
> -	u64 trfcr = drvdata->trfcr;
> +	u64 trfcr;
>   
>   	/* If the CPU doesn't support FEAT_TRF, nothing to do */
> -	if (!trfcr)
> +	if (!drvdata->trfcr)
>   		return;
>   
> -	if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
> -		trfcr &= ~TRFCR_ELx_ExTRE;
> -	if (drvdata->config.mode & ETM_MODE_EXCL_USER)
> -		trfcr &= ~TRFCR_ELx_E0TRE;
> +	if (drvdata->config.mode & ETM_MODE_EXCL_HOST)
> +		trfcr = drvdata->trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE);
> +	else
> +		trfcr = etm4x_get_kern_user_filter(drvdata);
>   
>   	write_trfcr(trfcr);
> +
> +	/*
> +	 * Filters for EL1 and EL0 (when running a guest) are stored in
> +	 * TRFCR_EL1 so write it there for VHE. For nVHE, the filters in
> +	 * have to be re-applied when switching to the guest instead.
> +	 */
> +	if (!is_kernel_in_hyp_mode())
> +		return;
> +
> +	if (drvdata->config.mode & ETM_MODE_EXCL_GUEST)
> +		trfcr = drvdata->trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE);
> +	else
> +		trfcr = etm4x_get_kern_user_filter(drvdata);
> +
> +	/*
> +	 * TRFCR_EL1 doesn't have CX and TRFCR_EL1.TS has no effect when TS is
> +	 * set in EL2 so mask them out.
> +	 */
> +	trfcr &= ~(TRFCR_ELx_TS_MASK | TRFCR_EL2_CX);
> +
> +	write_sysreg_s(trfcr, SYS_TRFCR_EL12);



While I agree with the intention of the patch, I am not sure if we
should do the TRFCR_EL1 (via TRFCR_EL12) updates from CoreSight driver.

It might be much better to do it from the KVM for both VHE and nVHE.


Marc

What are your thoughts on this ?

Suzuki


>   }
>   
>   #ifdef CONFIG_ETM4X_IMPDEF_FEATURE
> @@ -655,6 +688,12 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
>   	if (attr->exclude_user)
>   		config->mode = ETM_MODE_EXCL_USER;
>   
> +	if (attr->exclude_host)
> +		config->mode |= ETM_MODE_EXCL_HOST;
> +
> +	if (attr->exclude_guest)
> +		config->mode |= ETM_MODE_EXCL_GUEST;
> +
>   	/* Always start from the default config */
>   	etm4_set_default_config(config);
>   
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index 20e2e4cb7614..3f170599822f 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -841,7 +841,7 @@ enum etm_impdef_type {
>    * @s_ex_level: Secure ELs where tracing is supported.
>    */
>   struct etmv4_config {
> -	u32				mode;
> +	u64				mode;
>   	u32				pe_sel;
>   	u32				cfg;
>   	u32				eventctrl0;
> diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
> index 767076e07970..727dd27ba800 100644
> --- a/drivers/hwtracing/coresight/coresight-priv.h
> +++ b/drivers/hwtracing/coresight/coresight-priv.h
> @@ -39,6 +39,9 @@
>   
>   #define ETM_MODE_EXCL_KERN	BIT(30)
>   #define ETM_MODE_EXCL_USER	BIT(31)
> +#define ETM_MODE_EXCL_HOST	BIT(32)
> +#define ETM_MODE_EXCL_GUEST	BIT(33)
> +
>   struct cs_pair_attribute {
>   	struct device_attribute attr;
>   	u32 lo_off;


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] coresight: Allow guests to be traced when FEAT_TRF and VHE are present
  2023-09-12 17:37   ` Suzuki K Poulose
@ 2023-09-15 12:51     ` James Clark
  0 siblings, 0 replies; 6+ messages in thread
From: James Clark @ 2023-09-15 12:51 UTC (permalink / raw)
  To: Suzuki K Poulose, coresight, linux-arm-kernel, kvmarm, broonie,
	Marc Zyngier
  Cc: Catalin Marinas, Will Deacon, Mike Leach, Leo Yan,
	Alexander Shishkin, James Morse, Kristina Martsenko,
	Anshuman Khandual, Rob Herring, Jintack Lim, Joey Gouly,
	linux-kernel



On 12/09/2023 18:37, Suzuki K Poulose wrote:
> Hi James
> 
> 
> On 04/09/2023 15:07, James Clark wrote:
>> Currently the userspace and kernel filters for guests are never set, so
>> no trace will be generated for them. Add it by writing to the guest
>> filters when exclude_guest isn't set. By writing either E1TRE or E0TRE,
>> filtering on either guest kernel or guest userspace is also supported.
>>
>> Since TRFCR_EL1 access is trapped, this can't be  modified by the guest.
>>
>> This change also brings exclude_host support which is difficult to add
>> as a separate commit without excess churn and resulting in no trace at
>> all.
>>
>> Testing
>> =======
>>
>> The addresses were counted with the following:
>>
>>    $ perf report -D | grep -Eo 'EL2|EL1|EL0' | sort | uniq -c
>>
>> Guest kernel only:
>>
>>    $ perf record -e cs_etm//Gk -a -- true
>>      535 EL1
>>        1 EL2
>>
>> Guest user only (0 addresses expected because the guest OS hasn't reached
>> userspace yet):
>>
>>    $ perf record -e cs_etm//Gu -a -- true
>>
>> Host kernel only:
>>
>>    $  perf record -e cs_etm//Hk -a -- true
>>     3501 EL2
>>
>> Host userspace only:
>>
>>    $  perf record -e cs_etm//Hu -a -- true
>>      408 EL0
>>        1 EL2
>>
>> Reviewed-by: Mark Brown <broonie@kernel.org> (sysreg)
>> Signed-off-by: James Clark <james.clark@arm.com>
>> ---
>>   arch/arm64/tools/sysreg                       |  4 ++
>>   .../coresight/coresight-etm4x-core.c          | 51 ++++++++++++++++---
>>   drivers/hwtracing/coresight/coresight-etm4x.h |  2 +-
>>   drivers/hwtracing/coresight/coresight-priv.h  |  3 ++
>>   4 files changed, 53 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
>> index 6ca7db69d6c9..cae9139b6c05 100644
>> --- a/arch/arm64/tools/sysreg
>> +++ b/arch/arm64/tools/sysreg
>> @@ -2531,3 +2531,7 @@ EndSysreg
>>   Sysreg    TRFCR_EL2    3    4    1    2    1
>>   Fields    TRFCR_EL2
>>   EndSysreg
>> +
>> +Sysreg TRFCR_EL12    3    5    1    2    1
>> +Fields    TRFCR_ELx
>> +EndSysreg
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> index 77b0271ce6eb..6c16a14d6fbe 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> @@ -274,6 +274,18 @@ static void etm4x_prohibit_trace(struct
>> etmv4_drvdata *drvdata)
>>       cpu_prohibit_trace();
>>   }
>>   +static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
>> +{
>> +    u64 trfcr = drvdata->trfcr;
>> +
>> +    if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
>> +        trfcr &= ~TRFCR_ELx_ExTRE;
>> +    if (drvdata->config.mode & ETM_MODE_EXCL_USER)
>> +        trfcr &= ~TRFCR_ELx_E0TRE;
>> +
>> +    return trfcr;
>> +}
>> +
>>   /*
>>    * etm4x_allow_trace - Allow CPU tracing in the respective ELs,
>>    * as configured by the drvdata->config.mode for the current
>> @@ -286,18 +298,39 @@ static void etm4x_prohibit_trace(struct
>> etmv4_drvdata *drvdata)
>>    */
>>   static void etm4x_allow_trace(struct etmv4_drvdata *drvdata)
>>   {
>> -    u64 trfcr = drvdata->trfcr;
>> +    u64 trfcr;
>>         /* If the CPU doesn't support FEAT_TRF, nothing to do */
>> -    if (!trfcr)
>> +    if (!drvdata->trfcr)
>>           return;
>>   -    if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
>> -        trfcr &= ~TRFCR_ELx_ExTRE;
>> -    if (drvdata->config.mode & ETM_MODE_EXCL_USER)
>> -        trfcr &= ~TRFCR_ELx_E0TRE;
>> +    if (drvdata->config.mode & ETM_MODE_EXCL_HOST)
>> +        trfcr = drvdata->trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE);
>> +    else
>> +        trfcr = etm4x_get_kern_user_filter(drvdata);
>>         write_trfcr(trfcr);
>> +
>> +    /*
>> +     * Filters for EL1 and EL0 (when running a guest) are stored in
>> +     * TRFCR_EL1 so write it there for VHE. For nVHE, the filters in
>> +     * have to be re-applied when switching to the guest instead.
>> +     */
>> +    if (!is_kernel_in_hyp_mode())
>> +        return;
>> +
>> +    if (drvdata->config.mode & ETM_MODE_EXCL_GUEST)
>> +        trfcr = drvdata->trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE);
>> +    else
>> +        trfcr = etm4x_get_kern_user_filter(drvdata);
>> +
>> +    /*
>> +     * TRFCR_EL1 doesn't have CX and TRFCR_EL1.TS has no effect when
>> TS is
>> +     * set in EL2 so mask them out.
>> +     */
>> +    trfcr &= ~(TRFCR_ELx_TS_MASK | TRFCR_EL2_CX);
>> +
>> +    write_sysreg_s(trfcr, SYS_TRFCR_EL12);
> 
> 
> 
> While I agree with the intention of the patch, I am not sure if we
> should do the TRFCR_EL1 (via TRFCR_EL12) updates from CoreSight driver.
> 
> It might be much better to do it from the KVM for both VHE and nVHE.
> 

For the next version of the nVHE change [1] I planned to re-write it
just in terms of the guest trfcr register value rather than
exclude_guest/exclude host. That means that it would be pretty easy to
move the write to SYS_TRFCR_EL12 to the VHE implementation of
kvm_etm_set_guest_trfcr(). So yes I can make this change I think it
makes sense.

[1]:
https://lore.kernel.org/kvmarm/20230804101317.460697-1-james.clark@arm.com/

James

> 
> Marc
> 
> What are your thoughts on this ?
> 
> Suzuki
> 
> 
>>   }
>>     #ifdef CONFIG_ETM4X_IMPDEF_FEATURE
>> @@ -655,6 +688,12 @@ static int etm4_parse_event_config(struct
>> coresight_device *csdev,
>>       if (attr->exclude_user)
>>           config->mode = ETM_MODE_EXCL_USER;
>>   +    if (attr->exclude_host)
>> +        config->mode |= ETM_MODE_EXCL_HOST;
>> +
>> +    if (attr->exclude_guest)
>> +        config->mode |= ETM_MODE_EXCL_GUEST;
>> +
>>       /* Always start from the default config */
>>       etm4_set_default_config(config);
>>   diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h
>> b/drivers/hwtracing/coresight/coresight-etm4x.h
>> index 20e2e4cb7614..3f170599822f 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
>> @@ -841,7 +841,7 @@ enum etm_impdef_type {
>>    * @s_ex_level: Secure ELs where tracing is supported.
>>    */
>>   struct etmv4_config {
>> -    u32                mode;
>> +    u64                mode;
>>       u32                pe_sel;
>>       u32                cfg;
>>       u32                eventctrl0;
>> diff --git a/drivers/hwtracing/coresight/coresight-priv.h
>> b/drivers/hwtracing/coresight/coresight-priv.h
>> index 767076e07970..727dd27ba800 100644
>> --- a/drivers/hwtracing/coresight/coresight-priv.h
>> +++ b/drivers/hwtracing/coresight/coresight-priv.h
>> @@ -39,6 +39,9 @@
>>     #define ETM_MODE_EXCL_KERN    BIT(30)
>>   #define ETM_MODE_EXCL_USER    BIT(31)
>> +#define ETM_MODE_EXCL_HOST    BIT(32)
>> +#define ETM_MODE_EXCL_GUEST    BIT(33)
>> +
>>   struct cs_pair_attribute {
>>       struct device_attribute attr;
>>       u32 lo_off;
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-09-15 12:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-04 14:07 [PATCH v2 0/2] coresight: Allow guests to be traced when FEAT_TRF and VHE are present James Clark
2023-09-04 14:07 ` [PATCH v2 1/2] arm64/sysreg: Move TRFCR definitions to sysreg James Clark
2023-09-04 16:03   ` Mark Brown
2023-09-04 14:07 ` [PATCH v2 2/2] coresight: Allow guests to be traced when FEAT_TRF and VHE are present James Clark
2023-09-12 17:37   ` Suzuki K Poulose
2023-09-15 12:51     ` James Clark

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®