hi,
while testing the implementation in gdb of branch tracing on arm
processors using etm, I faced the the situation where a breakpoint was
set, was hit and then the execution of the program was continued. While
decoding generated traces, I got the address of the breakpoint
(0x400552) executed twice, and then the following address (0x400554)
also executed twice. the instruction at (0x400554) is a BL ( a function
call) and the second execution corrupts the function history.
here is a dump of generated trace elements
---------------------------------
trace_chan_id: 18
isa: CS_ETM_ISA_T32
start addr = 0x400552
end addr = 0x400554
instructions count = 1
last_i_type: OCSD_INSTR_OTHER
last_i_subtype: OCSD_S_INSTR_NONE
last instruction was executed
last instruction size: 2
---------------------------------
trace_chan_id: 18
isa: CS_ETM_ISA_T32
start addr = 0x400552
end addr = 0x400554
instructions count = 1
last_i_type: OCSD_INSTR_OTHER
last_i_subtype: OCSD_S_INSTR_NONE
last instruction was executed
last instruction size: 2
---------------------------------
trace_chan_id: 18
isa: CS_ETM_ISA_T32
start addr = 0x400554
end addr = 0x400558
instructions count = 1
last_i_type: OCSD_INSTR_BR
last_i_subtype: OCSD_S_INSTR_BR_LINK
last instruction was executed
last instruction size: 4
---------------------------------
trace_chan_id: 18
isa: CS_ETM_ISA_T32
start addr = 0x400554
end addr = 0x400558
instructions count = 1
last_i_type: OCSD_INSTR_BR
last_i_subtype: OCSD_S_INSTR_BR_LINK
last instruction was executed
last instruction size: 4
the explanation I have for this behavior is that :
-when setting the software breakpoint, the memory content of the
instruction (at 0x400552) was altered to the instruction BKPT,
-when the breakpoint was hit, the original opcode was set at (0x400552)
and a BKPT was set to the next instruction address (0x400554), then the
execution was continued
-when the second breakpoint (0x400554) was hit, the a BKPT opcode was
set at (0x400552) and the original opcode was set at (0x400554) then the
execution was continued
I am using the function "int target_read_code (CORE_ADDR memaddr,
gdb_byte *myaddr, ssize_t len)" to give program memory content to the
decoder. so the collected etm traces are correct, but, as memory was
altered in between, the decoder is "cheated".
I need to identify the re-execution of code due to breakpoint handling,
and roll back its impact on etm decoding.
is there a mean to get the actual content of program memory including
patched addresses?
is there a means of getting the history of patched addresses during the
debugging of a program?
what is the type and subtype of a BKPT instruction in a decoded trace
elements?
do you have any other idea for handling this situation?
I am attaching the source code of the program as well as the
disassembled binary. the code was compiled as an application running on
linux on an ARMv7 A (STM32MP157 SoC). the breakpoint was set at line 43
in the source code (line 238 in the disassembled code)
Kind Regards
Zied Guermazi
From: Linu Cherian <lcherian(a)marvell.com>
[ Upstream commit 6d578258b955fc8888e1bbd9a8fefe7b10065a84 ]
Coresight driver assumes sink is common across all the ETMs,
and tries to build a path between ETM and the first enabled
sink found using bus based search. This breaks sysFS usage
on implementations that has multiple per core sinks in
enabled state.
To fix this, coresight_get_enabled_sink API is updated to
do a connection based search starting from the given source,
instead of bus based search.
With sink selection using sysfs depecrated for perf interface,
provision for reset is removed as well in this API.
Signed-off-by: Linu Cherian <lcherian(a)marvell.com>
[Fixed indentation problem and removed obsolete comment]
Signed-off-by: Mathieu Poirier <mathieu.poirier(a)linaro.org>
Link: https://lore.kernel.org/r/20200916191737.4001561-15-mathieu.poirier@linaro.…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
drivers/hwtracing/coresight/coresight-priv.h | 3 +-
drivers/hwtracing/coresight/coresight.c | 62 +++++++++-----------
2 files changed, 29 insertions(+), 36 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index f2dc625ea5856..5fe773c4d6cc5 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -148,7 +148,8 @@ static inline void coresight_write_reg_pair(void __iomem *addr, u64 val,
void coresight_disable_path(struct list_head *path);
int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data);
struct coresight_device *coresight_get_sink(struct list_head *path);
-struct coresight_device *coresight_get_enabled_sink(bool reset);
+struct coresight_device *
+coresight_get_enabled_sink(struct coresight_device *source);
struct coresight_device *coresight_get_sink_by_id(u32 id);
struct coresight_device *
coresight_find_default_sink(struct coresight_device *csdev);
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index e9c90f2de34ac..bb4f9e0a5438d 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -540,50 +540,46 @@ struct coresight_device *coresight_get_sink(struct list_head *path)
return csdev;
}
-static int coresight_enabled_sink(struct device *dev, const void *data)
+static struct coresight_device *
+coresight_find_enabled_sink(struct coresight_device *csdev)
{
- const bool *reset = data;
- struct coresight_device *csdev = to_coresight_device(dev);
+ int i;
+ struct coresight_device *sink;
if ((csdev->type == CORESIGHT_DEV_TYPE_SINK ||
csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) &&
- csdev->activated) {
- /*
- * Now that we have a handle on the sink for this session,
- * disable the sysFS "enable_sink" flag so that possible
- * concurrent perf session that wish to use another sink don't
- * trip on it. Doing so has no ramification for the current
- * session.
- */
- if (*reset)
- csdev->activated = false;
+ csdev->activated)
+ return csdev;
- return 1;
+ /*
+ * Recursively explore each port found on this element.
+ */
+ for (i = 0; i < csdev->pdata->nr_outport; i++) {
+ struct coresight_device *child_dev;
+
+ child_dev = csdev->pdata->conns[i].child_dev;
+ if (child_dev)
+ sink = coresight_find_enabled_sink(child_dev);
+ if (sink)
+ return sink;
}
- return 0;
+ return NULL;
}
/**
- * coresight_get_enabled_sink - returns the first enabled sink found on the bus
- * @deactivate: Whether the 'enable_sink' flag should be reset
- *
- * When operated from perf the deactivate parameter should be set to 'true'.
- * That way the "enabled_sink" flag of the sink that was selected can be reset,
- * allowing for other concurrent perf sessions to choose a different sink.
+ * coresight_get_enabled_sink - returns the first enabled sink using
+ * connection based search starting from the source reference
*
- * When operated from sysFS users have full control and as such the deactivate
- * parameter should be set to 'false', hence mandating users to explicitly
- * clear the flag.
+ * @source: Coresight source device reference
*/
-struct coresight_device *coresight_get_enabled_sink(bool deactivate)
+struct coresight_device *
+coresight_get_enabled_sink(struct coresight_device *source)
{
- struct device *dev = NULL;
-
- dev = bus_find_device(&coresight_bustype, NULL, &deactivate,
- coresight_enabled_sink);
+ if (!source)
+ return NULL;
- return dev ? to_coresight_device(dev) : NULL;
+ return coresight_find_enabled_sink(source);
}
static int coresight_sink_by_id(struct device *dev, const void *data)
@@ -988,11 +984,7 @@ int coresight_enable(struct coresight_device *csdev)
goto out;
}
- /*
- * Search for a valid sink for this session but don't reset the
- * "enable_sink" flag in sysFS. Users get to do that explicitly.
- */
- sink = coresight_get_enabled_sink(false);
+ sink = coresight_get_enabled_sink(csdev);
if (!sink) {
ret = -EINVAL;
goto out;
--
2.25.1
This patchset introduces initial concepts in CoreSight complex system
configuration support.
Configurations consist of 2 elements:-
1) Features - programming combinations for devices, applied to a class of
device on the system (all ETMv4), or individual devices.
2) Configurations - a set of programmed features used when the named
configuration is selected.
Features and configurations are declared as a data table, a set of register,
resource and parameter requirements. Features and configurations are loaded
into the system by the virtual cs_syscfg device. This then matches features
to any registered devices and loads the feature into them.
Individual device classes that support feature and configuration register
with cs_syscfg.
Once loaded a configuration can be enabled for a specific trace run.
Configurations are registered with the perf cs_etm event as entries in
cs_etm/cs_config. These can be selected on the perf command line as follows:-
perf record -e cs_etm/@<config_name>/ ...
This patch set has one pre-loaded configuration and feature.
A named "strobing" feature is provided for ETMv4.
A named "autofdo" configuration is provided. This configuration enables
strobing on any ETM in used.
Thus the command:
perf record -e cs_etm/@autofdo/ ...
will trace the supplied application while enabling the "autofdo" configuation
on each ETM as it is enabled by perf. This in turn will enable strobing for
the ETM - with default parameters. (at present these default parameters can be
altered using sysfs for each individual ETM - but this is under review).
The sink used in the trace run will be automatically selected.
A configuation can supply up to 15 of preset parameter values, which will
subsitute in parameter values for any feature used in the configuration.
Selection of preset values as follows
perf record -e cs_etm/@autofdo,preset=1/ ...
(valid presets 1-N, where N is the number supplied in the configuration, not
exceeding 15. preset=0 is the same as not selecting a preset.)
Changes since v1:
1) Moved preloaded configurations and features out of individual drivers.
2) Added cs_syscfg driver to manage configurations and features. Individual
drivers register with cs_syscfg indicating support for config, and provide
matching information that the system uses to load features into the drivers.
This allows individual drivers to be updated on an as needed basis - and
removes the need to consider devices that cannot benefit from configuration -
static replicators, funnels, tpiu.
3) Added perf selection of configuarations.
4) Rebased onto the coresight module loading set.
Applies to coresight/next (5.9-rc1 base) with the coresight module load set
[1] applied.
To follow in future revisions / sets:-
a) load of additional config and features by loadable module.
b) load of additional config and features by configfs
c) enhanced resource management for ETMv4 and checking features have sufficient
resources to be enabled.
d) ECT and CTI support for configuration and features.
e) documentation file.
[1] https://lists.linaro.org/pipermail/coresight/2020-August/004704.html
Mike Leach (8):
coresight: syscfg: Initial coresight system configuration
coresight: syscfg: Add loading of features and configurations
coresight: syscfg: Add registration and feature loading for cs devices
coresight: config: Add configuration and feature generic functions
perf: cs_etm: update cs_etm processing to allow configuration
selection
coresight: etm-perf: update to handle configuration selection
coresight: etm4x: Add complex configuration handlers to etmv4
coresight: config: Add preloaded configurations
drivers/hwtracing/coresight/Makefile | 6 +-
.../coresight/coresight-cfg-preload.c | 165 +++++
.../hwtracing/coresight/coresight-config.c | 565 ++++++++++++++++++
.../hwtracing/coresight/coresight-config.h | 289 +++++++++
drivers/hwtracing/coresight/coresight-core.c | 36 +-
.../hwtracing/coresight/coresight-etm-perf.c | 91 ++-
.../hwtracing/coresight/coresight-etm-perf.h | 8 +-
.../hwtracing/coresight/coresight-etm4x-cfg.c | 226 +++++++
.../hwtracing/coresight/coresight-etm4x-cfg.h | 29 +
.../coresight/coresight-etm4x-core.c | 30 +-
.../coresight/coresight-etm4x-sysfs.c | 3 +
.../hwtracing/coresight/coresight-syscfg.c | 527 ++++++++++++++++
.../hwtracing/coresight/coresight-syscfg.h | 90 +++
include/linux/coresight-pmu.h | 3 +
include/linux/coresight.h | 8 +
tools/include/linux/coresight-pmu.h | 3 +
tools/perf/arch/arm/util/cs-etm.c | 17 +-
17 files changed, 2066 insertions(+), 30 deletions(-)
create mode 100644 drivers/hwtracing/coresight/coresight-cfg-preload.c
create mode 100644 drivers/hwtracing/coresight/coresight-config.c
create mode 100644 drivers/hwtracing/coresight/coresight-config.h
create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.c
create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.h
create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.c
create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.h
--
2.17.1