Skip to content

Commit 2d08cd0

Browse files
committed
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
2 parents 5c85121 + 3be3a07 commit 2d08cd0

File tree

5 files changed

+39
-54
lines changed

5 files changed

+39
-54
lines changed

Documentation/devices.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ Your cooperation is appreciated.
409409
193 = /dev/d7s SPARC 7-segment display
410410
194 = /dev/zkshim Zero-Knowledge network shim control
411411
195 = /dev/elographics/e2201 Elographics touchscreen E271-2201
412+
196 = /dev/vfio/vfio VFIO userspace driver interface
412413
198 = /dev/sexec Signed executable interface
413414
199 = /dev/scanners/cuecat :CueCat barcode scanner
414415
200 = /dev/net/tun TAP/TUN network device

drivers/vfio/pci/vfio_pci.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,9 +872,13 @@ static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
872872
return PCI_ERS_RESULT_DISCONNECT;
873873
}
874874

875+
mutex_lock(&vdev->igate);
876+
875877
if (vdev->err_trigger)
876878
eventfd_signal(vdev->err_trigger, 1);
877879

880+
mutex_unlock(&vdev->igate);
881+
878882
vfio_device_put(device);
879883

880884
return PCI_ERS_RESULT_CAN_RECOVER;

drivers/vfio/pci/vfio_pci_intrs.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -749,54 +749,37 @@ static int vfio_pci_set_err_trigger(struct vfio_pci_device *vdev,
749749
unsigned count, uint32_t flags, void *data)
750750
{
751751
int32_t fd = *(int32_t *)data;
752-
struct pci_dev *pdev = vdev->pdev;
753752

754753
if ((index != VFIO_PCI_ERR_IRQ_INDEX) ||
755754
!(flags & VFIO_IRQ_SET_DATA_TYPE_MASK))
756755
return -EINVAL;
757756

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-
764757
/* DATA_NONE/DATA_BOOL enables loopback testing */
765-
766758
if (flags & VFIO_IRQ_SET_DATA_NONE) {
767-
device_lock(&pdev->dev);
768759
if (vdev->err_trigger)
769760
eventfd_signal(vdev->err_trigger, 1);
770-
device_unlock(&pdev->dev);
771761
return 0;
772762
} else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
773763
uint8_t trigger = *(uint8_t *)data;
774-
device_lock(&pdev->dev);
775764
if (trigger && vdev->err_trigger)
776765
eventfd_signal(vdev->err_trigger, 1);
777-
device_unlock(&pdev->dev);
778766
return 0;
779767
}
780768

781769
/* Handle SET_DATA_EVENTFD */
782-
783770
if (fd == -1) {
784-
device_lock(&pdev->dev);
785771
if (vdev->err_trigger)
786772
eventfd_ctx_put(vdev->err_trigger);
787773
vdev->err_trigger = NULL;
788-
device_unlock(&pdev->dev);
789774
return 0;
790775
} else if (fd >= 0) {
791776
struct eventfd_ctx *efdctx;
792777
efdctx = eventfd_ctx_fdget(fd);
793778
if (IS_ERR(efdctx))
794779
return PTR_ERR(efdctx);
795-
device_lock(&pdev->dev);
796780
if (vdev->err_trigger)
797781
eventfd_ctx_put(vdev->err_trigger);
798782
vdev->err_trigger = efdctx;
799-
device_unlock(&pdev->dev);
800783
return 0;
801784
} else
802785
return -EINVAL;

drivers/vfio/vfio.c

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/idr.h>
2323
#include <linux/iommu.h>
2424
#include <linux/list.h>
25+
#include <linux/miscdevice.h>
2526
#include <linux/module.h>
2627
#include <linux/mutex.h>
2728
#include <linux/rwsem.h>
@@ -45,9 +46,7 @@ static struct vfio {
4546
struct idr group_idr;
4647
struct mutex group_lock;
4748
struct cdev group_cdev;
48-
struct device *dev;
49-
dev_t devt;
50-
struct cdev cdev;
49+
dev_t group_devt;
5150
wait_queue_head_t release_q;
5251
} vfio;
5352

@@ -142,8 +141,7 @@ EXPORT_SYMBOL_GPL(vfio_unregister_iommu_driver);
142141
*/
143142
static int vfio_alloc_group_minor(struct vfio_group *group)
144143
{
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);
147145
}
148146

