From ccf45b18ce89f598c69a0c945ced1635013fc0b1 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Tue, 7 Aug 2018 00:14:24 -0700 Subject: [PATCH 1/5] rpmsg: char: Migrate to iter versions of read and write In order to be able to use the aio interface for writing to a rpmsg_char the write_iter function must be implemented, so migrate to iter version for read and write functions. Regular read and write uses the iter methods if present and is as such unaffected. Signed-off-by: Bjorn Andersson --- drivers/rpmsg/rpmsg_char.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c index a76b963a7e50..eea5ebbb5119 100644 --- a/drivers/rpmsg/rpmsg_char.c +++ b/drivers/rpmsg/rpmsg_char.c @@ -167,9 +167,9 @@ static int rpmsg_eptdev_release(struct inode *inode, struct file *filp) return 0; } -static ssize_t rpmsg_eptdev_read(struct file *filp, char __user *buf, - size_t len, loff_t *f_pos) +static ssize_t rpmsg_eptdev_read_iter(struct kiocb *iocb, struct iov_iter *to) { + struct file *filp = iocb->ki_filp; struct rpmsg_eptdev *eptdev = filp->private_data; unsigned long flags; struct sk_buff *skb; @@ -205,8 +205,8 @@ static ssize_t rpmsg_eptdev_read(struct file *filp, char __user *buf, if (!skb) return -EFAULT; - use = min_t(size_t, len, skb->len); - if (copy_to_user(buf, skb->data, use)) + use = min_t(size_t, iov_iter_count(to), skb->len); + if (copy_to_iter(skb->data, use, to) != use) use = -EFAULT; kfree_skb(skb); @@ -214,16 +214,21 @@ static ssize_t rpmsg_eptdev_read(struct file *filp, char __user *buf, return use; } -static ssize_t rpmsg_eptdev_write(struct file *filp, const char __user *buf, - size_t len, loff_t *f_pos) +static ssize_t rpmsg_eptdev_write_iter(struct kiocb *iocb, + struct iov_iter *from) { + struct file *filp = iocb->ki_filp; struct rpmsg_eptdev *eptdev = filp->private_data; + size_t len = iov_iter_count(from); void *kbuf; int ret; - kbuf = memdup_user(buf, len); - if (IS_ERR(kbuf)) - return PTR_ERR(kbuf); + kbuf = kzalloc(len, GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + + if (!copy_from_iter_full(kbuf, len, from)) + return -EFAULT; if (mutex_lock_interruptible(&eptdev->ept_lock)) { ret = -ERESTARTSYS; @@ -281,8 +286,8 @@ static const struct file_operations rpmsg_eptdev_fops = { .owner = THIS_MODULE, .open = rpmsg_eptdev_open, .release = rpmsg_eptdev_release, - .read = rpmsg_eptdev_read, - .write = rpmsg_eptdev_write, + .read_iter = rpmsg_eptdev_read_iter, + .write_iter = rpmsg_eptdev_write_iter, .poll = rpmsg_eptdev_poll, .unlocked_ioctl = rpmsg_eptdev_ioctl, .compat_ioctl = rpmsg_eptdev_ioctl, From c8a54c0c9a7dbb8b99851e3a9cb2dacabf3b80c6 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 27 Aug 2018 20:52:43 -0500 Subject: [PATCH 2/5] rpmsg: Convert to using %pOFn instead of device_node.name In preparation to remove the node name pointer from struct device_node, convert printf users to use the %pOFn format specifier. Cc: Ohad Ben-Cohen Cc: Bjorn Andersson Cc: linux-remoteproc@vger.kernel.org Signed-off-by: Rob Herring Signed-off-by: Bjorn Andersson --- drivers/rpmsg/qcom_glink_smem.c | 2 +- drivers/rpmsg/qcom_smd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c index 2b5cf2790954..ab23da3d7131 100644 --- a/drivers/rpmsg/qcom_glink_smem.c +++ b/drivers/rpmsg/qcom_glink_smem.c @@ -205,7 +205,7 @@ struct qcom_glink *qcom_glink_smem_register(struct device *parent, dev->parent = parent; dev->of_node = node; dev->release = qcom_glink_smem_release; - dev_set_name(dev, "%s:%s", node->parent->name, node->name); + dev_set_name(dev, "%pOFn:%pOFn", node->parent, node); ret = device_register(dev); if (ret) { pr_err("failed to register glink edge\n"); diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index 8da83a4ebadc..0dae7c9f4a8f 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -1454,7 +1454,7 @@ struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent, edge->dev.release = qcom_smd_edge_release; edge->dev.of_node = node; edge->dev.groups = qcom_smd_edge_groups; - dev_set_name(&edge->dev, "%s:%s", dev_name(parent), node->name); + dev_set_name(&edge->dev, "%s:%pOFn", dev_name(parent), node); ret = device_register(&edge->dev); if (ret) { pr_err("failed to register smd edge\n"); From f0beb4ba9b185d497c8efe7b349363700092aee0 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Fri, 27 Jul 2018 17:47:27 +0530 Subject: [PATCH 3/5] rpmsg: glink: Remove chunk size word align warning It is possible for the chunk sizes coming from the non RPM remote procs to not be word aligned. Remove the alignment warning and continue to read from the FIFO so execution is not stalled. Signed-off-by: Chris Lew Signed-off-by: Arun Kumar Neelakantam Signed-off-by: Bjorn Andersson --- drivers/rpmsg/qcom_glink_native.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index e2ce4e638258..f46c787733e8 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -792,9 +792,6 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail) return -EAGAIN; } - if (WARN(chunk_size % 4, "Incoming data must be word aligned\n")) - return -EINVAL; - rcid = le16_to_cpu(hdr.msg.param1); spin_lock_irqsave(&glink->idr_lock, flags); channel = idr_find(&glink->rcids, rcid); From 940c620d6af8fca7d115de40f19870fba415efac Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 27 Sep 2018 22:36:27 +0100 Subject: [PATCH 4/5] rpmsg: smd: fix memory leak on channel create Currently a failed allocation of channel->name leads to an immediate return without freeing channel. Fix this by setting ret to -ENOMEM and jumping to an exit path that kfree's channel. Detected by CoverityScan, CID#1473692 ("Resource Leak") Fixes: 53e2822e56c7 ("rpmsg: Introduce Qualcomm SMD backend") Cc: stable@vger.kernel.org Signed-off-by: Colin Ian King Signed-off-by: Bjorn Andersson --- drivers/rpmsg/qcom_smd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index 0dae7c9f4a8f..4abbeea782fa 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -1122,8 +1122,10 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed channel->edge = edge; channel->name = kstrdup(name, GFP_KERNEL); - if (!channel->name) - return ERR_PTR(-ENOMEM); + if (!channel->name) { + ret = -ENOMEM; + goto free_channel; + } spin_lock_init(&channel->tx_lock); spin_lock_init(&channel->recv_lock); @@ -1173,6 +1175,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed free_name_and_channel: kfree(channel->name); +free_channel: kfree(channel); return ERR_PTR(ret); From 928002a5e9dab2ddc1a0fe3e00739e89be30dc6b Mon Sep 17 00:00:00 2001 From: Arun Kumar Neelakantam Date: Wed, 3 Oct 2018 17:08:20 +0530 Subject: [PATCH 5/5] rpmsg: glink: smem: Support rx peak for size less than 4 bytes The current rx peak function fails to read the data if size is less than 4bytes. Use memcpy_fromio to support data reads of size less than 4 bytes. Cc: stable@vger.kernel.org Fixes: f0beb4ba9b18 ("rpmsg: glink: Remove chunk size word align warning") Signed-off-by: Arun Kumar Neelakantam Signed-off-by: Bjorn Andersson --- drivers/rpmsg/qcom_glink_smem.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c index ab23da3d7131..64a5ce324c7f 100644 --- a/drivers/rpmsg/qcom_glink_smem.c +++ b/drivers/rpmsg/qcom_glink_smem.c @@ -89,15 +89,11 @@ static void glink_smem_rx_peak(struct qcom_glink_pipe *np, tail -= pipe->native.length; len = min_t(size_t, count, pipe->native.length - tail); - if (len) { - __ioread32_copy(data, pipe->fifo + tail, - len / sizeof(u32)); - } + if (len) + memcpy_fromio(data, pipe->fifo + tail, len); - if (len != count) { - __ioread32_copy(data + len, pipe->fifo, - (count - len) / sizeof(u32)); - } + if (len != count) + memcpy_fromio(data + len, pipe->fifo, (count - len)); } static void glink_smem_rx_advance(struct qcom_glink_pipe *np,