diff mbox series

[3/4] coresight/etm3x: disallow altering config via sysfs while enabled

Message ID 20241221165934.1161856-4-yeoreum.yun@arm.com (mailing list archive)
State New
Headers show
Series small fix for configuaring etm csdev via sysfs | expand

Commit Message

Yeoreum Yun Dec. 21, 2024, 4:59 p.m. UTC
When etm3x configuration is modified via sysfs while etm3x is being
enabled via perf, enabled etm3x could run with different configuration
from perf_event.

To address this, disallow altering config via sysfs while csdev is enabled.

Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
 .../coresight/coresight-etm3x-sysfs.c         | 120 ++++++++++++++++++
 1 file changed, 120 insertions(+)
diff mbox series

Patch

diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index 68c644be9813..b3ae9aba7490 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -75,6 +75,9 @@  static ssize_t reset_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	if (val) {
 		spin_lock(&drvdata->spinlock);
 		memset(config, 0, sizeof(struct etm_config));
@@ -117,6 +120,9 @@  static ssize_t mode_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->mode = val & ETM_MODE_ALL;
 
@@ -202,7 +208,12 @@  static ssize_t trigger_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->trigger_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
 
 	return size;
 }
@@ -232,7 +243,12 @@  static ssize_t enable_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->enable_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
 
 	return size;
 }
@@ -262,7 +278,12 @@  static ssize_t fifofull_level_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->fifofull_level = val;
+	spin_unlock(&drvdata->spinlock);
 
 	return size;
 }
@@ -295,6 +316,9 @@  static ssize_t addr_idx_store(struct device *dev,
 	if (val >= drvdata->nr_addr_cmp)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
@@ -343,6 +367,9 @@  static ssize_t addr_single_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
@@ -403,6 +430,9 @@  static ssize_t addr_range_store(struct device *dev,
 	if (val1 > val2)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (idx % 2 != 0) {
@@ -464,6 +494,9 @@  static ssize_t addr_start_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
@@ -518,6 +551,9 @@  static ssize_t addr_stop_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	idx = config->addr_idx;
 	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
@@ -563,6 +599,9 @@  static ssize_t addr_acctype_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->addr_acctype[config->addr_idx] = val;
 	spin_unlock(&drvdata->spinlock);
@@ -597,6 +636,10 @@  static ssize_t cntr_idx_store(struct device *dev,
 
 	if (val >= drvdata->nr_cntr)
 		return -EINVAL;
+
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
@@ -636,6 +679,9 @@  static ssize_t cntr_rld_val_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->cntr_rld_val[config->cntr_idx] = val;
 	spin_unlock(&drvdata->spinlock);
@@ -671,6 +717,9 @@  static ssize_t cntr_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->cntr_event[config->cntr_idx] = val & ETM_EVENT_MASK;
 	spin_unlock(&drvdata->spinlock);
@@ -706,6 +755,9 @@  static ssize_t cntr_rld_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->cntr_rld_event[config->cntr_idx] = val & ETM_EVENT_MASK;
 	spin_unlock(&drvdata->spinlock);
@@ -752,6 +804,9 @@  static ssize_t cntr_val_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->cntr_val[config->cntr_idx] = val;
 	spin_unlock(&drvdata->spinlock);
@@ -784,7 +839,13 @@  static ssize_t seq_12_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_12_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_12_event);
@@ -813,7 +874,13 @@  static ssize_t seq_21_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_21_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_21_event);
@@ -842,7 +909,13 @@  static ssize_t seq_23_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_23_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_23_event);
@@ -871,7 +944,13 @@  static ssize_t seq_31_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_31_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_31_event);
@@ -900,7 +979,13 @@  static ssize_t seq_32_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_32_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_32_event);
@@ -929,7 +1014,13 @@  static ssize_t seq_13_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_13_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(seq_13_event);
@@ -975,7 +1066,12 @@  static ssize_t seq_curr_state_store(struct device *dev,
 	if (val > ETM_SEQ_STATE_MAX_VAL)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->seq_curr_state = val;
+	spin_unlock(&drvdata->spinlock);
 
 	return size;
 }
@@ -1008,6 +1104,9 @@  static ssize_t ctxid_idx_store(struct device *dev,
 	if (val >= drvdata->nr_ctxid_cmp)
 		return -EINVAL;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	/*
 	 * Use spinlock to ensure index doesn't change while it gets
 	 * dereferenced multiple times within a spinlock block elsewhere.
@@ -1066,6 +1165,9 @@  static ssize_t ctxid_pid_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
 	spin_lock(&drvdata->spinlock);
 	config->ctxid_pid[config->ctxid_idx] = pid;
 	spin_unlock(&drvdata->spinlock);
@@ -1112,7 +1214,13 @@  static ssize_t ctxid_mask_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->ctxid_mask = val;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(ctxid_mask);
@@ -1141,7 +1249,13 @@  static ssize_t sync_freq_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->sync_freq = val & ETM_SYNC_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(sync_freq);
@@ -1170,7 +1284,13 @@  static ssize_t timestamp_event_store(struct device *dev,
 	if (ret)
 		return ret;
 
+	if (coresight_get_mode(drvdata->csdev))
+		return -EBUSY;
+
+	spin_lock(&drvdata->spinlock);
 	config->timestamp_event = val & ETM_EVENT_MASK;
+	spin_unlock(&drvdata->spinlock);
+
 	return size;
 }
 static DEVICE_ATTR_RW(timestamp_event);