diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index f8a3da1bdc19..16cd54324246 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -608,9 +608,8 @@ void rproc_vdev_release(struct kref *ref) static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc, int offset, int avail) { - struct rproc_mem_entry *trace; + struct rproc_debug_trace *trace; struct device *dev = &rproc->dev; - void *ptr; char name[15]; if (sizeof(*rsc) > avail) { @@ -624,28 +623,23 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc, return -EINVAL; } - /* what's the kernel address of this resource ? */ - ptr = rproc_da_to_va(rproc, rsc->da, rsc->len); - if (!ptr) { - dev_err(dev, "erroneous trace resource entry\n"); - return -EINVAL; - } - trace = kzalloc(sizeof(*trace), GFP_KERNEL); if (!trace) return -ENOMEM; /* set the trace buffer dma properties */ - trace->len = rsc->len; - trace->va = ptr; + trace->trace_mem.len = rsc->len; + trace->trace_mem.da = rsc->da; + + /* set pointer on rproc device */ + trace->rproc = rproc; /* make sure snprintf always null terminates, even if truncating */ snprintf(name, sizeof(name), "trace%d", rproc->num_traces); /* create the debugfs entry */ - trace->priv = rproc_create_trace_file(name, rproc, trace); - if (!trace->priv) { - trace->va = NULL; + trace->tfile = rproc_create_trace_file(name, rproc, trace); + if (!trace->tfile) { kfree(trace); return -EINVAL; } @@ -654,8 +648,8 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc, rproc->num_traces++; - dev_dbg(dev, "%s added: va %pK, da 0x%x, len 0x%x\n", - name, ptr, rsc->da, rsc->len); + dev_dbg(dev, "%s added: da 0x%x, len 0x%x\n", + name, rsc->da, rsc->len); return 0; } @@ -1249,15 +1243,16 @@ static void rproc_coredump_cleanup(struct rproc *rproc) static void rproc_resource_cleanup(struct rproc *rproc) { struct rproc_mem_entry *entry, *tmp; + struct rproc_debug_trace *trace, *ttmp; struct rproc_vdev *rvdev, *rvtmp; struct device *dev = &rproc->dev; /* clean up debugfs trace entries */ - list_for_each_entry_safe(entry, tmp, &rproc->traces, node) { - rproc_remove_trace_file(entry->priv); + list_for_each_entry_safe(trace, ttmp, &rproc->traces, node) { + rproc_remove_trace_file(trace->tfile); rproc->num_traces--; - list_del(&entry->node); - kfree(entry); + list_del(&trace->node); + kfree(trace); } /* clean up iommu mapping entries */ diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c index f330a9ad014f..6da934b8dc4b 100644 --- a/drivers/remoteproc/remoteproc_debugfs.c +++ b/drivers/remoteproc/remoteproc_debugfs.c @@ -47,10 +47,23 @@ static struct dentry *rproc_dbg; static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf, size_t count, loff_t *ppos) { - struct rproc_mem_entry *trace = filp->private_data; - int len = strnlen(trace->va, trace->len); + struct rproc_debug_trace *data = filp->private_data; + struct rproc_mem_entry *trace = &data->trace_mem; + void *va; + char buf[100]; + int len; - return simple_read_from_buffer(userbuf, count, ppos, trace->va, len); + va = rproc_da_to_va(data->rproc, trace->da, trace->len); + + if (!va) { + len = scnprintf(buf, sizeof(buf), "Trace %s not available\n", + trace->name); + va = buf; + } else { + len = strnlen(va, trace->len); + } + + return simple_read_from_buffer(userbuf, count, ppos, va, len); } static const struct file_operations trace_rproc_ops = { @@ -312,7 +325,7 @@ void rproc_remove_trace_file(struct dentry *tfile) } struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, - struct rproc_mem_entry *trace) + struct rproc_debug_trace *trace) { struct dentry *tfile; diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h index 2698775c5005..45ff76a06c72 100644 --- a/drivers/remoteproc/remoteproc_internal.h +++ b/drivers/remoteproc/remoteproc_internal.h @@ -25,6 +25,13 @@ struct rproc; +struct rproc_debug_trace { + struct rproc *rproc; + struct dentry *tfile; + struct list_head node; + struct rproc_mem_entry trace_mem; +}; + /* from remoteproc_core.c */ void rproc_release(struct kref *kref); irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id); @@ -37,7 +44,7 @@ int rproc_remove_virtio_dev(struct device *dev, void *data); /* from remoteproc_debugfs.c */ void rproc_remove_trace_file(struct dentry *tfile); struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, - struct rproc_mem_entry *trace); + struct rproc_debug_trace *trace); void rproc_delete_debug_dir(struct rproc *rproc); void rproc_create_debug_dir(struct rproc *rproc); void rproc_init_debugfs(void);