Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost

Pull virtio fixes from Michael Tsirkin:
"Fixes in virtio, vhost, and vdpa drivers"

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
vdpa/mlx5: Fix queue type selection logic
vdpa/mlx5: Avoid destroying MR on empty iotlb
tools/virtio: fix build
virtio_ring: pull in spinlock header
vringh: pull in spinlock header
virtio-blk: Add validation for block size in config space
vringh: Use wiov->used to check for read/write desc order
virtio_vdpa: reject invalid vq indices
vdpa: Add documentation for vdpa_alloc_device() macro
vDPA/ifcvf: Fix return value check for vdpa_alloc_device()
vp_vdpa: Fix return value check for vdpa_alloc_device()
vdpa_sim: Fix return value check for vdpa_alloc_device()
vhost: Fix the calculation in vhost_overflow()
vhost-vdpa: Fix integer overflow in vhost_vdpa_process_iotlb_update()
virtio_pci: Support surprise removal of virtio pci device
virtio: Protect vqs list access
virtio: Keep vring_del_virtqueue() mirror of VQ create
virtio: Improve vq->broken access to avoid any compiler optimization

+166 -36
+33 -6
drivers/block/virtio_blk.c
··· 692 692 static unsigned int virtblk_queue_depth; 693 693 module_param_named(queue_depth, virtblk_queue_depth, uint, 0444); 694 694 695 + static int virtblk_validate(struct virtio_device *vdev) 696 + { 697 + u32 blk_size; 698 + 699 + if (!vdev->config->get) { 700 + dev_err(&vdev->dev, "%s failure: config access disabled\n", 701 + __func__); 702 + return -EINVAL; 703 + } 704 + 705 + if (!virtio_has_feature(vdev, VIRTIO_BLK_F_BLK_SIZE)) 706 + return 0; 707 + 708 + blk_size = virtio_cread32(vdev, 709 + offsetof(struct virtio_blk_config, blk_size)); 710 + 711 + if (blk_size < SECTOR_SIZE || blk_size > PAGE_SIZE) 712 + __virtio_clear_bit(vdev, VIRTIO_BLK_F_BLK_SIZE); 713 + 714 + return 0; 715 + } 716 + 695 717 static int virtblk_probe(struct virtio_device *vdev) 696 718 { 697 719 struct virtio_blk *vblk; ··· 724 702 u16 min_io_size; 725 703 u8 physical_block_exp, alignment_offset; 726 704 unsigned int queue_depth; 727 - 728 - if (!vdev->config->get) { 729 - dev_err(&vdev->dev, "%s failure: config access disabled\n", 730 - __func__); 731 - return -EINVAL; 732 - } 733 705 734 706 err = ida_simple_get(&vd_index_ida, 0, minor_to_index(1 << MINORBITS), 735 707 GFP_KERNEL); ··· 839 823 else 840 824 blk_size = queue_logical_block_size(q); 841 825 826 + if (unlikely(blk_size < SECTOR_SIZE || blk_size > PAGE_SIZE)) { 827 + dev_err(&vdev->dev, 828 + "block size is changed unexpectedly, now is %u\n", 829 + blk_size); 830 + err = -EINVAL; 831 + goto err_cleanup_disk; 832 + } 833 + 842 834 /* Use topology information if available */ 843 835 err = virtio_cread_feature(vdev, VIRTIO_BLK_F_TOPOLOGY, 844 836 struct virtio_blk_config, physical_block_exp, ··· 905 881 device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups); 906 882 return 0; 907 883 884 + err_cleanup_disk: 885 + blk_cleanup_disk(vblk->disk); 908 886 out_free_tags: 909 887 blk_mq_free_tag_set(&vblk->tag_set); 910 888 out_free_vq: ··· 1009 983 .driver.name = KBUILD_MODNAME, 1010 984 .driver.owner = THIS_MODULE, 1011 985 .id_table = id_table, 986 + .validate = virtblk_validate, 1012 987 .probe = virtblk_probe, 1013 988 .remove = virtblk_remove, 1014 989 .config_changed = virtblk_config_changed,
+2 -2
drivers/vdpa/ifcvf/ifcvf_main.c
··· 493 493 494 494 adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa, 495 495 dev, &ifc_vdpa_ops, NULL); 496 - if (adapter == NULL) { 496 + if (IS_ERR(adapter)) { 497 497 IFCVF_ERR(pdev, "Failed to allocate vDPA structure"); 498 - return -ENOMEM; 498 + return PTR_ERR(adapter); 499 499 } 500 500 501 501 pci_set_master(pdev);
-9
drivers/vdpa/mlx5/core/mr.c
··· 512 512 mutex_unlock(&mr->mkey_mtx); 513 513 } 514 514 515 - static bool map_empty(struct vhost_iotlb *iotlb) 516 - { 517 - return !vhost_iotlb_itree_first(iotlb, 0, U64_MAX); 518 - } 519 - 520 515 int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb, 521 516 bool *change_map) 522 517 { ··· 519 524 int err = 0; 520 525 521 526 *change_map = false; 522 - if (map_empty(iotlb)) { 523 - mlx5_vdpa_destroy_mr(mvdev); 524 - return 0; 525 - } 526 527 mutex_lock(&mr->mkey_mtx); 527 528 if (mr->initialized) { 528 529 mlx5_vdpa_info(mvdev, "memory map update\n");
+10 -4
drivers/vdpa/mlx5/net/mlx5_vnet.c
··· 752 752 type_mask = MLX5_CAP_DEV_VDPA_EMULATION(ndev->mvdev.mdev, virtio_queue_type); 753 753 754 754 /* prefer split queue */ 755 - if (type_mask & MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_PACKED) 756 - return MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_PACKED; 755 + if (type_mask & MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_SPLIT) 756 + return MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_SPLIT; 757 757 758 - WARN_ON(!(type_mask & MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_SPLIT)); 758 + WARN_ON(!(type_mask & MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_PACKED)); 759 759 760 - return MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_SPLIT; 760 + return MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_PACKED; 761 761 } 762 762 763 763 static bool vq_is_tx(u16 idx) ··· 2029 2029 return -ENOSPC; 2030 2030 2031 2031 mdev = mgtdev->madev->mdev; 2032 + if (!(MLX5_CAP_DEV_VDPA_EMULATION(mdev, virtio_queue_type) & 2033 + MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_SPLIT)) { 2034 + dev_warn(mdev->device, "missing support for split virtqueues\n"); 2035 + return -EOPNOTSUPP; 2036 + } 2037 + 2032 2038 /* we save one virtqueue for control virtqueue should we require it */ 2033 2039 max_vqs = MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues); 2034 2040 max_vqs = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);
+3 -1
drivers/vdpa/vdpa_sim/vdpa_sim.c
··· 251 251 252 252 vdpasim = vdpa_alloc_device(struct vdpasim, vdpa, NULL, ops, 253 253 dev_attr->name); 254 - if (!vdpasim) 254 + if (IS_ERR(vdpasim)) { 255 + ret = PTR_ERR(vdpasim); 255 256 goto err_alloc; 257 + } 256 258 257 259 vdpasim->dev_attr = *dev_attr; 258 260 INIT_WORK(&vdpasim->work, dev_attr->work_fn);
+2 -2
drivers/vdpa/virtio_pci/vp_vdpa.c
··· 436 436 437 437 vp_vdpa = vdpa_alloc_device(struct vp_vdpa, vdpa, 438 438 dev, &vp_vdpa_ops, NULL); 439 - if (vp_vdpa == NULL) { 439 + if (IS_ERR(vp_vdpa)) { 440 440 dev_err(dev, "vp_vdpa: Failed to allocate vDPA structure\n"); 441 - return -ENOMEM; 441 + return PTR_ERR(vp_vdpa); 442 442 } 443 443 444 444 mdev = &vp_vdpa->mdev;
+2 -1
drivers/vhost/vdpa.c
··· 614 614 long pinned; 615 615 int ret = 0; 616 616 617 - if (msg->iova < v->range.first || 617 + if (msg->iova < v->range.first || !msg->size || 618 + msg->iova > U64_MAX - msg->size + 1 || 618 619 msg->iova + msg->size - 1 > v->range.last) 619 620 return -EINVAL; 620 621
+8 -2
drivers/vhost/vhost.c
··· 735 735 (sz + VHOST_PAGE_SIZE * 8 - 1) / VHOST_PAGE_SIZE / 8); 736 736 } 737 737 738 + /* Make sure 64 bit math will not overflow. */ 738 739 static bool vhost_overflow(u64 uaddr, u64 size) 739 740 { 740 - /* Make sure 64 bit math will not overflow. */ 741 - return uaddr > ULONG_MAX || size > ULONG_MAX || uaddr > ULONG_MAX - size; 741 + if (uaddr > ULONG_MAX || size > ULONG_MAX) 742 + return true; 743 + 744 + if (!size) 745 + return false; 746 + 747 + return uaddr > ULONG_MAX - size + 1; 742 748 } 743 749 744 750 /* Caller should have vq mutex and device mutex. */
+1 -1
drivers/vhost/vringh.c
··· 359 359 iov = wiov; 360 360 else { 361 361 iov = riov; 362 - if (unlikely(wiov && wiov->i)) { 362 + if (unlikely(wiov && wiov->used)) { 363 363 vringh_bad("Readable desc %p after writable", 364 364 &descs[i]); 365 365 err = -EINVAL;
+1
drivers/virtio/virtio.c
··· 355 355 virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); 356 356 357 357 INIT_LIST_HEAD(&dev->vqs); 358 + spin_lock_init(&dev->vqs_list_lock); 358 359 359 360 /* 360 361 * device_add() causes the bus infrastructure to look for a matching
+7
drivers/virtio/virtio_pci_common.c
··· 576 576 struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); 577 577 struct device *dev = get_device(&vp_dev->vdev.dev); 578 578 579 + /* 580 + * Device is marked broken on surprise removal so that virtio upper 581 + * layers can abort any ongoing operation. 582 + */ 583 + if (!pci_device_is_present(pci_dev)) 584 + virtio_break_device(&vp_dev->vdev); 585 + 579 586 pci_disable_sriov(pci_dev); 580 587 581 588 unregister_virtio_device(&vp_dev->vdev);
+15 -3
drivers/virtio/virtio_ring.c
··· 11 11 #include <linux/module.h> 12 12 #include <linux/hrtimer.h> 13 13 #include <linux/dma-mapping.h> 14 + #include <linux/spinlock.h> 14 15 #include <xen/xen.h> 15 16 16 17 #ifdef DEBUG ··· 1756 1755 cpu_to_le16(vq->packed.event_flags_shadow); 1757 1756 } 1758 1757 1758 + spin_lock(&vdev->vqs_list_lock); 1759 1759 list_add_tail(&vq->vq.list, &vdev->vqs); 1760 + spin_unlock(&vdev->vqs_list_lock); 1760 1761 return &vq->vq; 1761 1762 1762 1763 err_desc_extra: ··· 2232 2229 memset(vq->split.desc_state, 0, vring.num * 2233 2230 sizeof(struct vring_desc_state_split)); 2234 2231 2232 + spin_lock(&vdev->vqs_list_lock); 2235 2233 list_add_tail(&vq->vq.list, &vdev->vqs); 2234 + spin_unlock(&vdev->vqs_list_lock); 2236 2235 return &vq->vq; 2237 2236 2238 2237 err_extra: ··· 2296 2291 { 2297 2292 struct vring_virtqueue *vq = to_vvq(_vq); 2298 2293 2294 + spin_lock(&vq->vq.vdev->vqs_list_lock); 2295 + list_del(&_vq->list); 2296 + spin_unlock(&vq->vq.vdev->vqs_list_lock); 2297 + 2299 2298 if (vq->we_own_ring) { 2300 2299 if (vq->packed_ring) { 2301 2300 vring_free_queue(vq->vq.vdev, ··· 2330 2321 kfree(vq->split.desc_state); 2331 2322 kfree(vq->split.desc_extra); 2332 2323 } 2333 - list_del(&_vq->list); 2334 2324 kfree(vq); 2335 2325 } 2336 2326 EXPORT_SYMBOL_GPL(vring_del_virtqueue); ··· 2381 2373 { 2382 2374 struct vring_virtqueue *vq = to_vvq(_vq); 2383 2375 2384 - return vq->broken; 2376 + return READ_ONCE(vq->broken); 2385 2377 } 2386 2378 EXPORT_SYMBOL_GPL(virtqueue_is_broken); 2387 2379 ··· 2393 2385 { 2394 2386 struct virtqueue *_vq; 2395 2387 2388 + spin_lock(&dev->vqs_list_lock); 2396 2389 list_for_each_entry(_vq, &dev->vqs, list) { 2397 2390 struct vring_virtqueue *vq = to_vvq(_vq); 2398 - vq->broken = true; 2391 + 2392 + /* Pairs with READ_ONCE() in virtqueue_is_broken(). */ 2393 + WRITE_ONCE(vq->broken, true); 2399 2394 } 2395 + spin_unlock(&dev->vqs_list_lock); 2400 2396 } 2401 2397 EXPORT_SYMBOL_GPL(virtio_break_device); 2402 2398
+3
drivers/virtio/virtio_vdpa.c
··· 151 151 if (!name) 152 152 return NULL; 153 153 154 + if (index >= vdpa->nvqs) 155 + return ERR_PTR(-ENOENT); 156 + 154 157 /* Queue shouldn't already be set up. */ 155 158 if (ops->get_vq_ready(vdpa, index)) 156 159 return ERR_PTR(-ENOENT);
+6 -4
include/linux/mlx5/mlx5_ifc_vdpa.h
··· 11 11 }; 12 12 13 13 enum { 14 - MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_SPLIT = 0x1, // do I check this caps? 15 - MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_PACKED = 0x2, 14 + MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_SPLIT = 0, 15 + MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_PACKED = 1, 16 16 }; 17 17 18 18 enum { 19 - MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_SPLIT = 0, 20 - MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_PACKED = 1, 19 + MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_SPLIT = 20 + BIT(MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_SPLIT), 21 + MLX5_VIRTIO_EMULATION_CAP_VIRTIO_QUEUE_TYPE_PACKED = 22 + BIT(MLX5_VIRTIO_EMULATION_VIRTIO_QUEUE_TYPE_PACKED), 21 23 }; 22 24 23 25 struct mlx5_ifc_virtio_q_bits {
+11
include/linux/vdpa.h
··· 277 277 const struct vdpa_config_ops *config, 278 278 size_t size, const char *name); 279 279 280 + /** 281 + * vdpa_alloc_device - allocate and initilaize a vDPA device 282 + * 283 + * @dev_struct: the type of the parent structure 284 + * @member: the name of struct vdpa_device within the @dev_struct 285 + * @parent: the parent device 286 + * @config: the bus operations that is supported by this device 287 + * @name: name of the vdpa device 288 + * 289 + * Return allocated data structure or ERR_PTR upon error 290 + */ 280 291 #define vdpa_alloc_device(dev_struct, member, parent, config, name) \ 281 292 container_of(__vdpa_alloc_device( \ 282 293 parent, config, \
+1
include/linux/virtio.h
··· 110 110 bool config_enabled; 111 111 bool config_change_pending; 112 112 spinlock_t config_lock; 113 + spinlock_t vqs_list_lock; /* Protects VQs list access */ 113 114 struct device dev; 114 115 struct virtio_device_id id; 115 116 const struct virtio_config_ops *config;
+1
include/linux/vringh.h
··· 14 14 #include <linux/virtio_byteorder.h> 15 15 #include <linux/uio.h> 16 16 #include <linux/slab.h> 17 + #include <linux/spinlock.h> 17 18 #if IS_REACHABLE(CONFIG_VHOST_IOTLB) 18 19 #include <linux/dma-direction.h> 19 20 #include <linux/vhost_iotlb.h>
+2 -1
tools/virtio/Makefile
··· 4 4 virtio_test: virtio_ring.o virtio_test.o 5 5 vringh_test: vringh_test.o vringh.o virtio_ring.o 6 6 7 - CFLAGS += -g -O2 -Werror -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -include ../../include/linux/kconfig.h 7 + CFLAGS += -g -O2 -Werror -Wno-maybe-uninitialized -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -include ../../include/linux/kconfig.h 8 + LDFLAGS += -lpthread 8 9 vpath %.c ../../drivers/virtio ../../drivers/vhost 9 10 mod: 10 11 ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test V=${V}
+56
tools/virtio/linux/spinlock.h
··· 1 + #ifndef SPINLOCK_H_STUB 2 + #define SPINLOCK_H_STUB 3 + 4 + #include <pthread.h> 5 + 6 + typedef pthread_spinlock_t spinlock_t; 7 + 8 + static inline void spin_lock_init(spinlock_t *lock) 9 + { 10 + int r = pthread_spin_init(lock, 0); 11 + assert(!r); 12 + } 13 + 14 + static inline void spin_lock(spinlock_t *lock) 15 + { 16 + int ret = pthread_spin_lock(lock); 17 + assert(!ret); 18 + } 19 + 20 + static inline void spin_unlock(spinlock_t *lock) 21 + { 22 + int ret = pthread_spin_unlock(lock); 23 + assert(!ret); 24 + } 25 + 26 + static inline void spin_lock_bh(spinlock_t *lock) 27 + { 28 + spin_lock(lock); 29 + } 30 + 31 + static inline void spin_unlock_bh(spinlock_t *lock) 32 + { 33 + spin_unlock(lock); 34 + } 35 + 36 + static inline void spin_lock_irq(spinlock_t *lock) 37 + { 38 + spin_lock(lock); 39 + } 40 + 41 + static inline void spin_unlock_irq(spinlock_t *lock) 42 + { 43 + spin_unlock(lock); 44 + } 45 + 46 + static inline void spin_lock_irqsave(spinlock_t *lock, unsigned long f) 47 + { 48 + spin_lock(lock); 49 + } 50 + 51 + static inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long f) 52 + { 53 + spin_unlock(lock); 54 + } 55 + 56 + #endif
+2
tools/virtio/linux/virtio.h
··· 3 3 #define LINUX_VIRTIO_H 4 4 #include <linux/scatterlist.h> 5 5 #include <linux/kernel.h> 6 + #include <linux/spinlock.h> 6 7 7 8 struct device { 8 9 void *parent; ··· 13 12 struct device dev; 14 13 u64 features; 15 14 struct list_head vqs; 15 + spinlock_t vqs_list_lock; 16 16 }; 17 17 18 18 struct virtqueue {