summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSuzuki K Poulose <suzuki.poulose@arm.com>2021-09-23 15:39:16 +0100
committerMathieu Poirier <mathieu.poirier@linaro.org>2021-10-27 11:45:28 -0600
commit7037a39d379733f5352af5e04a202dad35562ef3 (patch)
tree682942993a15f0c90da29ec4ca3694c9b6feb456 /drivers
parent85fb92353e0dece18048bdb35c7e6b682129deff (diff)
downloadlinux-7037a39d379733f5352af5e04a202dad35562ef3.tar.bz2
coresight: trbe: Fix handling of spurious interrupts
On a spurious IRQ, right now we disable the TRBE and then re-enable it back, resetting the "buffer" pointers(i.e BASE, LIMIT and more importantly WRITE) to the original pointers from the AUX handle. This implies that we overwrite any trace that was written so far, (by overwriting TRBPTR) while we should have ignored the IRQ. On detecting a spurious IRQ after examining the TRBSR we simply re-enable the TRBE without touching the other parameters. Cc: Anshuman Khandual <anshuman.khandual@arm.com> Cc: Mathieu Poirier <mathieu.poirier@linaro.org> Cc: Mike Leach <mike.leach@linaro.org> Cc: Leo Yan <leo.yan@linaro.org> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20210923143919.2944311-3-suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwtracing/coresight/coresight-trbe.c22
1 files changed, 9 insertions, 13 deletions
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index e78800ba5b5b..47120d263639 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -684,20 +684,16 @@ static int arm_trbe_disable(struct coresight_device *csdev)
static void trbe_handle_spurious(struct perf_output_handle *handle)
{
- struct trbe_buf *buf = etm_perf_sink_config(handle);
+ u64 limitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
- buf->trbe_limit = compute_trbe_buffer_limit(handle);
- buf->trbe_write = buf->trbe_base + PERF_IDX2OFF(handle->head, buf);
- if (buf->trbe_limit == buf->trbe_base) {
- trbe_drain_and_disable_local();
- /*
- * Just communicate trace truncation event to the user space by
- * marking it with PERF_AUX_FLAG_TRUNCATED.
- */
- perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
- return;
- }
- trbe_enable_hw(buf);
+ /*
+ * If the IRQ was spurious, simply re-enable the TRBE
+ * back without modifying the buffer parameters to
+ * retain the trace collected so far.
+ */
+ limitr |= TRBLIMITR_ENABLE;
+ write_sysreg_s(limitr, SYS_TRBLIMITR_EL1);
+ isb();
}
static void trbe_handle_overflow(struct perf_output_handle *handle)