coresight: Pulse an ETM external output for a PMU event
Subsystems (5)
v2 cover coresight: Pulse an ETM external output for a PMU event
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/[email protected]
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
Signature · 1 line
2.52.0
PATCH v2 1/4 coresight: syscfg: Fail to enable a configuration not loaded on the device
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.
--- .../hwtracing/coresight/coresight-syscfg.c | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-)
drivers/hwtracing/coresight/coresight-syscfg.c +28 -25
@@ -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);
Signature · 1 line
2.52.0
Re: [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device
Quoted 6 lines · Amir Ayupov
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.
Quoted 7 lines
Return
-EINVALinstead, 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.5Signed-off-by Amir Ayupov <[email protected]>
Mike Leach
reviewerRE: [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device
In reply to Amir AyupovHi,
Quoted 21 lines
-----Original Message-----
From: Amir Ayupov <[email protected]>
Sent: Tuesday, October 13, 2026 12:05 AM
To: James Clark <[email protected]>; Leo Yan <[email protected]>; Suzuki Poulose <[email protected]>; Mike Leach <[email protected]>; Alexander Shishkin <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>; Jonathan Corbet <[email protected]>; Mathieu Poirier <[email protected]>; Randy Dunlap <[email protected]>; Shuah Khan <[email protected]>; [email protected]; [email protected]; linux- [email protected]; [email protected]
Subject: [PATCH v2 1/4] coresight: syscfg: Fail to enable a configuration not loaded on the device
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.
Quoted 4 lines
Return
-EINVALinstead, 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.
If you look at the original comments - the idea of this function is to enable a configuration on a device if it is present on that device. Not enabling a configuration is _not_ an error. This is a generic function that can cover multiple classes of coresight device.
Moving forwards matching configurations to devices can omit certain devices from the configuration.
For example, a system will have many CTIs, but we may only want to use a specific one or two - possibly to connect etm external outputs to trigger a PE interrupt. Thus the remaining CTIs would not be active in this configuration.
This conflicts with your purpose which I assume is to prevent perf from using ETM sources that cannot load the required configuration.
I think what is actually needed is a "can_activate" function to be run on the ETM/ETE sources at etm_setup_aux time so that none compliant devices can be filtered out of the active cpu mask at that point.
Regards
Mike
Quoted 84 lines
Fixes f8cce2ff3c04 ("coresight: syscfg: Add API to activate and enableconfigurations")
Assisted-by Devmate:Opus-5.5Signed-off-by Amir Ayupov <[email protected]>--- .../hwtracing/coresight/coresight-syscfg.c | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-)drivers/hwtracing/coresight/coresight-syscfg.c +19
-9@@ -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_ctxtdrivers/hwtracing/coresight/coresight-syscfg.c +0
-7-* 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);
drivers/hwtracing/coresight/coresight-syscfg.c +0
-5-if (csdev->active_cscfg_ctxt) - config_csdev_active->enabled = true; -else - err = -EBUSY ; - raw_spin_unlock_irqrestore(&csdev-Quoted 1 line
cscfg_csdev_lock, flags);drivers/hwtracing/coresight/coresight-syscfg.c +9
-5- } - -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
PATCH v2 2/4 coresight: syscfg: Match feature capabilities separately from device class
In reply to Amir AyupovA 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.
--- .../hwtracing/coresight/coresight-config.h | 6 ++++ .../hwtracing/coresight/coresight-syscfg.c | 35 +++++++++++++------ 2 files changed, 31 insertions(+), 10 deletions(-)
drivers/hwtracing/coresight/coresight-config.h +6 -0
@@ -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 */
drivers/hwtracing/coresight/coresight-syscfg.c +25 -10
@@ -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; }
Signature · 1 line
2.52.0
Leo Yan
reviewerRe: [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class
On Mon, Oct 12, 2026 at 04:05:21PM -0700, Amir Ayupov wrote:
[...]
drivers/hwtracing/coresight/coresight-config.h line 31
Quoted 5 lines
drivers/hwtracing/coresight/coresight-config.h +0
-0@@ -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)
drivers/hwtracing/coresight/coresight-config.h line 37
Quoted 5 lines
drivers/hwtracing/coresight/coresight-config.h +5
-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)
drivers/hwtracing/coresight/coresight-config.h line 40
Quoted 3 lines
drivers/hwtracing/coresight/coresight-config.h +1
-0+/* 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.
Quoted 8 lines
drivers/hwtracing/coresight/coresight-syscfg.c +0
-0@@ -172,7 +172,21 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc }/* load one feature into one coresight device */
drivers/hwtracing/coresight/coresight-syscfg.c cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc · line 184
Quoted 10 lines
drivers/hwtracing/coresight/coresight-syscfg.c +10
-0+/* +* 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
Re: [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class
Quoted 22 lines · On Wed, 21 Oct 2026 15:39:58 +0100 Leo Yan <[email protected]> wrote:
On Mon, Oct 12, 2026 at 04:05:21PM -0700, Amir Ayupov wrote:
[...]
drivers/hwtracing/coresight/coresight-config.h line 31
Quoted 5 lines
drivers/hwtracing/coresight/coresight-config.h +0
-0@@ -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)drivers/hwtracing/coresight/coresight-config.h line 37
Quoted 5 lines
drivers/hwtracing/coresight/coresight-config.h +5
-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 0x0000ff00To make the mask explicitly 32-bit unsigned:
Quoted 2 lines
#define CS_CFG_MATCH_CAP_MASK GENMASK_U32(15, 8)
Thanks, will apply in v3.
Quoted 7 lines
drivers/hwtracing/coresight/coresight-config.h line 40
Quoted 3 lines
drivers/hwtracing/coresight/coresight-config.h +1
-0+/* 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_ANYappears to be unused and could be removed in a separate cleanup patch.
Will drop in a separate patch in v3.
Quoted 32 lines
Quoted 8 lines
drivers/hwtracing/coresight/coresight-syscfg.c +0
-0@@ -172,7 +172,21 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc }/* load one feature into one coresight device */ drivers/hwtracing/coresight/coresight-syscfg.c cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc · line 184
Quoted 10 lines
drivers/hwtracing/coresight/coresight-syscfg.c +10
-0+/* +* 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;
Quoted 2 lines
Thanks,
Leo
Yes, that looks cleaner, thanks!
Sent using hkml (https://github.com/sjp38/hackermail)
Suzuki K Poulose
maintainerRe: [PATCH v2 2/4] coresight: syscfg: Match feature capabilities separately from device class
In reply to Leo YanQuoted 52 lines · Leo Yan
On Mon, Oct 12, 2026 at 04:05:21PM -0700, Amir Ayupov wrote:
[...]
drivers/hwtracing/coresight/coresight-config.h line 31
Quoted 5 lines
drivers/hwtracing/coresight/coresight-config.h +0
-0@@ -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)drivers/hwtracing/coresight/coresight-config.h line 37
Quoted 5 lines
drivers/hwtracing/coresight/coresight-config.h +5
-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 0x0000ff00To make the mask explicitly 32-bit unsigned:
#define CS_CFG_MATCH_CAP_MASK GENMASK_U32(15, 8)drivers/hwtracing/coresight/coresight-config.h line 40
Quoted 3 lines
drivers/hwtracing/coresight/coresight-config.h +1
-0+/* 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_ANYappears to be unused and could be removed in a separate cleanup patch.Quoted 8 lines
drivers/hwtracing/coresight/coresight-syscfg.c +0
-0@@ -172,7 +172,21 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc }/* load one feature into one coresight device */ drivers/hwtracing/coresight/coresight-syscfg.c cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc · line 184
Quoted 10 lines
drivers/hwtracing/coresight/coresight-syscfg.c +10
-0+/* +* 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:
Quoted 4 lines
/* Class type must be matches */
if ((feat_flags & CS_CFG_MATCH_CLASS_MASK) !=
(csdev_flags & CS_CFG_MATCH_CLASS_MASK)
return false;Why not use FIELD_GET() to compare to make it more explicit ?
Quoted 4 lines
/* No required capabilities miss from the device */
if (feat_flags & ~csdev_flags & CS_CFG_MATCH_CAP_MASK)
return false;Same here.
Suzuki>
Quoted 4 lines
return true;Thanks,
Leo
PATCH v2 3/4 coresight: etm4x: Report the external outputs the PMU counts
In reply to Amir AyupovSome 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.
--- .../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(-)
drivers/hwtracing/coresight/coresight-config.h +4 -0
@@ -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 */
drivers/hwtracing/coresight/coresight-etm4x-cfg.c +4 -1
@@ -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); }
drivers/hwtracing/coresight/coresight-etm4x-core.c +32 -0
@@ -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);
drivers/hwtracing/coresight/coresight-etm4x.h +3 -0
@@ -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;
drivers/hwtracing/coresight/coresight-syscfg-configfs.c +7 -0
@@ -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; }
Signature · 1 line
2.52.0
Leo Yan
reviewerRe: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts
On Mon, Oct 12, 2026 at 04:05:22PM -0700, Amir Ayupov wrote:
[...]
drivers/hwtracing/coresight/coresight-config.h line 41
Quoted 10 lines
drivers/hwtracing/coresight/coresight-config.h +4
-0@@ -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)
drivers/hwtracing/coresight/coresight-config.h
Quoted 11 lines
drivers/hwtracing/coresight/coresight-config.h +4
-1int 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 <[email protected]>
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.
--- .../coresight/coresight-etm4x-core.c | 13 +++++++-- .../coresight/coresight-etm4x-sysfs.c | 29 ++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-)
drivers/hwtracing/coresight/coresight-etm4x-core.c +11 -2
@@ -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
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +16 -13
@@ -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 |
Signature · 1 line
2.34.1
James Clark
reviewerRe: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts
Quoted 4 lines · Leo Yan
On Mon, Oct 12, 2026 at 04:05:22PM -0700, Amir Ayupov wrote:
[...]
Quoted 10 lines
drivers/hwtracing/coresight/coresight-config.h line 41
Quoted 10 lines
drivers/hwtracing/coresight/coresight-config.h +4
-0@@ -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?
Quoted 20 lines
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)drivers/hwtracing/coresight/coresight-config.h
Quoted 11 lines
drivers/hwtracing/coresight/coresight-config.h +4
-1int 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:
Quoted 6 lines
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.
Quoted 134 lines
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
95307fa0574b1e0b3922ffa23fe98144b2688496Mon Sep 17 00:00:00 2001
From: Leo Yan <[email protected]>
Date: Wed, 21 Oct 2026 17:05:18 +0100
Subject: [PATCH] coresight: etm4x: Fix event count decodingTRCIDR0.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 <[email protected]>--- .../coresight/coresight-etm4x-core.c | 13 +++++++-- .../coresight/coresight-etm4x-sysfs.c | 29 ++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-)drivers/hwtracing/coresight/coresight-etm4x-core.c +11
-2@@ -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 drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +16
-13@@ -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 |
Leo Yan
reviewerRe: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts
On Fri, Oct 23, 2026 at 10:49:40AM +0100, James Clark wrote:
[...]
Quoted 10 lines
Quoted 7 lines
Review
Quoted 7 lines
* a device that matches one of its classes and has all of its capabilities. */
#defineCS_CFG_MATCH_CAP_MASK0x0000ff00(quoted diff) +4
-0+/* 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()andFIELD_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?
James Clark
reviewerRe: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts
Quoted 15 lines · Leo Yan
On Fri, Oct 23, 2026 at 10:49:40AM +0100, James Clark wrote:
[...]
Quoted 10 lines
Quoted 7 lines
Review
Quoted 7 lines
* a device that matches one of its classes and has all of its capabilities. */
#defineCS_CFG_MATCH_CAP_MASK0x0000ff00(quoted diff) +4
-0+/* 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()andFIELD_PREP()does? Can we use that instead?
Quoted 4 lines
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_eventto indicate the number of external output signals?
Just the pattern of *_SHIFT and other stuff to make a bitfield is usually better done with GENMASK(). Or if there are only 4 of them, even defining four BIT()s would be clearer.
But yes if a single bit and caps->num_event works we should do that instead.
Re: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts
In reply to Leo YanQuoted 18 lines · On Wed, 21 Oct 2026 17:43:32 +0100 Leo Yan <[email protected]> wrote:
On Mon, Oct 12, 2026 at 04:05:22PM -0700, Amir Ayupov wrote:
[...]
drivers/hwtracing/coresight/coresight-config.h line 41
Quoted 10 lines
drivers/hwtracing/coresight/coresight-config.h +4
-0@@ -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:
Quoted 2 lines
#define CS_CFG_MATCH_CAP_TRCEXTOUT BIT(8)
Yes, single bit works.
Quoted 14 lines
drivers/hwtracing/coresight/coresight-config.h
Quoted 11 lines
drivers/hwtracing/coresight/coresight-config.h +4
-1int 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:
Quoted 6 lines
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.
Quoted 5 lines
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.
Quoted 131 lines
[1] https://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git branch: next
---8<---
From
95307fa0574b1e0b3922ffa23fe98144b2688496Mon Sep 17 00:00:00 2001
From: Leo Yan <[email protected]>
Date: Wed, 21 Oct 2026 17:05:18 +0100
Subject: [PATCH] coresight: etm4x: Fix event count decodingTRCIDR0.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 <[email protected]>--- .../coresight/coresight-etm4x-core.c | 13 +++++++-- .../coresight/coresight-etm4x-sysfs.c | 29 ++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-)drivers/hwtracing/coresight/coresight-etm4x-core.c +11
-2@@ -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 drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +16
-13@@ -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 |Signature · 1 line
2.34.1
Sent using hkml (https://github.com/sjp38/hackermail)
James Clark
reviewerRe: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts
In reply to Amir AyupovQuoted 94 lines · Amir Ayupov
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.5Signed-off-by Amir Ayupov <[email protected]>--- .../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(-)drivers/hwtracing/coresight/coresight-config.h +4
-0@@ -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 */ drivers/hwtracing/coresight/coresight-etm4x-cfg.c +4
-1@@ -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); }drivers/hwtracing/coresight/coresight-etm4x-core.c +16
-0@@ -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; +
drivers/hwtracing/coresight/coresight-etm4x-core.c static void etm4_fixup_wrong_ccitmin(struct etmv4_drvdata *drvdata) · line 1396
Quoted 10 lines
drivers/hwtracing/coresight/coresight-etm4x-core.c +10
-0+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.
Quoted 62 lines
drivers/hwtracing/coresight/coresight-etm4x-core.c +6
-0+ +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);drivers/hwtracing/coresight/coresight-etm4x.h +3
-0@@ -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;drivers/hwtracing/coresight/coresight-syscfg-configfs.c +7
-0@@ -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; }
Mike Leach
reviewerRE: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU counts
In reply to Amir AyupovHi,
Quoted 29 lines
-----Original Message-----
From: Amir Ayupov <[email protected]>
Sent: Tuesday, October 13, 2026 12:05 AM
To: James Clark <[email protected]>; Leo Yan <[email protected]>; Suzuki Poulose <[email protected]>; Mike Leach <[email protected]>; Alexander Shishkin <[email protected]>
Cc: Jonathan Corbet <[email protected]>; Randy Dunlap <[email protected]>; Shuah Khan <[email protected]>; [email protected]; [email protected]; linux- [email protected]; [email protected]
Subject: [PATCH v2 3/4] coresight: etm4x: Report the external outputs the PMU countsSome 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.
Quoted 7 lines
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.
The ability of the PMU to count extout events is a feature of the PMU, not a feature of the ETM/ETE.
The capability to use extout in a configuration should be predicated solely on the correctly interpreted values of TRCIDR0 and TRCIDR4 - the number of available extout events.
There does not have to be a valid pmu counter for a configuration using extout to work correctly - indeed the extout connections are often implementation defined and sometimes connected via coresight CTI.
If we have a use case that requires extout to trigger PMUs, then clearly we have both trace software and PMU software that must be initialised and run. It seems more relevant to me that the PMU software should check that it can count the extout when it is run, especially given the PMU command line detailed in the next patch is in part " -e armv8_pmuv3_0/trcextout1,aux-action=pause,period=1000," - specifically identifying extout1 as a parameter
Quoted 92 lines
Assisted-by Devmate:Opus-5.5Signed-off-by Amir Ayupov <[email protected]>--- .../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(-)drivers/hwtracing/coresight/coresight-config.h +3
-0@@ -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 */
+#defineCS_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. */
#defineCS_CFG_MATCH_INST_ANY0x80000000/* any instance
of a class */drivers/hwtracing/coresight/coresight-etm4x-cfg.c +3
-1@@ -174,9 +174,12 @@ static int etm4_cfg_load_feature(structcoresight_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);
drivers/hwtracing/coresight/coresight-etm4x-cfg.c +1
-0+return cscfg_register_csdev (csdev, match_flags, &ops); }drivers/hwtracing/coresight/coresight-etm4x-core.c +4
-0@@ -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.
+ */drivers/hwtracing/coresight/coresight-etm4x-core.c +8
-0+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)drivers/hwtracing/coresight/coresight-etm4x-core.c +4
-0+return 0 ; + + pmceid =read_pmceid0 () >>32 ; +/* nr_event is TRCIDR0.NUMEVENT, the number of events minus one
Quoted 1 line
*/
Not necessarily - this value depends on the ETM version.
Quoted 40 lines
drivers/hwtracing/coresight/coresight-etm4x-core.c +2
-0+for (n =0 ; n <= drvdata->nr_event; n++) { + if (pmceid &BIT_ULL(ARMV8_PMUV3_PERFCTR_TRCEXTOUT0 + n -
+ARMV8_PMUV3_EXT_COMMON_EVENT_BASE))drivers/hwtracing/coresight/coresight-etm4x-core.c +8
-0+ 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);drivers/hwtracing/coresight/coresight-etm4x.h +1
-0@@ -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.
drivers/hwtracing/coresight/coresight-etm4x.h struct etmv4_drvdata { · line 1050
Quoted 4 lines
drivers/hwtracing/coresight/coresight-etm4x.h +1
-0@@ -1045,6 +1047,7 @@ struct etmv4_drvdata {u8 nrseqstate;u8 nr_seq_ctrls;u8 nr_event; +u8 pmu_extout;
PMU connection to extout a feature of PMU not the etm. We don't want to add every single extout connection use-case into the ETM driver. Wouldn't scale well.
Regards
Mike.
Quoted 35 lines
drivers/hwtracing/coresight/coresight-etm4x.h +0
-0u8 nr_resource;u8 nr_ss_cmp;u8 trcid;drivers/hwtracing/coresight/coresight-syscfg-configfs.c +1
-0@@ -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;drivers/hwtracing/coresight/coresight-syscfg-configfs.c +6
-0if (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
PATCH v2 4/4 coresight: Add pmu_pulse/extout_pulse
In reply to Amir AyupovAdd 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.
--- .../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
Documentation/trace/coresight/coresight-config.rst +5 -0
@@ -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 ===================================
Documentation/trace/coresight/coresight-perf.rst +19 -0
@@ -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 -----------------------------------------------------------
drivers/hwtracing/coresight/Makefile +1 -0
@@ -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 \
drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c new file +55 -0
55 lines not on this page · raw message
drivers/hwtracing/coresight/coresight-cfg-preload.c +2 -0
@@ -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, #endifNULL };
@@ -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, #endifNULL };
drivers/hwtracing/coresight/coresight-cfg-preload.h +2 -0
@@ -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
Signature · 1 line
2.52.0
Re: [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse
On Mon, Oct 12, 2026 at 04:05:23PM -0700, Amir Ayupov wrote:
[...]
Documentation/trace/coresight/coresight-perf.rst Example for triggering AUX pause and resume with PMU event:: · line 123
Quoted 5 lines
Documentation/trace/coresight/coresight-perf.rst +5
-0+ 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:
Thanks,
Daniel
Re: [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse
Quoted 8 lines · On Mon, 12 Oct 2026 22:09:35 -0300 Daniel Pereira <[email protected]>…
On Mon, Oct 12, 2026 at 04:05:23PM -0700, Amir Ayupov wrote:
[...]Documentation/trace/coresight/coresight-perf.rst Example for triggering AUX pause and resume with PMU event:: · line 123
Quoted 5 lines
Documentation/trace/coresight/coresight-perf.rst +5
-0+ 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
Quoted 7 lines
The CPU PMU name depends on the system:
armv8_pmuv3_0is what ACPI systems get, while on devicetree systems it comes from the compatible string, e.g.armv8_pmuv3orarmv8_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.
Quoted 8 lines
I applied the documentation hunks and built htmldocs, no new warnings. With or without the above, for the documentation part:
Reviewed-by Daniel Pereira <[email protected]>Thanks,
Daniel
Sent using hkml (https://github.com/sjp38/hackermail)
James Clark
reviewerRe: [PATCH v2 4/4] coresight: Add pmu_pulse/extout_pulse
Quoted 15 lines · Amir Ayupov
Quoted 13 lines · On Mon, 12 Oct 2026 22:09:35 -0300 Daniel Pereira <[email protected]>…
On Mon, Oct 12, 2026 at 04:05:23PM -0700, Amir Ayupov wrote:
[...]Documentation/trace/coresight/coresight-perf.rst Example for triggering AUX pause and resume with PMU event:: · line 123
Quoted 5 lines
Documentation/trace/coresight/coresight-perf.rst +5
-0+ 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 \ + -- ./workloadThe CPU PMU name depends on the system:
armv8_pmuv3_0is what ACPI systems get, while on devicetree systems it comes from the compatible string, e.g.armv8_pmuv3orarmv8_cortex_a76. Maybe add a sentence after the example, along the lines of:
Quoted 4 lines
Quoted 2 lines
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 agree. Making the docs overly verbose makes them less useful. And I can't see a use case where a user would get stuck converting this example to their own system.
Quoted 10 lines
Quoted 8 lines
I applied the documentation hunks and built htmldocs, no new warnings. With or without the above, for the documentation part:
Reviewed-by Daniel Pereira <[email protected]>Thanks,
DanielSent using hkml (https://github.com/sjp38/hackermail)
v3 cover coresight: Pulse an ETM external output for a PMU event
In reply to Amir AyupovAdd 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/[email protected]
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
Signature · 1 line
2.52.0
PATCH v3 1/7 coresight: etm4x: Fix event count decoding
From: Leo Yan <[email protected]>
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.
--- .../coresight/coresight-etm4x-core.c | 13 +++++++-- .../coresight/coresight-etm4x-sysfs.c | 29 ++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-)
drivers/hwtracing/coresight/coresight-etm4x-core.c +11 -2
@@ -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
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +16 -13
@@ -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 |
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v3 1/7] coresight: etm4x: Fix event count decoding
Sashiko has reviewed this patch and found no issues.
Quoted 14 lines
From: Leo Yan <[email protected]>
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.
Quoted 8 lines
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 <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
PATCH v3 2/7 coresight: syscfg: Fail to enable a configuration not loaded on the device
In reply to Amir Ayupovcscfg_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.
--- .../hwtracing/coresight/coresight-syscfg.c | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-)
drivers/hwtracing/coresight/coresight-syscfg.c +28 -25
@@ -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);
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v3 2/7] coresight: syscfg: Fail to enable a configuration not loaded on the device
Sashiko has reviewed this patch and found no issues.
Quoted 6 lines
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.
Quoted 7 lines
Return
-EINVALinstead, 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.5Signed-off-by Amir Ayupov <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
PATCH v3 3/7 coresight: syscfg: Match feature capabilities separately from device class
In reply to Amir AyupovA 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.
--- .../hwtracing/coresight/coresight-config.h | 8 ++++ .../hwtracing/coresight/coresight-syscfg.c | 37 +++++++++++++------ 2 files changed, 34 insertions(+), 11 deletions(-)
drivers/hwtracing/coresight/coresight-config.h +8 -0
@@ -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 */
drivers/hwtracing/coresight/coresight-syscfg.c +26 -11
@@ -171,8 +171,22 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_descreturn 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; }
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v3 3/7] coresight: syscfg: Match feature capabilities separately from device class
Sashiko has reviewed this patch and found no issues.
Quoted 13 lines
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_MASKfor device classes andCS_CFG_MATCH_CAP_MASKfor capabilities. A feature now loads on a device that shares one of its classes and has all of its capabilities. Check this once incscfg_load_feat_csdev(), which both the feature and the device registration paths call. No capability flags are defined yet, so matching is unchanged.
Quoted 2 lines
Assisted-by Devmate:Opus-5.5Signed-off-by Amir Ayupov <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3
PATCH v3 4/7 coresight: syscfg: Remove unused CS_CFG_MATCH_INST_ANY
In reply to Amir AyupovCS_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.
--- drivers/hwtracing/coresight/coresight-config.h | 3 --- 1 file changed, 3 deletions(-)
drivers/hwtracing/coresight/coresight-config.h +0 -3
@@ -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
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v3 4/7] coresight: syscfg: Remove unused CS_CFG_MATCH_INST_ANY
Sashiko has reviewed this patch and found no issues.
Quoted 7 lines
CS_CFG_MATCH_INST_ANYhas been defined since the system configuration was introduced but is not used by any configuration, feature or device. Remove it.Suggested-by Leo Yan <[email protected]>Assisted-by Devmate:Opus-5.5Signed-off-by Amir Ayupov <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=4
PATCH v3 5/7 perf: arm_pmuv3: Add pmuv3_event_implemented()
In reply to Amir AyupovDrivers 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.
--- include/linux/perf/arm_pmu.h | 1 - include/linux/perf/arm_pmuv3.h | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-)
include/linux/perf/arm_pmu.h +0 -1
@@ -124,7 +124,6 @@ struct arm_pmu {u64 reg_brbidr;#define ARMV8_PMUV3_MAX_COMMON_EVENTS 0x40DECLARE_BITMAP (pmceid_bitmap,ARMV8_PMUV3_MAX_COMMON_EVENTS ); -#define ARMV8_PMUV3_EXT_COMMON_EVENT_BASE 0x4000DECLARE_BITMAP (pmceid_ext_bitmap,ARMV8_PMUV3_MAX_COMMON_EVENTS );/* Only to be used by ACPI probing code */
include/linux/perf/arm_pmuv3.h +22 -0
@@ -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
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v3 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented()
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Low] perf: arm_pmuv3: circular header inclusion in pmuv3_event_implemented() --
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] perf: arm_pmuv3: circular header inclusion in pmuv3_event_implemented() --
commit fe846ad9d18510169af8401fb7c59990c15ea903
Author: Amir Ayupov <[email protected]>
perf: arm_pmuv3: Add pmuv3_event_implemented()
This commit adds pmuv3_event_implemented() to include/linux/perf/arm_pmuv3.h to allow drivers outside the PMU driver to check whether the local CPU's PMU implements a common event via PMCEID0/1, and moves ARMV8_PMUV3_EXT_COMMON_EVENT_BASE into include/linux/perf/arm_pmuv3.h.
Quoted 4 lines
include/linux/perf/arm_pmuv3.h +0
-0
[ ... ]
Quoted 12 lines
include/linux/perf/arm_pmuv3.h +8
-0@@ -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) +{
include/linux/perf/arm_pmuv3.h line 338
Quoted 10 lines
include/linux/perf/arm_pmuv3.h +10
-0+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 )); +}
[Severity: Low]
Does defining pmuv3_event_implemented() here break arm64 builds due to a circular header dependency when a translation unit includes <asm/arm_pmuv3.h> before <asm/kvm_host.h> or <linux/perf/arm_pmuv3.h>?
For example, arch/arm64/kernel/cpufeature.c includes <asm/arm_pmuv3.h> first:
#include <asm/arm_pmuv3.h>
#include <asm/cpu.h>
#include <asm/cpufeature.h>
#include <asm/cpu_ops.h>
#include <asm/fpsimd.h>
#include <asm/hwcap.h>
#include <asm/insn.h>
#include <asm/kvm_host.h>In arch/arm64/include/asm/arm_pmuv3.h, the header guard __ASM_PMUV3_H is defined and <asm/kvm_host.h> is included at the top before read_pmuver(), read_pmceid0(), read_pmceid1(), and pmuv3_implemented() are defined:
#ifndef __ASM_PMUV3_H
#define __ASM_PMUV3_H
#include <asm/kvm_host.h>That triggers the inclusion chain:
arch/arm64/include/asm/arm_pmuv3.h
-> arch/arm64/include/asm/kvm_host.h
-> include/kvm/arm_pmu.h
-> include/linux/perf/arm_pmuv3.hWhen include/linux/perf/arm_pmuv3.h reaches #include <asm/arm_pmuv3.h>, it is skipped because __ASM_PMUV3_H is already defined, so pmuv3_event_implemented() is compiled before pmuv3_implemented(), read_pmuver(), read_pmceid0(), and read_pmceid1() have been declared.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=5
kernel test robot
build botRe: [PATCH v3 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented()
In reply to Amir Ayupovkernel test robot noticed the following build errors:
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/[email protected]/config) compiler: aarch64-linux-gcc (GCC) 16.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261026/[email protected]/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 <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
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
kernel test robot
build botRe: [PATCH v3 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented()
In reply to Amir Ayupovkernel test robot noticed the following build errors:
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-randconfig-1003-20261026 (https://download.01.org/0day-ci/archive/20261026/[email protected]/config) compiler: aarch64-linux-gcc (GCC) 8.5.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261026/[email protected]/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 <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
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:19: error: implicit declaration of function 'pmuv3_implemented'; did you mean 'pmuv3_event_implemented'? [-Werror=implicit-function-declaration]
if (id >= 64 || !pmuv3_implemented(read_pmuver()))
^~~~~~~~~~~~~~~~~
pmuv3_event_implemented
include/linux/perf/arm_pmuv3.h:333:37: error: implicit declaration of function 'read_pmuver'; did you mean 'read_tcr'? [-Werror=implicit-function-declaration]
if (id >= 64 || !pmuv3_implemented(read_pmuver()))
^~~~~~~~~~~
read_tcr
include/linux/perf/arm_pmuv3.h:336:21: error: implicit declaration of function 'read_pmceid0'; did you mean 'read_cpuid'? [-Werror=implicit-function-declaration]
pmceid = id < 32 ? read_pmceid0() : read_pmceid1();
^~~~~~~~~~~~
read_cpuid
include/linux/perf/arm_pmuv3.h:336:38: error: implicit declaration of function 'read_pmceid1'; did you mean 'read_cpuid'? [-Werror=implicit-function-declaration]
pmceid = id < 32 ? read_pmceid0() : read_pmceid1();
^~~~~~~~~~~~
read_cpuid
In file included from arch/arm64/kernel/cpufeature.c:80:
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'
static inline u32 read_pmuver(void)
^~~~~~~~~~~
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:333:37: note: previous implicit declaration of 'read_pmuver' was here
if (id >= 64 || !pmuv3_implemented(read_pmuver()))
^~~~~~~~~~~
In file included from arch/arm64/kernel/cpufeature.c:80:
>> arch/arm64/include/asm/arm_pmuv3.h:160:19: error: conflicting types for 'read_pmceid0'
static inline u64 read_pmceid0(void)
^~~~~~~~~~~~
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:336:21: note: previous implicit declaration of 'read_pmceid0' was here
pmceid = id < 32 ? read_pmceid0() : read_pmceid1();
^~~~~~~~~~~~
In file included from arch/arm64/kernel/cpufeature.c:80:
>> arch/arm64/include/asm/arm_pmuv3.h:165:19: error: conflicting types for 'read_pmceid1'
static inline u64 read_pmceid1(void)
^~~~~~~~~~~~
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:336:38: note: previous implicit declaration of 'read_pmceid1' was here
pmceid = id < 32 ? read_pmceid0() : read_pmceid1();
^~~~~~~~~~~~
In file included from arch/arm64/kernel/cpufeature.c:80:
>> arch/arm64/include/asm/arm_pmuv3.h:170:20: error: conflicting types for 'pmuv3_implemented'
static inline bool pmuv3_implemented(int pmuver)
^~~~~~~~~~~~~~~~~
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:333:19: note: previous implicit declaration of 'pmuv3_implemented' was here
if (id >= 64 || !pmuv3_implemented(read_pmuver()))
^~~~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3364:21: warning: initialized field overwritten [-Woverride-init]
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ISAR2_EL1, LUT, LUT6, CAP_HWCAP, KERNEL_HWCAP_SVE_LUT6),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3364:21: note: (near initialization for 'arm64_elf_hwcaps[44].matches')
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ISAR2_EL1, LUT, LUT6, CAP_HWCAP, KERNEL_HWCAP_SVE_LUT6),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3366:21: warning: initialized field overwritten [-Woverride-init]
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2p3, CAP_HWCAP, KERNEL_HWCAP_SVE2P3),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3366:21: note: (near initialization for 'arm64_elf_hwcaps[46].matches')
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2p3, CAP_HWCAP, KERNEL_HWCAP_SVE2P3),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3367:21: warning: initialized field overwritten [-Woverride-init]
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2p2, CAP_HWCAP, KERNEL_HWCAP_SVE2P2),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3367:21: note: (near initialization for 'arm64_elf_hwcaps[47].matches')
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2p2, CAP_HWCAP, KERNEL_HWCAP_SVE2P2),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3368:21: warning: initialized field overwritten [-Woverride-init]
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3368:21: note: (near initialization for 'arm64_elf_hwcaps[48].matches')
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3369:21: warning: initialized field overwritten [-Woverride-init]
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3369:21: note: (near initialization for 'arm64_elf_hwcaps[49].matches')
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3370:21: warning: initialized field overwritten [-Woverride-init]
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3370:21: note: (near initialization for 'arm64_elf_hwcaps[50].matches')
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3371:21: warning: initialized field overwritten [-Woverride-init]
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3371:21: note: (near initialization for 'arm64_elf_hwcaps[51].matches')
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~
arch/arm64/kernel/cpufeature.c:3372:21: warning: initialized field overwritten [-Woverride-init]
HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, AES, AES2, CAP_HWCAP, KERNEL_HWCAP_SVE_AES2),
^~~~~~~~~~~~~~~
arch/arm64/kernel/cpufeature.c:3273:14: note: in definition of macro 'HWCAP_CAP_MATCH_ID'
.matches = match, \
^~~~~ arch/arm64/kernel/cpufeature.c:3372:21: note: (near initialization for 'arm64_elf_hwcaps[52].matches')
vim +/read_pmuver +49 arch/arm64/include/asm/arm_pmuv3.h
df29ddf4f04b00 Marc Zyngier 2023-03-17 48
df29ddf4f04b00 Marc Zyngier 2023-03-17 @49 static inline u32 read_pmuver(void)
df29ddf4f04b00 Marc Zyngier 2023-03-17 50 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 51 u64 dfr0 = read_sysreg(id_aa64dfr0_el1);
df29ddf4f04b00 Marc Zyngier 2023-03-17 52
df29ddf4f04b00 Marc Zyngier 2023-03-17 53 return cpuid_feature_extract_unsigned_field(dfr0,
df29ddf4f04b00 Marc Zyngier 2023-03-17 54 ID_AA64DFR0_EL1_PMUVer_SHIFT);
df29ddf4f04b00 Marc Zyngier 2023-03-17 55 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 56
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 57) static inline bool pmuv3_has_icntr(void)
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 58) {
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 59) u64 dfr1 = read_sysreg(id_aa64dfr1_el1);
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 60)
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 61) return !!cpuid_feature_extract_unsigned_field(dfr1,
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 62) ID_AA64DFR1_EL1_PMICNTR_SHIFT);
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 63) }
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 64)
403edfa436286b Ilkka Koskinen 2023-11-02 65 static inline void write_pmcr(u64 val)
df29ddf4f04b00 Marc Zyngier 2023-03-17 66 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 67 write_sysreg(val, pmcr_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 68 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 69
403edfa436286b Ilkka Koskinen 2023-11-02 70 static inline u64 read_pmcr(void)
df29ddf4f04b00 Marc Zyngier 2023-03-17 71 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 72 return read_sysreg(pmcr_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 73 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 74
df29ddf4f04b00 Marc Zyngier 2023-03-17 75 static inline void write_pmselr(u32 val)
df29ddf4f04b00 Marc Zyngier 2023-03-17 76 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 77 write_sysreg(val, pmselr_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 78 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 79
df29ddf4f04b00 Marc Zyngier 2023-03-17 80 static inline void write_pmccntr(u64 val)
df29ddf4f04b00 Marc Zyngier 2023-03-17 81 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 82 write_sysreg(val, pmccntr_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 83 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 84
df29ddf4f04b00 Marc Zyngier 2023-03-17 85 static inline u64 read_pmccntr(void)
df29ddf4f04b00 Marc Zyngier 2023-03-17 86 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 87 return read_sysreg(pmccntr_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 88 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 89
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 90) static inline void write_pmicntr(u64 val)
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 91) {
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 92) write_sysreg_s(val, SYS_PMICNTR_EL0);
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 93) }
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 94)
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 95) static inline u64 read_pmicntr(void)
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 96) {
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 97) return read_sysreg_s(SYS_PMICNTR_EL0);
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 98) }
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 99)
a4a6e2078d85a9 Rob Herring (Arm 2024-07-31 100) static inline void write_pmcntenset(u64 val)
df29ddf4f04b00 Marc Zyngier 2023-03-17 101 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 102 write_sysreg(val, pmcntenset_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 103 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 104
a4a6e2078d85a9 Rob Herring (Arm 2024-07-31 105) static inline void write_pmcntenclr(u64 val)
df29ddf4f04b00 Marc Zyngier 2023-03-17 106 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 107 write_sysreg(val, pmcntenclr_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 108 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 109
a4a6e2078d85a9 Rob Herring (Arm 2024-07-31 110) static inline void write_pmintenset(u64 val)
df29ddf4f04b00 Marc Zyngier 2023-03-17 111 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 112 write_sysreg(val, pmintenset_el1);
df29ddf4f04b00 Marc Zyngier 2023-03-17 113 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 114
a4a6e2078d85a9 Rob Herring (Arm 2024-07-31 115) static inline void write_pmintenclr(u64 val)
df29ddf4f04b00 Marc Zyngier 2023-03-17 116 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 117 write_sysreg(val, pmintenclr_el1);
df29ddf4f04b00 Marc Zyngier 2023-03-17 118 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 119
403edfa436286b Ilkka Koskinen 2023-11-02 120 static inline void write_pmccfiltr(u64 val)
df29ddf4f04b00 Marc Zyngier 2023-03-17 121 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 122 write_sysreg(val, pmccfiltr_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 123 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 124
741ee5284551cf Rob Herring (Arm 2024-07-31 125) static inline u64 read_pmccfiltr(void)
741ee5284551cf Rob Herring (Arm 2024-07-31 126) {
741ee5284551cf Rob Herring (Arm 2024-07-31 127) return read_sysreg(pmccfiltr_el0);
741ee5284551cf Rob Herring (Arm 2024-07-31 128) }
741ee5284551cf Rob Herring (Arm 2024-07-31 129)
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 130) static inline void write_pmicfiltr(u64 val)
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 131) {
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 132) write_sysreg_s(val, SYS_PMICFILTR_EL0);
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 133) }
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 134)
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 135) static inline u64 read_pmicfiltr(void)
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 136) {
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 137) return read_sysreg_s(SYS_PMICFILTR_EL0);
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 138) }
d8226d8cfbaf5e Rob Herring (Arm 2024-07-31 139)
a4a6e2078d85a9 Rob Herring (Arm 2024-07-31 140) static inline void write_pmovsclr(u64 val)
df29ddf4f04b00 Marc Zyngier 2023-03-17 141 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 142 write_sysreg(val, pmovsclr_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 143 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 144
a4a6e2078d85a9 Rob Herring (Arm 2024-07-31 145) static inline u64 read_pmovsclr(void)
df29ddf4f04b00 Marc Zyngier 2023-03-17 146 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 147 return read_sysreg(pmovsclr_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 148 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 149
df29ddf4f04b00 Marc Zyngier 2023-03-17 150 static inline void write_pmuserenr(u32 val)
df29ddf4f04b00 Marc Zyngier 2023-03-17 151 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 152 write_sysreg(val, pmuserenr_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 153 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 154
0bbff9ed81654d Rob Herring (Arm 2024-10-02 155) static inline void write_pmuacr(u64 val)
0bbff9ed81654d Rob Herring (Arm 2024-10-02 156) {
0bbff9ed81654d Rob Herring (Arm 2024-10-02 157) write_sysreg_s(val, SYS_PMUACR_EL1);
0bbff9ed81654d Rob Herring (Arm 2024-10-02 158) }
0bbff9ed81654d Rob Herring (Arm 2024-10-02 159)
403edfa436286b Ilkka Koskinen 2023-11-02 @160 static inline u64 read_pmceid0(void)
df29ddf4f04b00 Marc Zyngier 2023-03-17 161 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 162 return read_sysreg(pmceid0_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 163 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 164
403edfa436286b Ilkka Koskinen 2023-11-02 @165 static inline u64 read_pmceid1(void)
df29ddf4f04b00 Marc Zyngier 2023-03-17 166 {
df29ddf4f04b00 Marc Zyngier 2023-03-17 167 return read_sysreg(pmceid1_el0);
df29ddf4f04b00 Marc Zyngier 2023-03-17 168 }
df29ddf4f04b00 Marc Zyngier 2023-03-17 169
711432770f78e5 Zaid Al-Bassam 2023-03-17 @170 static inline bool pmuv3_implemented(int pmuver)
711432770f78e5 Zaid Al-Bassam 2023-03-17 171 {
711432770f78e5 Zaid Al-Bassam 2023-03-17 172 return !(pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF ||
711432770f78e5 Zaid Al-Bassam 2023-03-17 173 pmuver == ID_AA64DFR0_EL1_PMUVer_NI);
711432770f78e5 Zaid Al-Bassam 2023-03-17 174 }
711432770f78e5 Zaid Al-Bassam 2023-03-17 175 --
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
PATCH v3 6/7 coresight: etm4x: Report whether the PMU counts the external outputs
In reply to Amir AyupovSome 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.
--- .../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(-)
drivers/hwtracing/coresight/coresight-config.h +2 -0
@@ -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
drivers/hwtracing/coresight/coresight-etm4x-cfg.c +5 -1
@@ -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); }
drivers/hwtracing/coresight/coresight-etm4x-core.c +26 -0
@@ -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);
drivers/hwtracing/coresight/coresight-etm4x.h +3 -0
@@ -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; };/**
drivers/hwtracing/coresight/coresight-syscfg-configfs.c +3 -0
@@ -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; }
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v3 6/7] coresight: etm4x: Report whether the PMU counts the external outputs
Sashiko has reviewed this patch and found no issues.
Quoted 13 lines
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.
Quoted 7 lines
Add a
CS_CFG_MATCH_CAP_TRCEXTOUTcapability 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.5Signed-off-by Amir Ayupov <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=6
PATCH v3 7/7 coresight: Add pmu_pulse/extout_pulse
In reply to Amir AyupovAdd 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.
--- .../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
Documentation/trace/coresight/coresight-config.rst +5 -0
@@ -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 ===================================
Documentation/trace/coresight/coresight-perf.rst +15 -0
@@ -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 -----------------------------------------------------------
drivers/hwtracing/coresight/Makefile +1 -0
@@ -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 \
drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c new file +55 -0
55 lines not on this page · raw message
drivers/hwtracing/coresight/coresight-cfg-preload.c +2 -0
@@ -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, #endifNULL };
@@ -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, #endifNULL };
drivers/hwtracing/coresight/coresight-cfg-preload.h +2 -0
@@ -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
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v3 7/7] coresight: Add pmu_pulse/extout_pulse
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] coresight: pmu_pulse loads on 1-event ETE lacking event 1 and TRCEXTOUT1 --
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] coresight: pmu_pulse loads on 1-event ETE lacking event 1 and TRCEXTOUT1 --
commit 75adf8bc69eef9902a1a675969ecaf268f815f11
Author: Amir Ayupov <[email protected]>
coresight: Add pmu_pulse/extout_pulse
This commit adds a built-in pmu_pulse configuration and extout_pulse feature for ETMv4/ETE trace units that program event 1 in TRCEVENTCTL0R to select the always-true resource and pulse external output 1 (TRCEXTOUT1) on every traced cycle.
Quoted 34 lines
drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c new file +28
-0@@ -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 , + },
drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c line 38
Quoted 10 lines
drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c new file +10
-0+/* 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, +};
[Severity: Medium]
Can extout_pulse_etm4x load on a 1-event ETE that only implements event 0 and TRCEXTOUT0, where event 1 (TRCEVENTCTL0R[15:8]) and TRCEXTOUT1 do not exist?
In drivers/hwtracing/coresight/coresight-etm4x-core.c, on an ETE where TRCIDR4.NUMRSPAIR > 0 and TRCIDR0.NUMEVENT == 0, etm4_init_arch_data() sets drvdata->caps.nr_event = 1. When etm4_cscfg_register() checks etm4_pmu_counts_extout(), it only verifies the events up to caps.nr_event:
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;
}When drvdata->caps.nr_event == 1 and ARMV8_PMUV3_PERFCTR_TRCEXTOUT0 is implemented, etm4_pmu_counts_extout() returns true and sets CS_CFG_MATCH_CAP_TRCEXTOUT without checking TRCEXTOUT1.
During feature loading in drivers/hwtracing/coresight/coresight-etm4x-cfg.c, etm4_cfg_load_feature() -> etm4_cfg_map_reg_offset() maps TRCEVENTCTL0R unconditionally via CHECKREG(TRCEVENTCTL0R, eventctrl0) without checking whether drvdata->caps.nr_event covers the event fields masked by the feature.
Should etm4_cfg_load_feature() or the capability check verify that drvdata->caps.nr_event >= 2 before allowing extout_pulse_etm4x to load and program TRCEVENTCTL0R[15:8]?
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=7
v4 cover coresight: Pulse an ETM external output for a PMU event
In reply to Amir AyupovAdd 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 v4:
- Fix the arm64 build: v3 defined pmuv3_event_implemented() in linux/perf/arm_pmuv3.h after including asm/arm_pmuv3.h, which broke files that include asm/arm_pmuv3.h directly, such as arch/arm64/kernel/cpufeature.c. Move it to the arm64 asm/arm_pmuv3.h, after the helpers it uses.
Breakage reported by kernel test robot.
- Link to v3: https://lore.kernel.org/r/[email protected]
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/[email protected]
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 ++++ arch/arm64/include/asm/arm_pmuv3.h | 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 | 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 | 3 + 16 files changed, 229 insertions(+), 55 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c
base-commit: 343cfcbb3ecfdb80aa576a428cfa3b65ad783842
Signature · 1 line
2.52.0
PATCH v4 1/7 coresight: etm4x: Fix event count decoding
From: Leo Yan <[email protected]>
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.
--- .../coresight/coresight-etm4x-core.c | 13 +++++++-- .../coresight/coresight-etm4x-sysfs.c | 29 ++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-)
drivers/hwtracing/coresight/coresight-etm4x-core.c +11 -2
@@ -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
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +16 -13
@@ -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 |
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v4 1/7] coresight: etm4x: Fix event count decoding
Sashiko has reviewed this patch and found no issues.
Quoted 14 lines
From: Leo Yan <[email protected]>
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.
Quoted 8 lines
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 <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
Re: [PATCH v4 1/7] coresight: etm4x: Fix event count decoding
In reply to Amir AyupovQuoted 111 lines · Amir Ayupov
From: Leo Yan <[email protected]>
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 <[email protected]>--- .../coresight/coresight-etm4x-core.c | 13 +++++++-- .../coresight/coresight-etm4x-sysfs.c | 29 ++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-)drivers/hwtracing/coresight/coresight-etm4x-core.c +11
-2@@ -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 drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +14
-12@@ -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 :
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c static ssize_t event_instren_store(struct device *dev, · line 589
Quoted 10 lines
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +2
-1+/* 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 |
PATCH v4 2/7 coresight: syscfg: Fail to enable a configuration not loaded on the device
In reply to Amir Ayupovcscfg_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.
--- .../hwtracing/coresight/coresight-syscfg.c | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-)
drivers/hwtracing/coresight/coresight-syscfg.c +28 -25
@@ -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);
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v4 2/7] coresight: syscfg: Fail to enable a configuration not loaded on the device
Sashiko has reviewed this patch and found no issues.
Quoted 6 lines
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.
Quoted 7 lines
Return
-EINVALinstead, 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.5Signed-off-by Amir Ayupov <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
PATCH v4 3/7 coresight: syscfg: Match feature capabilities separately from device class
In reply to Amir AyupovA 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.
--- .../hwtracing/coresight/coresight-config.h | 8 ++++ .../hwtracing/coresight/coresight-syscfg.c | 37 +++++++++++++------ 2 files changed, 34 insertions(+), 11 deletions(-)
drivers/hwtracing/coresight/coresight-config.h +8 -0
@@ -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 */
drivers/hwtracing/coresight/coresight-syscfg.c +26 -11
@@ -171,8 +171,22 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_descreturn 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; }
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v4 3/7] coresight: syscfg: Match feature capabilities separately from device class
Sashiko has reviewed this patch and found no issues.
Quoted 13 lines
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_MASKfor device classes andCS_CFG_MATCH_CAP_MASKfor capabilities. A feature now loads on a device that shares one of its classes and has all of its capabilities. Check this once incscfg_load_feat_csdev(), which both the feature and the device registration paths call. No capability flags are defined yet, so matching is unchanged.
Quoted 2 lines
Assisted-by Devmate:Opus-5.5Signed-off-by Amir Ayupov <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3
Re: [PATCH v4 3/7] coresight: syscfg: Match feature capabilities separately from device class
In reply to Amir AyupovQuoted 106 lines · Amir Ayupov
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_MASKfor device classes andCS_CFG_MATCH_CAP_MASKfor capabilities. A feature now loads on a device that shares one of its classes and has all of its capabilities. Check this once incscfg_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.5Signed-off-by Amir Ayupov <[email protected]>--- .../hwtracing/coresight/coresight-config.h | 8 ++++ .../hwtracing/coresight/coresight-syscfg.c | 37 +++++++++++++------ 2 files changed, 34 insertions(+), 11 deletions(-)drivers/hwtracing/coresight/coresight-config.h +8
-0@@ -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 */ drivers/hwtracing/coresight/coresight-syscfg.c +23
-7@@ -171,8 +171,22 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_descreturn 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) {
drivers/hwtracing/coresight/coresight-syscfg.c static int cscfg_add_feats_csdev(struct coresight_device *csdev, · line 764
Quoted 10 lines
drivers/hwtracing/coresight/coresight-syscfg.c +3
-4- 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; }
Suzuki K Poulose
maintainerRe: [PATCH v4 3/7] coresight: syscfg: Match feature capabilities separately from device class
In reply to Amir AyupovQuoted 54 lines · Amir Ayupov
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_MASKfor device classes andCS_CFG_MATCH_CAP_MASKfor capabilities. A feature now loads on a device that shares one of its classes and has all of its capabilities. Check this once incscfg_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.5Signed-off-by Amir Ayupov <[email protected]>--- .../hwtracing/coresight/coresight-config.h | 8 ++++ .../hwtracing/coresight/coresight-syscfg.c | 37 +++++++++++++------ 2 files changed, 34 insertions(+), 11 deletions(-)drivers/hwtracing/coresight/coresight-config.h +8
-0@@ -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 */ drivers/hwtracing/coresight/coresight-syscfg.c +0
-0@@ -171,8 +171,22 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_descreturn feat_csdev; }
drivers/hwtracing/coresight/coresight-syscfg.c cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc · line 182
Quoted 10 lines
drivers/hwtracing/coresight/coresight-syscfg.c +9
-1-/* 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;
Please could you address the following comment ?
https://lore.kernel.org/linux-arm-kernel/[email protected]/
Cheers
Suzuki
Quoted 52 lines
drivers/hwtracing/coresight/coresight-syscfg.c +17
-10+ +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; }
PATCH v4 4/7 coresight: syscfg: Remove unused CS_CFG_MATCH_INST_ANY
In reply to Amir AyupovCS_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.
--- drivers/hwtracing/coresight/coresight-config.h | 3 --- 1 file changed, 3 deletions(-)
drivers/hwtracing/coresight/coresight-config.h +0 -3
@@ -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
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v4 4/7] coresight: syscfg: Remove unused CS_CFG_MATCH_INST_ANY
Sashiko has reviewed this patch and found no issues.
Quoted 7 lines
CS_CFG_MATCH_INST_ANYhas been defined since the system configuration was introduced but is not used by any configuration, feature or device. Remove it.Suggested-by Leo Yan <[email protected]>Assisted-by Devmate:Opus-5.5Signed-off-by Amir Ayupov <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=4
Re: [PATCH v4 4/7] coresight: syscfg: Remove unused CS_CFG_MATCH_INST_ANY
In reply to Amir AyupovQuoted 16 lines · Amir Ayupov
CS_CFG_MATCH_INST_ANYhas been defined since the system configuration was introduced but is not used by any configuration, feature or device. Remove it.Suggested-by Leo Yan <[email protected]>Assisted-by Devmate:Opus-5.5Signed-off-by Amir Ayupov <[email protected]>--- drivers/hwtracing/coresight/coresight-config.h | 3 --- 1 file changed, 3 deletions(-)drivers/hwtracing/coresight/coresight-config.h +0
-0
drivers/hwtracing/coresight/coresight-config.h line 44
Quoted 9 lines
drivers/hwtracing/coresight/coresight-config.h +0
-3@@ -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
PATCH v4 5/7 perf: arm_pmuv3: Add pmuv3_event_implemented()
In reply to Amir AyupovDrivers 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() to the arm64 asm/arm_pmuv3.h, next to read_pmceid0() and read_pmceid1(). It 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 linux/perf/arm_pmuv3.h so it is available without CONFIG_ARM_PMU.
--- arch/arm64/include/asm/arm_pmuv3.h | 19 +++++++++++++++++++ include/linux/perf/arm_pmu.h | 1 - include/linux/perf/arm_pmuv3.h | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-)
arch/arm64/include/asm/arm_pmuv3.h +19 -0
@@ -173,6 +173,25 @@ static inline bool pmuv3_implemented(int pmuver) pmuver == ID_AA64DFR0_EL1_PMUVer_NI); } +/* +* 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 )); +} +static inline bool is_pmuv3p4 (int pmuver) {return pmuver >= ID_AA64DFR0_EL1_PMUVer_V3P4;
include/linux/perf/arm_pmu.h +0 -1
@@ -124,7 +124,6 @@ struct arm_pmu {u64 reg_brbidr;#define ARMV8_PMUV3_MAX_COMMON_EVENTS 0x40DECLARE_BITMAP (pmceid_bitmap,ARMV8_PMUV3_MAX_COMMON_EVENTS ); -#define ARMV8_PMUV3_EXT_COMMON_EVENT_BASE 0x4000DECLARE_BITMAP (pmceid_ext_bitmap,ARMV8_PMUV3_MAX_COMMON_EVENTS );/* Only to be used by ACPI probing code */
include/linux/perf/arm_pmuv3.h +3 -0
@@ -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
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v4 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented()
Sashiko has reviewed this patch and found no issues.
Quoted 12 lines
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()to the arm64asm/arm_pmuv3.h, next toread_pmceid0()andread_pmceid1(). It reads PMCEID0/1 on the calling CPU:
events 0x0000-0x003f are reported in bits [31:0], and the common events fromARMV8_PMUV3_EXT_COMMON_EVENT_BASEin bits [63:32] from PMUv3p1. MoveARMV8_PMUV3_EXT_COMMON_EVENT_BASEnext to the event numbers inlinux/perf/arm_pmuv3.hso it is available withoutCONFIG_ARM_PMU.
Quoted 3 lines
Suggested-by James Clark <[email protected]>Assisted-by Devmate:Opus-5.5Signed-off-by Amir Ayupov <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=5
Re: [PATCH v4 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented()
In reply to Amir AyupovQuoted 68 lines · Amir Ayupov
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()to the arm64asm/arm_pmuv3.h, next toread_pmceid0()andread_pmceid1(). It reads PMCEID0/1 on the calling CPU:
events 0x0000-0x003f are reported in bits [31:0], and the common events fromARMV8_PMUV3_EXT_COMMON_EVENT_BASEin bits [63:32] from PMUv3p1. MoveARMV8_PMUV3_EXT_COMMON_EVENT_BASEnext to the event numbers inlinux/perf/arm_pmuv3.hso it is available withoutCONFIG_ARM_PMU.Suggested-by James Clark <[email protected]>Assisted-by Devmate:Opus-5.5Signed-off-by Amir Ayupov <[email protected]>--- arch/arm64/include/asm/arm_pmuv3.h | 19 +++++++++++++++++++ include/linux/perf/arm_pmu.h | 1 - include/linux/perf/arm_pmuv3.h | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-)arch/arm64/include/asm/arm_pmuv3.h +19
-0@@ -173,6 +173,25 @@ static inline bool pmuv3_implemented(int pmuver) pmuver == ID_AA64DFR0_EL1_PMUVer_NI); } +/* +* 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 )); +} +static inline bool is_pmuv3p4 (int pmuver) {return pmuver >= ID_AA64DFR0_EL1_PMUVer_V3P4;include/linux/perf/arm_pmu.h +0
-1@@ -124,7 +124,6 @@ struct arm_pmu {u64 reg_brbidr;#define ARMV8_PMUV3_MAX_COMMON_EVENTS 0x40DECLARE_BITMAP (pmceid_bitmap,ARMV8_PMUV3_MAX_COMMON_EVENTS ); -#define ARMV8_PMUV3_EXT_COMMON_EVENT_BASE 0x4000DECLARE_BITMAP (pmceid_ext_bitmap,ARMV8_PMUV3_MAX_COMMON_EVENTS );/* Only to be used by ACPI probing code */ include/linux/perf/arm_pmuv3.h +0
-0
include/linux/perf/arm_pmuv3.h line 86
Quoted 9 lines
include/linux/perf/arm_pmuv3.h +3
-0@@ -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
Suzuki K Poulose
maintainerRe: [PATCH v4 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented()
In reply to Amir AyupovQuoted 56 lines · Amir Ayupov
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()to the arm64asm/arm_pmuv3.h, next toread_pmceid0()andread_pmceid1(). It reads PMCEID0/1 on the calling CPU:
events 0x0000-0x003f are reported in bits [31:0], and the common events fromARMV8_PMUV3_EXT_COMMON_EVENT_BASEin bits [63:32] from PMUv3p1. MoveARMV8_PMUV3_EXT_COMMON_EVENT_BASEnext to the event numbers inlinux/perf/arm_pmuv3.hso it is available withoutCONFIG_ARM_PMU.Suggested-by James Clark <[email protected]>Assisted-by Devmate:Opus-5.5Signed-off-by Amir Ayupov <[email protected]>--- arch/arm64/include/asm/arm_pmuv3.h | 19 +++++++++++++++++++ include/linux/perf/arm_pmu.h | 1 - include/linux/perf/arm_pmuv3.h | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-)arch/arm64/include/asm/arm_pmuv3.h +19
-0@@ -173,6 +173,25 @@ static inline bool pmuv3_implemented(int pmuver) pmuver == ID_AA64DFR0_EL1_PMUVer_NI); } +/* +* 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_pmceid1(); +return pmceid &BIT_ULL (id %32 + (ext ?32 :0 )); +} +static inline bool is_pmuv3p4 (int pmuver) {return pmuver >= ID_AA64DFR0_EL1_PMUVer_V3P4;include/linux/perf/arm_pmu.h +0
-0
include/linux/perf/arm_pmu.h struct arm_pmu { · line 127
Quoted 5 lines
include/linux/perf/arm_pmu.h +0
-1@@ -124,7 +124,6 @@ struct arm_pmu {u64 reg_brbidr;#define ARMV8_PMUV3_MAX_COMMON_EVENTS 0x40DECLARE_BITMAP (pmceid_bitmap,ARMV8_PMUV3_MAX_COMMON_EVENTS ); -#define ARMV8_PMUV3_EXT_COMMON_EVENT_BASE 0x4000DECLARE_BITMAP (pmceid_ext_bitmap,ARMV8_PMUV3_MAX_COMMON_EVENTS );
Could we not avoid this change ? Or why not move both of the definitions ?
Also, I would need an ACK from the arm_pmu maintainers to accept this change via coresight tree.
Cheers
Suzuki
Quoted 16 lines
include/linux/perf/arm_pmu.h +0
-0/* Only to be used by ACPI probing code */ include/linux/perf/arm_pmuv3.h +3
-0@@ -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
James Clark
reviewerRe: [PATCH v4 5/7] perf: arm_pmuv3: Add pmuv3_event_implemented()
Quoted 56 lines · Suzuki K Poulose
Quoted 55 lines · Amir Ayupov
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()to the arm64asm/arm_pmuv3.h, next toread_pmceid0()andread_pmceid1(). It reads PMCEID0/1 on the calling CPU:
events 0x0000-0x003f are reported in bits [31:0], and the common events fromARMV8_PMUV3_EXT_COMMON_EVENT_BASEin bits [63:32] from PMUv3p1. MoveARMV8_PMUV3_EXT_COMMON_EVENT_BASEnext to the event numbers inlinux/perf/arm_pmuv3.hso it is available withoutCONFIG_ARM_PMU.Suggested-by James Clark <[email protected]>Assisted-by Devmate:Opus-5.5Signed-off-by Amir Ayupov <[email protected]>---
arch/arm64/include/asm/arm_pmuv3.h| 19 +++++++++++++++++++ include/linux/perf/arm_pmu.h | 1 - include/linux/perf/arm_pmuv3.h | 3 +++3 files changed, 22 insertions(+), 1 deletion(-)arch/arm64/include/asm/arm_pmuv3.h +3
-0@@ -173,6 +173,25 @@ static inline bool pmuv3_implemented(int pmuver) pmuver == ID_AA64DFR0_EL1_PMUVer_NI); } +/* +* 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.
+ */arch/arm64/include/asm/arm_pmuv3.h +13
-0+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_pmceid1(); + return pmceid & BIT_ULL(id % 32 + (ext ? 32 : 0)); +} +static inline bool
is_pmuv3p4(int pmuver){
return pmuver >=ID_AA64DFR0_EL1_PMUVer_V3P4;include/linux/perf/arm_pmu.h +0
-0
Quoted 9 lines
include/linux/perf/arm_pmu.h struct arm_pmu { · line 127
Quoted 6 lines
include/linux/perf/arm_pmu.h +0
-1@@ -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);Could we not avoid this change ? Or why not move both of the definitions ?
I don't think you can avoid it unless you redefine it. But the place it's moved to has similar event number definitions, so it seems ok to me.
Moving both makes sense though.
Quoted 24 lines
Also, I would need an ACK from the
arm_pmumaintainers to accept this change via coresight tree.Cheers
SuzukiQuoted 15 lines
include/linux/perf/arm_pmu.h +0
-0/* Only to be used by ACPI probing code */include/linux/perf/arm_pmuv3.h +1
-0@@ -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 */
include/linux/perf/arm_pmuv3.h +2
-0+#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_FEED0x4001
PATCH v4 6/7 coresight: etm4x: Report whether the PMU counts the external outputs
In reply to Amir AyupovSome 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.
--- .../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(-)
drivers/hwtracing/coresight/coresight-config.h +2 -0
@@ -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
drivers/hwtracing/coresight/coresight-etm4x-cfg.c +5 -1
@@ -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); }
drivers/hwtracing/coresight/coresight-etm4x-core.c +26 -0
@@ -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);
drivers/hwtracing/coresight/coresight-etm4x.h +3 -0
@@ -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; };/**
drivers/hwtracing/coresight/coresight-syscfg-configfs.c +3 -0
@@ -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; }
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v4 6/7] coresight: etm4x: Report whether the PMU counts the external outputs
Sashiko has reviewed this patch and found no issues.
Quoted 13 lines
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.
Quoted 7 lines
Add a
CS_CFG_MATCH_CAP_TRCEXTOUTcapability 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.5Signed-off-by Amir Ayupov <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=6
Re: [PATCH v4 6/7] coresight: etm4x: Report whether the PMU counts the external outputs
In reply to Amir AyupovQuoted 137 lines · Amir Ayupov
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_TRCEXTOUTcapability 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.5Signed-off-by Amir Ayupov <[email protected]>--- .../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(-)drivers/hwtracing/coresight/coresight-config.h +2
-0@@ -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 drivers/hwtracing/coresight/coresight-etm4x-cfg.c +5
-1@@ -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); }drivers/hwtracing/coresight/coresight-etm4x-core.c +26
-0@@ -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);drivers/hwtracing/coresight/coresight-etm4x.h +3
-0@@ -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; };/** drivers/hwtracing/coresight/coresight-syscfg-configfs.c +0
-0
drivers/hwtracing/coresight/coresight-syscfg-configfs.c static ssize_t cscfg_feat_matches_show(struct config_item *item, char *page) · line 258
Quoted 9 lines
drivers/hwtracing/coresight/coresight-syscfg-configfs.c +3
-0@@ -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; }
Suzuki K Poulose
maintainerRe: [PATCH v4 6/7] coresight: etm4x: Report whether the PMU counts the external outputs
In reply to Amir AyupovQuoted 33 lines · Amir Ayupov
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_TRCEXTOUTcapability 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.5Signed-off-by Amir Ayupov <[email protected]>--- .../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(-)drivers/hwtracing/coresight/coresight-config.h +0
-0
drivers/hwtracing/coresight/coresight-config.h line 43
Quoted 6 lines
drivers/hwtracing/coresight/coresight-config.h +2
-0@@ -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)
Please could we rename this to :
CS_CFG_MATCH_CAP_ETE_TRCEXTOUT
as this is only applicable for ETEs ?
Quoted 77 lines
drivers/hwtracing/coresight/coresight-config.h +0
-0/* * Limit number of presets in a configuration drivers/hwtracing/coresight/coresight-etm4x-cfg.c +5
-1@@ -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); }drivers/hwtracing/coresight/coresight-etm4x-core.c +26
-0@@ -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);drivers/hwtracing/coresight/coresight-etm4x.h +0
-0
drivers/hwtracing/coresight/coresight-etm4x.h enum etm_impdef_type { · line 872
Quoted 5 lines
drivers/hwtracing/coresight/coresight-etm4x.h +2
-0@@ -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.
We don't seem to be using this after the CSFG flag initialisation, in which case could we directly call etm4_pmu_counts_extout() from etm4_cscfg_register() ?
Suzuki
Quoted 25 lines
drivers/hwtracing/coresight/coresight-etm4x.h +1
-0*/ 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; };/** drivers/hwtracing/coresight/coresight-syscfg-configfs.c +3
-0@@ -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; }
PATCH v4 7/7 coresight: Add pmu_pulse/extout_pulse
In reply to Amir AyupovAdd 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.
--- .../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
Documentation/trace/coresight/coresight-config.rst +5 -0
@@ -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 ===================================
Documentation/trace/coresight/coresight-perf.rst +15 -0
@@ -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 -----------------------------------------------------------
drivers/hwtracing/coresight/Makefile +1 -0
@@ -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 \
drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c new file +55 -0
55 lines not on this page · raw message
drivers/hwtracing/coresight/coresight-cfg-preload.c +2 -0
@@ -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, #endifNULL };
@@ -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, #endifNULL };
drivers/hwtracing/coresight/coresight-cfg-preload.h +2 -0
@@ -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
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v4 7/7] coresight: Add pmu_pulse/extout_pulse
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] coresight: extout_pulse loads on ETE with single event lacking TRCEXTOUT1 --
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] coresight: extout_pulse loads on ETE with single event lacking TRCEXTOUT1 --
commit 5f7a0d60c7147cc2e10191888168dd0008749154
Author: Amir Ayupov <[email protected]>
coresight: Add pmu_pulse/extout_pulse
This commit adds the built-in pmu_pulse configuration and extout_pulse feature for ETMv4/ETE to pulse external output 1 on every traced cycle for the PMU to count as TRCEXTOUT1.
Quoted 6 lines
drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c new file +0
-0@@ -0,0 +1,55 @@
[ ... ]
Quoted 8 lines
drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c new file +8
-0+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 , + },
drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c line 38
Quoted 10 lines
drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c new file +10
-0+/* 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, +};
[Severity: Medium]
Can extout_pulse_etm4x load and enable on an ETE implementation that only supports a single event (event 0 / TRCEXTOUT0), where event 1 and TRCEXTOUT1 do not exist?
In drivers/hwtracing/coresight/coresight-etm4x-core.c, when TRCIDR0.NUMEVENT is 0 and resources are present, etm4_init_arch_data() sets caps->nr_event to
1. Then etm4_pmu_counts_extout() checks whether the implemented events have matching PMU counters:
drivers/hwtracing/coresight/coresight-etm4x-core.c:etm4_pmu_counts_extout() {
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;
}When drvdata->caps.nr_event == 1 and ARMV8_PMUV3_PERFCTR_TRCEXTOUT0 is implemented, etm4_pmu_counts_extout() returns true and etm4_cscfg_register() advertises CS_CFG_MATCH_CAP_TRCEXTOUT.
When loading the feature, etm4_cfg_load_feature() -> etm4_cfg_map_reg_offset() maps TRCEVENTCTL0R without checking whether drvdata->caps.nr_event >= 2. By contrast, event_store() in drivers/hwtracing/coresight/coresight-etm4x-sysfs.c shows that EVENT1 (bits [15:8] of TRCEVENTCTL0R) is only implemented when caps->nr_event >= 2:
case 1: /* EVENT0, bits[7:0] */ sysfs_config->eventctrl0 = val & 0xFF; break; case 2: /* EVENT1, bits[15:8] */ sysfs_config->eventctrl0 = val & 0xFFFF; break;
On an ETE with caps.nr_event == 1, enabling pmu_pulse will succeed and write 0x0100 to the unimplemented EVENT1 field in TRCEVENTCTL0R while TRCEXTOUT1 does not exist. Should CS_CFG_MATCH_CAP_TRCEXTOUT or the feature loading path verify that event 1 (caps.nr_event >= 2 and TRCEXTOUT1) is available?
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=7
Re: [PATCH v4 7/7] coresight: Add pmu_pulse/extout_pulse
In reply to Amir AyupovQuoted 159 lines · Amir Ayupov
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.5Signed-off-by Amir Ayupov <[email protected]>Reviewed-by Daniel Pereira <[email protected]>--- .../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.cDocumentation/trace/coresight/coresight-config.rst +5
-0@@ -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 ===================================Documentation/trace/coresight/coresight-perf.rst +15
-0@@ -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 -----------------------------------------------------------drivers/hwtracing/coresight/Makefile +1
-0@@ -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 \drivers/hwtracing/coresight/coresight-cfg-pmu-pulse.c new file +55
-0@@ -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) */ drivers/hwtracing/coresight/coresight-cfg-preload.c +2
-0@@ -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, #endifNULL };@@ -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, #endifNULL };drivers/hwtracing/coresight/coresight-cfg-preload.h +0
-0
drivers/hwtracing/coresight/coresight-cfg-preload.h extern struct cscfg_feature_desc strobe_etm4x; · line 17
Quoted 6 lines
drivers/hwtracing/coresight/coresight-cfg-preload.h +2
-0@@ -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
Quoted 7 lines · Amir Ayupov
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.
Maybe it is worth to update patch 03 for Suzuki's comment:
https://lore.kernel.org/linux-arm-kernel/[email protected]/
This series looks good to me and I have verified it: