From a0f890aba2be33377f4eb24e13633c4a76a68f38 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 5 Feb 2019 16:24:53 -0700 Subject: coresight: cpu-debug: Support for CA73 CPUs This patch is to add the AMBA device ID for CA73 CPU, so that CPU debug module can be initialized successfully when a SoC contain CA73 CPUs. This patch has been verified on 96boards Hikey960. Signed-off-by: Leo Yan Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-cpu-debug.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c index 45b2460f3166..e8819d750938 100644 --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c @@ -668,6 +668,10 @@ static const struct amba_id debug_ids[] = { .id = 0x000bbd08, .mask = 0x000fffff, }, + { /* Debug for Cortex-A73 */ + .id = 0x000bbd09, + .mask = 0x000fffff, + }, { 0, 0 }, }; -- cgit v1.2.3 From a7325a6ca45f6a53ad8f639b7b69f22961ad3757 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 5 Feb 2019 16:24:54 -0700 Subject: coresight: stm: Remove set but not used variable 'res_size' Fixes gcc '-Wunused-but-set-variable' warning: drivers/hwtracing/coresight/coresight-stm.c: In function 'stm_probe': drivers/hwtracing/coresight/coresight-stm.c:796:9: warning: variable 'res_size' set but not used [-Wunused-but-set-variable] It never used since introduction in commit 237483aa5cf4 ("coresight: stm: adding driver for CoreSight STM component") Signed-off-by: YueHaibing Tested-by: Leo Yan Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-stm.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index ef339ff22090..f07825df5c7a 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -793,7 +793,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) struct stm_drvdata *drvdata; struct resource *res = &adev->res; struct resource ch_res; - size_t res_size, bitmap_size; + size_t bitmap_size; struct coresight_desc desc = { 0 }; struct device_node *np = adev->dev.of_node; @@ -833,15 +833,11 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id) drvdata->write_bytes = stm_fundamental_data_size(drvdata); - if (boot_nr_channel) { + if (boot_nr_channel) drvdata->numsp = boot_nr_channel; - res_size = min((resource_size_t)(boot_nr_channel * - BYTES_PER_CHANNEL), resource_size(res)); - } else { + else drvdata->numsp = stm_num_stimulus_port(drvdata); - res_size = min((resource_size_t)(drvdata->numsp * - BYTES_PER_CHANNEL), resource_size(res)); - } + bitmap_size = BITS_TO_LONGS(drvdata->numsp) * sizeof(long); guaranteed = devm_kzalloc(dev, bitmap_size, GFP_KERNEL); -- cgit v1.2.3 From c2bc02f8828d2efef2852249ce61acb8967d4f4a Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 5 Feb 2019 16:24:55 -0700 Subject: coresight: Use of_node_name_eq for node name comparisons Convert string compares of DT node names to use of_node_name_eq helper instead. This removes direct access to the node name pointer. Cc: Mathieu Poirier Cc: Alexander Shishkin Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Rob Herring Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/of_coresight.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index 89092f83567e..7045930fc958 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -80,8 +80,8 @@ static struct device_node *of_coresight_get_port_parent(struct device_node *ep) * Skip one-level up to the real device node, if we * are using the new bindings. */ - if (!of_node_cmp(parent->name, "in-ports") || - !of_node_cmp(parent->name, "out-ports")) + if (of_node_name_eq(parent, "in-ports") || + of_node_name_eq(parent, "out-ports")) parent = of_get_next_parent(parent); return parent; -- cgit v1.2.3 From e11a5795cb7cd1e25bbd1697baa109943938c0f6 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Tue, 5 Feb 2019 16:24:56 -0700 Subject: perf/aux: Make perf_event accessible to setup_aux() When pmu::setup_aux() is called the coresight PMU needs to know which sink to use for the session by looking up the information in the event's attr::config2 field. As such simply replace the cpu information by the complete perf_event structure and change all affected customers. Signed-off-by: Mathieu Poirier Reviewed-by: Suzuki K Poulose Acked-by: Peter Zijlstra (Intel) Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etm-perf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index abe8249b893b..f21eb28b6782 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -177,15 +177,15 @@ static void etm_free_aux(void *data) schedule_work(&event_data->work); } -static void *etm_setup_aux(int event_cpu, void **pages, +static void *etm_setup_aux(struct perf_event *event, void **pages, int nr_pages, bool overwrite) { - int cpu; + int cpu = event->cpu; cpumask_t *mask; struct coresight_device *sink; struct etm_event_data *event_data = NULL; - event_data = alloc_event_data(event_cpu); + event_data = alloc_event_data(cpu); if (!event_data) return NULL; INIT_WORK(&event_data->work, free_event_data); -- cgit v1.2.3 From 988036f9d322cbd787d8f6a776dbe903d05bae22 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Tue, 5 Feb 2019 16:24:57 -0700 Subject: coresight: perf: Add "sinks" group to PMU directory Add a "sinks" directory entry so that users can see all the sinks available in the system in a single place. Individual sink are added as they are registered with the coresight bus. Signed-off-by: Mathieu Poirier Acked-by: Peter Zijlstra (Intel) Reviewed-by: Suzuki K Poulose Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etm-perf.c | 82 ++++++++++++++++++++++++ drivers/hwtracing/coresight/coresight-etm-perf.h | 6 +- drivers/hwtracing/coresight/coresight.c | 18 ++++++ 3 files changed, 105 insertions(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index f21eb28b6782..cdbdb28dc175 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -43,8 +44,18 @@ static const struct attribute_group etm_pmu_format_group = { .attrs = etm_config_formats_attr, }; +static struct attribute *etm_config_sinks_attr[] = { + NULL, +}; + +static const struct attribute_group etm_pmu_sinks_group = { + .name = "sinks", + .attrs = etm_config_sinks_attr, +}; + static const struct attribute_group *etm_pmu_attr_groups[] = { &etm_pmu_format_group, + &etm_pmu_sinks_group, NULL, }; @@ -479,6 +490,77 @@ int etm_perf_symlink(struct coresight_device *csdev, bool link) return 0; } +static ssize_t etm_perf_sink_name_show(struct device *dev, + struct device_attribute *dattr, + char *buf) +{ + struct dev_ext_attribute *ea; + + ea = container_of(dattr, struct dev_ext_attribute, attr); + return scnprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)(ea->var)); +} + +int etm_perf_add_symlink_sink(struct coresight_device *csdev) +{ + int ret; + unsigned long hash; + const char *name; + struct device *pmu_dev = etm_pmu.dev; + struct device *pdev = csdev->dev.parent; + struct dev_ext_attribute *ea; + + if (csdev->type != CORESIGHT_DEV_TYPE_SINK && + csdev->type != CORESIGHT_DEV_TYPE_LINKSINK) + return -EINVAL; + + if (csdev->ea != NULL) + return -EINVAL; + + if (!etm_perf_up) + return -EPROBE_DEFER; + + ea = devm_kzalloc(pdev, sizeof(*ea), GFP_KERNEL); + if (!ea) + return -ENOMEM; + + name = dev_name(pdev); + /* See function coresight_get_sink_by_id() to know where this is used */ + hash = hashlen_hash(hashlen_string(NULL, name)); + + ea->attr.attr.name = devm_kstrdup(pdev, name, GFP_KERNEL); + if (!ea->attr.attr.name) + return -ENOMEM; + + ea->attr.attr.mode = 0444; + ea->attr.show = etm_perf_sink_name_show; + ea->var = (unsigned long *)hash; + + ret = sysfs_add_file_to_group(&pmu_dev->kobj, + &ea->attr.attr, "sinks"); + + if (!ret) + csdev->ea = ea; + + return ret; +} + +void etm_perf_del_symlink_sink(struct coresight_device *csdev) +{ + struct device *pmu_dev = etm_pmu.dev; + struct dev_ext_attribute *ea = csdev->ea; + + if (csdev->type != CORESIGHT_DEV_TYPE_SINK && + csdev->type != CORESIGHT_DEV_TYPE_LINKSINK) + return; + + if (!ea) + return; + + sysfs_remove_file_from_group(&pmu_dev->kobj, + &ea->attr.attr, "sinks"); + csdev->ea = NULL; +} + static int __init etm_perf_init(void) { int ret; diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h index da7d9336a15c..015213abe00a 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.h +++ b/drivers/hwtracing/coresight/coresight-etm-perf.h @@ -59,6 +59,8 @@ struct etm_event_data { #ifdef CONFIG_CORESIGHT int etm_perf_symlink(struct coresight_device *csdev, bool link); +int etm_perf_add_symlink_sink(struct coresight_device *csdev); +void etm_perf_del_symlink_sink(struct coresight_device *csdev); static inline void *etm_perf_sink_config(struct perf_output_handle *handle) { struct etm_event_data *data = perf_get_aux(handle); @@ -70,7 +72,9 @@ static inline void *etm_perf_sink_config(struct perf_output_handle *handle) #else static inline int etm_perf_symlink(struct coresight_device *csdev, bool link) { return -EINVAL; } - +int etm_perf_add_symlink_sink(struct coresight_device *csdev) +{ return -EINVAL; } +void etm_perf_del_symlink_sink(struct coresight_device *csdev) {} static inline void *etm_perf_sink_config(struct perf_output_handle *handle) { return NULL; diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 2b0df1a0a8df..d7fa90be6f42 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -18,6 +18,7 @@ #include #include +#include "coresight-etm-perf.h" #include "coresight-priv.h" static DEFINE_MUTEX(coresight_mutex); @@ -1167,6 +1168,22 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) goto err_out; } + if (csdev->type == CORESIGHT_DEV_TYPE_SINK || + csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) { + ret = etm_perf_add_symlink_sink(csdev); + + if (ret) { + device_unregister(&csdev->dev); + /* + * As with the above, all resources are free'd + * explicitly via coresight_device_release() triggered + * from put_device(), which is in turn called from + * function device_unregister(). + */ + goto err_out; + } + } + mutex_lock(&coresight_mutex); coresight_fixup_device_conns(csdev); @@ -1185,6 +1202,7 @@ EXPORT_SYMBOL_GPL(coresight_register); void coresight_unregister(struct coresight_device *csdev) { + etm_perf_del_symlink_sink(csdev); /* Remove references of that device in the topology */ coresight_remove_conns(csdev); device_unregister(&csdev->dev); -- cgit v1.2.3 From b5390f4b5e0b75634c7f08c88e97b5fe0e833599 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Tue, 5 Feb 2019 16:24:58 -0700 Subject: coresight: Use event attributes for sink selection This patch uses the information conveyed by perf_event::attr::config2 to select a sink to use for the session. That way a sink can easily be selected to be used by more than one source, something that isn't currently possible with the sysfs implementation. Signed-off-by: Mathieu Poirier Acked-by: Peter Zijlstra (Intel) Reviewed-by: Suzuki K Poulose Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etm-perf.c | 24 +++++++------- drivers/hwtracing/coresight/coresight-priv.h | 1 + drivers/hwtracing/coresight/coresight.c | 42 ++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 12 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index cdbdb28dc175..8c88bf0a1e5f 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -31,11 +31,14 @@ static DEFINE_PER_CPU(struct coresight_device *, csdev_src); PMU_FORMAT_ATTR(cycacc, "config:" __stringify(ETM_OPT_CYCACC)); PMU_FORMAT_ATTR(timestamp, "config:" __stringify(ETM_OPT_TS)); PMU_FORMAT_ATTR(retstack, "config:" __stringify(ETM_OPT_RETSTK)); +/* Sink ID - same for all ETMs */ +PMU_FORMAT_ATTR(sinkid, "config2:0-31"); static struct attribute *etm_config_formats_attr[] = { &format_attr_cycacc.attr, &format_attr_timestamp.attr, &format_attr_retstack.attr, + &format_attr_sinkid.attr, NULL, }; @@ -191,6 +194,7 @@ static void etm_free_aux(void *data) static void *etm_setup_aux(struct perf_event *event, void **pages, int nr_pages, bool overwrite) { + u32 id; int cpu = event->cpu; cpumask_t *mask; struct coresight_device *sink; @@ -201,18 +205,14 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, return NULL; INIT_WORK(&event_data->work, free_event_data); - /* - * In theory nothing prevent tracers in a trace session from being - * associated with different sinks, nor having a sink per tracer. But - * until we have HW with this kind of topology we need to assume tracers - * in a trace session are using the same sink. Therefore go through - * the coresight bus and pick the first enabled sink. - * - * When operated from sysFS users are responsible to enable the sink - * while from perf, the perf tools will do it based on the choice made - * on the cmd line. As such the "enable_sink" flag in sysFS is reset. - */ - sink = coresight_get_enabled_sink(true); + /* First get the selected sink from user space. */ + if (event->attr.config2) { + id = (u32)event->attr.config2; + sink = coresight_get_sink_by_id(id); + } else { + sink = coresight_get_enabled_sink(true); + } + if (!sink || !sink_ops(sink)->alloc_buffer) goto err; diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 579f34943bf1..b936c6d7e13f 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -147,6 +147,7 @@ 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_sink_by_id(u32 id); struct list_head *coresight_build_path(struct coresight_device *csdev, struct coresight_device *sink); void coresight_release_path(struct list_head *path); diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index d7fa90be6f42..29cef898afba 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -541,6 +542,47 @@ struct coresight_device *coresight_get_enabled_sink(bool deactivate) return dev ? to_coresight_device(dev) : NULL; } +static int coresight_sink_by_id(struct device *dev, void *data) +{ + struct coresight_device *csdev = to_coresight_device(dev); + unsigned long hash; + + if (csdev->type == CORESIGHT_DEV_TYPE_SINK || + csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) { + + if (!csdev->ea) + return 0; + /* + * See function etm_perf_add_symlink_sink() to know where + * this comes from. + */ + hash = (unsigned long)csdev->ea->var; + + if ((u32)hash == *(u32 *)data) + return 1; + } + + return 0; +} + +/** + * coresight_get_sink_by_id - returns the sink that matches the id + * @id: Id of the sink to match + * + * The name of a sink is unique, whether it is found on the AMBA bus or + * otherwise. As such the hash of that name can easily be used to identify + * a sink. + */ +struct coresight_device *coresight_get_sink_by_id(u32 id) +{ + struct device *dev = NULL; + + dev = bus_find_device(&coresight_bustype, NULL, &id, + coresight_sink_by_id); + + return dev ? to_coresight_device(dev) : NULL; +} + /* * coresight_grab_device - Power up this device and any of the helper * devices connected to it for trace operation. Since the helper devices -- cgit v1.2.3 From 8d86f6b4306f4be38b39d420456edf61a7b7119e Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 12 Feb 2019 15:43:02 -0600 Subject: intel_th: Mark expected switch fall-throughs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation to enabling -Wimplicit-fallthrough, mark switch cases where we are expecting to fall through. This patch fixes the following warnings: drivers/hwtracing/intel_th/sth.c: In function ‘sth_stm_packet’: drivers/hwtracing/intel_th/sth.c:86:7: warning: this statement may fall through [-Wimplicit-fallthrough=] reg += 4; ~~~~^~~~ drivers/hwtracing/intel_th/sth.c:87:2: note: here case STP_PACKET_XSYNC: ^~~~ drivers/hwtracing/intel_th/sth.c:88:7: warning: this statement may fall through [-Wimplicit-fallthrough=] reg += 8; ~~~~^~~~ drivers/hwtracing/intel_th/sth.c:89:2: note: here case STP_PACKET_TRIG: ^~~~ Warning level 3 was used: -Wimplicit-fallthrough=3 This patch is part of the ongoing efforts to enable -Wimplicit-fallthrough. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/sth.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/sth.c b/drivers/hwtracing/intel_th/sth.c index 4b7ae47789d2..3a1f4e650378 100644 --- a/drivers/hwtracing/intel_th/sth.c +++ b/drivers/hwtracing/intel_th/sth.c @@ -84,8 +84,12 @@ static ssize_t notrace sth_stm_packet(struct stm_data *stm_data, /* Global packets (GERR, XSYNC, TRIG) are sent with register writes */ case STP_PACKET_GERR: reg += 4; + /* fall through */ + case STP_PACKET_XSYNC: reg += 8; + /* fall through */ + case STP_PACKET_TRIG: if (flags & STP_PACKET_TIMESTAMPED) reg += 4; -- cgit v1.2.3 From ba828cc9dcc8ffefd0d17165be9b132bd5232063 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Mon, 12 Nov 2018 13:30:24 +0200 Subject: intel_th: Only create useful device nodes Right now, the driver will create a device node for each output port, with the intent to provide read access to that port's data. However, only the memory ports are readable this way (msc0, msc1). Other output ports don't need device nodes, so remove them. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index fc6b7f8b62fb..7c1acc2f801c 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -422,6 +422,7 @@ static const struct intel_th_subdevice { unsigned nres; unsigned type; unsigned otype; + bool mknode; unsigned scrpd; int id; } intel_th_subdevices[] = { @@ -456,6 +457,7 @@ static const struct intel_th_subdevice { .name = "msc", .id = 0, .type = INTEL_TH_OUTPUT, + .mknode = true, .otype = GTH_MSU, .scrpd = SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC0_IS_ENABLED, }, @@ -476,6 +478,7 @@ static const struct intel_th_subdevice { .name = "msc", .id = 1, .type = INTEL_TH_OUTPUT, + .mknode = true, .otype = GTH_MSU, .scrpd = SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC1_IS_ENABLED, }, @@ -635,7 +638,8 @@ intel_th_subdevice_alloc(struct intel_th *th, } if (subdev->type == INTEL_TH_OUTPUT) { - thdev->dev.devt = MKDEV(th->major, th->num_thdevs); + if (subdev->mknode) + thdev->dev.devt = MKDEV(th->major, th->num_thdevs); thdev->output.type = subdev->otype; thdev->output.port = -1; thdev->output.scratchpad = subdev->scrpd; -- cgit v1.2.3 From 1d2ef028bf9a9272c658782d9c75f60658770ba4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 4 May 2018 22:19:25 +0300 Subject: intel_th: pti: Use sysfs_match_string() helper Use sysfs_match_string() helper instead of open coded variant. Signed-off-by: Andy Shevchenko Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/pti.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/pti.c b/drivers/hwtracing/intel_th/pti.c index 56694339cb06..0da6b787f553 100644 --- a/drivers/hwtracing/intel_th/pti.c +++ b/drivers/hwtracing/intel_th/pti.c @@ -272,19 +272,17 @@ static ssize_t lpp_dest_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct pti_device *pti = dev_get_drvdata(dev); - ssize_t ret = -EINVAL; int i; - for (i = 0; i < ARRAY_SIZE(lpp_dest_str); i++) - if (sysfs_streq(buf, lpp_dest_str[i])) - break; + i = sysfs_match_string(lpp_dest_str, buf); + if (i < 0) + return i; - if (i < ARRAY_SIZE(lpp_dest_str) && pti->lpp_dest_mask & BIT(i)) { - pti->lpp_dest = i; - ret = size; - } + if (!(pti->lpp_dest_mask & BIT(i))) + return -EINVAL; - return ret; + pti->lpp_dest = i; + return size; } static DEVICE_ATTR_RW(lpp_dest); -- cgit v1.2.3 From 9ed3f22223c33347ed963e7c7019cf2956dd4e37 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Thu, 24 Jan 2019 15:11:53 +0200 Subject: intel_th: Don't reference unassigned outputs When an output port driver is removed, also remove references to it from any masters. Failing to do this causes a NULL ptr dereference when configuring another output port: > BUG: unable to handle kernel NULL pointer dereference at 000000000000000d > RIP: 0010:master_attr_store+0x9d/0x160 [intel_th_gth] > Call Trace: > dev_attr_store+0x1b/0x30 > sysfs_kf_write+0x3c/0x50 > kernfs_fop_write+0x125/0x1a0 > __vfs_write+0x3a/0x190 > ? __vfs_write+0x5/0x190 > ? _cond_resched+0x1a/0x50 > ? rcu_all_qs+0x5/0xb0 > ? __vfs_write+0x5/0x190 > vfs_write+0xb8/0x1b0 > ksys_write+0x55/0xc0 > __x64_sys_write+0x1a/0x20 > do_syscall_64+0x5a/0x140 > entry_SYSCALL_64_after_hwframe+0x44/0xa9 Signed-off-by: Alexander Shishkin Fixes: b27a6a3f97b9 ("intel_th: Add Global Trace Hub driver") CC: stable@vger.kernel.org # v4.4+ Reported-by: Ammy Yi --- drivers/hwtracing/intel_th/gth.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c index 8426b7970c14..cc287cf6eb29 100644 --- a/drivers/hwtracing/intel_th/gth.c +++ b/drivers/hwtracing/intel_th/gth.c @@ -607,6 +607,7 @@ static void intel_th_gth_unassign(struct intel_th_device *thdev, { struct gth_device *gth = dev_get_drvdata(&thdev->dev); int port = othdev->output.port; + int master; if (thdev->host_mode) return; @@ -615,6 +616,9 @@ static void intel_th_gth_unassign(struct intel_th_device *thdev, othdev->output.port = -1; othdev->output.active = false; gth->output[port].output = NULL; + for (master = 0; master < TH_CONFIGURABLE_MASTERS; master++) + if (gth->master[master] == port) + gth->master[master] = -1; spin_unlock(>h->gth_lock); } -- cgit v1.2.3 From a1d75dad3a2c689e70a1c4e0214cca9de741d0aa Mon Sep 17 00:00:00 2001 From: Zhi Jin Date: Thu, 6 Sep 2018 15:22:10 +0800 Subject: stm class: Fix an endless loop in channel allocation There is a bug in the channel allocation logic that leads to an endless loop when looking for a contiguous range of channels in a range with a mixture of free and occupied channels. For example, opening three consequtive channels, closing the first two and requesting 4 channels in a row will trigger this soft lockup. The bug is that the search loop forgets to skip over the range once it detects that one channel in that range is occupied. Restore the original intent to the logic by fixing the omission. Signed-off-by: Zhi Jin Signed-off-by: Alexander Shishkin Fixes: 7bd1d4093c2f ("stm class: Introduce an abstraction for System Trace Module devices") CC: stable@vger.kernel.org # v4.4+ --- drivers/hwtracing/stm/core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c index 93ce3aa740a9..c80b064224f6 100644 --- a/drivers/hwtracing/stm/core.c +++ b/drivers/hwtracing/stm/core.c @@ -244,6 +244,9 @@ static int find_free_channels(unsigned long *bitmap, unsigned int start, ; if (i == width) return pos; + + /* step over [pos..pos+i) to continue search */ + pos += i; } return -1; -- cgit v1.2.3 From bf7cbaae0831252b416f375ca9b1027ecd4642dd Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Thu, 21 Feb 2019 14:19:17 +0200 Subject: stm class: Prevent division by zero Using STP_POLICY_ID_SET ioctl command with dummy_stm device, or any STM device that supplies zero mmio channel size, will trigger a division by zero bug in the kernel. Prevent this by disallowing channel widths other than 1 for such devices. Signed-off-by: Alexander Shishkin Fixes: 7bd1d4093c2f ("stm class: Introduce an abstraction for System Trace Module devices") CC: stable@vger.kernel.org # v4.4+ --- drivers/hwtracing/stm/core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c index c80b064224f6..c7ba8acfd4d5 100644 --- a/drivers/hwtracing/stm/core.c +++ b/drivers/hwtracing/stm/core.c @@ -735,7 +735,7 @@ static int stm_char_policy_set_ioctl(struct stm_file *stmf, void __user *arg) struct stm_device *stm = stmf->stm; struct stp_policy_id *id; char *ids[] = { NULL, NULL }; - int ret = -EINVAL; + int ret = -EINVAL, wlimit = 1; u32 size; if (stmf->output.nr_chans) @@ -763,8 +763,10 @@ static int stm_char_policy_set_ioctl(struct stm_file *stmf, void __user *arg) if (id->__reserved_0 || id->__reserved_1) goto err_free; - if (id->width < 1 || - id->width > PAGE_SIZE / stm->data->sw_mmiosz) + if (stm->data->sw_mmiosz) + wlimit = PAGE_SIZE / stm->data->sw_mmiosz; + + if (id->width < 1 || id->width > wlimit) goto err_free; ids[0] = id->id; -- cgit v1.2.3 From 5666dfd1d8a45a167f0d8b4ef47ea7f780b1f24a Mon Sep 17 00:00:00 2001 From: Sai Prakash Ranjan Date: Mon, 25 Feb 2019 10:54:01 -0700 Subject: coresight: etm4x: Add support to enable ETMv4.2 SDM845 has ETMv4.2 and can use the existing etm4x driver. But the current etm driver checks only for ETMv4.0 and errors out for other etm4x versions. This patch adds this missing support to enable SoC's with ETMv4x to use same driver by checking only the ETM architecture major version number. Without this change, we get below error during etm probe: / # dmesg | grep etm [ 6.660093] coresight-etm4x: probe of 7040000.etm failed with error -22 [ 6.666902] coresight-etm4x: probe of 7140000.etm failed with error -22 [ 6.673708] coresight-etm4x: probe of 7240000.etm failed with error -22 [ 6.680511] coresight-etm4x: probe of 7340000.etm failed with error -22 [ 6.687313] coresight-etm4x: probe of 7440000.etm failed with error -22 [ 6.694113] coresight-etm4x: probe of 7540000.etm failed with error -22 [ 6.700914] coresight-etm4x: probe of 7640000.etm failed with error -22 [ 6.707717] coresight-etm4x: probe of 7740000.etm failed with error -22 With this change, etm probe is successful: / # dmesg | grep etm [ 6.659198] coresight-etm4x 7040000.etm: CPU0: ETM v4.2 initialized [ 6.665848] coresight-etm4x 7140000.etm: CPU1: ETM v4.2 initialized [ 6.672493] coresight-etm4x 7240000.etm: CPU2: ETM v4.2 initialized [ 6.679129] coresight-etm4x 7340000.etm: CPU3: ETM v4.2 initialized [ 6.685770] coresight-etm4x 7440000.etm: CPU4: ETM v4.2 initialized [ 6.692403] coresight-etm4x 7540000.etm: CPU5: ETM v4.2 initialized [ 6.699024] coresight-etm4x 7640000.etm: CPU6: ETM v4.2 initialized [ 6.705646] coresight-etm4x 7740000.etm: CPU7: ETM v4.2 initialized Signed-off-by: Sai Prakash Ranjan Reviewed-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etm4x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 53e2fb6e86f6..fe76b176974a 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -55,7 +55,8 @@ static void etm4_os_unlock(struct etmv4_drvdata *drvdata) static bool etm4_arch_supported(u8 arch) { - switch (arch) { + /* Mask out the minor version number */ + switch (arch & 0xf0) { case ETM_ARCH_V4: break; default: -- cgit v1.2.3 From 91d3f8a629849968dc91d6ce54f2d46abf4feb7f Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 1 Mar 2019 10:09:55 +0200 Subject: intel_th: gth: Fix an off-by-one in output unassigning Commit 9ed3f22223c3 ("intel_th: Don't reference unassigned outputs") fixes a NULL dereference for all masters except the last one ("256+"), which keeps the stale pointer after the output driver had been unassigned. Fix the off-by-one. Signed-off-by: Alexander Shishkin Fixes: 9ed3f22223c3 ("intel_th: Don't reference unassigned outputs") Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/intel_th/gth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c index cc287cf6eb29..edc52d75e6bd 100644 --- a/drivers/hwtracing/intel_th/gth.c +++ b/drivers/hwtracing/intel_th/gth.c @@ -616,7 +616,7 @@ static void intel_th_gth_unassign(struct intel_th_device *thdev, othdev->output.port = -1; othdev->output.active = false; gth->output[port].output = NULL; - for (master = 0; master < TH_CONFIGURABLE_MASTERS; master++) + for (master = 0; master <= TH_CONFIGURABLE_MASTERS; master++) if (gth->master[master] == port) gth->master[master] = -1; spin_unlock(>h->gth_lock); -- cgit v1.2.3