Commit 585bf074 authored by Suzuki K Poulose's avatar Suzuki K Poulose Committed by Junhao He
Browse files

coresight: etm4x: Safe access for TRCQCLTR

mainline inclusion
from mainline-v6.10-rc1
commit 46bf8d7cd8530eca607379033b9bc4ac5590a0cd
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAKVFA
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=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: f188b5e7 ("coresight: etm4x: Save/restore state across CPU low power states")
Reported-by: default avatarYabin Cui <yabinc@google.com>
Reviewed-by: default avatarMike Leach <mike.leach@linaro.org>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Tested-by: default avatarYabin Cui <yabinc@google.com>
Link: https://lore.kernel.org/r/20240412142702.2882478-4-suzuki.poulose@arm.com


Signed-off-by: default avatarJunhao He <hejunhao3@huawei.com>
parent ad45edfb
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -1122,6 +1122,8 @@ static void etm4_init_arch_data(void *info)
	drvdata->nr_event = BMVAL(etmidr0, 10, 11);
	/* QSUPP, bits[16:15] Q element support field */
	drvdata->q_support = BMVAL(etmidr0, 15, 16);
	if (drvdata->q_support)
		drvdata->q_filt = BMVAL(etmidr0, 14, 14);
	/* TSSIZE, bits[28:24] Global timestamp size field */
	drvdata->ts_size = BMVAL(etmidr0, 24, 28);

@@ -1645,6 +1647,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
	state->trcccctlr = etm4x_read32(csa, TRCCCCTLR);
	state->trcbbctlr = etm4x_read32(csa, TRCBBCTLR);
	state->trctraceidr = etm4x_read32(csa, TRCTRACEIDR);
	if (drvdata->q_filt)
		state->trcqctlr = etm4x_read32(csa, TRCQCTLR);

	state->trcvictlr = etm4x_read32(csa, TRCVICTLR);
@@ -1774,6 +1777,7 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
	etm4x_relaxed_write32(csa, state->trcccctlr, TRCCCCTLR);
	etm4x_relaxed_write32(csa, state->trcbbctlr, TRCBBCTLR);
	etm4x_relaxed_write32(csa, state->trctraceidr, TRCTRACEIDR);
	if (drvdata->q_filt)
		etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR);

	etm4x_relaxed_write32(csa, state->trcvictlr, TRCVICTLR);
+2 −0
Original line number Diff line number Diff line
@@ -855,6 +855,7 @@ struct etmv4_save_state {
 * @os_unlock:  True if access to management registers is allowed.
 * @instrp0:	Tracing of load and store instructions
 *		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.
 * @trccond:	If the trace unit supports conditional
 *		instruction tracing.
@@ -918,6 +919,7 @@ struct etmv4_drvdata {
	bool				boot_enable;
	bool				os_unlock;
	bool				instrp0;
	bool				q_filt;
	bool				trcbb;
	bool				trccond;
	bool				retstack;