mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
coresight: etm4x: Safe access for TRCQCLTR
[ Upstream commit 46bf8d7cd8530eca607379033b9bc4ac5590a0cd ]
ETM4x implements TRCQCLTR only when the Q elements are supported
and the Q element filtering is supported (TRCIDR0.QFILT). Access
to the register otherwise could be fatal. Fix this by tracking the
availability, like the others.
Fixes: f188b5e76a ("coresight: etm4x: Save/restore state across CPU low power states")
Reported-by: Yabin Cui <yabinc@google.com>
Reviewed-by: Mike Leach <mike.leach@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Tested-by: Yabin Cui <yabinc@google.com>
Link: https://lore.kernel.org/r/20240412142702.2882478-4-suzuki.poulose@arm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
cf9a077ab5
commit
3a8a24cbdd
@@ -1120,6 +1120,8 @@ static void etm4_init_arch_data(void *info)
|
|||||||
drvdata->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0);
|
drvdata->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0);
|
||||||
/* QSUPP, bits[16:15] Q element support field */
|
/* QSUPP, bits[16:15] Q element support field */
|
||||||
drvdata->q_support = FIELD_GET(TRCIDR0_QSUPP_MASK, etmidr0);
|
drvdata->q_support = FIELD_GET(TRCIDR0_QSUPP_MASK, etmidr0);
|
||||||
|
if (drvdata->q_support)
|
||||||
|
drvdata->q_filt = !!(etmidr0 & TRCIDR0_QFILT);
|
||||||
/* TSSIZE, bits[28:24] Global timestamp size field */
|
/* TSSIZE, bits[28:24] Global timestamp size field */
|
||||||
drvdata->ts_size = FIELD_GET(TRCIDR0_TSSIZE_MASK, etmidr0);
|
drvdata->ts_size = FIELD_GET(TRCIDR0_TSSIZE_MASK, etmidr0);
|
||||||
|
|
||||||
@@ -1615,7 +1617,8 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
|
|||||||
state->trcccctlr = etm4x_read32(csa, TRCCCCTLR);
|
state->trcccctlr = etm4x_read32(csa, TRCCCCTLR);
|
||||||
state->trcbbctlr = etm4x_read32(csa, TRCBBCTLR);
|
state->trcbbctlr = etm4x_read32(csa, TRCBBCTLR);
|
||||||
state->trctraceidr = etm4x_read32(csa, TRCTRACEIDR);
|
state->trctraceidr = etm4x_read32(csa, TRCTRACEIDR);
|
||||||
state->trcqctlr = etm4x_read32(csa, TRCQCTLR);
|
if (drvdata->q_filt)
|
||||||
|
state->trcqctlr = etm4x_read32(csa, TRCQCTLR);
|
||||||
|
|
||||||
state->trcvictlr = etm4x_read32(csa, TRCVICTLR);
|
state->trcvictlr = etm4x_read32(csa, TRCVICTLR);
|
||||||
state->trcviiectlr = etm4x_read32(csa, TRCVIIECTLR);
|
state->trcviiectlr = etm4x_read32(csa, TRCVIIECTLR);
|
||||||
@@ -1745,7 +1748,8 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
|
|||||||
etm4x_relaxed_write32(csa, state->trcccctlr, TRCCCCTLR);
|
etm4x_relaxed_write32(csa, state->trcccctlr, TRCCCCTLR);
|
||||||
etm4x_relaxed_write32(csa, state->trcbbctlr, TRCBBCTLR);
|
etm4x_relaxed_write32(csa, state->trcbbctlr, TRCBBCTLR);
|
||||||
etm4x_relaxed_write32(csa, state->trctraceidr, TRCTRACEIDR);
|
etm4x_relaxed_write32(csa, state->trctraceidr, TRCTRACEIDR);
|
||||||
etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR);
|
if (drvdata->q_filt)
|
||||||
|
etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR);
|
||||||
|
|
||||||
etm4x_relaxed_write32(csa, state->trcvictlr, TRCVICTLR);
|
etm4x_relaxed_write32(csa, state->trcvictlr, TRCVICTLR);
|
||||||
etm4x_relaxed_write32(csa, state->trcviiectlr, TRCVIIECTLR);
|
etm4x_relaxed_write32(csa, state->trcviiectlr, TRCVIIECTLR);
|
||||||
|
|||||||
@@ -135,6 +135,7 @@
|
|||||||
#define TRCIDR0_TRCCCI BIT(7)
|
#define TRCIDR0_TRCCCI BIT(7)
|
||||||
#define TRCIDR0_RETSTACK BIT(9)
|
#define TRCIDR0_RETSTACK BIT(9)
|
||||||
#define TRCIDR0_NUMEVENT_MASK GENMASK(11, 10)
|
#define TRCIDR0_NUMEVENT_MASK GENMASK(11, 10)
|
||||||
|
#define TRCIDR0_QFILT BIT(14)
|
||||||
#define TRCIDR0_QSUPP_MASK GENMASK(16, 15)
|
#define TRCIDR0_QSUPP_MASK GENMASK(16, 15)
|
||||||
#define TRCIDR0_TSSIZE_MASK GENMASK(28, 24)
|
#define TRCIDR0_TSSIZE_MASK GENMASK(28, 24)
|
||||||
|
|
||||||
@@ -951,6 +952,7 @@ struct etmv4_save_state {
|
|||||||
* @os_unlock: True if access to management registers is allowed.
|
* @os_unlock: True if access to management registers is allowed.
|
||||||
* @instrp0: Tracing of load and store instructions
|
* @instrp0: Tracing of load and store instructions
|
||||||
* as P0 elements is supported.
|
* as P0 elements is supported.
|
||||||
|
* @q_filt: Q element filtering support, if Q elements are supported.
|
||||||
* @trcbb: Indicates if the trace unit supports branch broadcast tracing.
|
* @trcbb: Indicates if the trace unit supports branch broadcast tracing.
|
||||||
* @trccond: If the trace unit supports conditional
|
* @trccond: If the trace unit supports conditional
|
||||||
* instruction tracing.
|
* instruction tracing.
|
||||||
@@ -1013,6 +1015,7 @@ struct etmv4_drvdata {
|
|||||||
bool boot_enable;
|
bool boot_enable;
|
||||||
bool os_unlock;
|
bool os_unlock;
|
||||||
bool instrp0;
|
bool instrp0;
|
||||||
|
bool q_filt;
|
||||||
bool trcbb;
|
bool trcbb;
|
||||||
bool trccond;
|
bool trccond;
|
||||||
bool retstack;
|
bool retstack;
|
||||||
|
|||||||
Reference in New Issue
Block a user