Add argument 'reversed' to function find_vqs() in order to allow virtio devices to request host-side virtio-queues. The argument 'reversed' may be NULL if reversed virtio-queues are not requested. Signed-off-by: Sjur Brændeland <sjur.brandeland@xxxxxxxxxxxxxx> --- drivers/char/virtio_console.c | 3 ++- drivers/lguest/lguest_device.c | 5 ++++- drivers/net/virtio_net.c | 3 ++- drivers/remoteproc/remoteproc_virtio.c | 3 ++- drivers/rpmsg/virtio_rpmsg_bus.c | 2 +- drivers/s390/kvm/kvm_virtio.c | 5 ++++- drivers/scsi/virtio_scsi.c | 2 +- drivers/virtio/virtio_balloon.c | 3 ++- drivers/virtio/virtio_mmio.c | 5 ++++- drivers/virtio/virtio_pci.c | 3 ++- include/linux/virtio_config.h | 7 +++++-- 11 files changed, 29 insertions(+), 12 deletions(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 4ad8aca..6c96ec7 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1780,7 +1780,8 @@ static int init_vqs(struct ports_device *portdev) /* Find the queues. */ err = portdev->vdev->config->find_vqs(portdev->vdev, nr_queues, vqs, io_callbacks, - (const char **)io_names); + (const char **)io_names, + NULL); if (err) goto free; diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index fc92ccb..724e084 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c @@ -369,7 +369,8 @@ static void lg_del_vqs(struct virtio_device *vdev) static int lg_find_vqs(struct virtio_device *vdev, unsigned nvqs, struct virtqueue *vqs[], vq_callback_t *callbacks[], - const char *names[]) + const char *names[], + const bool reversed[]) { struct lguest_device *ldev = to_lgdev(vdev); int i; @@ -379,6 +380,8 @@ static int lg_find_vqs(struct virtio_device *vdev, unsigned nvqs, return -ENOENT; for (i = 0; i < nvqs; ++i) { + if (reversed || reversed[i]) + goto error; vqs[i] = lg_find_vq(vdev, i, callbacks[i], names[i]); if (IS_ERR(vqs[i])) goto error; diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 6289891..0eb5b2b 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1026,7 +1026,8 @@ static int init_vqs(struct virtnet_info *vi) * and optionally control. */ nvqs = virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ? 3 : 2; - err = vi->vdev->config->find_vqs(vi->vdev, nvqs, vqs, callbacks, names); + err = vi->vdev->config->find_vqs(vi->vdev, nvqs, vqs, callbacks, names, + NULL); if (err) return err; diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index e7a4780..a825f67 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c @@ -140,7 +140,8 @@ static void rproc_virtio_del_vqs(struct virtio_device *vdev) static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, struct virtqueue *vqs[], vq_callback_t *callbacks[], - const char *names[]) + const char *names[], + bool reversed[]) { struct rproc *rproc = vdev_to_rproc(vdev); int i, ret; diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 027096f..3b2f727 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -946,7 +946,7 @@ static int rpmsg_probe(struct virtio_device *vdev) init_waitqueue_head(&vrp->sendq); /* We expect two virtqueues, rx and tx (and in this order) */ - err = vdev->config->find_vqs(vdev, 2, vqs, vq_cbs, names); + err = vdev->config->find_vqs(vdev, 2, vqs, vq_cbs, names, NULL); if (err) goto free_vrp; diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 7dabef6..74cc7e8 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c @@ -246,7 +246,8 @@ static void kvm_del_vqs(struct virtio_device *vdev) static int kvm_find_vqs(struct virtio_device *vdev, unsigned nvqs, struct virtqueue *vqs[], vq_callback_t *callbacks[], - const char *names[]) + const char *names[], + const bool reversed[]) { struct kvm_device *kdev = to_kvmdev(vdev); int i; @@ -256,6 +257,8 @@ static int kvm_find_vqs(struct virtio_device *vdev, unsigned nvqs, return -ENOENT; for (i = 0; i < nvqs; ++i) { + if (reversed || reversed[i]) + goto error; vqs[i] = kvm_find_vq(vdev, i, callbacks[i], names[i]); if (IS_ERR(vqs[i])) goto error; diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index d5f9f45..e21660c 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -645,7 +645,7 @@ static int virtscsi_init(struct virtio_device *vdev, }; /* Discover virtqueues and write information to configuration. */ - err = vdev->config->find_vqs(vdev, 3, vqs, callbacks, names); + err = vdev->config->find_vqs(vdev, 3, vqs, callbacks, names, NULL); if (err) return err; diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 586395c..3fa01e0 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -315,7 +315,8 @@ static int init_vqs(struct virtio_balloon *vb) * optionally stat. */ nvqs = virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ) ? 3 : 2; - err = vb->vdev->config->find_vqs(vb->vdev, nvqs, vqs, callbacks, names); + err = vb->vdev->config->find_vqs(vb->vdev, nvqs, vqs, callbacks, names, + NULL); if (err) return err; diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 5a0e1d3..a3d1f03 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -394,7 +394,8 @@ error_available: static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs, struct virtqueue *vqs[], vq_callback_t *callbacks[], - const char *names[]) + const char *names[], + const bool reversed[]) { struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); unsigned int irq = platform_get_irq(vm_dev->pdev, 0); @@ -406,6 +407,8 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs, return err; for (i = 0; i < nvqs; ++i) { + if (reversed || reversed[i]) + return -EINVAL; vqs[i] = vm_setup_vq(vdev, i, callbacks[i], names[i]); if (IS_ERR(vqs[i])) { vm_del_vqs(vdev); diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index e3ecc94..0ec1be6 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -598,7 +598,8 @@ error_request: static int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs, struct virtqueue *vqs[], vq_callback_t *callbacks[], - const char *names[]) + const char *names[], + const bool reversed[]) { int err; diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index 29b9104..a94b94e 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h @@ -37,6 +37,8 @@ * include a NULL entry for vqs that do not need a callback * names: array of virtqueue names (mainly for debugging) * include a NULL entry for vqs unused by driver + * reversed: array of bool indicating reversed host-side rings. + * NULL is legal and indicates no reversed rings are used. * Returns 0 on success or error status * @del_vqs: free virtqueues found by find_vqs(). * @get_features: get the array of feature bits for this device. @@ -64,7 +66,8 @@ struct virtio_config_ops { int (*find_vqs)(struct virtio_device *, unsigned nvqs, struct virtqueue *vqs[], vq_callback_t *callbacks[], - const char *names[]); + const char *names[], + const bool reversed[]); void (*del_vqs)(struct virtio_device *); u32 (*get_features)(struct virtio_device *vdev); void (*finalize_features)(struct virtio_device *vdev); @@ -130,7 +133,7 @@ struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev, vq_callback_t *callbacks[] = { c }; const char *names[] = { n }; struct virtqueue *vq; - int err = vdev->config->find_vqs(vdev, 1, &vq, callbacks, names); + int err = vdev->config->find_vqs(vdev, 1, &vq, callbacks, names, NULL); if (err < 0) return ERR_PTR(err); return vq; -- 1.7.5.4 _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization