Merge tag 'rpmsg-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux

Pull rpmsg updates from Bjorn Andersson:
 "Fix a GLINK endpoint teardown deadlock during driver detach and order
  SMEM FIFO reads after the remote-updated availability check.

  Prevent duplicate rpmsg character endpoint teardown when remoteproc
  shutdown races with RPMSG_DESTROY_EPT_IOCTL.

  Replace unsafe string and sysfs formatting helpers, and correct the
  unregister_rpmsg_driver() return value documentation"

* tag 'rpmsg-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux:
  rpmsg: glink: smem: order FIFO read after availability check
  rpmsg: glink: fix deadlock in endpoint destroy during driver detach
  rpmsg: char: Check for ongoing chrdev destroy
  rpmsg: glink: Replace strcpy() with strscpy()
  rpmsg: core: Fix incorrect return value documentation
  rpmsg: Replace sprintf() with sysfs_emit() in sysfs show
This commit is contained in:
Linus Torvalds
2026-08-25 14:13:38 -07:00
6 changed files with 19 additions and 13 deletions

View File

@@ -212,7 +212,6 @@ be probed with.
unregisters an rpmsg driver from the rpmsg bus. user should provide
a pointer to a previously-registered rpmsg_driver struct.
Returns 0 on success, and an appropriate error value on failure.
Typical usage

View File

@@ -501,7 +501,7 @@ static int qcom_glink_send_open_req(struct qcom_glink *glink,
req->cmd = cpu_to_le16(GLINK_CMD_OPEN);
req->param1 = cpu_to_le16(channel->lcid);
req->param2 = cpu_to_le32(name_len);
strcpy(req->data, channel->name);
strscpy(req->data, channel->name, GLINK_NAME_SIZE);
trace_qcom_glink_cmd_open_tx(glink->label, channel->name,
channel->lcid, channel->rcid);
@@ -1418,9 +1418,6 @@ static void qcom_glink_destroy_ept(struct rpmsg_endpoint *ept)
channel->ept.cb = NULL;
spin_unlock_irqrestore(&channel->recv_lock, flags);
/* Decouple the potential rpdev from the channel */
qcom_glink_remove_rpmsg_device(glink, channel);
qcom_glink_send_close_req(glink, channel);
}

View File

@@ -103,6 +103,13 @@ static void glink_smem_rx_peek(struct qcom_glink_pipe *np,
if (tail >= pipe->native.length)
tail -= pipe->native.length;
/*
* Order the availability (head) read in glink_smem_rx_avail()
* against the FIFO payload read below, so APPS never consumes
* stale data the remote has not yet published.
*/
rmb();
len = min_t(size_t, count, pipe->native.length - tail);
if (len)
memcpy_fromio(data, pipe->fifo + tail, len);

View File

@@ -1460,7 +1460,7 @@ static ssize_t rpmsg_name_show(struct device *dev,
{
struct qcom_smd_edge *edge = to_smd_edge(dev);
return sprintf(buf, "%s\n", edge->name);
return sysfs_emit(buf, "%s\n", edge->name);
}
static DEVICE_ATTR_RO(rpmsg_name);

View File

@@ -79,6 +79,11 @@ int rpmsg_chrdev_eptdev_destroy(struct device *dev, void *data)
struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev);
mutex_lock(&eptdev->ept_lock);
if (!eptdev->rpdev) {
mutex_unlock(&eptdev->ept_lock);
return 0;
}
eptdev->rpdev = NULL;
if (eptdev->ept) {
/* The default endpoint is released by the rpmsg core */
@@ -371,7 +376,7 @@ static ssize_t name_show(struct device *dev, struct device_attribute *attr,
{
struct rpmsg_eptdev *eptdev = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", eptdev->chinfo.name);
return sysfs_emit(buf, "%s\n", eptdev->chinfo.name);
}
static DEVICE_ATTR_RO(name);
@@ -380,7 +385,7 @@ static ssize_t src_show(struct device *dev, struct device_attribute *attr,
{
struct rpmsg_eptdev *eptdev = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", eptdev->chinfo.src);
return sysfs_emit(buf, "%d\n", eptdev->chinfo.src);
}
static DEVICE_ATTR_RO(src);
@@ -389,7 +394,7 @@ static ssize_t dst_show(struct device *dev, struct device_attribute *attr,
{
struct rpmsg_eptdev *eptdev = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", eptdev->chinfo.dst);
return sysfs_emit(buf, "%d\n", eptdev->chinfo.dst);
}
static DEVICE_ATTR_RO(dst);

View File

@@ -348,7 +348,7 @@ field##_show(struct device *dev, \
{ \
struct rpmsg_device *rpdev = to_rpmsg_device(dev); \
\
return sprintf(buf, format_string, rpdev->path); \
return sysfs_emit(buf, format_string, rpdev->path); \
} \
static DEVICE_ATTR_RO(field);
@@ -368,7 +368,7 @@ static ssize_t modalias_show(struct device *dev,
if (len != -ENODEV)
return len;
return sprintf(buf, RPMSG_DEVICE_MODALIAS_FMT "\n", rpdev->id.name);
return sysfs_emit(buf, RPMSG_DEVICE_MODALIAS_FMT "\n", rpdev->id.name);
}
static DEVICE_ATTR_RO(modalias);
@@ -598,8 +598,6 @@ EXPORT_SYMBOL(__register_rpmsg_driver);
/**
* unregister_rpmsg_driver() - unregister an rpmsg driver from the rpmsg bus
* @rpdrv: pointer to a struct rpmsg_driver
*
* Return: 0 on success, and an appropriate error value on failure.
*/
void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv)
{