in drivers/virtio_uml.c [998:1049]
static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[], vq_callback_t *callbacks[],
const char * const names[], const bool *ctx,
struct irq_affinity *desc)
{
struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev);
int i, queue_idx = 0, rc;
struct virtqueue *vq;
/* not supported for now */
if (WARN_ON(nvqs > 64))
return -EINVAL;
rc = vhost_user_set_mem_table(vu_dev);
if (rc)
return rc;
for (i = 0; i < nvqs; ++i) {
if (!names[i]) {
vqs[i] = NULL;
continue;
}
vqs[i] = vu_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
ctx ? ctx[i] : false);
if (IS_ERR(vqs[i])) {
rc = PTR_ERR(vqs[i]);
goto error_setup;
}
}
list_for_each_entry(vq, &vdev->vqs, list) {
struct virtio_uml_vq_info *info = vq->priv;
if (info->kick_fd >= 0) {
rc = vhost_user_set_vring_kick(vu_dev, vq->index,
info->kick_fd);
if (rc)
goto error_setup;
}
rc = vhost_user_set_vring_enable(vu_dev, vq->index, true);
if (rc)
goto error_setup;
}
return 0;
error_setup:
vu_del_vqs(vdev);
return rc;
}