diff options
author | Ohad Ben-Cohen <ohad@wizery.com> | 2012-02-09 08:16:41 -0500 |
---|---|---|
committer | Ohad Ben-Cohen <ohad@wizery.com> | 2012-02-28 12:09:54 -0500 |
commit | fa2d7795b2e859574c86cf186e488d12178d51b3 (patch) | |
tree | af37a844c4531936e0236ead5d6a2ce80686d208 /drivers/rpmsg/virtio_rpmsg_bus.c | |
parent | 9cd8eb433cbd440b25d4080b5add998da21fdb9c (diff) |
rpmsg: fix name service endpoint leak
The name service endpoint wasn't destroyed, so fix it.
This is achieved by introducing an internal __rpmsg_destroy_ept
function which doesn't assume the given ept is bound to an rpmsg
channel (much like the existing __rpmsg_create_ept).
This is needed because the name service ept belongs to the rpmsg bus,
and is never bound with a specific rpdev.
Reported-by: Omar Ramirez Luna <omar.ramirez@ti.com>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Mark Grosen <mgrosen@ti.com>
Cc: Suman Anna <s-anna@ti.com>
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Cc: Rob Clark <rob@ti.com>
Cc: Ludovic BARRE <ludovic.barre@stericsson.com>
Cc: Loic PALLARDY <loic.pallardy@stericsson.com>
Cc: Omar Ramirez Luna <omar.ramirez@ti.com>
Diffstat (limited to 'drivers/rpmsg/virtio_rpmsg_bus.c')
-rw-r--r-- | drivers/rpmsg/virtio_rpmsg_bus.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 8980ac2cc546..4db9cf8754a0 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c | |||
@@ -290,22 +290,36 @@ struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev, | |||
290 | EXPORT_SYMBOL(rpmsg_create_ept); | 290 | EXPORT_SYMBOL(rpmsg_create_ept); |
291 | 291 | ||
292 | /** | 292 | /** |
293 | * rpmsg_destroy_ept() - destroy an existing rpmsg endpoint | 293 | * __rpmsg_destroy_ept() - destroy an existing rpmsg endpoint |
294 | * @vrp: virtproc which owns this ept | ||
294 | * @ept: endpoing to destroy | 295 | * @ept: endpoing to destroy |
295 | * | 296 | * |
296 | * Should be used by drivers to destroy an rpmsg endpoint previously | 297 | * An internal function which destroy an ept without assuming it is |
297 | * created with rpmsg_create_ept(). | 298 | * bound to an rpmsg channel. This is needed for handling the internal |
299 | * name service endpoint, which isn't bound to an rpmsg channel. | ||
300 | * See also __rpmsg_create_ept(). | ||
298 | */ | 301 | */ |
299 | void rpmsg_destroy_ept(struct rpmsg_endpoint *ept) | 302 | static void |
303 | __rpmsg_destroy_ept(struct virtproc_info *vrp, struct rpmsg_endpoint *ept) | ||
300 | { | 304 | { |
301 | struct virtproc_info *vrp = ept->rpdev->vrp; | ||
302 | |||
303 | mutex_lock(&vrp->endpoints_lock); | 305 | mutex_lock(&vrp->endpoints_lock); |
304 | idr_remove(&vrp->endpoints, ept->addr); | 306 | idr_remove(&vrp->endpoints, ept->addr); |
305 | mutex_unlock(&vrp->endpoints_lock); | 307 | mutex_unlock(&vrp->endpoints_lock); |
306 | 308 | ||
307 | kfree(ept); | 309 | kfree(ept); |
308 | } | 310 | } |
311 | |||
312 | /** | ||
313 | * rpmsg_destroy_ept() - destroy an existing rpmsg endpoint | ||
314 | * @ept: endpoing to destroy | ||
315 | * | ||
316 | * Should be used by drivers to destroy an rpmsg endpoint previously | ||
317 | * created with rpmsg_create_ept(). | ||
318 | */ | ||
319 | void rpmsg_destroy_ept(struct rpmsg_endpoint *ept) | ||
320 | { | ||
321 | __rpmsg_destroy_ept(ept->rpdev->vrp, ept); | ||
322 | } | ||
309 | EXPORT_SYMBOL(rpmsg_destroy_ept); | 323 | EXPORT_SYMBOL(rpmsg_destroy_ept); |
310 | 324 | ||
311 | /* | 325 | /* |
@@ -964,6 +978,9 @@ static void __devexit rpmsg_remove(struct virtio_device *vdev) | |||
964 | if (ret) | 978 | if (ret) |
965 | dev_warn(&vdev->dev, "can't remove rpmsg device: %d\n", ret); | 979 | dev_warn(&vdev->dev, "can't remove rpmsg device: %d\n", ret); |
966 | 980 | ||
981 | if (vrp->ns_ept) | ||
982 | __rpmsg_destroy_ept(vrp, vrp->ns_ept); | ||
983 | |||
967 | idr_remove_all(&vrp->endpoints); | 984 | idr_remove_all(&vrp->endpoints); |
968 | idr_destroy(&vrp->endpoints); | 985 | idr_destroy(&vrp->endpoints); |
969 | 986 | ||