149147
static void vfio_free_group_minor(int minor)
@@ -243,7 +241,8 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group)
243241
}
244242
}
245243

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),
247246
group, "%d", iommu_group_id(iommu_group));
248247
if (IS_ERR(dev)) {
249248
vfio_free_group_minor(minor);
@@ -268,7 +267,7 @@ static void vfio_group_release(struct kref *kref)
268267

269268
WARN_ON(!list_empty(&group->device_list));
270269

271-
device_destroy(vfio.class, MKDEV(MAJOR(vfio.devt), group->minor));
270+
device_destroy(vfio.class, MKDEV(MAJOR(vfio.group_devt), group->minor));
272271
list_del(&group->vfio_next);
273272
vfio_free_group_minor(group->minor);
274273
vfio_group_unlock_and_free(group);
@@ -1419,12 +1418,17 @@ EXPORT_SYMBOL_GPL(vfio_external_user_iommu_id);
14191418
*/
14201419
static char *vfio_devnode(struct device *dev, umode_t *mode)
14211420
{
1422-
if (mode && (MINOR(dev->devt) == 0))
1423-
*mode = S_IRUGO | S_IWUGO;
1424-
14251421
return kasprintf(GFP_KERNEL, "vfio/%s", dev_name(dev));
14261422
}
14271423

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+
14281432
static int __init vfio_init(void)
14291433
{
14301434
int ret;
@@ -1436,6 +1440,13 @@ static int __init vfio_init(void)
14361440
INIT_LIST_HEAD(&vfio.iommu_drivers_list);
14371441
init_waitqueue_head(&vfio.release_q);
14381442

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 */
14391450
vfio.class = class_create(THIS_MODULE, "vfio");
14401451
if (IS_ERR(vfio.class)) {
14411452
ret = PTR_ERR(vfio.class);
@@ -1444,27 +1455,14 @@ static int __init vfio_init(void)
14441455

14451456
vfio.class->devnode = vfio_devnode;
14461457

1447-
ret = alloc_chrdev_region(&vfio.devt, 0, MINORMASK, "vfio");
1448-
if (ret)
1449-
goto err_base_chrdev;
1450-
1451-
cdev_init(&vfio.cdev, &vfio_fops);
1452-
ret = cdev_add(&vfio.cdev, vfio.devt, 1);
1458+
ret = alloc_chrdev_region(&vfio.group_devt, 0, MINORMASK, "vfio");
14531459
if (ret)
1454-
goto err_base_cdev;
1460+
goto err_alloc_chrdev;
14551461

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 */
14631462
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);
14661464
if (ret)
1467-
goto err_groups_cdev;
1465+
goto err_cdev_add;
14681466

14691467
pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
14701468

@@ -1478,16 +1476,13 @@ static int __init vfio_init(void)
14781476

14791477
return 0;
14801478

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:
14881482
class_destroy(vfio.class);
14891483
vfio.class = NULL;
14901484
err_class:
1485+
misc_deregister(&vfio_dev);
14911486
return ret;
14921487
}
14931488

@@ -1497,11 +1492,10 @@ static void __exit vfio_cleanup(void)
14971492

14981493
idr_destroy(&vfio.group_idr);
14991494
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);
15031496
class_destroy(vfio.class);
15041497
vfio.class = NULL;
1498+
misc_deregister(&vfio_dev);
15051499
}
15061500

15071501
module_init(vfio_init);
@@ -1511,3 +1505,5 @@ MODULE_VERSION(DRIVER_VERSION);
15111505
MODULE_LICENSE("GPL v2");
15121506
MODULE_AUTHOR(DRIVER_AUTHOR);
15131507
MODULE_DESCRIPTION(DRIVER_DESC);
1508+
MODULE_ALIAS_MISCDEV(VFIO_MINOR);
1509+
MODULE_ALIAS("devname:vfio/vfio");

include/linux/miscdevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#define STORE_QUEUE_MINOR 155
3131
#define I2O_MINOR 166
3232
#define MICROCODE_MINOR 184
33+
#define VFIO_MINOR 196
3334
#define TUN_MINOR 200
3435
#define CUSE_MINOR 203
3536
#define MWAVE_MINOR 219 /* ACP/Mwave Modem */

0 commit comments

Comments
 (0)