Commit 2d08cd0ef89a24f5eb6c6801c48cd06bca230d6d

Authored by Linus Torvalds

Merge tag 'vfio-v3.14-rc1' of git://github.com/awilliam/linux-vfio

Pull vfio update from Alex Williamson:
 - convert to misc driver to support module auto loading
 - remove unnecessary and dangerous use of device_lock

* tag 'vfio-v3.14-rc1' of git://github.com/awilliam/linux-vfio:
  vfio-pci: Don't use device_lock around AER interrupt setup
  vfio: Convert control interface to misc driver
  misc: Reserve minor for VFIO

Showing 5 changed files Side-by-side Diff

Documentation/devices.txt
... ... @@ -409,6 +409,7 @@
409 409 193 = /dev/d7s SPARC 7-segment display
410 410 194 = /dev/zkshim Zero-Knowledge network shim control
411 411 195 = /dev/elographics/e2201 Elographics touchscreen E271-2201
  412 + 196 = /dev/vfio/vfio VFIO userspace driver interface
412 413 198 = /dev/sexec Signed executable interface
413 414 199 = /dev/scanners/cuecat :CueCat barcode scanner
414 415 200 = /dev/net/tun TAP/TUN network device
drivers/vfio/pci/vfio_pci.c
... ... @@ -872,8 +872,12 @@
872 872 return PCI_ERS_RESULT_DISCONNECT;
873 873 }
874 874  
  875 + mutex_lock(&vdev->igate);
  876 +
875 877 if (vdev->err_trigger)
876 878 eventfd_signal(vdev->err_trigger, 1);
  879 +
  880 + mutex_unlock(&vdev->igate);
877 881  
878 882 vfio_device_put(device);
879 883  
drivers/vfio/pci/vfio_pci_intrs.c
... ... @@ -749,54 +749,37 @@
749 749 unsigned count, uint32_t flags, void *data)
750 750 {
751 751 int32_t fd = *(int32_t *)data;
752   - struct pci_dev *pdev = vdev->pdev;
753 752  
754 753 if ((index != VFIO_PCI_ERR_IRQ_INDEX) ||
755 754 !(flags & VFIO_IRQ_SET_DATA_TYPE_MASK))
756 755 return -EINVAL;
757 756  
758   - /*
759   - * device_lock synchronizes setting and checking of
760   - * err_trigger. The vfio_pci_aer_err_detected() is also
761   - * called with device_lock held.
762   - */
763   -
764 757 /* DATA_NONE/DATA_BOOL enables loopback testing */
765   -
766 758 if (flags & VFIO_IRQ_SET_DATA_NONE) {
767   - device_lock(&pdev->dev);
768 759 if (vdev->err_trigger)
769 760 eventfd_signal(vdev->err_trigger, 1);
770   - device_unlock(&pdev->dev);
771 761 return 0;
772 762 } else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
773 763 uint8_t trigger = *(uint8_t *)data;
774   - device_lock(&pdev->dev);
775 764 if (trigger && vdev->err_trigger)
776 765 eventfd_signal(vdev->err_trigger, 1);
777   - device_unlock(&pdev->dev);
778 766 return 0;
779 767 }
780 768  
781 769 /* Handle SET_DATA_EVENTFD */
782   -
783 770 if (fd == -1) {
784   - device_lock(&pdev->dev);
785 771 if (vdev->err_trigger)
786 772 eventfd_ctx_put(vdev->err_trigger);
787 773 vdev->err_trigger = NULL;
788   - device_unlock(&pdev->dev);
789 774 return 0;
790 775 } else if (fd >= 0) {
791 776 struct eventfd_ctx *efdctx;
792 777 efdctx = eventfd_ctx_fdget(fd);
793 778 if (IS_ERR(efdctx))
794 779 return PTR_ERR(efdctx);
795   - device_lock(&pdev->dev);
796 780 if (vdev->err_trigger)
797 781 eventfd_ctx_put(vdev->err_trigger);
798 782 vdev->err_trigger = efdctx;
799   - device_unlock(&pdev->dev);
800 783 return 0;
801 784 } else
802 785 return -EINVAL;
... ... @@ -22,6 +22,7 @@
22 22 #include <linux/idr.h>
23 23 #include <linux/iommu.h>
24 24 #include <linux/list.h>
  25 +#include <linux/miscdevice.h>
