/* 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 */
 
        return 0;
 
+unwind_vring_allocations:
+       for (i--; i >= 0; i--)
+               rproc_free_vring(&rvdev->vring[i]);
 remove_rvdev:
        list_del(&rvdev->node);
 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);
 
        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))
        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;
                rvring = vq->priv;
                rvring->vq = NULL;
                vring_del_virtqueue(vq);
-               rproc_free_vring(rvring);
        }
 }