From df0bfe7501e9319546ea380d39674a4179e059c3 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 12 Mar 2019 15:06:53 +0800 Subject: [PATCH 1/7] virtio_ring: Fix potential mem leak in virtqueue_add_indirect_packed 'desc' should be freed before leaving from err handing path. Fixes: 1ce9e6055fa0 ("virtio_ring: introduce packed ring support") Signed-off-by: YueHaibing Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang stable@vger.kernel.org --- drivers/virtio/virtio_ring.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 5df92c308286..021010424fa5 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1004,6 +1004,7 @@ static int virtqueue_add_indirect_packed(struct vring_virtqueue *vq, if (unlikely(vq->vq.num_free < 1)) { pr_debug("Can't add buf len 1 - avail = 0\n"); + kfree(desc); END_USE(vq); return -ENOSPC; } From d63031bb0fc0314541340f08a0c35c40216ca72a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Mon, 18 Mar 2019 17:27:34 +0100 Subject: [PATCH 2/7] tools/virtio/ringtest: Remove bogus definition of BUG_ON() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG_ON(x) should raise an error if x is true, but assert(x) raises an error if x is false. Remove this bogus definition of BUG_ON(), which isn't used anyway. Signed-off-by: Jonathan Neuschäfer Signed-off-by: Michael S. Tsirkin --- tools/virtio/ringtest/ptr_ring.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/virtio/ringtest/ptr_ring.c b/tools/virtio/ringtest/ptr_ring.c index 2d566fbd236b..c9b26335f891 100644 --- a/tools/virtio/ringtest/ptr_ring.c +++ b/tools/virtio/ringtest/ptr_ring.c @@ -18,7 +18,6 @@ #define ALIGN(x, a) (((x) + (a) - 1) / (a) * (a)) #define SIZE_MAX (~(size_t)0) #define KMALLOC_MAX_SIZE SIZE_MAX -#define BUG_ON(x) assert(x) typedef pthread_spinlock_t spinlock_t; From 889e31e73a738183a402cf4dbca991dce2abce96 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 16 Apr 2019 10:56:08 +0200 Subject: [PATCH 3/7] vhost-scsi: remove incorrect memory barrier At this point, vs_tpg is not public at all; tv_tpg_vhost_count is accessed under tpg->tv_tpg_mutex; tpg->vhost_scsi is accessed under vhost_scsi_mutex. Therefor there are no atomic operations involved at all here, just remove the barrier. Reported-by: Andrea Parri Signed-off-by: Paolo Bonzini Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang --- drivers/vhost/scsi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 618fb6461017..c090d177bd75 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -1443,7 +1443,6 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs, tpg->tv_tpg_vhost_count++; tpg->vhost_scsi = vs; vs_tpg[tpg->tport_tpgt] = tpg; - smp_mb__after_atomic(); match = true; } mutex_unlock(&tpg->tv_tpg_mutex); From a5581206c565a7f1113a84232f734e7135b90a61 Mon Sep 17 00:00:00 2001 From: Jiang Biao Date: Tue, 23 Apr 2019 18:25:12 +0800 Subject: [PATCH 4/7] virtio/virtio_ring: do some comment fixes There are lots of mismatches between comments and codes, this patch do these comment fixes. Signed-off-by: Jiang Biao Signed-off-by: Michael S. Tsirkin --- drivers/virtio/virtio_ring.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 021010424fa5..0a7b3ce3fb75 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1719,10 +1719,10 @@ static inline int virtqueue_add(struct virtqueue *_vq, /** * virtqueue_add_sgs - expose buffers to other end - * @vq: the struct virtqueue we're talking about. + * @_vq: the struct virtqueue we're talking about. * @sgs: array of terminated scatterlists. - * @out_num: the number of scatterlists readable by other side - * @in_num: the number of scatterlists which are writable (after readable ones) + * @out_sgs: the number of scatterlists readable by other side + * @in_sgs: the number of scatterlists which are writable (after readable ones) * @data: the token identifying the buffer. * @gfp: how to do memory allocations (if necessary). * @@ -1822,7 +1822,7 @@ EXPORT_SYMBOL_GPL(virtqueue_add_inbuf_ctx); /** * virtqueue_kick_prepare - first half of split virtqueue_kick call. - * @vq: the struct virtqueue + * @_vq: the struct virtqueue * * Instead of virtqueue_kick(), you can do: * if (virtqueue_kick_prepare(vq)) @@ -1842,7 +1842,7 @@ EXPORT_SYMBOL_GPL(virtqueue_kick_prepare); /** * virtqueue_notify - second half of split virtqueue_kick call. - * @vq: the struct virtqueue + * @_vq: the struct virtqueue * * This does not need to be serialized. * @@ -1886,8 +1886,9 @@ EXPORT_SYMBOL_GPL(virtqueue_kick); /** * virtqueue_get_buf - get the next used buffer - * @vq: the struct virtqueue we're talking about. + * @_vq: the struct virtqueue we're talking about. * @len: the length written into the buffer + * @ctx: extra context for the token * * If the device wrote data into the buffer, @len will be set to the * amount written. This means you don't need to clear the buffer @@ -1917,7 +1918,7 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len) EXPORT_SYMBOL_GPL(virtqueue_get_buf); /** * virtqueue_disable_cb - disable callbacks - * @vq: the struct virtqueue we're talking about. + * @_vq: the struct virtqueue we're talking about. * * Note that this is not necessarily synchronous, hence unreliable and only * useful as an optimization. @@ -1937,7 +1938,7 @@ EXPORT_SYMBOL_GPL(virtqueue_disable_cb); /** * virtqueue_enable_cb_prepare - restart callbacks after disable_cb - * @vq: the struct virtqueue we're talking about. + * @_vq: the struct virtqueue we're talking about. * * This re-enables callbacks; it returns current queue state * in an opaque unsigned value. This value should be later tested by @@ -1958,7 +1959,7 @@ EXPORT_SYMBOL_GPL(virtqueue_enable_cb_prepare); /** * virtqueue_poll - query pending used buffers - * @vq: the struct virtqueue we're talking about. + * @_vq: the struct virtqueue we're talking about. * @last_used_idx: virtqueue state (from call to virtqueue_enable_cb_prepare). * * Returns "true" if there are pending used buffers in the queue. @@ -1977,7 +1978,7 @@ EXPORT_SYMBOL_GPL(virtqueue_poll); /** * virtqueue_enable_cb - restart callbacks after disable_cb. - * @vq: the struct virtqueue we're talking about. + * @_vq: the struct virtqueue we're talking about. * * This re-enables callbacks; it returns "false" if there are pending * buffers in the queue, to detect a possible race between the driver @@ -1996,7 +1997,7 @@ EXPORT_SYMBOL_GPL(virtqueue_enable_cb); /** * virtqueue_enable_cb_delayed - restart callbacks after disable_cb. - * @vq: the struct virtqueue we're talking about. + * @_vq: the struct virtqueue we're talking about. * * This re-enables callbacks but hints to the other side to delay * interrupts until most of the available buffers have been processed; @@ -2018,7 +2019,7 @@ EXPORT_SYMBOL_GPL(virtqueue_enable_cb_delayed); /** * virtqueue_detach_unused_buf - detach first unused buffer - * @vq: the struct virtqueue we're talking about. + * @_vq: the struct virtqueue we're talking about. * * Returns NULL or the "data" token handed to virtqueue_add_*(). * This is not valid on an active queue; it is useful only for device @@ -2250,7 +2251,7 @@ EXPORT_SYMBOL_GPL(vring_transport_features); /** * virtqueue_get_vring_size - return the size of the virtqueue's vring - * @vq: the struct virtqueue containing the vring of interest. + * @_vq: the struct virtqueue containing the vring of interest. * * Returns the size of the vring. This is mainly used for boasting to * userspace. Unlike other operations, this need not be serialized. From 3279beac545190ed252cd3df0eb41056537463df Mon Sep 17 00:00:00 2001 From: Halil Pasic Date: Fri, 26 Apr 2019 20:32:36 +0200 Subject: [PATCH 5/7] virtio/s390: use vring_create_virtqueue The commit 2a2d1382fe9d ("virtio: Add improved queue allocation API") establishes a new way of allocating virtqueues (as a part of the effort that taught DMA to virtio rings). In the future we will want virtio-ccw to use the DMA API as well. Let us switch from the legacy method of allocating virtqueues to vring_create_virtqueue() as the first step into that direction. Signed-off-by: Halil Pasic Signed-off-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck --- drivers/s390/virtio/virtio_ccw.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c index 74c328321889..2c66941ef3d0 100644 --- a/drivers/s390/virtio/virtio_ccw.c +++ b/drivers/s390/virtio/virtio_ccw.c @@ -108,7 +108,6 @@ struct virtio_rev_info { struct virtio_ccw_vq_info { struct virtqueue *vq; int num; - void *queue; union { struct vq_info_block s; struct vq_info_block_legacy l; @@ -423,7 +422,6 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw) struct virtio_ccw_device *vcdev = to_vc_device(vq->vdev); struct virtio_ccw_vq_info *info = vq->priv; unsigned long flags; - unsigned long size; int ret; unsigned int index = vq->index; @@ -461,8 +459,6 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw) ret, index); vring_del_virtqueue(vq); - size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN)); - free_pages_exact(info->queue, size); kfree(info->info_block); kfree(info); } @@ -494,8 +490,9 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, int err; struct virtqueue *vq = NULL; struct virtio_ccw_vq_info *info; - unsigned long size = 0; /* silence the compiler */ + u64 queue; unsigned long flags; + bool may_reduce; /* Allocate queue. */ info = kzalloc(sizeof(struct virtio_ccw_vq_info), GFP_KERNEL); @@ -516,33 +513,30 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, err = info->num; goto out_err; } - size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN)); - info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); - if (info->queue == NULL) { - dev_warn(&vcdev->cdev->dev, "no queue\n"); - err = -ENOMEM; - goto out_err; - } + may_reduce = vcdev->revision > 0; + vq = vring_create_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN, + vdev, true, may_reduce, ctx, + virtio_ccw_kvm_notify, callback, name); - vq = vring_new_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN, vdev, - true, ctx, info->queue, virtio_ccw_kvm_notify, - callback, name); if (!vq) { /* For now, we fail if we can't get the requested size. */ dev_warn(&vcdev->cdev->dev, "no vq\n"); err = -ENOMEM; goto out_err; } + /* it may have been reduced */ + info->num = virtqueue_get_vring_size(vq); /* Register it with the host. */ + queue = virtqueue_get_desc_addr(vq); if (vcdev->revision == 0) { - info->info_block->l.queue = (__u64)info->queue; + info->info_block->l.queue = queue; info->info_block->l.align = KVM_VIRTIO_CCW_RING_ALIGN; info->info_block->l.index = i; info->info_block->l.num = info->num; ccw->count = sizeof(info->info_block->l); } else { - info->info_block->s.desc = (__u64)info->queue; + info->info_block->s.desc = queue; info->info_block->s.index = i; info->info_block->s.num = info->num; info->info_block->s.avail = (__u64)virtqueue_get_avail(vq); @@ -572,8 +566,6 @@ out_err: if (vq) vring_del_virtqueue(vq); if (info) { - if (info->queue) - free_pages_exact(info->queue, size); kfree(info->info_block); } kfree(info); From f35f54f11f7f96dc6d43fa79c4a7297a9115627f Mon Sep 17 00:00:00 2001 From: Halil Pasic Date: Fri, 26 Apr 2019 20:32:37 +0200 Subject: [PATCH 6/7] virtio/s390: DMA support for virtio-ccw Currently virtio-ccw devices do not work if the device has VIRTIO_F_IOMMU_PLATFORM. In future we do want to support DMA API with virtio-ccw. Let us do the plumbing, so the feature VIRTIO_F_IOMMU_PLATFORM works with virtio-ccw. Let us also switch from legacy avail/used accessors to the DMA aware ones (even if it isn't strictly necessary), and remove the legacy accessors (we were the last users). Signed-off-by: Halil Pasic Signed-off-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck --- drivers/s390/virtio/virtio_ccw.c | 22 +++++++++++++++------- include/linux/virtio.h | 17 ----------------- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c index 2c66941ef3d0..42832a164546 100644 --- a/drivers/s390/virtio/virtio_ccw.c +++ b/drivers/s390/virtio/virtio_ccw.c @@ -66,6 +66,7 @@ struct virtio_ccw_device { bool device_lost; unsigned int config_ready; void *airq_info; + u64 dma_mask; }; struct vq_info_block_legacy { @@ -539,8 +540,8 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, info->info_block->s.desc = queue; info->info_block->s.index = i; info->info_block->s.num = info->num; - info->info_block->s.avail = (__u64)virtqueue_get_avail(vq); - info->info_block->s.used = (__u64)virtqueue_get_used(vq); + info->info_block->s.avail = (__u64)virtqueue_get_avail_addr(vq); + info->info_block->s.used = (__u64)virtqueue_get_used_addr(vq); ccw->count = sizeof(info->info_block->s); } ccw->cmd_code = CCW_CMD_SET_VQ; @@ -772,10 +773,8 @@ out_free: static void ccw_transport_features(struct virtio_device *vdev) { /* - * Packed ring isn't enabled on virtio_ccw for now, - * because virtio_ccw uses some legacy accessors, - * e.g. virtqueue_get_avail() and virtqueue_get_used() - * which aren't available in packed ring currently. + * There shouldn't be anything that precludes supporting packed. + * TODO: Remove the limitation after having another look into this. */ __virtio_clear_bit(vdev, VIRTIO_F_RING_PACKED); } @@ -1258,6 +1257,16 @@ static int virtio_ccw_online(struct ccw_device *cdev) ret = -ENOMEM; goto out_free; } + + vcdev->vdev.dev.parent = &cdev->dev; + cdev->dev.dma_mask = &vcdev->dma_mask; + /* we are fine with common virtio infrastructure using 64 bit DMA */ + ret = dma_set_mask_and_coherent(&cdev->dev, DMA_BIT_MASK(64)); + if (ret) { + dev_warn(&cdev->dev, "Failed to enable 64-bit DMA.\n"); + goto out_free; + } + vcdev->config_block = kzalloc(sizeof(*vcdev->config_block), GFP_DMA | GFP_KERNEL); if (!vcdev->config_block) { @@ -1272,7 +1281,6 @@ static int virtio_ccw_online(struct ccw_device *cdev) vcdev->is_thinint = virtio_ccw_use_airq; /* at least try */ - vcdev->vdev.dev.parent = &cdev->dev; vcdev->vdev.dev.release = virtio_ccw_release_dev; vcdev->vdev.config = &virtio_ccw_config_ops; vcdev->cdev = cdev; diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 673fe3ef3607..15f906e4a748 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -90,23 +90,6 @@ dma_addr_t virtqueue_get_desc_addr(struct virtqueue *vq); dma_addr_t virtqueue_get_avail_addr(struct virtqueue *vq); dma_addr_t virtqueue_get_used_addr(struct virtqueue *vq); -/* - * Legacy accessors -- in almost all cases, these are the wrong functions - * to use. - */ -static inline void *virtqueue_get_desc(struct virtqueue *vq) -{ - return virtqueue_get_vring(vq)->desc; -} -static inline void *virtqueue_get_avail(struct virtqueue *vq) -{ - return virtqueue_get_vring(vq)->avail; -} -static inline void *virtqueue_get_used(struct virtqueue *vq) -{ - return virtqueue_get_vring(vq)->used; -} - /** * virtio_device - representation of a device using virtio * @index: unique position on the virtio bus From 050f4c4d2fbbd8217d94dc21051cc597d2a6848b Mon Sep 17 00:00:00 2001 From: Halil Pasic Date: Fri, 26 Apr 2019 20:32:38 +0200 Subject: [PATCH 7/7] virtio/s390: enable packed ring Nothing precludes to accepting VIRTIO_F_RING_PACKED any more. Signed-off-by: Halil Pasic Signed-off-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck --- drivers/s390/virtio/virtio_ccw.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c index 42832a164546..6d989c360f38 100644 --- a/drivers/s390/virtio/virtio_ccw.c +++ b/drivers/s390/virtio/virtio_ccw.c @@ -773,10 +773,8 @@ out_free: static void ccw_transport_features(struct virtio_device *vdev) { /* - * There shouldn't be anything that precludes supporting packed. - * TODO: Remove the limitation after having another look into this. + * Currently nothing to do here. */ - __virtio_clear_bit(vdev, VIRTIO_F_RING_PACKED); } static int virtio_ccw_finalize_features(struct virtio_device *vdev)