On 26/10/2026 05:48, Amir Ayupov wrote:
From: Leo Yan leo.yan@arm.com
TRCIDR0.NUMEVENT normally encodes the number of events minus one. From ETMv4.3 onwards, including ETE, a zero TRCIDR4.NUMRSPAIR instead means that no events are implemented and NUMEVENT is zero. The sysfs event controls currently interpret this combination as one event and allow writes to unsupported event fields.
Decode NUMEVENT after NUMRSPAIR and store the actual number of events in nr_event. Use the decoded resource count so that older ETM versions, where a zero NUMRSPAIR represents one resource pair, still report at least one event. Update both sysfs event controls to use the actual count and clear their event fields when no events are implemented.
Also correct the instruction event enable mask for the single-event case to use INSTEN[0]. The existing mask uses INSTEN[1], preventing event 0 from being enabled.
This change depends on the recent driver refactoring. With no reported failures, it is not intended for stable backporting.
Signed-off-by: Leo Yan leo.yan@arm.com
.../coresight/coresight-etm4x-core.c | 13 +++++++-- .../coresight/coresight-etm4x-sysfs.c | 29 ++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index e21be6468e954..af017bd8a5477 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -1451,8 +1451,6 @@ static void etm4_init_arch_data(void *info) caps->trccci = !!(etmidr0 & TRCIDR0_TRCCCI); /* RETSTACK, bit[9] Return stack bit */ caps->retstack = !!(etmidr0 & TRCIDR0_RETSTACK);
- /* NUMEVENT, bits[11:10] Number of events field */
- caps->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0); /* QSUPP, bits[16:15] Q element support field */ caps->q_support = FIELD_GET(TRCIDR0_QSUPP_MASK, etmidr0); if (caps->q_support)
@@ -1519,6 +1517,17 @@ static void etm4_init_arch_data(void *info) caps->nr_resource = FIELD_GET(TRCIDR4_NUMRSPAIR_MASK, etmidr4); if ((drvdata->arch < ETM_ARCH_V4_3) || (caps->nr_resource > 0)) caps->nr_resource += 1;
- /*
* NUMEVENT encodes the number of events minus one. From ETMv4.3,* including ETE, NUMRSPAIR == 0 means no events are implemented.* nr_resource already accounts for the pre-ETMv4.3 encoding.*/- if (caps->nr_resource)
caps->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0) + 1;- else
caps->nr_event = 0;- /*
- NUMSSCC, bits[23:20] the number of single-shot
- comparator control for tracing. Read any status regs as these
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c index db9e603f97ba8..fb38f0102290a 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -513,19 +513,22 @@ static ssize_t event_store(struct device *dev, raw_spin_lock(&drvdata->spinlock); switch (caps->nr_event) {
- case 0x0:
- case 0:
sysfs_config->eventctrl0 = 0;break;- case 1: /* EVENT0, bits[7:0] */ sysfs_config->eventctrl0 = val & 0xFF; break;
- case 0x1:
/* EVENT1, bits[15:8] */
- case 2:
sysfs_config->eventctrl0 = val & 0xFFFF; break;/* EVENT1, bits[15:8] */
- case 0x2:
- case 3: /* EVENT2, bits[23:16] */ sysfs_config->eventctrl0 = val & 0xFFFFFF; break;
- case 0x3:
- case 4: /* EVENT3, bits[31:24] */ sysfs_config->eventctrl0 = val; break;
@@ -565,22 +568,22 @@ static ssize_t event_instren_store(struct device *dev, /* start by clearing all instruction event enable bits */ sysfs_config->eventctrl1 &= ~TRCEVENTCTL1R_INSTEN_MASK; switch (caps->nr_event) {
- case 0x0:
/* generate Event element for event 1 */sysfs_config->eventctrl1 |= val & TRCEVENTCTL1R_INSTEN_1;
- case 1:
/* generate Event element for event 0 */ break;sysfs_config->eventctrl1 |= val & TRCEVENTCTL1R_INSTEN_0;
- case 0x1:
/* generate Event element for event 1 and 2 */
- case 2:
sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1); break;/* generate Event element for events 0 and 1 */
- case 0x2:
/* generate Event element for event 1, 2 and 3 */
- case 3:
sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1 | TRCEVENTCTL1R_INSTEN_2); break;/* generate Event element for events 0, 1 and 2 */
- case 0x3:
- case 4: /* generate Event element for all 4 events */ sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1 |
Reviewed-by: James Clark james.clark@linaro.org