Skip to content

Commit bf11eb6

Browse files
committed
Merge: rpmsg: backport missing upstream fixes
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6373 ## Summary of Changes Backport various missing fixes from upstream that impact the rpmsg subsystem. See [here](https://issues.redhat.com/browse/VROOM-26465?focusedId=26573712&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-26573712) for the rationale behind commits chosen to backport. ## Approved Development Ticket(s) JIRA: https://issues.redhat.com/browse/RHEL-78824 Signed-off-by: Jared Kangas <jkangas@redhat.com> Approved-by: Radu Rendec <rrendec@redhat.com> Approved-by: Eric Chanudet <echanude@redhat.com> Approved-by: Brian Masney <bmasney@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Patrick Talbert <ptalbert@redhat.com>
2 parents fb3cb7f + 93ee6fd commit bf11eb6

File tree

10 files changed

+88
-32
lines changed

10 files changed

+88
-32
lines changed

drivers/rpmsg/mtk_rpmsg.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,9 @@ static void mtk_register_device_work_function(struct work_struct *register_work)
234234
if (info->registered)
235235
continue;
236236

237+
mutex_unlock(&subdev->channels_lock);
237238
ret = mtk_rpmsg_register_device(subdev, &info->info);
239+
mutex_lock(&subdev->channels_lock);
238240
if (ret) {
239241
dev_err(&pdev->dev, "Can't create rpmsg_device\n");
240242
continue;

drivers/rpmsg/qcom_glink_native.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,7 @@ static void qcom_glink_rpdev_release(struct device *dev)
14481448
{
14491449
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
14501450

1451+
kfree(rpdev->driver_override);
14511452
kfree(rpdev);
14521453
}
14531454

@@ -1691,6 +1692,7 @@ static void qcom_glink_device_release(struct device *dev)
16911692

16921693
/* Release qcom_glink_alloc_channel() reference */
16931694
kref_put(&channel->refcount, qcom_glink_channel_release);
1695+
kfree(rpdev->driver_override);
16941696
kfree(rpdev);
16951697
}
16961698

drivers/rpmsg/qcom_smd.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,7 @@ static int qcom_smd_parse_edge(struct device *dev,
13831383
}
13841384

13851385
edge->ipc_regmap = syscon_node_to_regmap(syscon_np);
1386+
of_node_put(syscon_np);
13861387
if (IS_ERR(edge->ipc_regmap)) {
13871388
ret = PTR_ERR(edge->ipc_regmap);
13881389
goto put_node;
@@ -1407,9 +1408,9 @@ static int qcom_smd_parse_edge(struct device *dev,
14071408
edge->name = node->name;
14081409

14091410
irq = irq_of_parse_and_map(node, 0);
1410-
if (irq < 0) {
1411+
if (!irq) {
14111412
dev_err(dev, "required smd interrupt missing\n");
1412-
ret = irq;
1413+
ret = -EINVAL;
14131414
goto put_node;
14141415
}
14151416

drivers/rpmsg/rpmsg_char.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,11 @@ int rpmsg_chrdev_eptdev_destroy(struct device *dev, void *data)
7575
struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev);
7676

7777
mutex_lock(&eptdev->ept_lock);
78+
eptdev->rpdev = NULL;
7879
if (eptdev->ept) {
79-
rpmsg_destroy_ept(eptdev->ept);
80+
/* The default endpoint is released by the rpmsg core */
81+
if (!eptdev->default_ept)
82+
rpmsg_destroy_ept(eptdev->ept);
8083
eptdev->ept = NULL;
8184
}
8285
mutex_unlock(&eptdev->ept_lock);
@@ -120,8 +123,16 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
120123
struct rpmsg_device *rpdev = eptdev->rpdev;
121124
struct device *dev = &eptdev->dev;
122125

123-
if (eptdev->ept)
126+
mutex_lock(&eptdev->ept_lock);
127+
if (eptdev->ept) {
128+
mutex_unlock(&eptdev->ept_lock);
124129
return -EBUSY;
130+
}
131+
132+
if (!eptdev->rpdev) {
133+
mutex_unlock(&eptdev->ept_lock);
134+
return -ENETRESET;
135+
}
125136

126137
get_device(dev);
127138

@@ -137,11 +148,13 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
137148
if (!ept) {
138149
dev_err(dev, "failed to open %s\n", eptdev->chinfo.name);
139150
put_device(dev);
151+
mutex_unlock(&eptdev->ept_lock);
140152
return -EINVAL;
141153
}
142154

143155
eptdev->ept = ept;
144156
filp->private_data = eptdev;
157+
mutex_unlock(&eptdev->ept_lock);
145158

146159
return 0;
147160
}
@@ -272,7 +285,9 @@ static __poll_t rpmsg_eptdev_poll(struct file *filp, poll_table *wait)
272285
if (!skb_queue_empty(&eptdev->queue))
273286
mask |= EPOLLIN | EPOLLRDNORM;
274287

288+
mutex_lock(&eptdev->ept_lock);
275289
mask |= rpmsg_poll(eptdev->ept, filp, wait);
290+
mutex_unlock(&eptdev->ept_lock);
276291

277292
return mask;
278293
}

drivers/rpmsg/rpmsg_core.c

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ field##_store(struct device *dev, struct device_attribute *attr, \
400400
const char *buf, size_t sz) \
401401
{ \
402402
struct rpmsg_device *rpdev = to_rpmsg_device(dev); \
403-
char *new, *old; \
403+
const char *old; \
404+
char *new; \
404405
\
405406
new = kstrndup(buf, sz, GFP_KERNEL); \
406407
if (!new) \
@@ -525,7 +526,7 @@ static int rpmsg_dev_probe(struct device *dev)
525526
goto out;
526527

527528
if (rpdrv->callback) {
528-
strncpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
529+
strscpy(chinfo.name, rpdev->id.name, sizeof(chinfo.name));
529530
chinfo.src = rpdev->src;
530531
chinfo.dst = RPMSG_ADDR_ANY;
531532

@@ -592,24 +593,52 @@ static struct bus_type rpmsg_bus = {
592593
.remove = rpmsg_dev_remove,
593594
};
594595

595-
int rpmsg_register_device(struct rpmsg_device *rpdev)
596+
/*
597+
* A helper for registering rpmsg device with driver override and name.
598+
* Drivers should not be using it, but instead rpmsg_register_device().
599+
*/
600+
int rpmsg_register_device_override(struct rpmsg_device *rpdev,
601+
const char *driver_override)
596602
{
597603
struct device *dev = &rpdev->dev;
598604
int ret;
599605

600-
dev_set_name(&rpdev->dev, "%s.%s.%d.%d", dev_name(dev->parent),
606+
if (driver_override)
607+
strscpy_pad(rpdev->id.name, driver_override, RPMSG_NAME_SIZE);
608+
609+
dev_set_name(dev, "%s.%s.%d.%d", dev_name(dev->parent),
601610
rpdev->id.name, rpdev->src, rpdev->dst);
602611

603-
rpdev->dev.bus = &rpmsg_bus;
612+
dev->bus = &rpmsg_bus;
613+
614+
device_initialize(dev);
615+
if (driver_override) {
616+
ret = driver_set_override(dev, &rpdev->driver_override,
617+
driver_override,
618+
strlen(driver_override));
619+
if (ret) {
620+
dev_err(dev, "device_set_override failed: %d\n", ret);
621+
put_device(dev);
622+
return ret;
623+
}
624+
}
604625

605-
ret = device_register(&rpdev->dev);
626+
ret = device_add(dev);
606627
if (ret) {
607-
dev_err(dev, "device_register failed: %d\n", ret);
608-
put_device(&rpdev->dev);
628+
dev_err(dev, "device_add failed: %d\n", ret);
629+
kfree(rpdev->driver_override);
630+
rpdev->driver_override = NULL;
631+
put_device(dev);
609632
}
610633

611634
return ret;
612635
}
636+
EXPORT_SYMBOL(rpmsg_register_device_override);
637+
638+
int rpmsg_register_device(struct rpmsg_device *rpdev)
639+
{
640+
return rpmsg_register_device_override(rpdev, NULL);
641+
}
613642
EXPORT_SYMBOL(rpmsg_register_device);
614643

615644
/*

drivers/rpmsg/rpmsg_ctrl.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,12 @@ static void rpmsg_ctrldev_remove(struct rpmsg_device *rpdev)
194194
struct rpmsg_ctrldev *ctrldev = dev_get_drvdata(&rpdev->dev);
195195
int ret;
196196

197+
mutex_lock(&ctrldev->ctrl_lock);
197198
/* Destroy all endpoints */
198199
ret = device_for_each_child(&ctrldev->dev, NULL, rpmsg_chrdev_eptdev_destroy);
199200
if (ret)
200201
dev_warn(&rpdev->dev, "failed to nuke endpoints: %d\n", ret);
202+
mutex_unlock(&ctrldev->ctrl_lock);
201203

202204
cdev_device_del(&ctrldev->cdev, &ctrldev->dev);
203205
put_device(&ctrldev->dev);

drivers/rpmsg/rpmsg_internal.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ struct rpmsg_device_ops {
4141
rpmsg_rx_cb_t cb, void *priv,
4242
struct rpmsg_channel_info chinfo);
4343

44-
int (*announce_create)(struct rpmsg_device *ept);
45-
int (*announce_destroy)(struct rpmsg_device *ept);
44+
int (*announce_create)(struct rpmsg_device *rpdev);
45+
int (*announce_destroy)(struct rpmsg_device *rpdev);
4646
};
4747

4848
/**
@@ -94,10 +94,7 @@ int rpmsg_release_channel(struct rpmsg_device *rpdev,
9494
*/
9595
static inline int rpmsg_ctrldev_register_device(struct rpmsg_device *rpdev)
9696
{
97-
strcpy(rpdev->id.name, "rpmsg_ctrl");
98-
rpdev->driver_override = "rpmsg_ctrl";
99-
100-
return rpmsg_register_device(rpdev);
97+
return rpmsg_register_device_override(rpdev, "rpmsg_ctrl");
10198
}
10299

103100
#endif

drivers/rpmsg/rpmsg_ns.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,10 @@
2020
*/
2121
int rpmsg_ns_register_device(struct rpmsg_device *rpdev)
2222
{
23-
strcpy(rpdev->id.name, "rpmsg_ns");
24-
rpdev->driver_override = "rpmsg_ns";
2523
rpdev->src = RPMSG_NS_ADDR;
2624
rpdev->dst = RPMSG_NS_ADDR;
2725

28-
return rpmsg_register_device(rpdev);
26+
return rpmsg_register_device_override(rpdev, "rpmsg_ns");
2927
}
3028
EXPORT_SYMBOL(rpmsg_ns_register_device);
3129

@@ -52,7 +50,7 @@ static int rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len,
5250
/* don't trust the remote processor for null terminating the name */
5351
msg->name[RPMSG_NAME_SIZE - 1] = '\0';
5452

55-
strncpy(chinfo.name, msg->name, sizeof(chinfo.name));
53+
strscpy_pad(chinfo.name, msg->name, sizeof(chinfo.name));
5654
chinfo.src = RPMSG_ADDR_ANY;
5755
chinfo.dst = rpmsg32_to_cpu(rpdev, msg->addr);
5856

drivers/rpmsg/virtio_rpmsg_bus.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ static int virtio_rpmsg_announce_create(struct rpmsg_device *rpdev)
329329
virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
330330
struct rpmsg_ns_msg nsm;
331331

332-
strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
332+
strscpy_pad(nsm.name, rpdev->id.name, sizeof(nsm.name));
333333
nsm.addr = cpu_to_rpmsg32(rpdev, rpdev->ept->addr);
334334
nsm.flags = cpu_to_rpmsg32(rpdev, RPMSG_NS_CREATE);
335335

@@ -353,7 +353,7 @@ static int virtio_rpmsg_announce_destroy(struct rpmsg_device *rpdev)
353353
virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
354354
struct rpmsg_ns_msg nsm;
355355

356-
strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
356+
strscpy_pad(nsm.name, rpdev->id.name, sizeof(nsm.name));
357357
nsm.addr = cpu_to_rpmsg32(rpdev, rpdev->ept->addr);
358358
nsm.flags = cpu_to_rpmsg32(rpdev, RPMSG_NS_DESTROY);
359359

@@ -378,6 +378,7 @@ static void virtio_rpmsg_release_device(struct device *dev)
378378
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
379379
struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev);
380380

381+
kfree(rpdev->driver_override);
381382
kfree(vch);
382383
}
383384

@@ -424,7 +425,7 @@ static struct rpmsg_device *__rpmsg_create_channel(struct virtproc_info *vrp,
424425
*/
425426
rpdev->announce = rpdev->src != RPMSG_ADDR_ANY;
426427

427-
strncpy(rpdev->id.name, chinfo->name, RPMSG_NAME_SIZE);
428+
strscpy(rpdev->id.name, chinfo->name, sizeof(rpdev->id.name));
428429

429430
rpdev->dev.parent = &vrp->vdev->dev;
430431
rpdev->dev.release = virtio_rpmsg_release_device;
@@ -851,7 +852,7 @@ static struct rpmsg_device *rpmsg_virtio_add_ctrl_dev(struct virtio_device *vdev
851852

852853
err = rpmsg_ctrldev_register_device(rpdev_ctrl);
853854
if (err) {
854-
kfree(vch);
855+
/* vch will be free in virtio_rpmsg_release_device() */
855856
return ERR_PTR(err);
856857
}
857858

@@ -862,7 +863,7 @@ static void rpmsg_virtio_del_ctrl_dev(struct rpmsg_device *rpdev_ctrl)
862863
{
863864
if (!rpdev_ctrl)
864865
return;
865-
kfree(to_virtio_rpmsg_channel(rpdev_ctrl));
866+
device_unregister(&rpdev_ctrl->dev);
866867
}
867868

868869
static int rpmsg_probe(struct virtio_device *vdev)
@@ -973,7 +974,8 @@ static int rpmsg_probe(struct virtio_device *vdev)
973974

974975
err = rpmsg_ns_register_device(rpdev_ns);
975976
if (err)
976-
goto free_vch;
977+
/* vch will be free in virtio_rpmsg_release_device() */
978+
goto free_ctrldev;
977979
}
978980

979981
/*
@@ -997,8 +999,6 @@ static int rpmsg_probe(struct virtio_device *vdev)
997999

9981000
return 0;
9991001

1000-
free_vch:
1001-
kfree(vch);
10021002
free_ctrldev:
10031003
rpmsg_virtio_del_ctrl_dev(rpdev_ctrl);
10041004
free_coherent:

include/linux/rpmsg.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ struct rpmsg_channel_info {
4141
* rpmsg_device - device that belong to the rpmsg bus
4242
* @dev: the device struct
4343
* @id: device id (used to match between rpmsg drivers and devices)
44-
* @driver_override: driver name to force a match
44+
* @driver_override: driver name to force a match; do not set directly,
45+
* because core frees it; use driver_set_override() to
46+
* set or clear it.
4547
* @src: local address
4648
* @dst: destination address
4749
* @ept: the rpmsg endpoint of this channel
@@ -51,7 +53,7 @@ struct rpmsg_channel_info {
5153
struct rpmsg_device {
5254
struct device dev;
5355
struct rpmsg_device_id id;
54-
char *driver_override;
56+
const char *driver_override;
5557
u32 src;
5658
u32 dst;
5759
struct rpmsg_endpoint *ept;
@@ -163,6 +165,8 @@ static inline __rpmsg64 cpu_to_rpmsg64(struct rpmsg_device *rpdev, u64 val)
163165

164166
#if IS_ENABLED(CONFIG_RPMSG)
165167

168+
int rpmsg_register_device_override(struct rpmsg_device *rpdev,
169+
const char *driver_override);
166170
int rpmsg_register_device(struct rpmsg_device *rpdev);
167171
int rpmsg_unregister_device(struct device *parent,
168172
struct rpmsg_channel_info *chinfo);
@@ -190,6 +194,12 @@ ssize_t rpmsg_get_mtu(struct rpmsg_endpoint *ept);
190194

191195
#else
192196

197+
static inline int rpmsg_register_device_override(struct rpmsg_device *rpdev,
198+
const char *driver_override)
199+
{
200+
return -ENXIO;
201+
}
202+
193203
static inline int rpmsg_register_device(struct rpmsg_device *rpdev)
194204
{
195205
return -ENXIO;

0 commit comments

Comments
 (0)