[PATCH v3 10/10] coresight: trbe: Prohibit trace before disabling TRBE
Anshuman Khandual
anshuman.khandual at arm.com
Tue Sep 14 23:58:16 PDT 2021
On 9/14/21 3:56 PM, Suzuki K Poulose wrote:
> When the TRBE generates an IRQ, we stop the TRBE, collect the trace
> and then reprogram the TRBE with the updated buffer pointers, whenever
> possible. We might also leave the TRBE disabled, if there is not
> enough space left in the buffer. However, we do not touch the ETE at
> all during all of this. This means the ETE is only disabled when
> the event is disabled later (via irq_work). This is incorrect, as the
> ETE trace is still ON without actually being captured and may be routed
> to the ATB (even if it is for a short duration).
>
> So, we move the CPU into trace prohibited state always before disabling
> the TRBE, upon entering the IRQ handler. The state is restored if the
> TRBE is enabled back. Otherwise the trace remains prohibited.
>
> Since, the ETM/ETE driver now controls the TRFCR_EL1 per session, the
> tracing can be restored/enabled back when the event is rescheduled
> in.
>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
> .../hwtracing/coresight/coresight-self-hosted-trace.h | 4 +++-
> drivers/hwtracing/coresight/coresight-trbe.c | 9 +++++++++
> 2 files changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-self-hosted-trace.h b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h
> index 586d26e0cba3..34372482a3cd 100644
> --- a/drivers/hwtracing/coresight/coresight-self-hosted-trace.h
> +++ b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h
> @@ -22,11 +22,13 @@ static inline void write_trfcr(u64 val)
> isb();
> }
>
> -static inline void cpu_prohibit_trace(void)
> +static inline u64 cpu_prohibit_trace(void)
> {
> u64 trfcr = read_trfcr();
>
> /* Prohibit tracing at EL0 & the kernel EL */
> write_trfcr(trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE));
> + /* Return the original value of the TRFCR */
> + return trfcr;
> }
> #endif /* __CORESIGHT_SELF_HOSTED_TRACE_H */
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index d05cb5ffc128..d4c57aed05e5 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -16,6 +16,7 @@
> #define pr_fmt(fmt) DRVNAME ": " fmt
>
> #include <asm/barrier.h>
> +#include "coresight-self-hosted-trace.h"
> #include "coresight-trbe.h"
>
> #define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT))
> @@ -760,6 +761,7 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
> enum trbe_fault_action act;
> u64 status;
> bool truncated = false;
> + u64 trfcr;
>
> /* Reads to TRBSR_EL1 is fine when TRBE is active */
> status = read_sysreg_s(SYS_TRBSR_EL1);
> @@ -770,6 +772,8 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
> if (!is_trbe_irq(status))
> return IRQ_NONE;
>
> + /* Prohibit the CPU from tracing before we disable the TRBE */
> + trfcr = cpu_prohibit_trace();
> /*
> * Ensure the trace is visible to the CPUs and
> * any external aborts have been resolved.
> @@ -801,9 +805,14 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
> /*
> * If the buffer was truncated, ensure perf callbacks
> * have completed, which will disable the event.
> + *
> + * Otherwise, restore the trace filter controls to
> + * allow the tracing.
> */
> if (truncated)
> irq_work_run();
> + else
> + write_trfcr(trfcr);
>
> return IRQ_HANDLED;
> }
>
More information about the linux-arm-kernel
mailing list