* [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event
@ 2026-10-12 23:05 Amir Ayupov
2026-10-12 23:05 ` [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov
` (4 more replies)
0 siblings, 5 replies; 24+ messages in thread
From: Amir Ayupov @ 2026-10-12 23:05 UTC (permalink / raw)
To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin
Cc: Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier,
Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc,
linux-kernel
Add an ETMv4 configuration, pmu_pulse, that drives trace unit external
output 1 on every traced cycle, so a PMU event counting it (TRCEXTOUT1)
can end a fixed-length ETM window, for example with aux-action=pause.
The feature only loads on ETMs whose PMU counts that output.
Changes in v2:
- Split the -EINVAL fix for a configuration that is active but not loaded
on the device into its own patch, with a Fixes tag and an early return
(Leo).
- Match capability flags separately from the device class: a feature
loads on a device that shares one of its classes and has all of its
capabilities, checked once in cscfg_load_feat_csdev() (Leo).
- Report each external output the PMU counts, TRCEXTOUT0-3, instead of
only output 1 (Leo).
- Detect the outputs from TRCIDR0.NUMEVENT and PMCEID0_EL0, and drop the
MIDR list (Leo, James).
- extout_pulse requires CS_CFG_MATCH_CLASS_SRC_ETM4 and
CS_CFG_MATCH_CAP_PMU_EXTOUT(1). It still uses event and output 1:
event 0 is the trace unit trigger, which the TRBE driver treats as
fatal (James).
- Link to v1: https://lore.kernel.org/r/20261001063744.2143819-1-aaupov@fb.com
Tested on Grace/Neoverse V2, pmu_pulse config loaded successfully.
Amir Ayupov (4):
coresight: syscfg: Fail to enable a configuration not loaded on the
device
coresight: syscfg: Match feature capabilities separately from device
class
coresight: etm4x: Report the external outputs the PMU counts
coresight: Add pmu_pulse/extout_pulse
.../trace/coresight/coresight-config.rst | 5 ++
.../trace/coresight/coresight-perf.rst | 19 ++++
drivers/hwtracing/coresight/Makefile | 1 +
.../coresight/coresight-cfg-pmu-pulse.c | 55 ++++++++++++
.../coresight/coresight-cfg-preload.c | 2 +
.../coresight/coresight-cfg-preload.h | 2 +
.../hwtracing/coresight/coresight-config.h | 10 +++
.../hwtracing/coresight/coresight-etm4x-cfg.c | 5 +-
.../coresight/coresight-etm4x-core.c | 32 +++++++
drivers/hwtracing/coresight/coresight-etm4x.h | 3 +
.../coresight/coresight-syscfg-configfs.c | 7 ++
.../hwtracing/coresight/coresight-syscfg.c | 88 +++++++++++--------
12 files changed, 193 insertions(+), 36 deletions(-)
create mode 100644 drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c
base-commit: bc01105ed65d15787b2eb93ac26e8624a2139e35
--
2.52.0
^ permalink raw reply [flat|nested] 24+ messages in thread* [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device 2026-10-12 23:05 [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event Amir Ayupov @ 2026-10-12 23:05 ` Amir Ayupov 2026-10-21 14:09 ` Leo Yan 2026-10-12 23:05 ` [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class Amir Ayupov ` (3 subsequent siblings) 4 siblings, 1 reply; 24+ messages in thread From: Amir Ayupov @ 2026-10-12 23:05 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel cscfg_csdev_enable_active_config() looks up the selected configuration in the device's loaded configurations, and returns success when it is not there. A configuration is only loaded on devices that match at least one of its features, so a perf session or sysfs enable that selects it on any other device runs without the configuration, with no error. Return -EINVAL instead, so enabling the source fails on that device. The function is only called with a non-zero configuration hash, so sources enabled without a configuration are unaffected. Fixes: f8cce2ff3c04 ("coresight: syscfg: Add API to activate and enable configurations") Assisted-by: Devmate:Opus-5.5 Signed-off-by: Amir Ayupov <aaupov@fb.com> --- .../hwtracing/coresight/coresight-syscfg.c | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index 2bfdd7b45e49c..a816c22c87bc8 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -1088,36 +1088,39 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev, raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags); /* - * If found, attempt to enable + * The configuration is active but not loaded on this device, because + * none of its features match the device. Fail rather than trace + * without it. */ - if (config_csdev_active) { + if (!config_csdev_active) + return -EINVAL; + + /* + * Call the generic routine that will program up the internal + * driver structures prior to programming up the hardware. + * This routine takes the driver spinlock saved in the configs. + */ + err = cscfg_csdev_enable_config(config_csdev_active, preset); + if (!err) { /* - * Call the generic routine that will program up the internal - * driver structures prior to programming up the hardware. - * This routine takes the driver spinlock saved in the configs. + * Successful programming. Check the active_cscfg_ctxt + * pointer to ensure no pre-emption disabled it via + * cscfg_csdev_disable_active_config() before + * we could start. + * + * Set enabled if OK, err if not. */ - err = cscfg_csdev_enable_config(config_csdev_active, preset); - if (!err) { - /* - * Successful programming. Check the active_cscfg_ctxt - * pointer to ensure no pre-emption disabled it via - * cscfg_csdev_disable_active_config() before - * we could start. - * - * Set enabled if OK, err if not. - */ - raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags); - if (csdev->active_cscfg_ctxt) - config_csdev_active->enabled = true; - else - err = -EBUSY; - raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags); - } - - if (err) - cscfg_config_desc_put(config_desc); + raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags); + if (csdev->active_cscfg_ctxt) + config_csdev_active->enabled = true; + else + err = -EBUSY; + raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags); } + if (err) + cscfg_config_desc_put(config_desc); + return err; } EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config); -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device 2026-10-12 23:05 ` [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov @ 2026-10-21 14:09 ` Leo Yan 0 siblings, 0 replies; 24+ messages in thread From: Leo Yan @ 2026-10-21 14:09 UTC (permalink / raw) To: Amir Ayupov Cc: James Clark, Suzuki K Poulose, Mike Leach, Alexander Shishkin, Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel On Mon, Oct 12, 2026 at 04:05:20PM -0700, Amir Ayupov wrote: > cscfg_csdev_enable_active_config() looks up the selected configuration in > the device's loaded configurations, and returns success when it is not > there. A configuration is only loaded on devices that match at least one > of its features, so a perf session or sysfs enable that selects it on any > other device runs without the configuration, with no error. > > Return -EINVAL instead, so enabling the source fails on that device. The > function is only called with a non-zero configuration hash, so sources > enabled without a configuration are unaffected. > > Fixes: f8cce2ff3c04 ("coresight: syscfg: Add API to activate and enable configurations") > Assisted-by: Devmate:Opus-5.5 > Signed-off-by: Amir Ayupov <aaupov@fb.com> Reviewed-by: Leo Yan <leo.yan@arm.com> ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class 2026-10-12 23:05 [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event Amir Ayupov 2026-10-12 23:05 ` [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov @ 2026-10-12 23:05 ` Amir Ayupov 2026-10-21 14:39 ` Leo Yan 2026-10-12 23:05 ` [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts Amir Ayupov ` (2 subsequent siblings) 4 siblings, 1 reply; 24+ messages in thread From: Amir Ayupov @ 2026-10-12 23:05 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel A feature loads on a device when the two share any match flag. That works for device classes, where a feature wants any one of them, but not for capabilities a device may or may not have: a feature that sets a class and a capability would still load on a device of that class without the capability. Reserve CS_CFG_MATCH_CAP_MASK for capability flags. A feature now loads on a device that shares one of its other flags and has all of its capabilities. Check this once in cscfg_load_feat_csdev(), which both the feature and the device registration paths call. No capability flags are defined yet, so matching is unchanged. Assisted-by: Devmate:Opus-5.5 Signed-off-by: Amir Ayupov <aaupov@fb.com> --- .../hwtracing/coresight/coresight-config.h | 6 ++++ .../hwtracing/coresight/coresight-syscfg.c | 35 +++++++++++++------ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 90fd937d3bd83..af6ef96b9ae01 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -30,6 +30,12 @@ #define CS_CFG_MATCH_CLASS_SRC_ALL 0x0001 /* match any source */ #define CS_CFG_MATCH_CLASS_SRC_ETM4 0x0002 /* match any ETMv4 device */ +/* + * flags defining device capabilities a feature can require. A feature loads on + * a device that matches one of its classes and has all of its capabilities. + */ +#define CS_CFG_MATCH_CAP_MASK 0x0000ff00 + /* flags defining device instance matching - used in config match desc data. */ #define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */ diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index a816c22c87bc8..1545d64afec01 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -172,7 +172,21 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc } /* load one feature into one coresight device */ +/* + * A feature matches a device that shares one of its class flags and has all of + * the capability flags it requires. + */ +static bool cscfg_match_feat_csdev(u32 feat_flags, u32 csdev_flags) +{ + u32 caps = feat_flags & CS_CFG_MATCH_CAP_MASK; + + return (feat_flags & csdev_flags & ~CS_CFG_MATCH_CAP_MASK) && + (csdev_flags & caps) == caps; +} + +/* Load the feature into the device if it matches, otherwise skip it. */ static int cscfg_load_feat_csdev(struct coresight_device *csdev, + u32 match_flags, struct cscfg_feature_desc *feat_desc, struct cscfg_csdev_feat_ops *ops) { @@ -183,6 +197,9 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev, if (!ops->load_feat) return -EINVAL; + if (!cscfg_match_feat_csdev(feat_desc->match_flags, match_flags)) + return 0; + feat_csdev = cscfg_alloc_csdev_feat(csdev, feat_desc); if (!feat_csdev) return -ENOMEM; @@ -212,11 +229,11 @@ static int cscfg_add_feat_to_csdevs(struct cscfg_feature_desc *feat_desc) int err; list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) { - if (csdev_item->match_flags & feat_desc->match_flags) { - err = cscfg_load_feat_csdev(csdev_item->csdev, feat_desc, &csdev_item->ops); - if (err) - return err; - } + err = cscfg_load_feat_csdev(csdev_item->csdev, + csdev_item->match_flags, feat_desc, + &csdev_item->ops); + if (err) + return err; } return 0; } @@ -739,11 +756,9 @@ static int cscfg_add_feats_csdev(struct coresight_device *csdev, return -EINVAL; list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) { - if (feat_desc->match_flags & match_flags) { - err = cscfg_load_feat_csdev(csdev, feat_desc, ops); - if (err) - break; - } + err = cscfg_load_feat_csdev(csdev, match_flags, feat_desc, ops); + if (err) + break; } return err; } -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class 2026-10-12 23:05 ` [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class Amir Ayupov @ 2026-10-21 14:39 ` Leo Yan 2026-10-25 6:21 ` Amir Ayupov 0 siblings, 1 reply; 24+ messages in thread From: Leo Yan @ 2026-10-21 14:39 UTC (permalink / raw) To: Amir Ayupov Cc: James Clark, Suzuki K Poulose, Mike Leach, Alexander Shishkin, Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel On Mon, Oct 12, 2026 at 04:05:21PM -0700, Amir Ayupov wrote: [...] > --- a/drivers/hwtracing/coresight/coresight-config.h > +++ b/drivers/hwtracing/coresight/coresight-config.h > @@ -30,6 +30,12 @@ > #define CS_CFG_MATCH_CLASS_SRC_ALL 0x0001 /* match any source */ > #define CS_CFG_MATCH_CLASS_SRC_ETM4 0x0002 /* match any ETMv4 device */ It is good to introduce a marco: #define CS_CFG_MATCH_CLASS_MASK GENMASK_U32(7, 0) > +/* > + * flags defining device capabilities a feature can require. A feature loads on > + * a device that matches one of its classes and has all of its capabilities. > + */ > +#define CS_CFG_MATCH_CAP_MASK 0x0000ff00 To make the mask explicitly 32-bit unsigned: #define CS_CFG_MATCH_CAP_MASK GENMASK_U32(15, 8) > + > /* flags defining device instance matching - used in config match desc data. */ > #define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */ Not an issue with this patch, but CS_CFG_MATCH_INST_ANY appears to be unused and could be removed in a separate cleanup patch. > diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c > index a816c22c87bc8..1545d64afec01 100644 > --- a/drivers/hwtracing/coresight/coresight-syscfg.c > +++ b/drivers/hwtracing/coresight/coresight-syscfg.c > @@ -172,7 +172,21 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc > } > > /* load one feature into one coresight device */ > +/* > + * A feature matches a device that shares one of its class flags and has all of > + * the capability flags it requires. > + */ > +static bool cscfg_match_feat_csdev(u32 feat_flags, u32 csdev_flags) > +{ > + u32 caps = feat_flags & CS_CFG_MATCH_CAP_MASK; > + > + return (feat_flags & csdev_flags & ~CS_CFG_MATCH_CAP_MASK) && > + (csdev_flags & caps) == caps; For clearer comparison conditions: /* Class type must be matches */ if ((feat_flags & CS_CFG_MATCH_CLASS_MASK) != (csdev_flags & CS_CFG_MATCH_CLASS_MASK) return false; /* No required capabilities miss from the device */ if (feat_flags & ~csdev_flags & CS_CFG_MATCH_CAP_MASK) return false; return true; Thanks, Leo ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class 2026-10-21 14:39 ` Leo Yan @ 2026-10-25 6:21 ` Amir Ayupov 0 siblings, 0 replies; 24+ messages in thread From: Amir Ayupov @ 2026-10-25 6:21 UTC (permalink / raw) To: Leo Yan Cc: James Clark, Suzuki K Poulose, Mike Leach, Alexander Shishkin, Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel On Wed, 21 Oct 2026 15:39:58 +0100 Leo Yan <leo.yan@arm.com> wrote: > On Mon, Oct 12, 2026 at 04:05:21PM -0700, Amir Ayupov wrote: > > [...] > > > --- a/drivers/hwtracing/coresight/coresight-config.h > > +++ b/drivers/hwtracing/coresight/coresight-config.h > > @@ -30,6 +30,12 @@ > > #define CS_CFG_MATCH_CLASS_SRC_ALL 0x0001 /* match any source */ > > #define CS_CFG_MATCH_CLASS_SRC_ETM4 0x0002 /* match any ETMv4 device */ > > It is good to introduce a marco: > > #define CS_CFG_MATCH_CLASS_MASK GENMASK_U32(7, 0) > > > +/* > > + * flags defining device capabilities a feature can require. A feature loads on > > + * a device that matches one of its classes and has all of its capabilities. > > + */ > > +#define CS_CFG_MATCH_CAP_MASK 0x0000ff00 > > To make the mask explicitly 32-bit unsigned: > > #define CS_CFG_MATCH_CAP_MASK GENMASK_U32(15, 8) > Thanks, will apply in v3. > > + > > /* flags defining device instance matching - used in config match desc data. */ > > #define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */ > > Not an issue with this patch, but CS_CFG_MATCH_INST_ANY appears to be > unused and could be removed in a separate cleanup patch. > Will drop in a separate patch in v3. > > diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c > > index a816c22c87bc8..1545d64afec01 100644 > > --- a/drivers/hwtracing/coresight/coresight-syscfg.c > > +++ b/drivers/hwtracing/coresight/coresight-syscfg.c > > @@ -172,7 +172,21 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc > > } > > > > /* load one feature into one coresight device */ > > +/* > > + * A feature matches a device that shares one of its class flags and has all of > > + * the capability flags it requires. > > + */ > > +static bool cscfg_match_feat_csdev(u32 feat_flags, u32 csdev_flags) > > +{ > > + u32 caps = feat_flags & CS_CFG_MATCH_CAP_MASK; > > + > > + return (feat_flags & csdev_flags & ~CS_CFG_MATCH_CAP_MASK) && > > + (csdev_flags & caps) == caps; > > For clearer comparison conditions: > > /* Class type must be matches */ > if ((feat_flags & CS_CFG_MATCH_CLASS_MASK) != > (csdev_flags & CS_CFG_MATCH_CLASS_MASK) > return false; > > /* No required capabilities miss from the device */ > if (feat_flags & ~csdev_flags & CS_CFG_MATCH_CAP_MASK) > return false; > > return true; > > Thanks, > Leo Yes, that looks cleaner, thanks! Sent using hkml (https://github.com/sjp38/hackermail) ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts 2026-10-12 23:05 [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event Amir Ayupov 2026-10-12 23:05 ` [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov 2026-10-12 23:05 ` [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class Amir Ayupov @ 2026-10-12 23:05 ` Amir Ayupov 2026-10-21 16:43 ` Leo Yan 2026-10-23 9:57 ` James Clark 2026-10-12 23:05 ` [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 0/7] coresight: Pulse an ETM external output for a PMU event Amir Ayupov 4 siblings, 2 replies; 24+ messages in thread From: Amir Ayupov @ 2026-10-12 23:05 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel Some CPUs count the trace unit's external outputs as the PMU common events TRCEXTOUT0-3 (0x4010-0x4013), which lets a configuration drive a PMU event from trace unit events. Other CPUs, Neoverse N1 for example, have no such events, and a feature relying on them would silently do nothing there. Detect at probe, on the trace unit's CPU, which outputs the PMU counts: the trace unit has an external output for each of its events (TRCIDR0.NUMEVENT), and from PMUv3p1, PMCEID0_EL0[63:32] reports which of the common events 0x4000-0x401f are implemented. Per the ETE specification, an implemented TRCEXTOUTn event counts external output n; only whether that output is also an external input is IMPLEMENTATION DEFINED. Add a capability match flag for each output, CS_CFG_MATCH_CAP_PMU_EXTOUT(n), set it on ETMs whose PMU counts that output, and show it in the feature's configfs 'matches' attribute. With capabilities matched separately from the device class, a feature that requires one only loads on those ETMs. Assisted-by: Devmate:Opus-5.5 Signed-off-by: Amir Ayupov <aaupov@fb.com> --- .../hwtracing/coresight/coresight-config.h | 4 +++ .../hwtracing/coresight/coresight-etm4x-cfg.c | 5 ++- .../coresight/coresight-etm4x-core.c | 32 +++++++++++++++++++ drivers/hwtracing/coresight/coresight-etm4x.h | 3 ++ .../coresight/coresight-syscfg-configfs.c | 7 ++++ 5 files changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index af6ef96b9ae01..10e95f5ecc8d9 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -35,6 +35,10 @@ * a device that matches one of its classes and has all of its capabilities. */ #define CS_CFG_MATCH_CAP_MASK 0x0000ff00 +/* trace unit external output n is countable by the PMU as TRCEXTOUTn */ +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT 8 +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_NR 4 /* TRCEXTOUT0-3 */ +#define CS_CFG_MATCH_CAP_PMU_EXTOUT(n) BIT(CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT + (n)) /* flags defining device instance matching - used in config match desc data. */ #define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */ diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c index e1a59b4345052..09a7a6b86968c 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c @@ -174,9 +174,12 @@ static int etm4_cfg_load_feature(struct coresight_device *csdev, int etm4_cscfg_register(struct coresight_device *csdev) { + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); struct cscfg_csdev_feat_ops ops; + u32 match_flags = CS_CFG_ETM4_MATCH_FLAGS; ops.load_feat = &etm4_cfg_load_feature; + match_flags |= (u32)drvdata->pmu_extout << CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT; - return cscfg_register_csdev(csdev, CS_CFG_ETM4_MATCH_FLAGS, &ops); + return cscfg_register_csdev(csdev, match_flags, &ops); } diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 2247ad55d4442..1e78774025d13 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -30,6 +30,7 @@ #include <linux/uaccess.h> #include <linux/perf_event.h> #include <linux/perf/arm_pmu.h> +#include <linux/perf/arm_pmuv3.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/property.h> @@ -1368,6 +1369,35 @@ static void etm4_fixup_wrong_ccitmin(struct etmv4_drvdata *drvdata) } } +/* + * Find the external outputs of this trace unit that the PMU counts as the + * common events TRCEXTOUT0-3. The trace unit has an external output for each + * of its events, and PMCEID0_EL0[63:32] reports the common events + * 0x4000-0x401f from PMUv3p1. + * + * Must run on the CPU that owns the trace unit. + */ +static u8 etm4_pmu_extout(struct etmv4_drvdata *drvdata) +{ + int pmuver = read_pmuver(); + u64 pmceid; + u8 extout = 0; + int n; + + if (!pmuv3_implemented(pmuver) || pmuver < ID_AA64DFR0_EL1_PMUVer_V3P1) + return 0; + + pmceid = read_pmceid0() >> 32; + /* nr_event is TRCIDR0.NUMEVENT, the number of events minus one */ + for (n = 0; n <= drvdata->nr_event; n++) { + if (pmceid & BIT_ULL(ARMV8_PMUV3_PERFCTR_TRCEXTOUT0 + n - + ARMV8_PMUV3_EXT_COMMON_EVENT_BASE)) + extout |= BIT(n); + } + + return extout; +} + static void etm4_init_arch_data(void *info) { u32 etmidr0; @@ -1522,6 +1552,8 @@ static void etm4_init_arch_data(void *info) /* NUMCNTR, bits[30:28] number of counters available for tracing */ drvdata->nr_cntr = FIELD_GET(TRCIDR5_NUMCNTR_MASK, etmidr5); + drvdata->pmu_extout = etm4_pmu_extout(drvdata); + coresight_clear_self_claim_tag_unlocked(csa); etm4_cs_lock(drvdata, csa); cpu_detect_trace_filtering(drvdata); diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index df9e0748d71ec..11d95a4518b88 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -979,6 +979,8 @@ struct etmv4_save_state { * @nrseqstate: The number of sequencer states that are implemented. * @nr_seq_ctrls: The number of sequence state transition control registers. * @nr_event: Indicates how many events the trace unit support. + * @pmu_extout: Bitmap of the external outputs n that the PMU counts as + * TRCEXTOUTn. * @nr_resource:The number of resource selection pairs available for tracing. * @nr_ss_cmp: Number of single-shot comparator controls that are available. * @trcid: value of the current ID for this component. @@ -1045,6 +1047,7 @@ struct etmv4_drvdata { u8 nrseqstate; u8 nr_seq_ctrls; u8 nr_event; + u8 pmu_extout; u8 nr_resource; u8 nr_ss_cmp; u8 trcid; diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c index 2b40e556be872..7893d40f2e9ea 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c @@ -243,6 +243,7 @@ static ssize_t cscfg_feat_matches_show(struct config_item *item, char *page) struct cscfg_fs_feature, group); u32 match_flags = fs_feat->feat_desc->match_flags; int used = 0; + int n; if (match_flags & CS_CFG_MATCH_CLASS_SRC_ALL) used = scnprintf(page, PAGE_SIZE, "SRC_ALL "); @@ -250,6 +251,12 @@ static ssize_t cscfg_feat_matches_show(struct config_item *item, char *page) if (match_flags & CS_CFG_MATCH_CLASS_SRC_ETM4) used += scnprintf(page + used, PAGE_SIZE - used, "SRC_ETMV4 "); + for (n = 0; n < CS_CFG_MATCH_CAP_PMU_EXTOUT_NR; n++) { + if (match_flags & CS_CFG_MATCH_CAP_PMU_EXTOUT(n)) + used += scnprintf(page + used, PAGE_SIZE - used, + "PMU_EXTOUT%d ", n); + } + used += scnprintf(page + used, PAGE_SIZE - used, "\n"); return used; } -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts 2026-10-12 23:05 ` [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts Amir Ayupov @ 2026-10-21 16:43 ` Leo Yan 2026-10-23 9:49 ` James Clark 2026-10-25 6:34 ` Amir Ayupov 2026-10-23 9:57 ` James Clark 1 sibling, 2 replies; 24+ messages in thread From: Leo Yan @ 2026-10-21 16:43 UTC (permalink / raw) To: Amir Ayupov Cc: James Clark, Suzuki K Poulose, Mike Leach, Alexander Shishkin, Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel On Mon, Oct 12, 2026 at 04:05:22PM -0700, Amir Ayupov wrote: [...] > --- a/drivers/hwtracing/coresight/coresight-config.h > +++ b/drivers/hwtracing/coresight/coresight-config.h > @@ -35,6 +35,10 @@ > * a device that matches one of its classes and has all of its capabilities. > */ > #define CS_CFG_MATCH_CAP_MASK 0x0000ff00 > +/* trace unit external output n is countable by the PMU as TRCEXTOUTn */ > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT 8 > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_NR 4 /* TRCEXTOUT0-3 */ > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT(n) BIT(CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT + (n)) We can just use a single capacity for all output singals. It would be good to follow the naming convention in the Arm ARM: #define CS_CFG_MATCH_CAP_TRCEXTOUT BIT(8) > int etm4_cscfg_register(struct coresight_device *csdev) > { > + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > struct cscfg_csdev_feat_ops ops; > + u32 match_flags = CS_CFG_ETM4_MATCH_FLAGS; > > ops.load_feat = &etm4_cfg_load_feature; > + match_flags |= (u32)drvdata->pmu_extout << CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT; > > - return cscfg_register_csdev(csdev, CS_CFG_ETM4_MATCH_FLAGS, &ops); > + return cscfg_register_csdev(csdev, match_flags, &ops); I would suggest to enable the capability bit base on drvdata->caps: if (etm4x_is_ete(drvdata) && drvdata->caps.nr_events) match_flags |= CS_CFG_MATCH_CAP_TRCEXTOUT; For now, we can enable TRCEXTOUT for ETE only, as this should be sufficient to detect the feature safely. I'd like to leave this to James and Mike as I got suggestions from them. Please also rebase onto the latest CoreSight next branch [1], which moves the capability fields into drvdata->caps. I found an issue in the decoding of caps.nr_event; the attached patch fixes it and makes the field hold the actual event count. [1] https://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git branch: next ---8<--- From 95307fa0574b1e0b3922ffa23fe98144b2688496 Mon Sep 17 00:00:00 2001 From: Leo Yan <leo.yan@arm.com> Date: Wed, 21 Oct 2026 17:05:18 +0100 Subject: [PATCH] coresight: etm4x: Fix event count decoding 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: + /* EVENT1, bits[15:8] */ sysfs_config->eventctrl0 = val & 0xFFFF; break; - 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 */ + sysfs_config->eventctrl1 |= val & TRCEVENTCTL1R_INSTEN_0; break; - case 0x1: - /* generate Event element for event 1 and 2 */ + case 2: + /* generate Event element for events 0 and 1 */ sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1); break; - case 0x2: - /* generate Event element for event 1, 2 and 3 */ + case 3: + /* generate Event element for events 0, 1 and 2 */ sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1 | TRCEVENTCTL1R_INSTEN_2); break; - case 0x3: + case 4: /* generate Event element for all 4 events */ sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1 | -- 2.34.1 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts 2026-10-21 16:43 ` Leo Yan @ 2026-10-23 9:49 ` James Clark 2026-10-23 14:00 ` Leo Yan 2026-10-25 6:34 ` Amir Ayupov 1 sibling, 1 reply; 24+ messages in thread From: James Clark @ 2026-10-23 9:49 UTC (permalink / raw) To: Leo Yan, Amir Ayupov Cc: Suzuki K Poulose, Mike Leach, Alexander Shishkin, Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel On 21/10/2026 17:43, Leo Yan wrote: > On Mon, Oct 12, 2026 at 04:05:22PM -0700, Amir Ayupov wrote: > > [...] > >> --- a/drivers/hwtracing/coresight/coresight-config.h >> +++ b/drivers/hwtracing/coresight/coresight-config.h >> @@ -35,6 +35,10 @@ >> * a device that matches one of its classes and has all of its capabilities. >> */ >> #define CS_CFG_MATCH_CAP_MASK 0x0000ff00 >> +/* trace unit external output n is countable by the PMU as TRCEXTOUTn */ >> +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT 8 >> +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_NR 4 /* TRCEXTOUT0-3 */ >> +#define CS_CFG_MATCH_CAP_PMU_EXTOUT(n) BIT(CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT + (n)) Isn't this recreating what GENMASK() and FIELD_PREP() does? Can we use that instead? > > We can just use a single capacity for all output singals. It would be > good to follow the naming convention in the Arm ARM: > > #define CS_CFG_MATCH_CAP_TRCEXTOUT BIT(8) > >> int etm4_cscfg_register(struct coresight_device *csdev) >> { >> + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); >> struct cscfg_csdev_feat_ops ops; >> + u32 match_flags = CS_CFG_ETM4_MATCH_FLAGS; >> >> ops.load_feat = &etm4_cfg_load_feature; >> + match_flags |= (u32)drvdata->pmu_extout << CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT; >> >> - return cscfg_register_csdev(csdev, CS_CFG_ETM4_MATCH_FLAGS, &ops); >> + return cscfg_register_csdev(csdev, match_flags, &ops); > > I would suggest to enable the capability bit base on drvdata->caps: > > if (etm4x_is_ete(drvdata) && drvdata->caps.nr_events) > match_flags |= CS_CFG_MATCH_CAP_TRCEXTOUT; > > For now, we can enable TRCEXTOUT for ETE only, as this should be > sufficient to detect the feature safely. I'd like to leave this to > James and Mike as I got suggestions from them. ETE only makes sense to me. > > Please also rebase onto the latest CoreSight next branch [1], which > moves the capability fields into drvdata->caps. I found an issue in the > decoding of caps.nr_event; the attached patch fixes it and makes the > field hold the actual event count. > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git branch: next > > ---8<--- > > From 95307fa0574b1e0b3922ffa23fe98144b2688496 Mon Sep 17 00:00:00 2001 > From: Leo Yan <leo.yan@arm.com> > Date: Wed, 21 Oct 2026 17:05:18 +0100 > Subject: [PATCH] coresight: etm4x: Fix event count decoding > > 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: > + /* EVENT1, bits[15:8] */ > sysfs_config->eventctrl0 = val & 0xFFFF; > break; > - 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 */ > + sysfs_config->eventctrl1 |= val & TRCEVENTCTL1R_INSTEN_0; > break; > - case 0x1: > - /* generate Event element for event 1 and 2 */ > + case 2: > + /* generate Event element for events 0 and 1 */ > sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | > TRCEVENTCTL1R_INSTEN_1); > break; > - case 0x2: > - /* generate Event element for event 1, 2 and 3 */ > + case 3: > + /* generate Event element for events 0, 1 and 2 */ > sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | > TRCEVENTCTL1R_INSTEN_1 | > TRCEVENTCTL1R_INSTEN_2); > break; > - case 0x3: > + case 4: > /* generate Event element for all 4 events */ > sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | > TRCEVENTCTL1R_INSTEN_1 | ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts 2026-10-23 9:49 ` James Clark @ 2026-10-23 14:00 ` Leo Yan 0 siblings, 0 replies; 24+ messages in thread From: Leo Yan @ 2026-10-23 14:00 UTC (permalink / raw) To: James Clark Cc: Amir Ayupov, Suzuki K Poulose, Mike Leach, Alexander Shishkin, Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel On Fri, Oct 23, 2026 at 10:49:40AM +0100, James Clark wrote: [...] > > > * a device that matches one of its classes and has all of its capabilities. > > > */ > > > #define CS_CFG_MATCH_CAP_MASK 0x0000ff00 > > > +/* trace unit external output n is countable by the PMU as TRCEXTOUTn */ > > > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT 8 > > > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_NR 4 /* TRCEXTOUT0-3 */ > > > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT(n) BIT(CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT + (n)) > > Isn't this recreating what GENMASK() and FIELD_PREP() does? Can we use that > instead? TBC, are you suggesting using separate capability bits to represent TRCEXTOUT0-3? Why can't we use a single capability bit to indicate whether the feature is supported and caps->num_event to indicate the number of external output signals? ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts 2026-10-21 16:43 ` Leo Yan 2026-10-23 9:49 ` James Clark @ 2026-10-25 6:34 ` Amir Ayupov 1 sibling, 0 replies; 24+ messages in thread From: Amir Ayupov @ 2026-10-25 6:34 UTC (permalink / raw) To: Leo Yan Cc: James Clark, Suzuki K Poulose, Mike Leach, Alexander Shishkin, Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel On Wed, 21 Oct 2026 17:43:32 +0100 Leo Yan <leo.yan@arm.com> wrote: > On Mon, Oct 12, 2026 at 04:05:22PM -0700, Amir Ayupov wrote: > > [...] > > > --- a/drivers/hwtracing/coresight/coresight-config.h > > +++ b/drivers/hwtracing/coresight/coresight-config.h > > @@ -35,6 +35,10 @@ > > * a device that matches one of its classes and has all of its capabilities. > > */ > > #define CS_CFG_MATCH_CAP_MASK 0x0000ff00 > > +/* trace unit external output n is countable by the PMU as TRCEXTOUTn */ > > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT 8 > > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_NR 4 /* TRCEXTOUT0-3 */ > > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT(n) BIT(CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT + (n)) > > We can just use a single capacity for all output singals. It would be > good to follow the naming convention in the Arm ARM: > > #define CS_CFG_MATCH_CAP_TRCEXTOUT BIT(8) > Yes, single bit works. > > int etm4_cscfg_register(struct coresight_device *csdev) > > { > > + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > > struct cscfg_csdev_feat_ops ops; > > + u32 match_flags = CS_CFG_ETM4_MATCH_FLAGS; > > > > ops.load_feat = &etm4_cfg_load_feature; > > + match_flags |= (u32)drvdata->pmu_extout << CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT; > > > > - return cscfg_register_csdev(csdev, CS_CFG_ETM4_MATCH_FLAGS, &ops); > > + return cscfg_register_csdev(csdev, match_flags, &ops); > > I would suggest to enable the capability bit base on drvdata->caps: > > if (etm4x_is_ete(drvdata) && drvdata->caps.nr_events) > match_flags |= CS_CFG_MATCH_CAP_TRCEXTOUT; > > For now, we can enable TRCEXTOUT for ETE only, as this should be > sufficient to detect the feature safely. I'd like to leave this to > James and Mike as I got suggestions from them. I'll keep an extra condition that PMU must also implement TRCEXTOUT for each of the nr_events outputs. Otherwise it'll start but the pause event would never fire. I'll also use pmuv3_event_implemented helper suggested by James but let me know if I should just check is_ete && nr_events. > > Please also rebase onto the latest CoreSight next branch [1], which > moves the capability fields into drvdata->caps. I found an issue in the > decoding of caps.nr_event; the attached patch fixes it and makes the > field hold the actual event count. Rebased in v3. > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git branch: next > > ---8<--- > > From 95307fa0574b1e0b3922ffa23fe98144b2688496 Mon Sep 17 00:00:00 2001 > From: Leo Yan <leo.yan@arm.com> > Date: Wed, 21 Oct 2026 17:05:18 +0100 > Subject: [PATCH] coresight: etm4x: Fix event count decoding > > 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: > + /* EVENT1, bits[15:8] */ > sysfs_config->eventctrl0 = val & 0xFFFF; > break; > - 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 */ > + sysfs_config->eventctrl1 |= val & TRCEVENTCTL1R_INSTEN_0; > break; > - case 0x1: > - /* generate Event element for event 1 and 2 */ > + case 2: > + /* generate Event element for events 0 and 1 */ > sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | > TRCEVENTCTL1R_INSTEN_1); > break; > - case 0x2: > - /* generate Event element for event 1, 2 and 3 */ > + case 3: > + /* generate Event element for events 0, 1 and 2 */ > sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | > TRCEVENTCTL1R_INSTEN_1 | > TRCEVENTCTL1R_INSTEN_2); > break; > - case 0x3: > + case 4: > /* generate Event element for all 4 events */ > sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | > TRCEVENTCTL1R_INSTEN_1 | > -- > 2.34.1 Sent using hkml (https://github.com/sjp38/hackermail) ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts 2026-10-12 23:05 ` [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts Amir Ayupov 2026-10-21 16:43 ` Leo Yan @ 2026-10-23 9:57 ` James Clark 1 sibling, 0 replies; 24+ messages in thread From: James Clark @ 2026-10-23 9:57 UTC (permalink / raw) To: Amir Ayupov, Leo Yan, Mike Leach Cc: Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel, Suzuki K Poulose, Alexander Shishkin On 13/10/2026 00:05, Amir Ayupov wrote: > Some CPUs count the trace unit's external outputs as the PMU common > events TRCEXTOUT0-3 (0x4010-0x4013), which lets a configuration drive a > PMU event from trace unit events. Other CPUs, Neoverse N1 for example, > have no such events, and a feature relying on them would silently do > nothing there. > > Detect at probe, on the trace unit's CPU, which outputs the PMU counts: > the trace unit has an external output for each of its events > (TRCIDR0.NUMEVENT), and from PMUv3p1, PMCEID0_EL0[63:32] reports which of > the common events 0x4000-0x401f are implemented. Per the ETE > specification, an implemented TRCEXTOUTn event counts external output n; > only whether that output is also an external input is IMPLEMENTATION > DEFINED. > > Add a capability match flag for each output, > CS_CFG_MATCH_CAP_PMU_EXTOUT(n), set it on ETMs whose PMU counts that > output, and show it in the feature's configfs 'matches' attribute. With > capabilities matched separately from the device class, a feature that > requires one only loads on those ETMs. > > Assisted-by: Devmate:Opus-5.5 > Signed-off-by: Amir Ayupov <aaupov@fb.com> > --- > .../hwtracing/coresight/coresight-config.h | 4 +++ > .../hwtracing/coresight/coresight-etm4x-cfg.c | 5 ++- > .../coresight/coresight-etm4x-core.c | 32 +++++++++++++++++++ > drivers/hwtracing/coresight/coresight-etm4x.h | 3 ++ > .../coresight/coresight-syscfg-configfs.c | 7 ++++ > 5 files changed, 50 insertions(+), 1 deletion(-) > > diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h > index af6ef96b9ae01..10e95f5ecc8d9 100644 > --- a/drivers/hwtracing/coresight/coresight-config.h > +++ b/drivers/hwtracing/coresight/coresight-config.h > @@ -35,6 +35,10 @@ > * a device that matches one of its classes and has all of its capabilities. > */ > #define CS_CFG_MATCH_CAP_MASK 0x0000ff00 > +/* trace unit external output n is countable by the PMU as TRCEXTOUTn */ > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT 8 > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT_NR 4 /* TRCEXTOUT0-3 */ > +#define CS_CFG_MATCH_CAP_PMU_EXTOUT(n) BIT(CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT + (n)) > > /* flags defining device instance matching - used in config match desc data. */ > #define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */ > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c > index e1a59b4345052..09a7a6b86968c 100644 > --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c > +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c > @@ -174,9 +174,12 @@ static int etm4_cfg_load_feature(struct coresight_device *csdev, > > int etm4_cscfg_register(struct coresight_device *csdev) > { > + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > struct cscfg_csdev_feat_ops ops; > + u32 match_flags = CS_CFG_ETM4_MATCH_FLAGS; > > ops.load_feat = &etm4_cfg_load_feature; > + match_flags |= (u32)drvdata->pmu_extout << CS_CFG_MATCH_CAP_PMU_EXTOUT_SHIFT; > > - return cscfg_register_csdev(csdev, CS_CFG_ETM4_MATCH_FLAGS, &ops); > + return cscfg_register_csdev(csdev, match_flags, &ops); > } > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c > index 2247ad55d4442..1e78774025d13 100644 > --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c > +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c > @@ -30,6 +30,7 @@ > #include <linux/uaccess.h> > #include <linux/perf_event.h> > #include <linux/perf/arm_pmu.h> > +#include <linux/perf/arm_pmuv3.h> > #include <linux/platform_device.h> > #include <linux/pm_runtime.h> > #include <linux/property.h> > @@ -1368,6 +1369,35 @@ static void etm4_fixup_wrong_ccitmin(struct etmv4_drvdata *drvdata) > } > } > > +/* > + * Find the external outputs of this trace unit that the PMU counts as the > + * common events TRCEXTOUT0-3. The trace unit has an external output for each > + * of its events, and PMCEID0_EL0[63:32] reports the common events > + * 0x4000-0x401f from PMUv3p1. > + * > + * Must run on the CPU that owns the trace unit. > + */ > +static u8 etm4_pmu_extout(struct etmv4_drvdata *drvdata) > +{ > + int pmuver = read_pmuver(); > + u64 pmceid; > + u8 extout = 0; > + int n; > + > + if (!pmuv3_implemented(pmuver) || pmuver < ID_AA64DFR0_EL1_PMUVer_V3P1) > + return 0; > + > + pmceid = read_pmceid0() >> 32; > + /* nr_event is TRCIDR0.NUMEVENT, the number of events minus one */ > + for (n = 0; n <= drvdata->nr_event; n++) { > + if (pmceid & BIT_ULL(ARMV8_PMUV3_PERFCTR_TRCEXTOUT0 + n - > + ARMV8_PMUV3_EXT_COMMON_EVENT_BASE)) > + extout |= BIT(n); > + } Maybe an pmuv3_event_implemented() function in arm_pmuv3.c would be a better fit for this. It can do something like: if (event > ARMV8_PMUV3_EXT_COMMON_EVENT_BASE) return (event - ARMV8_PMUV3_EXT_COMMON_EVENT_BASE) & pmceid_IDhi; else return event & pmceid_IDlo; etc. > + > + return extout; > +} > + > static void etm4_init_arch_data(void *info) > { > u32 etmidr0; > @@ -1522,6 +1552,8 @@ static void etm4_init_arch_data(void *info) > /* NUMCNTR, bits[30:28] number of counters available for tracing */ > drvdata->nr_cntr = FIELD_GET(TRCIDR5_NUMCNTR_MASK, etmidr5); > > + drvdata->pmu_extout = etm4_pmu_extout(drvdata); > + > coresight_clear_self_claim_tag_unlocked(csa); > etm4_cs_lock(drvdata, csa); > cpu_detect_trace_filtering(drvdata); > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h > index df9e0748d71ec..11d95a4518b88 100644 > --- a/drivers/hwtracing/coresight/coresight-etm4x.h > +++ b/drivers/hwtracing/coresight/coresight-etm4x.h > @@ -979,6 +979,8 @@ struct etmv4_save_state { > * @nrseqstate: The number of sequencer states that are implemented. > * @nr_seq_ctrls: The number of sequence state transition control registers. > * @nr_event: Indicates how many events the trace unit support. > + * @pmu_extout: Bitmap of the external outputs n that the PMU counts as > + * TRCEXTOUTn. > * @nr_resource:The number of resource selection pairs available for tracing. > * @nr_ss_cmp: Number of single-shot comparator controls that are available. > * @trcid: value of the current ID for this component. > @@ -1045,6 +1047,7 @@ struct etmv4_drvdata { > u8 nrseqstate; > u8 nr_seq_ctrls; > u8 nr_event; > + u8 pmu_extout; > u8 nr_resource; > u8 nr_ss_cmp; > u8 trcid; > diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c > index 2b40e556be872..7893d40f2e9ea 100644 > --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c > +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c > @@ -243,6 +243,7 @@ static ssize_t cscfg_feat_matches_show(struct config_item *item, char *page) > struct cscfg_fs_feature, group); > u32 match_flags = fs_feat->feat_desc->match_flags; > int used = 0; > + int n; > > if (match_flags & CS_CFG_MATCH_CLASS_SRC_ALL) > used = scnprintf(page, PAGE_SIZE, "SRC_ALL "); > @@ -250,6 +251,12 @@ static ssize_t cscfg_feat_matches_show(struct config_item *item, char *page) > if (match_flags & CS_CFG_MATCH_CLASS_SRC_ETM4) > used += scnprintf(page + used, PAGE_SIZE - used, "SRC_ETMV4 "); > > + for (n = 0; n < CS_CFG_MATCH_CAP_PMU_EXTOUT_NR; n++) { > + if (match_flags & CS_CFG_MATCH_CAP_PMU_EXTOUT(n)) > + used += scnprintf(page + used, PAGE_SIZE - used, > + "PMU_EXTOUT%d ", n); > + } > + > used += scnprintf(page + used, PAGE_SIZE - used, "\n"); > return used; > } ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse 2026-10-12 23:05 [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event Amir Ayupov ` (2 preceding siblings ...) 2026-10-12 23:05 ` [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts Amir Ayupov @ 2026-10-12 23:05 ` Amir Ayupov 2026-10-13 1:09 ` Daniel Pereira 2026-10-25 6:39 ` [PATCH v3 0/7] coresight: Pulse an ETM external output for a PMU event Amir Ayupov 4 siblings, 1 reply; 24+ messages in thread From: Amir Ayupov @ 2026-10-12 23:05 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel Add ETMv4 configuration 'pmu_pulse' with 'extout_pulse' feature which requires an ETM whose PMU counts external output 1 (CS_CFG_MATCH_CAP_PMU_EXTOUT(1)): event 1 selects the always-true resource and drives TRCEXTOUT1 PMU event which pulses on every cycle while the trace unit is enabled. The intended use is for CSSPGO profiling: a fixed-length ETM strobing window that ends at a PMU event. The window is decoded into branch stack, PMU event is carrying callchains. pmu_pulse allows specifying the window in ETM cycles. Assisted-by: Devmate:Opus-5.5 Signed-off-by: Amir Ayupov <aaupov@fb.com> --- .../trace/coresight/coresight-config.rst | 5 ++ .../trace/coresight/coresight-perf.rst | 19 +++++++ drivers/hwtracing/coresight/Makefile | 1 + .../coresight/coresight-cfg-pmu-pulse.c | 55 +++++++++++++++++++ .../coresight/coresight-cfg-preload.c | 2 + .../coresight/coresight-cfg-preload.h | 2 + 6 files changed, 84 insertions(+) create mode 100644 drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst index 6d5ffa6f73471..3eed728bf0de1 100644 --- a/Documentation/trace/coresight/coresight-config.rst +++ b/Documentation/trace/coresight/coresight-config.rst @@ -129,6 +129,11 @@ The following steps take place in the operation of a configuration. 5) At the end of the perf session, the configuration will be disabled. +The built-in 'pmu_pulse' configuration pulses ETM external output 1 for a PMU +event to count. It only pulses while the ETM is enabled, so combined with AUX +pause and resume the PMU event can time each trace window (see +coresight-perf.rst). + Viewing Configurations and Features =================================== diff --git a/Documentation/trace/coresight/coresight-perf.rst b/Documentation/trace/coresight/coresight-perf.rst index 0a77741a431ef..7163d206f9b36 100644 --- a/Documentation/trace/coresight/coresight-perf.rst +++ b/Documentation/trace/coresight/coresight-perf.rst @@ -109,6 +109,25 @@ Example for triggering AUX pause and resume with PMU event:: -e cycles/aux-action=pause,period=10000000/ \ -e cycles/aux-action=resume,period=1050000/ -- sleep 1 +ETM-timed pause events +~~~~~~~~~~~~~~~~~~~~~~ + +The built-in ``pmu_pulse`` configuration pulses ETM external output 1 on every +cycle of allowed trace, and a PMU event counting that output pauses trace after +``N`` pulses, here 1000 cycles:: + + perf record -T \ + -e cs_etm/pmu_pulse,aux-action=start-paused,timestamp/u \ + -e armv8_pmuv3_0/cpu_cycles,aux-action=resume,period=1050031/u \ + -e armv8_pmuv3_0/trcextout1,aux-action=pause,period=1000,call-graph=fp/u \ + -- ./workload + +Each window is about ``N`` traced cycles plus the pause interrupt latency, so +windows are never empty and a callchain on the pause event is taken where +trace ends. The configuration only loads where the PMU counts ETM external +output 1, which the feature's configfs 'matches' attribute shows as +PMU_EXTOUT1; elsewhere a session selecting it fails to start. + Perf test - Verify kernel and userspace perf CoreSight work ----------------------------------------------------------- diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index ab16d06783a57..568e797ac5a17 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_CORESIGHT) += coresight.o coresight-y := coresight-core.o coresight-etm-perf.o coresight-platform.o \ coresight-sysfs.o coresight-syscfg.o coresight-config.o \ coresight-cfg-preload.o coresight-cfg-afdo.o coresight-cfg-pstop.o \ + coresight-cfg-pmu-pulse.o \ coresight-syscfg-configfs.o coresight-trace-id.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \ diff --git a/drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c b/drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c new file mode 100644 index 0000000000000..3772e5bd6cccf --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Pulse ETM external output 1 on every traced cycle for a PMU event to count. + * Based on coresight-cfg-afdo.c + */ + +#include "coresight-config.h" + +/* ETMv4 includes and features */ +#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) +#include "coresight-etm4x-cfg.h" + +/* + * extout_pulse feature: event 1 selects the always-true resource, so ETM + * external output 1 pulses on every cycle while the trace unit is enabled. A + * PMU event counting that output (TRCEXTOUT1), for example with + * aux-action=pause, then fires after as many traced cycles as its sample + * period. Event 0 is avoided because it is the trace unit trigger, and the + * TRBE driver treats a detected trigger as fatal. + */ +static struct cscfg_regval_desc extout_pulse_regs[] = { + /* event 1: resource selector 1 (always true), drives external output 1 */ + { + .type = CS_CFG_REG_TYPE_STD | CS_CFG_REG_TYPE_VAL_MASK, + .offset = TRCEVENTCTL0R, + .val32 = 0x0100, + .mask32 = 0xff00, + }, + /* end of regs */ +}; + +struct cscfg_feature_desc extout_pulse_etm4x = { + .name = "extout_pulse", + .description = "Pulse external output 1 on every traced cycle.\n", + .match_flags = CS_CFG_MATCH_CLASS_SRC_ETM4 | CS_CFG_MATCH_CAP_PMU_EXTOUT(1), + .nr_regs = ARRAY_SIZE(extout_pulse_regs), + .regs_desc = extout_pulse_regs, +}; + +/* create a pmu_pulse configuration */ + +static const char *pmu_pulse_ref_names[] = { + "extout_pulse", +}; + +struct cscfg_config_desc pmu_pulse_etm4x = { + .name = "pmu_pulse", + .description = "Pulse ETM external output 1 on every traced cycle for the PMU\n" + "to count as TRCEXTOUT1\n", + .nr_feat_refs = ARRAY_SIZE(pmu_pulse_ref_names), + .feat_ref_names = pmu_pulse_ref_names, +}; + +/* end of ETM4x configurations */ +#endif /* IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) */ diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.c b/drivers/hwtracing/coresight/coresight-cfg-preload.c index 4980e68483c5b..a9a60a1c40845 100644 --- a/drivers/hwtracing/coresight/coresight-cfg-preload.c +++ b/drivers/hwtracing/coresight/coresight-cfg-preload.c @@ -14,6 +14,7 @@ static struct cscfg_feature_desc *preload_feats[] = { #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) &strobe_etm4x, &gen_etrig_etm4x, + &extout_pulse_etm4x, #endif NULL }; @@ -22,6 +23,7 @@ static struct cscfg_config_desc *preload_cfgs[] = { #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) &afdo_etm4x, &pstop_etm4x, + &pmu_pulse_etm4x, #endif NULL }; diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.h b/drivers/hwtracing/coresight/coresight-cfg-preload.h index 291ba530a6a52..0058627f65ae5 100644 --- a/drivers/hwtracing/coresight/coresight-cfg-preload.h +++ b/drivers/hwtracing/coresight/coresight-cfg-preload.h @@ -12,4 +12,6 @@ extern struct cscfg_feature_desc strobe_etm4x; extern struct cscfg_config_desc afdo_etm4x; extern struct cscfg_feature_desc gen_etrig_etm4x; extern struct cscfg_config_desc pstop_etm4x; +extern struct cscfg_feature_desc extout_pulse_etm4x; +extern struct cscfg_config_desc pmu_pulse_etm4x; #endif -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse 2026-10-12 23:05 ` [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse Amir Ayupov @ 2026-10-13 1:09 ` Daniel Pereira 2026-10-25 6:38 ` Amir Ayupov 0 siblings, 1 reply; 24+ messages in thread From: Daniel Pereira @ 2026-10-13 1:09 UTC (permalink / raw) To: Amir Ayupov Cc: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin, Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel On Mon, Oct 12, 2026 at 04:05:23PM -0700, Amir Ayupov wrote: [...] > + perf record -T \ > + -e cs_etm/pmu_pulse,aux-action=start-paused,timestamp/u \ > + -e armv8_pmuv3_0/cpu_cycles,aux-action=resume,period=1050031/u \ > + -e armv8_pmuv3_0/trcextout1,aux-action=pause,period=1000,call-graph=fp/u \ > + -- ./workload The CPU PMU name depends on the system: armv8_pmuv3_0 is what ACPI systems get, while on devicetree systems it comes from the compatible string, e.g. armv8_pmuv3 or armv8_cortex_a76. Maybe add a sentence after the example, along the lines of: The CPU PMU name depends on the system; the available PMUs are listed under /sys/bus/event_source/devices/. I applied the documentation hunks and built htmldocs, no new warnings. With or without the above, for the documentation part: Reviewed-by: Daniel Pereira <danielmaraboo@gmail.com> Thanks, Daniel ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse 2026-10-13 1:09 ` Daniel Pereira @ 2026-10-25 6:38 ` Amir Ayupov 0 siblings, 0 replies; 24+ messages in thread From: Amir Ayupov @ 2026-10-25 6:38 UTC (permalink / raw) To: Daniel Pereira Cc: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin, Jonathan Corbet, Randy Dunlap, Shuah Khan, coresight, linux-arm-kernel, linux-doc, linux-kernel On Mon, 12 Oct 2026 22:09:35 -0300 Daniel Pereira <danielmaraboo@gmail.com> wrote: > On Mon, Oct 12, 2026 at 04:05:23PM -0700, Amir Ayupov wrote: > [...] > > + perf record -T \ > > + -e cs_etm/pmu_pulse,aux-action=start-paused,timestamp/u \ > > + -e armv8_pmuv3_0/cpu_cycles,aux-action=resume,period=1050031/u \ > > + -e armv8_pmuv3_0/trcextout1,aux-action=pause,period=1000,call-graph=fp/u \ > > + -- ./workload > > The CPU PMU name depends on the system: armv8_pmuv3_0 is what ACPI > systems get, while on devicetree systems it comes from the compatible > string, e.g. armv8_pmuv3 or armv8_cortex_a76. Maybe add a sentence > after the example, along the lines of: > > The CPU PMU name depends on the system; the available PMUs are > listed under /sys/bus/event_source/devices/. I'd rather drop PMU specifiers as this is not something this patch series focuses on, and examples above avoid them too. > > I applied the documentation hunks and built htmldocs, no new warnings. > With or without the above, for the documentation part: > > Reviewed-by: Daniel Pereira <danielmaraboo@gmail.com> > > Thanks, > Daniel Sent using hkml (https://github.com/sjp38/hackermail) ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 0/7] coresight: Pulse an ETM external output for a PMU event 2026-10-12 23:05 [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event Amir Ayupov ` (3 preceding siblings ...) 2026-10-12 23:05 ` [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse Amir Ayupov @ 2026-10-25 6:39 ` Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 1/7] coresight: etm4x: Fix event count decoding Amir Ayupov ` (6 more replies) 4 siblings, 7 replies; 24+ messages in thread From: Amir Ayupov @ 2026-10-25 6:39 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Will Deacon, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier, Randy Dunlap, Shuah Khan, Daniel Pereira, coresight, linux-arm-kernel, linux-perf-users, linux-doc, linux-kernel Add an ETMv4 configuration, pmu_pulse, that drives trace unit external output 1 on every traced cycle, so a PMU event counting it (TRCEXTOUT1) can end a fixed-length ETM window, for example with aux-action=pause. The feature only loads on an ETE whose PMU counts its external outputs. Patch 1 is Leo's fix for TRCIDR0.NUMEVENT decoding, which patch 6 relies on for the number of external outputs. Changes in v3: - Rebase onto coresight next, which moves the capability fields into drvdata->caps (Leo). - Carry Leo's "coresight: etm4x: Fix event count decoding" (Leo). - Add Leo's Reviewed-by to "Fail to enable a configuration not loaded on the device". - Define CS_CFG_MATCH_CLASS_MASK and CS_CFG_MATCH_CAP_MASK with GENMASK_U32() and split the match check into early returns (Leo). The class check stays an intersection, as ETMv4 devices register with SRC_ALL | SRC_ETM4 while the built-in features only set SRC_ETM4. - Remove the unused CS_CFG_MATCH_INST_ANY in a separate patch (Leo). - Replace the per-output CS_CFG_MATCH_CAP_PMU_EXTOUT(n) bits with a single CS_CFG_MATCH_CAP_TRCEXTOUT, set on ETE only (Leo, James). - Check the PMU events through a new pmuv3_event_implemented() helper instead of open-coding PMCEID0_EL0 in etm4x (James). - Use PMU-agnostic event names in the documentation example (Daniel). - Add Daniel's Reviewed-by to "Add pmu_pulse/extout_pulse". - Link to v2: https://lore.kernel.org/r/20261012230527.750567-1-aaupov@fb.com Amir Ayupov (6): coresight: syscfg: Fail to enable a configuration not loaded on the device coresight: syscfg: Match feature capabilities separately from device class coresight: syscfg: Remove unused CS_CFG_MATCH_INST_ANY perf: arm_pmuv3: Add pmuv3_event_implemented() coresight: etm4x: Report whether the PMU counts the external outputs coresight: Add pmu_pulse/extout_pulse Leo Yan (1): coresight: etm4x: Fix event count decoding .../trace/coresight/coresight-config.rst | 5 ++ .../trace/coresight/coresight-perf.rst | 15 ++++ drivers/hwtracing/coresight/Makefile | 1 + .../coresight/coresight-cfg-pmu-pulse.c | 55 ++++++++++++ .../coresight/coresight-cfg-preload.c | 2 + .../coresight/coresight-cfg-preload.h | 2 + .../hwtracing/coresight/coresight-config.h | 11 ++- .../hwtracing/coresight/coresight-etm4x-cfg.c | 6 +- .../coresight/coresight-etm4x-core.c | 39 +++++++- .../coresight/coresight-etm4x-sysfs.c | 29 +++--- drivers/hwtracing/coresight/coresight-etm4x.h | 3 + .../coresight/coresight-syscfg-configfs.c | 3 + .../hwtracing/coresight/coresight-syscfg.c | 90 +++++++++++-------- include/linux/perf/arm_pmu.h | 1 - include/linux/perf/arm_pmuv3.h | 22 +++++ 15 files changed, 229 insertions(+), 55 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c base-commit: 343cfcbb3ecfdb80aa576a428cfa3b65ad783842 -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 1/7] coresight: etm4x: Fix event count decoding 2026-10-25 6:39 ` [PATCH v3 0/7] coresight: Pulse an ETM external output for a PMU event Amir Ayupov @ 2026-10-25 6:39 ` Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 2/7] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov ` (5 subsequent siblings) 6 siblings, 0 replies; 24+ messages in thread From: Amir Ayupov @ 2026-10-25 6:39 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Will Deacon, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier, Randy Dunlap, Shuah Khan, Daniel Pereira, coresight, linux-arm-kernel, linux-perf-users, linux-doc, linux-kernel 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: + /* EVENT1, bits[15:8] */ sysfs_config->eventctrl0 = val & 0xFFFF; break; - 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 */ + sysfs_config->eventctrl1 |= val & TRCEVENTCTL1R_INSTEN_0; break; - case 0x1: - /* generate Event element for event 1 and 2 */ + case 2: + /* generate Event element for events 0 and 1 */ sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1); break; - case 0x2: - /* generate Event element for event 1, 2 and 3 */ + case 3: + /* generate Event element for events 0, 1 and 2 */ sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1 | TRCEVENTCTL1R_INSTEN_2); break; - case 0x3: + case 4: /* generate Event element for all 4 events */ sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1 | -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 2/7] coresight: syscfg: Fail to enable a configuration not loaded on the device 2026-10-25 6:39 ` [PATCH v3 0/7] coresight: Pulse an ETM external output for a PMU event Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 1/7] coresight: etm4x: Fix event count decoding Amir Ayupov @ 2026-10-25 6:39 ` Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 3/7] coresight: syscfg: Match feature capabilities separately from device class Amir Ayupov ` (4 subsequent siblings) 6 siblings, 0 replies; 24+ messages in thread From: Amir Ayupov @ 2026-10-25 6:39 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Will Deacon, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier, Randy Dunlap, Shuah Khan, Daniel Pereira, coresight, linux-arm-kernel, linux-perf-users, linux-doc, linux-kernel cscfg_csdev_enable_active_config() looks up the selected configuration in the device's loaded configurations, and returns success when it is not there. A configuration is only loaded on devices that match at least one of its features, so a perf session or sysfs enable that selects it on any other device runs without the configuration, with no error. Return -EINVAL instead, so enabling the source fails on that device. The function is only called with a non-zero configuration hash, so sources enabled without a configuration are unaffected. Fixes: f8cce2ff3c04 ("coresight: syscfg: Add API to activate and enable configurations") Assisted-by: Devmate:Opus-5.5 Signed-off-by: Amir Ayupov <aaupov@fb.com> Reviewed-by: Leo Yan <leo.yan@arm.com> --- .../hwtracing/coresight/coresight-syscfg.c | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index 2bfdd7b45e49c..a816c22c87bc8 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -1088,36 +1088,39 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev, raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags); /* - * If found, attempt to enable + * The configuration is active but not loaded on this device, because + * none of its features match the device. Fail rather than trace + * without it. */ - if (config_csdev_active) { + if (!config_csdev_active) + return -EINVAL; + + /* + * Call the generic routine that will program up the internal + * driver structures prior to programming up the hardware. + * This routine takes the driver spinlock saved in the configs. + */ + err = cscfg_csdev_enable_config(config_csdev_active, preset); + if (!err) { /* - * Call the generic routine that will program up the internal - * driver structures prior to programming up the hardware. - * This routine takes the driver spinlock saved in the configs. + * Successful programming. Check the active_cscfg_ctxt + * pointer to ensure no pre-emption disabled it via + * cscfg_csdev_disable_active_config() before + * we could start. + * + * Set enabled if OK, err if not. */ - err = cscfg_csdev_enable_config(config_csdev_active, preset); - if (!err) { - /* - * Successful programming. Check the active_cscfg_ctxt - * pointer to ensure no pre-emption disabled it via - * cscfg_csdev_disable_active_config() before - * we could start. - * - * Set enabled if OK, err if not. - */ - raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags); - if (csdev->active_cscfg_ctxt) - config_csdev_active->enabled = true; - else - err = -EBUSY; - raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags); - } - - if (err) - cscfg_config_desc_put(config_desc); + raw_spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags); + if (csdev->active_cscfg_ctxt) + config_csdev_active->enabled = true; + else + err = -EBUSY; + raw_spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags); } + if (err) + cscfg_config_desc_put(config_desc); + return err; } EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config); -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 3/7] coresight: syscfg: Match feature capabilities separately from device class 2026-10-25 6:39 ` [PATCH v3 0/7] coresight: Pulse an ETM external output for a PMU event Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 1/7] coresight: etm4x: Fix event count decoding Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 2/7] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov @ 2026-10-25 6:39 ` Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 4/7] coresight: syscfg: Remove unused CS_CFG_MATCH_INST_ANY Amir Ayupov ` (3 subsequent siblings) 6 siblings, 0 replies; 24+ messages in thread From: Amir Ayupov @ 2026-10-25 6:39 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Will Deacon, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier, Randy Dunlap, Shuah Khan, Daniel Pereira, coresight, linux-arm-kernel, linux-perf-users, linux-doc, linux-kernel A feature loads on a device when the two share any match flag. That works for device classes, where a feature wants any one of them, but not for capabilities a device may or may not have: a feature that sets a class and a capability would still load on a device of that class without the capability. Split the match flags into CS_CFG_MATCH_CLASS_MASK for device classes and CS_CFG_MATCH_CAP_MASK for capabilities. A feature now loads on a device that shares one of its classes and has all of its capabilities. Check this once in cscfg_load_feat_csdev(), which both the feature and the device registration paths call. No capability flags are defined yet, so matching is unchanged. Assisted-by: Devmate:Opus-5.5 Signed-off-by: Amir Ayupov <aaupov@fb.com> --- .../hwtracing/coresight/coresight-config.h | 8 ++++ .../hwtracing/coresight/coresight-syscfg.c | 37 +++++++++++++------ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index ae6295e308131..f04e73b91d9a6 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -7,6 +7,7 @@ #ifndef _CORESIGHT_CORESIGHT_CONFIG_H #define _CORESIGHT_CORESIGHT_CONFIG_H +#include <linux/bits.h> #include <linux/cleanup.h> #include <linux/coresight.h> #include <linux/types.h> @@ -30,6 +31,13 @@ */ #define CS_CFG_MATCH_CLASS_SRC_ALL 0x0001 /* match any source */ #define CS_CFG_MATCH_CLASS_SRC_ETM4 0x0002 /* match any ETMv4 device */ +#define CS_CFG_MATCH_CLASS_MASK GENMASK_U32(7, 0) + +/* + * flags defining device capabilities a feature can require. A feature loads on + * a device that matches one of its classes and has all of its capabilities. + */ +#define CS_CFG_MATCH_CAP_MASK GENMASK_U32(15, 8) /* flags defining device instance matching - used in config match desc data. */ #define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */ diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index a816c22c87bc8..3ee104e94a4cd 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -171,8 +171,22 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc return feat_csdev; } -/* load one feature into one coresight device */ +static bool cscfg_match_feat_csdev(u32 feat_flags, u32 csdev_flags) +{ + /* The device must be in one of the feature's classes */ + if (!(feat_flags & csdev_flags & CS_CFG_MATCH_CLASS_MASK)) + return false; + + /* The device must have every capability the feature requires */ + if (feat_flags & ~csdev_flags & CS_CFG_MATCH_CAP_MASK) + return false; + + return true; +} + +/* Load the feature into the device if it matches, otherwise skip it. */ static int cscfg_load_feat_csdev(struct coresight_device *csdev, + u32 match_flags, struct cscfg_feature_desc *feat_desc, struct cscfg_csdev_feat_ops *ops) { @@ -183,6 +197,9 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev, if (!ops->load_feat) return -EINVAL; + if (!cscfg_match_feat_csdev(feat_desc->match_flags, match_flags)) + return 0; + feat_csdev = cscfg_alloc_csdev_feat(csdev, feat_desc); if (!feat_csdev) return -ENOMEM; @@ -212,11 +229,11 @@ static int cscfg_add_feat_to_csdevs(struct cscfg_feature_desc *feat_desc) int err; list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) { - if (csdev_item->match_flags & feat_desc->match_flags) { - err = cscfg_load_feat_csdev(csdev_item->csdev, feat_desc, &csdev_item->ops); - if (err) - return err; - } + err = cscfg_load_feat_csdev(csdev_item->csdev, + csdev_item->match_flags, feat_desc, + &csdev_item->ops); + if (err) + return err; } return 0; } @@ -739,11 +756,9 @@ static int cscfg_add_feats_csdev(struct coresight_device *csdev, return -EINVAL; list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) { - if (feat_desc->match_flags & match_flags) { - err = cscfg_load_feat_csdev(csdev, feat_desc, ops); - if (err) - break; - } + err = cscfg_load_feat_csdev(csdev, match_flags, feat_desc, ops); + if (err) + break; } return err; } -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 4/7] coresight: syscfg: Remove unused CS_CFG_MATCH_INST_ANY 2026-10-25 6:39 ` [PATCH v3 0/7] coresight: Pulse an ETM external output for a PMU event Amir Ayupov ` (2 preceding siblings ...) 2026-10-25 6:39 ` [PATCH v3 3/7] coresight: syscfg: Match feature capabilities separately from device class Amir Ayupov @ 2026-10-25 6:39 ` Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented() Amir Ayupov ` (2 subsequent siblings) 6 siblings, 0 replies; 24+ messages in thread From: Amir Ayupov @ 2026-10-25 6:39 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Will Deacon, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier, Randy Dunlap, Shuah Khan, Daniel Pereira, coresight, linux-arm-kernel, linux-perf-users, linux-doc, linux-kernel CS_CFG_MATCH_INST_ANY has been defined since the system configuration was introduced but is not used by any configuration, feature or device. Remove it. Suggested-by: Leo Yan <leo.yan@arm.com> Assisted-by: Devmate:Opus-5.5 Signed-off-by: Amir Ayupov <aaupov@fb.com> --- drivers/hwtracing/coresight/coresight-config.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index f04e73b91d9a6..220bc54f8e5e1 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -39,9 +39,6 @@ */ #define CS_CFG_MATCH_CAP_MASK GENMASK_U32(15, 8) -/* flags defining device instance matching - used in config match desc data. */ -#define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */ - /* * Limit number of presets in a configuration * This is related to the number of bits (4) we use to select the preset on -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented() 2026-10-25 6:39 ` [PATCH v3 0/7] coresight: Pulse an ETM external output for a PMU event Amir Ayupov ` (3 preceding siblings ...) 2026-10-25 6:39 ` [PATCH v3 4/7] coresight: syscfg: Remove unused CS_CFG_MATCH_INST_ANY Amir Ayupov @ 2026-10-25 6:39 ` Amir Ayupov 2026-10-25 17:05 ` kernel test robot 2026-10-25 6:39 ` [PATCH v3 6/7] coresight: etm4x: Report whether the PMU counts the external outputs Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 7/7] coresight: Add pmu_pulse/extout_pulse Amir Ayupov 6 siblings, 1 reply; 24+ messages in thread From: Amir Ayupov @ 2026-10-25 6:39 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Will Deacon, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier, Randy Dunlap, Shuah Khan, Daniel Pereira, coresight, linux-arm-kernel, linux-perf-users, linux-doc, linux-kernel Drivers outside the PMU driver may need to know whether the local CPU's PMU implements a common event before relying on it, for example a trace unit driver checking that the PMU counts its external outputs as TRCEXTOUTn. Add pmuv3_event_implemented(), which reads PMCEID0/1 on the calling CPU: events 0x0000-0x003f are reported in bits [31:0], and the common events from ARMV8_PMUV3_EXT_COMMON_EVENT_BASE in bits [63:32] from PMUv3p1. Move ARMV8_PMUV3_EXT_COMMON_EVENT_BASE next to the event numbers in arm_pmuv3.h so it is available without CONFIG_ARM_PMU. Suggested-by: James Clark <james.clark@linaro.org> Assisted-by: Devmate:Opus-5.5 Signed-off-by: Amir Ayupov <aaupov@fb.com> --- include/linux/perf/arm_pmu.h | 1 - include/linux/perf/arm_pmuv3.h | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index 02d2c7f45b527..792283d29d7b5 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h @@ -124,7 +124,6 @@ struct arm_pmu { u64 reg_brbidr; #define ARMV8_PMUV3_MAX_COMMON_EVENTS 0x40 DECLARE_BITMAP(pmceid_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS); -#define ARMV8_PMUV3_EXT_COMMON_EVENT_BASE 0x4000 DECLARE_BITMAP(pmceid_ext_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS); /* Only to be used by ACPI probing code */ diff --git a/include/linux/perf/arm_pmuv3.h b/include/linux/perf/arm_pmuv3.h index d698efba28a27..965c40b28dd77 100644 --- a/include/linux/perf/arm_pmuv3.h +++ b/include/linux/perf/arm_pmuv3.h @@ -78,6 +78,9 @@ #define ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND 0x003E #define ARMV8_PMUV3_PERFCTR_STALL_SLOT 0x003F +/* Base of the common events reported in PMCEID{0,1}[63:32] from PMUv3p1 */ +#define ARMV8_PMUV3_EXT_COMMON_EVENT_BASE 0x4000 + /* Statistical profiling extension microarchitectural events */ #define ARMV8_SPE_PERFCTR_SAMPLE_POP 0x4000 #define ARMV8_SPE_PERFCTR_SAMPLE_FEED 0x4001 @@ -315,4 +318,23 @@ #include <asm/arm_pmuv3.h> +/* + * Whether this CPU's PMU implements a common event, as reported by + * PMCEID{0,1}: events 0x0000-0x003f in bits [31:0], and from PMUv3p1 events + * 0x4000-0x403f in bits [63:32], which read as zero before PMUv3p1. + * Must run on the CPU whose PMU is queried. + */ +static inline bool pmuv3_event_implemented(u16 event) +{ + bool ext = event >= ARMV8_PMUV3_EXT_COMMON_EVENT_BASE; + u16 id = ext ? event - ARMV8_PMUV3_EXT_COMMON_EVENT_BASE : event; + u64 pmceid; + + if (id >= 64 || !pmuv3_implemented(read_pmuver())) + return false; + + pmceid = id < 32 ? read_pmceid0() : read_pmceid1(); + return pmceid & BIT_ULL(id % 32 + (ext ? 32 : 0)); +} + #endif -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v3 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented() 2026-10-25 6:39 ` [PATCH v3 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented() Amir Ayupov @ 2026-10-25 17:05 ` kernel test robot 0 siblings, 0 replies; 24+ messages in thread From: kernel test robot @ 2026-10-25 17:05 UTC (permalink / raw) To: Amir Ayupov, James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: oe-kbuild-all, Will Deacon, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier, Randy Dunlap, Shuah Khan, Daniel Pereira, coresight, linux-arm-kernel, linux-perf-users, linux-doc, linux-kernel Hi Amir, kernel test robot noticed the following build errors: [auto build test ERROR on 343cfcbb3ecfdb80aa576a428cfa3b65ad783842] url: https://github.com/intel-lab-lkp/linux/commits/Amir-Ayupov/coresight-etm4x-Fix-event-count-decoding/20261024-233901 base: 343cfcbb3ecfdb80aa576a428cfa3b65ad783842 patch link: https://lore.kernel.org/r/cd3e622681f7254216b0488f09d2cb2d91a2d8ca.1792907333.git.aaupov%40fb.com patch subject: [PATCH v3 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented() config: arm64-allnoconfig (https://download.01.org/0day-ci/archive/20261026/202610260043.uPhMX80G-lkp@intel.com/config) compiler: aarch64-linux-gcc (GCC) 16.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261026/202610260043.uPhMX80G-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202610260043.uPhMX80G-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from include/kvm/arm_pmu.h:11, from arch/arm64/include/asm/kvm_host.h:38, from arch/arm64/include/asm/arm_pmuv3.h:9, from arch/arm64/kernel/cpufeature.c:80: include/linux/perf/arm_pmuv3.h: In function 'pmuv3_event_implemented': >> include/linux/perf/arm_pmuv3.h:333:26: error: implicit declaration of function 'pmuv3_implemented'; did you mean 'pmuv3_event_implemented'? [-Wimplicit-function-declaration] 333 | if (id >= 64 || !pmuv3_implemented(read_pmuver())) | ^~~~~~~~~~~~~~~~~ | pmuv3_event_implemented >> include/linux/perf/arm_pmuv3.h:333:44: error: implicit declaration of function 'read_pmuver' [-Wimplicit-function-declaration] 333 | if (id >= 64 || !pmuv3_implemented(read_pmuver())) | ^~~~~~~~~~~ >> include/linux/perf/arm_pmuv3.h:336:28: error: implicit declaration of function 'read_pmceid0' [-Wimplicit-function-declaration] 336 | pmceid = id < 32 ? read_pmceid0() : read_pmceid1(); | ^~~~~~~~~~~~ >> include/linux/perf/arm_pmuv3.h:336:45: error: implicit declaration of function 'read_pmceid1' [-Wimplicit-function-declaration] 336 | pmceid = id < 32 ? read_pmceid0() : read_pmceid1(); | ^~~~~~~~~~~~ arch/arm64/include/asm/arm_pmuv3.h: At top level: >> arch/arm64/include/asm/arm_pmuv3.h:49:19: error: conflicting types for 'read_pmuver'; have 'u32(void)' {aka 'unsigned int(void)'} 49 | static inline u32 read_pmuver(void) | ^~~~~~~~~~~ include/linux/perf/arm_pmuv3.h:333:44: note: previous implicit declaration of 'read_pmuver' with type 'int()' 333 | if (id >= 64 || !pmuv3_implemented(read_pmuver())) | ^~~~~~~~~~~ >> arch/arm64/include/asm/arm_pmuv3.h:160:19: error: conflicting types for 'read_pmceid0'; have 'u64(void)' {aka 'long long unsigned int(void)'} 160 | static inline u64 read_pmceid0(void) | ^~~~~~~~~~~~ include/linux/perf/arm_pmuv3.h:336:28: note: previous implicit declaration of 'read_pmceid0' with type 'int()' 336 | pmceid = id < 32 ? read_pmceid0() : read_pmceid1(); | ^~~~~~~~~~~~ >> arch/arm64/include/asm/arm_pmuv3.h:165:19: error: conflicting types for 'read_pmceid1'; have 'u64(void)' {aka 'long long unsigned int(void)'} 165 | static inline u64 read_pmceid1(void) | ^~~~~~~~~~~~ include/linux/perf/arm_pmuv3.h:336:45: note: previous implicit declaration of 'read_pmceid1' with type 'int()' 336 | pmceid = id < 32 ? read_pmceid0() : read_pmceid1(); | ^~~~~~~~~~~~ >> arch/arm64/include/asm/arm_pmuv3.h:170:20: error: conflicting types for 'pmuv3_implemented'; have 'bool(int)' {aka '_Bool(int)'} 170 | static inline bool pmuv3_implemented(int pmuver) | ^~~~~~~~~~~~~~~~~ include/linux/perf/arm_pmuv3.h:333:26: note: previous implicit declaration of 'pmuv3_implemented' with type 'int()' 333 | if (id >= 64 || !pmuv3_implemented(read_pmuver())) | ^~~~~~~~~~~~~~~~~ vim +333 include/linux/perf/arm_pmuv3.h 320 321 /* 322 * Whether this CPU's PMU implements a common event, as reported by 323 * PMCEID{0,1}: events 0x0000-0x003f in bits [31:0], and from PMUv3p1 events 324 * 0x4000-0x403f in bits [63:32], which read as zero before PMUv3p1. 325 * Must run on the CPU whose PMU is queried. 326 */ 327 static inline bool pmuv3_event_implemented(u16 event) 328 { 329 bool ext = event >= ARMV8_PMUV3_EXT_COMMON_EVENT_BASE; 330 u16 id = ext ? event - ARMV8_PMUV3_EXT_COMMON_EVENT_BASE : event; 331 u64 pmceid; 332 > 333 if (id >= 64 || !pmuv3_implemented(read_pmuver())) 334 return false; 335 > 336 pmceid = id < 32 ? read_pmceid0() : read_pmceid1(); 337 return pmceid & BIT_ULL(id % 32 + (ext ? 32 : 0)); 338 } 339 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 6/7] coresight: etm4x: Report whether the PMU counts the external outputs 2026-10-25 6:39 ` [PATCH v3 0/7] coresight: Pulse an ETM external output for a PMU event Amir Ayupov ` (4 preceding siblings ...) 2026-10-25 6:39 ` [PATCH v3 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented() Amir Ayupov @ 2026-10-25 6:39 ` Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 7/7] coresight: Add pmu_pulse/extout_pulse Amir Ayupov 6 siblings, 0 replies; 24+ messages in thread From: Amir Ayupov @ 2026-10-25 6:39 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Will Deacon, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier, Randy Dunlap, Shuah Khan, Daniel Pereira, coresight, linux-arm-kernel, linux-perf-users, linux-doc, linux-kernel Some CPUs count the trace unit's external outputs as the PMU common events TRCEXTOUT0-3 (0x4010-0x4013), which lets a configuration drive a PMU event from trace unit events. Other CPUs, Neoverse N1 for example, have no such events, and a feature relying on them would silently do nothing there. Detect at probe, on the trace unit's CPU, whether the PMU counts every external output: the trace unit has an external output for each of its events (caps.nr_event), and pmuv3_event_implemented() reports whether the PMU implements TRCEXTOUTn. Only check ETE: per its specification, an implemented TRCEXTOUTn event counts external output n, while whether that output is also an external input is IMPLEMENTATION DEFINED. Add a CS_CFG_MATCH_CAP_TRCEXTOUT capability match flag, set it on those trace units, and show it in the feature's configfs 'matches' attribute. With capabilities matched separately from the device class, a feature that requires it only loads on those trace units. Assisted-by: Devmate:Opus-5.5 Signed-off-by: Amir Ayupov <aaupov@fb.com> --- .../hwtracing/coresight/coresight-config.h | 2 ++ .../hwtracing/coresight/coresight-etm4x-cfg.c | 6 ++++- .../coresight/coresight-etm4x-core.c | 26 +++++++++++++++++++ drivers/hwtracing/coresight/coresight-etm4x.h | 3 +++ .../coresight/coresight-syscfg-configfs.c | 3 +++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 220bc54f8e5e1..4cf53230854d0 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -38,6 +38,8 @@ * a device that matches one of its classes and has all of its capabilities. */ #define CS_CFG_MATCH_CAP_MASK GENMASK_U32(15, 8) +/* the PMU counts the trace unit's external outputs as TRCEXTOUTn */ +#define CS_CFG_MATCH_CAP_TRCEXTOUT BIT(8) /* * Limit number of presets in a configuration diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c index 52cb036bb04b9..9e4dc5950c13d 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c @@ -176,9 +176,13 @@ static int etm4_cfg_load_feature(struct coresight_device *csdev, int etm4_cscfg_register(struct coresight_device *csdev) { + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); struct cscfg_csdev_feat_ops ops; + u32 match_flags = CS_CFG_ETM4_MATCH_FLAGS; ops.load_feat = &etm4_cfg_load_feature; + if (drvdata->caps.trcextout) + match_flags |= CS_CFG_MATCH_CAP_TRCEXTOUT; - return cscfg_register_csdev(csdev, CS_CFG_ETM4_MATCH_FLAGS, &ops); + return cscfg_register_csdev(csdev, match_flags, &ops); } diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index af017bd8a5477..cb5fbb0279b88 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -30,6 +30,7 @@ #include <linux/uaccess.h> #include <linux/perf_event.h> #include <linux/perf/arm_pmu.h> +#include <linux/perf/arm_pmuv3.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/property.h> @@ -1399,6 +1400,29 @@ static void etm4_fixup_wrong_ccitmin(struct etmv4_caps *caps) } } +/* + * Whether the PMU counts each external output of this trace unit as + * TRCEXTOUTn. The trace unit has an external output for each of its events. + * Only ETE is checked: per its specification, an implemented TRCEXTOUTn event + * counts external output n. + * + * Must run on the CPU that owns the trace unit. + */ +static bool etm4_pmu_counts_extout(struct etmv4_drvdata *drvdata) +{ + int n; + + if (!etm4x_is_ete(drvdata) || !drvdata->caps.nr_event) + return false; + + for (n = 0; n < drvdata->caps.nr_event; n++) { + if (!pmuv3_event_implemented(ARMV8_PMUV3_PERFCTR_TRCEXTOUT0 + n)) + return false; + } + + return true; +} + static void etm4_init_arch_data(void *info) { u32 etmidr0; @@ -1562,6 +1586,8 @@ static void etm4_init_arch_data(void *info) /* NUMCNTR, bits[30:28] number of counters available for tracing */ caps->nr_cntr = FIELD_GET(TRCIDR5_NUMCNTR_MASK, etmidr5); + caps->trcextout = etm4_pmu_counts_extout(drvdata); + coresight_clear_self_claim_tag_unlocked(csa); etm4_cs_lock(drvdata, csa); cpu_detect_trace_filtering(drvdata); diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index 5417280cdb274..33994ad4b2641 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -868,6 +868,8 @@ enum etm_impdef_type { * @lpoverride: If the implementation can support low-power state over. * @skip_power_up: Indicates if an implementation can skip powering up * the trace unit. + * @trcextout: The trace unit is an ETE whose PMU counts its external + * outputs as TRCEXTOUTn. */ struct etmv4_caps { u8 nr_pe; @@ -907,6 +909,7 @@ struct etmv4_caps { bool atbtrig : 1; bool lpoverride : 1; bool skip_power_up : 1; + bool trcextout : 1; }; /** diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c index 2b40e556be872..7b3800138f625 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c @@ -250,6 +250,9 @@ static ssize_t cscfg_feat_matches_show(struct config_item *item, char *page) if (match_flags & CS_CFG_MATCH_CLASS_SRC_ETM4) used += scnprintf(page + used, PAGE_SIZE - used, "SRC_ETMV4 "); + if (match_flags & CS_CFG_MATCH_CAP_TRCEXTOUT) + used += scnprintf(page + used, PAGE_SIZE - used, "TRCEXTOUT "); + used += scnprintf(page + used, PAGE_SIZE - used, "\n"); return used; } -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v3 7/7] coresight: Add pmu_pulse/extout_pulse 2026-10-25 6:39 ` [PATCH v3 0/7] coresight: Pulse an ETM external output for a PMU event Amir Ayupov ` (5 preceding siblings ...) 2026-10-25 6:39 ` [PATCH v3 6/7] coresight: etm4x: Report whether the PMU counts the external outputs Amir Ayupov @ 2026-10-25 6:39 ` Amir Ayupov 6 siblings, 0 replies; 24+ messages in thread From: Amir Ayupov @ 2026-10-25 6:39 UTC (permalink / raw) To: James Clark, Leo Yan, Suzuki K Poulose, Mike Leach, Alexander Shishkin Cc: Will Deacon, Mark Rutland, Greg Kroah-Hartman, Jonathan Corbet, Mathieu Poirier, Randy Dunlap, Shuah Khan, Daniel Pereira, coresight, linux-arm-kernel, linux-perf-users, linux-doc, linux-kernel Add ETMv4 configuration 'pmu_pulse' with 'extout_pulse' feature which requires an ETE whose PMU counts its external outputs (CS_CFG_MATCH_CAP_TRCEXTOUT): event 1 selects the always-true resource and drives TRCEXTOUT1 PMU event which pulses on every cycle while the trace unit is enabled. Assisted-by: Devmate:Opus-5.5 Signed-off-by: Amir Ayupov <aaupov@fb.com> Reviewed-by: Daniel Pereira <danielmaraboo@gmail.com> --- .../trace/coresight/coresight-config.rst | 5 ++ .../trace/coresight/coresight-perf.rst | 15 +++++ drivers/hwtracing/coresight/Makefile | 1 + .../coresight/coresight-cfg-pmu-pulse.c | 55 +++++++++++++++++++ .../coresight/coresight-cfg-preload.c | 2 + .../coresight/coresight-cfg-preload.h | 2 + 6 files changed, 80 insertions(+) create mode 100644 drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst index 6d5ffa6f73471..3eed728bf0de1 100644 --- a/Documentation/trace/coresight/coresight-config.rst +++ b/Documentation/trace/coresight/coresight-config.rst @@ -129,6 +129,11 @@ The following steps take place in the operation of a configuration. 5) At the end of the perf session, the configuration will be disabled. +The built-in 'pmu_pulse' configuration pulses ETM external output 1 for a PMU +event to count. It only pulses while the ETM is enabled, so combined with AUX +pause and resume the PMU event can time each trace window (see +coresight-perf.rst). + Viewing Configurations and Features =================================== diff --git a/Documentation/trace/coresight/coresight-perf.rst b/Documentation/trace/coresight/coresight-perf.rst index 0a77741a431ef..6770a455c6b59 100644 --- a/Documentation/trace/coresight/coresight-perf.rst +++ b/Documentation/trace/coresight/coresight-perf.rst @@ -109,6 +109,21 @@ Example for triggering AUX pause and resume with PMU event:: -e cycles/aux-action=pause,period=10000000/ \ -e cycles/aux-action=resume,period=1050000/ -- sleep 1 +ETM-timed pause events +~~~~~~~~~~~~~~~~~~~~~~ + +The built-in ``pmu_pulse`` configuration pulses ETM external output 1 on every +cycle of allowed trace, and a PMU event counting that output pauses trace after +``N`` pulses, here 1000 cycles:: + + perf record -a -e cs_etm/pmu_pulse,aux-action=start-paused/u \ + -e cycles/aux-action=resume,period=10000000/u \ + -e trcextout1/aux-action=pause,period=1000/u \ + -- sleep 1 + +Each window is about ``N`` traced cycles plus the pause interrupt latency. +The configuration only loads on an ETE whose PMU counts its external outputs. + Perf test - Verify kernel and userspace perf CoreSight work ----------------------------------------------------------- diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index ab16d06783a57..568e797ac5a17 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_CORESIGHT) += coresight.o coresight-y := coresight-core.o coresight-etm-perf.o coresight-platform.o \ coresight-sysfs.o coresight-syscfg.o coresight-config.o \ coresight-cfg-preload.o coresight-cfg-afdo.o coresight-cfg-pstop.o \ + coresight-cfg-pmu-pulse.o \ coresight-syscfg-configfs.o coresight-trace-id.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \ diff --git a/drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c b/drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c new file mode 100644 index 0000000000000..61472154dd02a --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Pulse ETM external output 1 on every traced cycle for a PMU event to count. + * Based on coresight-cfg-afdo.c + */ + +#include "coresight-config.h" + +/* ETMv4 includes and features */ +#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) +#include "coresight-etm4x-cfg.h" + +/* + * extout_pulse feature: event 1 selects the always-true resource, so ETM + * external output 1 pulses on every cycle while the trace unit is enabled. A + * PMU event counting that output (TRCEXTOUT1), for example with + * aux-action=pause, then fires after as many traced cycles as its sample + * period. Event 0 is avoided because it is the trace unit trigger, and the + * TRBE driver treats a detected trigger as fatal. + */ +static struct cscfg_regval_desc extout_pulse_regs[] = { + /* event 1: resource selector 1 (always true), drives external output 1 */ + { + .type = CS_CFG_REG_TYPE_STD | CS_CFG_REG_TYPE_VAL_MASK, + .offset = TRCEVENTCTL0R, + .val32 = 0x0100, + .mask32 = 0xff00, + }, + /* end of regs */ +}; + +struct cscfg_feature_desc extout_pulse_etm4x = { + .name = "extout_pulse", + .description = "Pulse external output 1 on every traced cycle.\n", + .match_flags = CS_CFG_MATCH_CLASS_SRC_ETM4 | CS_CFG_MATCH_CAP_TRCEXTOUT, + .nr_regs = ARRAY_SIZE(extout_pulse_regs), + .regs_desc = extout_pulse_regs, +}; + +/* create a pmu_pulse configuration */ + +static const char *pmu_pulse_ref_names[] = { + "extout_pulse", +}; + +struct cscfg_config_desc pmu_pulse_etm4x = { + .name = "pmu_pulse", + .description = "Pulse ETM external output 1 on every traced cycle for the PMU\n" + "to count as TRCEXTOUT1\n", + .nr_feat_refs = ARRAY_SIZE(pmu_pulse_ref_names), + .feat_ref_names = pmu_pulse_ref_names, +}; + +/* end of ETM4x configurations */ +#endif /* IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) */ diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.c b/drivers/hwtracing/coresight/coresight-cfg-preload.c index 4980e68483c5b..a9a60a1c40845 100644 --- a/drivers/hwtracing/coresight/coresight-cfg-preload.c +++ b/drivers/hwtracing/coresight/coresight-cfg-preload.c @@ -14,6 +14,7 @@ static struct cscfg_feature_desc *preload_feats[] = { #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) &strobe_etm4x, &gen_etrig_etm4x, + &extout_pulse_etm4x, #endif NULL }; @@ -22,6 +23,7 @@ static struct cscfg_config_desc *preload_cfgs[] = { #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) &afdo_etm4x, &pstop_etm4x, + &pmu_pulse_etm4x, #endif NULL }; diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.h b/drivers/hwtracing/coresight/coresight-cfg-preload.h index 291ba530a6a52..0058627f65ae5 100644 --- a/drivers/hwtracing/coresight/coresight-cfg-preload.h +++ b/drivers/hwtracing/coresight/coresight-cfg-preload.h @@ -12,4 +12,6 @@ extern struct cscfg_feature_desc strobe_etm4x; extern struct cscfg_config_desc afdo_etm4x; extern struct cscfg_feature_desc gen_etrig_etm4x; extern struct cscfg_config_desc pstop_etm4x; +extern struct cscfg_feature_desc extout_pulse_etm4x; +extern struct cscfg_config_desc pmu_pulse_etm4x; #endif -- 2.52.0 ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2026-10-25 17:06 UTC | newest] Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-10-12 23:05 [PATCH v2 0/4] coresight: Pulse an ETM external output for a PMU event Amir Ayupov 2026-10-12 23:05 ` [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov 2026-10-21 14:09 ` Leo Yan 2026-10-12 23:05 ` [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class Amir Ayupov 2026-10-21 14:39 ` Leo Yan 2026-10-25 6:21 ` Amir Ayupov 2026-10-12 23:05 ` [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts Amir Ayupov 2026-10-21 16:43 ` Leo Yan 2026-10-23 9:49 ` James Clark 2026-10-23 14:00 ` Leo Yan 2026-10-25 6:34 ` Amir Ayupov 2026-10-23 9:57 ` James Clark 2026-10-12 23:05 ` [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse Amir Ayupov 2026-10-13 1:09 ` Daniel Pereira 2026-10-25 6:38 ` Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 0/7] coresight: Pulse an ETM external output for a PMU event Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 1/7] coresight: etm4x: Fix event count decoding Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 2/7] coresight: syscfg: Fail to enable a configuration not loaded on the device Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 3/7] coresight: syscfg: Match feature capabilities separately from device class Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 4/7] coresight: syscfg: Remove unused CS_CFG_MATCH_INST_ANY Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented() Amir Ayupov 2026-10-25 17:05 ` kernel test robot 2026-10-25 6:39 ` [PATCH v3 6/7] coresight: etm4x: Report whether the PMU counts the external outputs Amir Ayupov 2026-10-25 6:39 ` [PATCH v3 7/7] coresight: Add pmu_pulse/extout_pulse Amir Ayupov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®