diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 67f581d0c488..bb78316f8120 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -370,6 +370,13 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, /* remember the resource offset*/ rvdev->rsc_offset = offset; + /* allocate the vring resources */ + for (i = 0; i < rsc->num_of_vrings; i++) { + ret = rproc_alloc_vring(rvdev, i); + if (ret) + goto unwind_vring_allocations; + } + list_add_tail(&rvdev->node, &rproc->rvdevs); /* it is now safe to add the virtio device */ @@ -379,6 +386,9 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, return 0; +unwind_vring_allocations: + for (i--; i >= 0; i--) + rproc_free_vring(&rvdev->vring[i]); remove_rvdev: list_del(&rvdev->node); free_rvdev: @@ -389,6 +399,16 @@ free_rvdev: void rproc_vdev_release(struct kref *ref) { struct rproc_vdev *rvdev = container_of(ref, struct rproc_vdev, refcount); + struct rproc_vring *rvring; + int id; + + for (id = 0; id < ARRAY_SIZE(rvdev->vring); id++) { + rvring = &rvdev->vring[id]; + if (!rvring->va) + continue; + + rproc_free_vring(rvring); + } list_del(&rvdev->node); kfree(rvdev); diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index 0d1ad3ed149d..364411fb7734 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c @@ -79,7 +79,7 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev, struct rproc_vring *rvring; struct virtqueue *vq; void *addr; - int len, size, ret; + int len, size; /* we're temporarily limited to two virtqueues per rvdev */ if (id >= ARRAY_SIZE(rvdev->vring)) @@ -88,10 +88,6 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev, if (!name) return NULL; - ret = rproc_alloc_vring(rvdev, id); - if (ret) - return ERR_PTR(ret); - rvring = &rvdev->vring[id]; addr = rvring->va; len = rvring->len; @@ -130,7 +126,6 @@ static void __rproc_virtio_del_vqs(struct virtio_device *vdev) rvring = vq->priv; rvring->vq = NULL; vring_del_virtqueue(vq); - rproc_free_vring(rvring); } }