25 26 #include <linux/module.h>
26 27 #include <linux/mutex.h>
27 28 #include <linux/rwsem.h>
... ... @@ -45,9 +46,7 @@
45 46 struct idr group_idr;
46 47 struct mutex group_lock;
47 48 struct cdev group_cdev;
48   - struct device *dev;
49   - dev_t devt;
50   - struct cdev cdev;
  49 + dev_t group_devt;
51 50 wait_queue_head_t release_q;
52 51 } vfio;
53 52  
... ... @@ -142,8 +141,7 @@
142 141 */
143 142 static int vfio_alloc_group_minor(struct vfio_group *group)
144 143 {
145   - /* index 0 is used by /dev/vfio/vfio */
146   - return idr_alloc(&vfio.group_idr, group, 1, MINORMASK + 1, GFP_KERNEL);
  144 + return idr_alloc(&vfio.group_idr, group, 0, MINORMASK + 1, GFP_KERNEL);
147 145 }
148 146  
149 147 static void vfio_free_group_minor(int minor)
... ... @@ -243,7 +241,8 @@
243 241 }
244 242 }
245 243  
246   - dev = device_create(vfio.class, NULL, MKDEV(MAJOR(vfio.devt), minor),
  244 + dev = device_create(vfio.class, NULL,
  245 + MKDEV(MAJOR(vfio.group_devt), minor),
247 246 group, "%d", iommu_group_id(iommu_group));
248 247 if (IS_ERR(dev)) {
249 248 vfio_free_group_minor(minor);
... ... @@ -268,7 +267,7 @@
268 267  
269 268 WARN_ON(!list_empty(&group->device_list));
270 269  
271   - device_destroy(vfio.class, MKDEV(MAJOR(vfio.devt), group->minor));
  270 + device_destroy(vfio.class, MKDEV(MAJOR(vfio.group_devt), group->minor));
272 271 list_del(&group->vfio_next);
273 272 vfio_free_group_minor(group->minor);
274 273 vfio_group_unlock_and_free(group);
275 274  
... ... @@ -1419,12 +1418,17 @@
1419 1418 */
1420 1419 static char *vfio_devnode(struct device *dev, umode_t *mode)
1421 1420 {
1422   - if (mode && (MINOR(dev->devt) == 0))
1423   - *mode = S_IRUGO | S_IWUGO;
1424   -
1425 1421 return kasprintf(GFP_KERNEL, "vfio/%s", dev_name(dev));
1426 1422 }
1427 1423  
  1424 +static struct miscdevice vfio_dev = {
  1425 + .minor = VFIO_MINOR,
  1426 + .name = "vfio",
  1427 + .fops = &vfio_fops,
  1428 + .nodename = "vfio/vfio",
  1429 + .mode = S_IRUGO | S_IWUGO,
  1430 +};
  1431 +
1428 1432 static int __init vfio_init(void)
1429 1433 {
1430 1434 int ret;
... ... @@ -1436,6 +1440,13 @@
1436 1440 INIT_LIST_HEAD(&vfio.iommu_drivers_list);
1437 1441 init_waitqueue_head(&vfio.release_q);
1438 1442  
  1443 + ret = misc_register(&vfio_dev);
  1444 + if (ret) {
  1445 + pr_err("vfio: misc device register failed\n");
  1446 + return ret;
  1447 + }
  1448 +
  1449 + /* /dev/vfio/$GROUP */
1439 1450 vfio.class = class_create(THIS_MODULE, "vfio");
1440 1451 if (IS_ERR(vfio.class)) {
1441 1452 ret = PTR_ERR(vfio.class);
1442 1453  
1443 1454  
1444 1455  
1445 1456  
... ... @@ -1444,27 +1455,14 @@
1444 1455  
1445 1456 vfio.class->devnode = vfio_devnode;
1446 1457  
1447   - ret = alloc_chrdev_region(&vfio.devt, 0, MINORMASK, "vfio");
  1458 + ret = alloc_chrdev_region(&vfio.group_devt, 0, MINORMASK, "vfio");
1448 1459 if (ret)
1449   - goto err_base_chrdev;
  1460 + goto err_alloc_chrdev;
1450 1461  
1451   - cdev_init(&vfio.cdev, &vfio_fops);
1452   - ret = cdev_add(&vfio.cdev, vfio.devt, 1);
1453   - if (ret)
1454   - goto err_base_cdev;
1455   -
1456   - vfio.dev = device_create(vfio.class, NULL, vfio.devt, NULL, "vfio");
1457   - if (IS_ERR(vfio.dev)) {
1458   - ret = PTR_ERR(vfio.dev);
1459   - goto err_base_dev;
1460   - }
1461   -
1462   - /* /dev/vfio/$GROUP */
1463 1462 cdev_init(&vfio.group_cdev, &vfio_group_fops);
1464   - ret = cdev_add(&vfio.group_cdev,
1465   - MKDEV(MAJOR(vfio.devt), 1), MINORMASK - 1);
  1463 + ret = cdev_add(&vfio.group_cdev, vfio.group_devt, MINORMASK);
1466 1464 if (ret)
1467   - goto err_groups_cdev;
  1465 + goto err_cdev_add;
1468 1466  
1469 1467 pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1470 1468  
1471 1469  
... ... @@ -1478,16 +1476,13 @@
1478 1476  
1479 1477 return 0;
1480 1478  
1481   -err_groups_cdev:
1482   - device_destroy(vfio.class, vfio.devt);
1483   -err_base_dev:
1484   - cdev_del(&vfio.cdev);
1485   -err_base_cdev:
1486   - unregister_chrdev_region(vfio.devt, MINORMASK);
1487   -err_base_chrdev:
  1479 +err_cdev_add:
  1480 + unregister_chrdev_region(vfio.group_devt, MINORMASK);
  1481 +err_alloc_chrdev:
1488 1482 class_destroy(vfio.class);
1489 1483 vfio.class = NULL;
1490 1484 err_class:
  1485 + misc_deregister(&vfio_dev);
1491 1486 return ret;
1492 1487 }
1493 1488  
1494 1489  
... ... @@ -1497,11 +1492,10 @@
1497 1492  
1498 1493 idr_destroy(&vfio.group_idr);
1499 1494 cdev_del(&vfio.group_cdev);
1500   - device_destroy(vfio.class, vfio.devt);
1501   - cdev_del(&vfio.cdev);
1502   - unregister_chrdev_region(vfio.devt, MINORMASK);
  1495 + unregister_chrdev_region(vfio.group_devt, MINORMASK);
1503 1496 class_destroy(vfio.class);
1504 1497 vfio.class = NULL;
  1498 + misc_deregister(&vfio_dev);
1505 1499 }
1506 1500  
1507 1501 module_init(vfio_init);
... ... @@ -1511,4 +1505,6 @@
1511 1505 MODULE_LICENSE("GPL v2");
1512 1506 MODULE_AUTHOR(DRIVER_AUTHOR);
1513 1507 MODULE_DESCRIPTION(DRIVER_DESC);
  1508 +MODULE_ALIAS_MISCDEV(VFIO_MINOR);
  1509 +MODULE_ALIAS("devname:vfio/vfio");
include/linux/miscdevice.h
... ... @@ -30,6 +30,7 @@
30 30 #define STORE_QUEUE_MINOR 155
31 31 #define I2O_MINOR 166
32 32 #define MICROCODE_MINOR 184
  33 +#define VFIO_MINOR 196
33 34 #define TUN_MINOR 200
34 35 #define CUSE_MINOR 203
35 36 #define MWAVE_MINOR 219 /* ACP/Mwave Modem */