Unverified Commit a8adb1a9 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!2642 Synchronize coresight driver bugfix patches to openEuler

Merge Pull Request from: @ci-robot 
 
PR sync from: Junhao He <hejunhao3@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/JFWERSUEK7RF2T3JACT7R6A66U3RMD6E/ 
1. Fix memory leak
coresight: Fix memory leak in acpi_buffer->pointer
2. Fix TRBE bug
coresight: trbe: Fix TRBE potential sleep in atomic context
coresight: trbe: Allocate platform data per device
coresight: trbe: Fix return value check in arm_trbe_register_coresight_cpu()
3. Fix ETR bug
coresight: Fix run time warnings while reusing ETR buffer
coresight: tmc-etr: Disable warnings for allocation failures


Junhao He (2)
  coresight: Fix memory leak in acpi_buffer->pointer
  coresight: trbe: Fix TRBE potential sleep in atomic context

Linu Cherian (1):
  coresight: Fix run time warnings while reusing ETR buffer

Suzuki K Poulose (2):
  coresight: trbe: Allocate platform data per device
  coresight: tmc-etr: Disable warnings for allocation failures

Wei Yongjun (1):
  coresight: trbe: Fix return value check in
    arm_trbe_register_coresight_cpu()

 
https://gitee.com/openeuler/kernel/issues/I8BC14 
 
Link:https://gitee.com/openeuler/kernel/pulls/2642

 

Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents c4df3531 4f7671fa
Loading
Loading
Loading
Loading
+30 −16
Original line number Diff line number Diff line
@@ -518,19 +518,18 @@ static inline bool acpi_validate_dsd_graph(const union acpi_object *graph)

/* acpi_get_dsd_graph	- Find the _DSD Graph property for the given device. */
static const union acpi_object *
acpi_get_dsd_graph(struct acpi_device *adev)
acpi_get_dsd_graph(struct acpi_device *adev, struct acpi_buffer *buf)
{
	int i;
	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
	acpi_status status;
	const union acpi_object *dsd;

	status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL,
					    &buf, ACPI_TYPE_PACKAGE);
					    buf, ACPI_TYPE_PACKAGE);
	if (ACPI_FAILURE(status))
		return NULL;

	dsd = buf.pointer;
	dsd = buf->pointer;

	/*
	 * _DSD property consists tuples { Prop_UUID, Package() }
@@ -581,12 +580,12 @@ acpi_validate_coresight_graph(const union acpi_object *cs_graph)
 * returns NULL.
 */
