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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'vfio-v7.1-rc1-pt2' of https://github.com/awilliam/linux-vfio

Pull more VFIO updates from Alex Williamson:

- Fix ordering of dma-buf cleanup versus device disabling in vfio-pci
(Matt Evans)

- Resolve an inconsistent and incorrect use of spinlock-irq in the
virtio vfio-pci variant by conversion to mutex and proceed to
modernize and simplify driver with use of guards (Alex Williamson)

- Resurrect the removal of the remaining class_create() call in vfio,
replacing with const struct class and class_register() (Jori
Koolstra, Alex Williamson)

- Fix NULL pointer dereference, properly serialize interrupt setup, and
cleanup interrupt state tracking in the cdx vfio bus driver (Prasanna
Kumar T S M, Alex Williamson)

* tag 'vfio-v7.1-rc1-pt2' of https://github.com/awilliam/linux-vfio:
vfio/cdx: Consolidate MSI configured state onto cdx_irqs
vfio/cdx: Serialize VFIO_DEVICE_SET_IRQS with a per-device mutex
vfio/cdx: Fix NULL pointer dereference in interrupt trigger path
vfio: replace vfio->device_class with a const struct class
vfio/virtio: Use guard() for bar_mutex in legacy I/O
vfio/virtio: Use guard() for migf->lock where applicable
vfio/virtio: Use guard() for list_lock where applicable
vfio/virtio: Convert list_lock from spinlock to mutex
vfio/pci: Clean up DMABUFs before disabling function

