[PATCH v2 06/28] coresight: etm4x: Add context synchronization before enabling trace

From: Leo Yan
Date: Tue Jul 01 2025 - 10:55:57 EST


According to the software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), a
Context synchronization event is required before enabling the trace
unit. An ISB is added to meet this requirement.

Improved the barrier comments to provide more accurate information by
specifying which section of the document the requirement comes from and
clarifying its intended purpose.

Fixes: 1ab3bb9df5e3 ("coresight: etm4x: Add necessary synchronization for sysreg access")
Signed-off-by: Leo Yan <leo.yan@xxxxxxx>
---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 37 +++++++++++++++++++---
1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index af9d3b2319c5f49ccd40dfa0ccf0f694ce9e2f4f..e3a73718d0c903ee9c72b97028b56565f5ee1053 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -445,13 +445,37 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata)
etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR);

etm4x_allow_trace(drvdata);
+
+ /*
+ * According to software usage PKLXF in Arm ARM (ARM DDI 0487 L.a),
+ * execute a Context synchronization event to guarantee the trace unit
+ * will observe the new values of the System registers.
+ */
+ if (!csa->io_mem)
+ isb();
+
/* Enable the trace unit */
etm4x_relaxed_write32(csa, 1, TRCPRGCTLR);

- /* Synchronize the register updates for sysreg access */
+ /*
+ * As recommended by section 4.3.7 ("Synchronization when using system
+ * instructions to progrom the trace unit") of ARM IHI 0064H.b, the
+ * self-hosted trace analyzer must perform a Context synchronization
+ * event between writing to the TRCPRGCTLR and reading the TRCSTATR.
+ */
if (!csa->io_mem)
isb();

+ /*
+ * For the memory-mapped interface, the registers are mapped as Device
+ * type (Device-nGnRE). As described in section 4.3.7 ("Synchronization
+ * of register updates") of ARM IHI0064H.b, read back the value of any
+ * register in the trace unit to ensure writes have completed.
+ *
+ * Therefore, polling on TRCSTATR ensures that the writing TRCPRGCTLR
+ * is complete.
+ */
+
/* wait for TRCSTATR.IDLE to go back down to '0' */
if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) {
dev_err(etm_dev,
@@ -931,11 +955,16 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata)
*/
etm4x_prohibit_trace(drvdata);
/*
- * Make sure everything completes before disabling, as recommended
- * by section 7.3.77 ("TRCVICTLR, ViewInst Main Control Register,
- * SSTATUS") of ARM IHI 0064D
+ * Prevent being speculative at the point of disabling the trace unit,
+ * as recommended by section 7.3.77 ("TRCVICTLR, ViewInst Main Control
+ * Register, SSTATUS") of ARM IHI 0064D
*/
dsb(sy);
+ /*
+ * According to software usage VKHHY in Arm ARM (ARM DDI 0487 L.a),
+ * execute a Context synchronization event to guarantee no new
+ * program-flow trace is generated.
+ */
isb();
/* Trace synchronization barrier, is a nop if not supported */
tsb_csync();

--
2.34.1