static const union acpi_object *
acpi_get_coresight_graph(struct acpi_device *adev)
acpi_get_coresight_graph(struct acpi_device *adev, struct acpi_buffer *buf)
{
	const union acpi_object *graph_list, *graph;
	int i, nr_graphs;

	graph_list = acpi_get_dsd_graph(adev);
	graph_list = acpi_get_dsd_graph(adev, buf);
	if (!graph_list)
		return graph_list;

@@ -686,22 +685,24 @@ static int acpi_coresight_parse_link(struct acpi_device *adev,
static int acpi_coresight_parse_graph(struct acpi_device *adev,
				      struct coresight_platform_data *pdata)
{
	int ret = 0;
	int rc, i, nlinks;
	const union acpi_object *graph;
	struct coresight_connection *conns, *ptr;
	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };

	pdata->nr_inport = pdata->nr_outport = 0;
	graph = acpi_get_coresight_graph(adev);
	graph = acpi_get_coresight_graph(adev, &buf);
	/*
	 * There are no graph connections, which is fine for some components.
	 * e.g., ETE
	 */
	if (!graph)
		return 0;
		goto free;

	nlinks = graph->package.elements[2].integer.value;
	if (!nlinks)
		return 0;
		goto free;

	/*
	 * To avoid scanning the table twice (once for finding the number of
@@ -710,16 +711,20 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
	 * it to the pdata.
	 */
	conns = devm_kcalloc(&adev->dev, nlinks, sizeof(*conns), GFP_KERNEL);
	if (!conns)
		return -ENOMEM;
	if (!conns) {
		ret = -ENOMEM;
		goto free;
	}
	ptr = conns;
	for (i = 0; i < nlinks; i++) {
		const union acpi_object *link = &graph->package.elements[3 + i];
		int dir;

		dir = acpi_coresight_parse_link(adev, link, ptr);
		if (dir < 0)
			return dir;
		if (dir < 0) {
			ret = dir;
			goto free;
		}

		if (dir == ACPI_CORESIGHT_LINK_MASTER) {
			if (ptr->outport >= pdata->nr_outport)
@@ -740,8 +745,10 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
	}

	rc = coresight_alloc_conns(&adev->dev, pdata);
	if (rc)
		return rc;
	if (rc) {
		ret = rc;
		goto free;
	}

	/* Copy the connection information to the final location */
	for (i = 0; conns + i < ptr; i++) {
@@ -753,7 +760,14 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
	}

	devm_kfree(&adev->dev, conns);
	return 0;
free:
	/*
	 * When ACPI fails to alloc a buffer, it will free the buffer
	 * created via ACPI_ALLOCATE_BUFFER and set to NULL.
	 * ACPI_FREE can handle NULL pointers, so free it directly.
	 */
	ACPI_FREE(buf.pointer);
	return ret;
}

/*
+12 −11
Original line number Diff line number Diff line
@@ -611,7 +611,8 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata,

	flat_buf->vaddr = dma_alloc_noncoherent(real_dev, etr_buf->size,
						&flat_buf->daddr,
						DMA_FROM_DEVICE, GFP_KERNEL);
						DMA_FROM_DEVICE,
						GFP_KERNEL | __GFP_NOWARN);
	if (!flat_buf->vaddr) {
		kfree(flat_buf);
		return -ENOMEM;
@@ -1191,16 +1192,6 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
		goto out;
	}

	/*
	 * In sysFS mode we can have multiple writers per sink.  Since this
	 * sink is already enabled no memory is needed and the HW need not be
	 * touched, even if the buffer size has changed.
	 */
	if (drvdata->mode == CS_MODE_SYSFS) {
		atomic_inc(csdev->refcnt);
		goto out;
	}

	/*
	 * If we don't have a buffer or it doesn't match the requested size,
	 * use the buffer allocated above. Otherwise reuse the existing buffer.
@@ -1211,6 +1202,16 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
		drvdata->sysfs_buf = new_buf;
	}

	/*
	 * In sysFS mode we can have multiple writers per sink.  Since this
	 * sink is already enabled no memory is needed and the HW need not be
	 * touched, even if the buffer size has changed.
	 */
	if (drvdata->mode == CS_MODE_SYSFS) {
		atomic_inc(csdev->refcnt);
		goto out;
	}

	ret = tmc_etr_enable_hw(drvdata, drvdata->sysfs_buf);
	if (!ret) {
		drvdata->mode = CS_MODE_SYSFS;
+20 −21
Original line number Diff line number Diff line
@@ -921,6 +921,14 @@ static void arm_trbe_enable_cpu(void *info)
	enable_percpu_irq(drvdata->irq, IRQ_TYPE_NONE);
}

static void arm_trbe_disable_cpu(void *info)
{
	struct trbe_drvdata *drvdata = info;

	disable_percpu_irq(drvdata->irq);
	trbe_reset_local();
}

static void arm_trbe_register_coresight_cpu(struct trbe_drvdata *drvdata, int cpu)
{
	struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
@@ -937,13 +945,16 @@ static void arm_trbe_register_coresight_cpu(struct trbe_drvdata *drvdata, int cp

	dev = &cpudata->drvdata->pdev->dev;
	desc.name = devm_kasprintf(dev, GFP_KERNEL, "trbe%d", cpu);
	if (IS_ERR(desc.name))
	if (!desc.name)
		goto cpu_clear;

	desc.pdata = coresight_get_platform_data(dev);
	if (IS_ERR(desc.pdata))
		goto cpu_clear;

	desc.type = CORESIGHT_DEV_TYPE_SINK;
	desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_PERCPU_SYSMEM;
	desc.ops = &arm_trbe_cs_ops;
	desc.pdata = dev_get_platdata(dev);
	desc.groups = arm_trbe_groups;
	desc.dev = dev;
	trbe_csdev = coresight_register(&desc);
@@ -993,18 +1004,12 @@ static void arm_trbe_probe_cpu(void *info)
	cpumask_clear_cpu(cpu, &drvdata->supported_cpus);
}

static void arm_trbe_remove_coresight_cpu(void *info)
static void arm_trbe_remove_coresight_cpu(struct trbe_drvdata *drvdata, int cpu)
{
	int cpu = smp_processor_id();
	struct trbe_drvdata *drvdata = info;
	struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
	struct coresight_device *trbe_csdev = coresight_get_percpu_sink(cpu);

	disable_percpu_irq(drvdata->irq);
	trbe_reset_local();
	if (trbe_csdev) {
		coresight_unregister(trbe_csdev);
		cpudata->drvdata = NULL;
		coresight_set_percpu_sink(cpu, NULL);
	}
}
@@ -1033,8 +1038,10 @@ static int arm_trbe_remove_coresight(struct trbe_drvdata *drvdata)
{
	int cpu;

	for_each_cpu(cpu, &drvdata->supported_cpus)
		smp_call_function_single(cpu, arm_trbe_remove_coresight_cpu, drvdata, 1);
	for_each_cpu(cpu, &drvdata->supported_cpus) {
		smp_call_function_single(cpu, arm_trbe_disable_cpu, drvdata, 1);
		arm_trbe_remove_coresight_cpu(drvdata, cpu);
	}
	free_percpu(drvdata->cpudata);
	return 0;
}
@@ -1066,10 +1073,8 @@ static int arm_trbe_cpu_teardown(unsigned int cpu, struct hlist_node *node)
{
	struct trbe_drvdata *drvdata = hlist_entry_safe(node, struct trbe_drvdata, hotplug_node);

	if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) {
		disable_percpu_irq(drvdata->irq);
		trbe_reset_local();
	}
	if (cpumask_test_cpu(cpu, &drvdata->supported_cpus))
		arm_trbe_disable_cpu(drvdata);
	return 0;
}

@@ -1137,7 +1142,6 @@ static void arm_trbe_remove_irq(struct trbe_drvdata *drvdata)

static int arm_trbe_device_probe(struct platform_device *pdev)
{
	struct coresight_platform_data *pdata;
	struct trbe_drvdata *drvdata;
	struct device *dev = &pdev->dev;
	int ret;
@@ -1146,12 +1150,7 @@ static int arm_trbe_device_probe(struct platform_device *pdev)
	if (!drvdata)
		return -ENOMEM;

	pdata = coresight_get_platform_data(dev);
	if (IS_ERR(pdata))
		return PTR_ERR(pdata);

	dev_set_drvdata(dev, drvdata);
	dev->platform_data = pdata;
	drvdata->pdev = pdev;
	ret = arm_trbe_probe_irq(pdev, drvdata);
	if (ret)