When a sysfs session is disabled, seq_curr_state is read back from the hardware into sysfs_config, overwriting any value written while the session was enabled. Return -EBUSY in that case.
Do the mode check and the write under drvdata->spinlock. etm_enable_sysfs() takes the mode before copying sysfs_config to curr_config under the same lock, so either the new value is included in the copy, or the store sees that the session is enabled. etm_disable_sysfs() does the read back before releasing the mode, so a store can't succeed until it's done.
Fixes: a939fc5a71ad ("coresight-etm: add CoreSight ETM/PTM driver") Reported-by: Sashiko sashiko-bot@kernel.org Closes: https://sashiko.dev/#/bug/linux-d70beb3d-d997-429d-9828-d396e1bbfbb5 Signed-off-by: James Clark james.clark@linaro.org --- drivers/hwtracing/coresight/coresight-etm3x-sysfs.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c index d185fb8270e1..08c10fd146d5 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c @@ -1014,6 +1014,11 @@ static ssize_t seq_curr_state_store(struct device *dev, if (val > ETM_SEQ_STATE_MAX_VAL) return -EINVAL;
+ guard(spinlock)(&drvdata->spinlock); + if (IS_ERR_OR_NULL(drvdata->csdev) || + coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) + return -EBUSY; + sysfs_config->seq_curr_state = val;
return size;