In the function coresight_enable_path(), all adjacent helper components along the path are enabled first. Without proper locking, a race condition may occur between concurrent sysfs and perf calls to these functions, potentially leading to incorrectly obtained settings or misconfigured CATU control-enable flags.
Requires spinlock in catu_enable()/catu_disable() to: - Serialize sysfs/perf concurrent accesses - Prevent corruption of CATU control-enable flags
Signed-off-by: Junhao He hejunhao3@huawei.com --- drivers/hwtracing/coresight/coresight-catu.c | 6 ++++++ drivers/hwtracing/coresight/coresight-catu.h | 1 + 2 files changed, 7 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index 275cc0d9f505..54ce13254d7c 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -461,6 +461,8 @@ static int catu_enable(struct coresight_device *csdev, enum cs_mode mode, int rc; struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev);
+ guard(spinlock_irqsave)(&catu_drvdata->spinlock); + CS_UNLOCK(catu_drvdata->base); rc = catu_enable_hw(catu_drvdata, mode, data); CS_LOCK(catu_drvdata->base); @@ -489,6 +491,8 @@ static int catu_disable(struct coresight_device *csdev, void *__unused) int rc; struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev);
+ guard(spinlock_irqsave)(&catu_drvdata->spinlock); + CS_UNLOCK(catu_drvdata->base); rc = catu_disable_hw(catu_drvdata); CS_LOCK(catu_drvdata->base); @@ -523,6 +527,8 @@ static int __catu_probe(struct device *dev, struct resource *res) goto out; }
+ spin_lock_init(&drvdata->spinlock); + /* Setup dma mask for the device */ dma_mask = readl_relaxed(base + CORESIGHT_DEVID) & 0x3f; switch (dma_mask) { diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h index 141feac1c14b..eb7c9189b066 100644 --- a/drivers/hwtracing/coresight/coresight-catu.h +++ b/drivers/hwtracing/coresight/coresight-catu.h @@ -64,6 +64,7 @@ struct catu_drvdata { struct clk *pclk; void __iomem *base; struct coresight_device *csdev; + spinlock_t spinlock; int irq; };