+107 -106
+18 -20
drivers/vfio/cdx/intr.c
··· 32 32 return -ENOMEM; 33 33 34 34 ret = cdx_enable_msi(cdx_dev); 35 - if (ret) { 36 - kfree(vdev->cdx_irqs); 37 - return ret; 38 - } 35 + if (ret) 36 + goto err_free; 39 37 40 38 /* Allocate cdx MSIs */ 41 39 ret = msi_domain_alloc_irqs(dev, MSI_DEFAULT_DOMAIN, nvec); 42 - if (ret) { 43 - cdx_disable_msi(cdx_dev); 44 - kfree(vdev->cdx_irqs); 45 - return ret; 46 - } 40 + if (ret) 41 + goto err_disable; 47 42 48 43 for (msi_idx = 0; msi_idx < nvec; msi_idx++) 49 44 vdev->cdx_irqs[msi_idx].irq_no = msi_get_virq(dev, msi_idx); 50 45 51 46 vdev->msi_count = nvec; 52 - vdev->config_msi = 1; 53 47 54 48 return 0; 49 + 50 + err_disable: 51 + cdx_disable_msi(cdx_dev); 52 + err_free: 53 + kfree(vdev->cdx_irqs); 54 + vdev->cdx_irqs = NULL; 55 + return ret; 55 56 } 56 57 57 58 static int vfio_cdx_msi_set_vector_signal(struct vfio_cdx_device *vdev, ··· 130 129 131 130 vfio_cdx_msi_set_block(vdev, 0, vdev->msi_count, NULL); 132 131 133 - if (!vdev->config_msi) 132 + if (!vdev->cdx_irqs) 134 133 return; 135 134 136 135 msi_domain_free_irqs_all(dev, MSI_DEFAULT_DOMAIN); ··· 139 138 140 139 vdev->cdx_irqs = NULL; 141 140 vdev->msi_count = 0; 142 - vdev->config_msi = 0; 143 141 } 144 142 145 143 static int vfio_cdx_set_msi_trigger(struct vfio_cdx_device *vdev, ··· 152 152 if (start + count > cdx_dev->num_msi) 153 153 return -EINVAL; 154 154 155 + guard(mutex)(&vdev->cdx_irqs_lock); 156 + 155 157 if (!count && (flags & VFIO_IRQ_SET_DATA_NONE)) { 156 158 vfio_cdx_msi_disable(vdev); 157 159 return 0; ··· 163 161 s32 *fds = data; 164 162 int ret; 165 163 166 - if (vdev->config_msi) 164 + if (vdev->cdx_irqs) 167 165 return vfio_cdx_msi_set_block(vdev, start, count, 168 166 fds); 169 167 ret = vfio_cdx_msi_enable(vdev, cdx_dev->num_msi); ··· 176 174 177 175 return ret; 178 176 } 177 + 178 + if (!vdev->cdx_irqs) 179 + return -EINVAL; 179 180 180 181 for (i = start; i < start + count; i++) { 181 182 if (!vdev->cdx_irqs[i].trigger) ··· 211 206 /* Free All IRQs for the given device */ 212 207 void vfio_cdx_irqs_cleanup(struct vfio_cdx_device *vdev) 213 208 { 214 - /* 215 - * Device does not support any interrupt or the interrupts 216 - * were not configured 217 - */ 218 - if (!vdev->cdx_irqs) 219 - return; 220 - 221 209 vfio_cdx_set_msi_trigger(vdev, 0, 0, 0, VFIO_IRQ_SET_DATA_NONE, NULL); 222 210 }
+19
drivers/vfio/cdx/main.c
··· 8 8 9 9 #include "private.h" 10 10 11 + static int vfio_cdx_init_dev(struct vfio_device *core_vdev) 12 + { 13 + struct vfio_cdx_device *vdev = 14 + container_of(core_vdev, struct vfio_cdx_device, vdev); 15 + 16 + mutex_init(&vdev->cdx_irqs_lock); 17 + return 0; 18 + } 19 + 20 + static void vfio_cdx_release_dev(struct vfio_device *core_vdev) 21 + { 22 + struct vfio_cdx_device *vdev = 23 + container_of(core_vdev, struct vfio_cdx_device, vdev); 24 + 25 + mutex_destroy(&vdev->cdx_irqs_lock); 26 + } 27 + 11 28 static int vfio_cdx_open_device(struct vfio_device *core_vdev) 12 29 { 13 30 struct vfio_cdx_device *vdev = ··· 290 273 291 274 static const struct vfio_device_ops vfio_cdx_ops = { 292 275 .name = "vfio-cdx", 276 + .init = vfio_cdx_init_dev, 277 + .release = vfio_cdx_release_dev, 293 278 .open_device = vfio_cdx_open_device, 294 279 .close_device = vfio_cdx_close_device, 295 280 .ioctl = vfio_cdx_ioctl,
+3 -1
drivers/vfio/cdx/private.h
··· 6 6 #ifndef VFIO_CDX_PRIVATE_H 7 7 #define VFIO_CDX_PRIVATE_H 8 8 9 + #include <linux/mutex.h> 10 + 9 11 #define VFIO_CDX_OFFSET_SHIFT 40 10 12 11 13 static inline u64 vfio_cdx_index_to_offset(u32 index) ··· 33 31 struct vfio_cdx_device { 34 32 struct vfio_device vdev; 35 33 struct vfio_cdx_region *regions; 34 + struct mutex cdx_irqs_lock; 36 35 struct vfio_cdx_irq *cdx_irqs; 37 36 u32 flags; 38 37 #define BME_SUPPORT BIT(0) 39 38 u32 msi_count; 40 - u8 config_msi; 41 39 }; 42 40 43 41 #ifdef CONFIG_GENERIC_MSI_IRQ
+1 -7
drivers/vfio/device_cdev.c
··· 293 293 return 0; 294 294 } 295 295 296 - static char *vfio_device_devnode(const struct device *dev, umode_t *mode) 296 + int vfio_cdev_init(void) 297 297 { 298 - return kasprintf(GFP_KERNEL, "vfio/devices/%s", dev_name(dev)); 299 - } 300 - 301 - int vfio_cdev_init(struct class *device_class) 302 - { 303 - device_class->devnode = vfio_device_devnode; 304 298 return alloc_chrdev_region(&device_devt, 0, 305 299 MINORMASK + 1, "vfio-dev"); 306 300 }
+2 -2
drivers/vfio/pci/vfio_pci_core.c
··· 734 734 #if IS_ENABLED(CONFIG_EEH) 735 735 eeh_dev_release(vdev->pdev); 736 736 #endif 737 - vfio_pci_core_disable(vdev); 738 - 739 737 vfio_pci_dma_buf_cleanup(vdev); 738 + 739 + vfio_pci_core_disable(vdev); 740 740 741 741 mutex_lock(&vdev->igate); 742 742 vfio_pci_eventfd_replace_locked(vdev, &vdev->err_trigger, NULL);
+1 -1
drivers/vfio/pci/virtio/common.h
··· 68 68 enum virtiovf_migf_state state; 69 69 enum virtiovf_load_state load_state; 70 70 /* synchronize access to the lists */ 71 - spinlock_t list_lock; 71 + struct mutex list_lock; 72 72 struct list_head buf_list; 73 73 struct list_head avail_list; 74 74 struct virtiovf_data_buffer *buf;
+8 -9
drivers/vfio/pci/virtio/legacy_io.c
··· 34 34 common = pos < VIRTIO_PCI_CONFIG_OFF(msix_enabled); 35 35 /* offset within the relevant configuration area */ 36 36 offset = common ? pos : pos - VIRTIO_PCI_CONFIG_OFF(msix_enabled); 37 - mutex_lock(&virtvdev->bar_mutex); 37 + 38 + guard(mutex)(&virtvdev->bar_mutex); 39 + 38 40 if (read) { 39 41 if (common) 40 42 ret = virtio_pci_admin_legacy_common_io_read(pdev, offset, ··· 45 43 ret = virtio_pci_admin_legacy_device_io_read(pdev, offset, 46 44 count, bar0_buf + pos); 47 45 if (ret) 48 - goto out; 46 + return ret; 49 47 if (copy_to_user(buf, bar0_buf + pos, count)) 50 - ret = -EFAULT; 48 + return -EFAULT; 51 49 } else { 52 - if (copy_from_user(bar0_buf + pos, buf, count)) { 53 - ret = -EFAULT; 54 - goto out; 55 - } 50 + if (copy_from_user(bar0_buf + pos, buf, count)) 51 + return -EFAULT; 56 52 57 53 if (common) 58 54 ret = virtio_pci_admin_legacy_common_io_write(pdev, offset, ··· 59 59 ret = virtio_pci_admin_legacy_device_io_write(pdev, offset, 60 60 count, bar0_buf + pos); 61 61 } 62 - out: 63 - mutex_unlock(&virtvdev->bar_mutex); 62 + 64 63 return ret; 65 64 } 66 65
+37 -53
drivers/vfio/pci/virtio/migrate.c
··· 142 142 143 143 static void virtiovf_put_data_buffer(struct virtiovf_data_buffer *buf) 144 144 { 145 - spin_lock_irq(&buf->migf->list_lock); 145 + guard(mutex)(&buf->migf->list_lock); 146 146 list_add_tail(&buf->buf_elm, &buf->migf->avail_list); 147 - spin_unlock_irq(&buf->migf->list_lock); 148 147 } 149 148 150 149 static int ··· 169 170 170 171 INIT_LIST_HEAD(&free_list); 171 172 172 - spin_lock_irq(&migf->list_lock); 173 + mutex_lock(&migf->list_lock); 173 174 list_for_each_entry_safe(buf, temp_buf, &migf->avail_list, buf_elm) { 174 175 list_del_init(&buf->buf_elm); 175 176 if (buf->allocated_length >= length) { 176 - spin_unlock_irq(&migf->list_lock); 177 + mutex_unlock(&migf->list_lock); 177 178 goto found; 178 179 } 179 180 /* 180 181 * Prevent holding redundant buffers. Put in a free 181 - * list and call at the end not under the spin lock 182 + * list and call at the end not under the mutex 182 183 * (&migf->list_lock) to minimize its scope usage. 183 184 */ 184 185 list_add(&buf->buf_elm, &free_list); 185 186 } 186 - spin_unlock_irq(&migf->list_lock); 187 + mutex_unlock(&migf->list_lock); 187 188 buf = virtiovf_alloc_data_buffer(migf, length); 188 189 189 190 found: ··· 224 225 225 226 static void virtiovf_disable_fd(struct virtiovf_migration_file *migf) 226 227 { 227 - mutex_lock(&migf->lock); 228 + guard(mutex)(&migf->lock); 228 229 migf->state = VIRTIOVF_MIGF_STATE_ERROR; 229 230 migf->filp->f_pos = 0; 230 - mutex_unlock(&migf->lock); 231 231 } 232 232 233 233 static void virtiovf_disable_fds(struct virtiovf_pci_core_device *virtvdev) ··· 293 295 struct virtiovf_migration_file *migf = filp->private_data; 294 296 295 297 virtiovf_disable_fd(migf); 298 + mutex_destroy(&migf->list_lock); 296 299 mutex_destroy(&migf->lock); 297 300 kfree(migf); 298 301 return 0; ··· 304 305 loff_t pos, bool *end_of_data) 305 306 { 306 307 struct virtiovf_data_buffer *buf; 307 - bool found = false; 308 308 309 309 *end_of_data = false; 310 - spin_lock_irq(&migf->list_lock); 310 + guard(mutex)(&migf->list_lock); 311 + 311 312 if (list_empty(&migf->buf_list)) { 312 313 *end_of_data = true; 313 - goto end; 314 + return NULL; 314 315 } 315 316 316 317 buf = list_first_entry(&migf->buf_list, struct virtiovf_data_buffer, 317 318 buf_elm); 318 319 if (pos >= buf->start_pos && 319 - pos < buf->start_pos + buf->length) { 320 - found = true; 321 - goto end; 322 - } 320 + pos < buf->start_pos + buf->length) 321 + return buf; 323 322 324 323 /* 325 324 * As we use a stream based FD we may expect having the data always 326 325 * on first chunk 327 326 */ 328 327 migf->state = VIRTIOVF_MIGF_STATE_ERROR; 329 - 330 - end: 331 - spin_unlock_irq(&migf->list_lock); 332 - return found ? buf : NULL; 328 + return NULL; 333 329 } 334 330 335 331 static ssize_t virtiovf_buf_read(struct virtiovf_data_buffer *vhca_buf, ··· 363 369 } 364 370 365 371 if (*pos >= vhca_buf->start_pos + vhca_buf->length) { 366 - spin_lock_irq(&vhca_buf->migf->list_lock); 372 + guard(mutex)(&vhca_buf->migf->list_lock); 367 373 list_del_init(&vhca_buf->buf_elm); 368 374 list_add_tail(&vhca_buf->buf_elm, &vhca_buf->migf->avail_list); 369 - spin_unlock_irq(&vhca_buf->migf->list_lock); 370 375 } 371 376 372 377 return done; ··· 384 391 return -ESPIPE; 385 392 pos = &filp->f_pos; 386 393 387 - mutex_lock(&migf->lock); 388 - if (migf->state == VIRTIOVF_MIGF_STATE_ERROR) { 389 - done = -ENODEV; 390 - goto out_unlock; 391 - } 394 + guard(mutex)(&migf->lock); 395 + 396 + if (migf->state == VIRTIOVF_MIGF_STATE_ERROR) 397 + return -ENODEV; 392 398 393 399 while (len) { 394 400 ssize_t count; ··· 396 404 if (first_loop_call) { 397 405 first_loop_call = false; 398 406 /* Temporary end of file as part of PRE_COPY */ 399 - if (end_of_data && migf->state == VIRTIOVF_MIGF_STATE_PRECOPY) { 400 - done = -ENOMSG; 401 - goto out_unlock; 402 - } 403 - if (end_of_data && migf->state != VIRTIOVF_MIGF_STATE_COMPLETE) { 404 - done = -EINVAL; 405 - goto out_unlock; 406 - } 407 + if (end_of_data && migf->state == VIRTIOVF_MIGF_STATE_PRECOPY) 408 + return -ENOMSG; 409 + if (end_of_data && migf->state != VIRTIOVF_MIGF_STATE_COMPLETE) 410 + return -EINVAL; 407 411 } 408 412 409 413 if (end_of_data) 410 - goto out_unlock; 414 + return done; 411 415 412 - if (!vhca_buf) { 413 - done = -EINVAL; 414 - goto out_unlock; 415 - } 416 + if (!vhca_buf) 417 + return -EINVAL; 416 418 417 419 count = virtiovf_buf_read(vhca_buf, &buf, &len, pos); 418 - if (count < 0) { 419 - done = count; 420 - goto out_unlock; 421 - } 420 + if (count < 0) 421 + return count; 422 422 done += count; 423 423 } 424 424 425 - out_unlock: 426 - mutex_unlock(&migf->lock); 427 425 return done; 428 426 } 429 427 ··· 531 549 header_buf->length = sizeof(header); 532 550 header_buf->start_pos = header_buf->migf->max_pos; 533 551 migf->max_pos += header_buf->length; 534 - spin_lock_irq(&migf->list_lock); 535 - list_add_tail(&header_buf->buf_elm, &migf->buf_list); 536 - spin_unlock_irq(&migf->list_lock); 552 + 553 + scoped_guard(mutex, &migf->list_lock) 554 + list_add_tail(&header_buf->buf_elm, &migf->buf_list); 555 + 537 556 return 0; 538 557 } 539 558 ··· 599 616 600 617 buf->start_pos = buf->migf->max_pos; 601 618 migf->max_pos += buf->length; 602 - spin_lock(&migf->list_lock); 603 - list_add_tail(&buf->buf_elm, &migf->buf_list); 604 - spin_unlock_irq(&migf->list_lock); 619 + 620 + scoped_guard(mutex, &migf->list_lock) 621 + list_add_tail(&buf->buf_elm, &migf->buf_list); 622 + 605 623 return 0; 606 624 607 625 out_header: ··· 671 687 mutex_init(&migf->lock); 672 688 INIT_LIST_HEAD(&migf->buf_list); 673 689 INIT_LIST_HEAD(&migf->avail_list); 674 - spin_lock_init(&migf->list_lock); 690 + mutex_init(&migf->list_lock); 675 691 migf->virtvdev = virtvdev; 676 692 677 693 lockdep_assert_held(&virtvdev->state_mutex); ··· 1061 1077 mutex_init(&migf->lock); 1062 1078 INIT_LIST_HEAD(&migf->buf_list); 1063 1079 INIT_LIST_HEAD(&migf->avail_list); 1064 - spin_lock_init(&migf->list_lock); 1080 + mutex_init(&migf->list_lock); 1065 1081 1066 1082 buf = virtiovf_alloc_data_buffer(migf, VIRTIOVF_TARGET_INITIAL_BUF_SIZE); 1067 1083 if (IS_ERR(buf)) {
+2 -2
drivers/vfio/vfio.h
··· 377 377 long vfio_df_ioctl_bind_iommufd(struct vfio_device_file *df, 378 378 struct vfio_device_bind_iommufd __user *arg); 379 379 void vfio_df_unbind_iommufd(struct vfio_device_file *df); 380 - int vfio_cdev_init(struct class *device_class); 380 + int vfio_cdev_init(void); 381 381 void vfio_cdev_cleanup(void); 382 382 #else 383 383 static inline void vfio_init_device_cdev(struct vfio_device *device) ··· 410 410 { 411 411 } 412 412 413 - static inline int vfio_cdev_init(struct class *device_class) 413 + static inline int vfio_cdev_init(void) 414 414 { 415 415 return 0; 416 416 }
+16 -11
drivers/vfio/vfio_main.c
··· 49 49 #define VFIO_MAGIC 0x5646494f /* "VFIO" */ 50 50 51 51 static struct vfio { 52 - struct class *device_class; 53 52 struct ida device_ida; 54 53 struct vfsmount *vfs_mount; 55 54 int fs_count; ··· 62 63 #endif 63 64 64 65 static DEFINE_XARRAY(vfio_device_set_xa); 66 + 67 + static char *vfio_device_devnode(const struct device *dev, umode_t *mode) 68 + { 69 + return kasprintf(GFP_KERNEL, "vfio/devices/%s", dev_name(dev)); 70 + } 71 + 72 + static const struct class vfio_device_class = { 73 + .name = "vfio-dev", 74 + .devnode = vfio_device_devnode 75 + }; 65 76 66 77 int vfio_assign_device_set(struct vfio_device *device, void *set_id) 67 78 { ··· 308 299 309 300 device_initialize(&device->device); 310 301 device->device.release = vfio_device_release; 311 - device->device.class = vfio.device_class; 302 + device->device.class = &vfio_device_class; 312 303 device->device.parent = device->dev; 313 304 return 0; 314 305 ··· 1813 1804 goto err_virqfd; 1814 1805 1815 1806 /* /sys/class/vfio-dev/vfioX */ 1816 - vfio.device_class = class_create("vfio-dev"); 1817 - if (IS_ERR(vfio.device_class)) { 1818 - ret = PTR_ERR(vfio.device_class); 1807 + ret = class_register(&vfio_device_class); 1808 + if (ret) 1819 1809 goto err_dev_class; 1820 - } 1821 1810 1822 - ret = vfio_cdev_init(vfio.device_class); 1811 + ret = vfio_cdev_init(); 1823 1812 if (ret) 1824 1813 goto err_alloc_dev_chrdev; 1825 1814 ··· 1826 1819 return 0; 1827 1820 1828 1821 err_alloc_dev_chrdev: 1829 - class_destroy(vfio.device_class); 1830 - vfio.device_class = NULL; 1822 + class_unregister(&vfio_device_class); 1831 1823 err_dev_class: 1832 1824 vfio_virqfd_exit(); 1833 1825 err_virqfd: ··· 1839 1833 vfio_debugfs_remove_root(); 1840 1834 ida_destroy(&vfio.device_ida); 1841 1835 vfio_cdev_cleanup(); 1842 - class_destroy(vfio.device_class); 1843 - vfio.device_class = NULL; 1836 + class_unregister(&vfio_device_class); 1844 1837 vfio_virqfd_exit(); 1845 1838 vfio_group_cleanup(); 1846 1839 xa_destroy(&vfio_device_set_xa);