aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vfio/pci/vfio_pci.c
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2014-08-07 13:12:07 -0400
committerAlex Williamson <alex.williamson@redhat.com>2014-08-07 13:12:07 -0400
commitbc4fba77124e2fe4eb14bcb52875c0b0228deace (patch)
tree32c9a964e7e40735ef6e9841f2509053f5e24729 /drivers/vfio/pci/vfio_pci.c
parent61d792562b53c610f9fe917f2bbc22218aa39c22 (diff)
vfio-pci: Attempt bus/slot reset on release
Each time a device is released, mark whether a local reset was successful or whether a bus/slot reset is needed. If a reset is needed and all of the affected devices are bound to vfio-pci and unused, allow the reset. This is most useful when the userspace driver is killed and releases all the devices in an unclean state, such as when a QEMU VM quits. Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/vfio/pci/vfio_pci.c')
-rw-r--r--drivers/vfio/pci/vfio_pci.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index c9d756b7ee9e..1651c0769b72 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -39,6 +39,8 @@ MODULE_PARM_DESC(nointxmask,
39 39
40static DEFINE_MUTEX(driver_lock); 40static DEFINE_MUTEX(driver_lock);
41 41
42static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev);
43
42static int vfio_pci_enable(struct vfio_pci_device *vdev) 44static int vfio_pci_enable(struct vfio_pci_device *vdev)
43{ 45{
44 struct pci_dev *pdev = vdev->pdev; 46 struct pci_dev *pdev = vdev->pdev;
@@ -123,6 +125,8 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)
123 vdev->barmap[bar] = NULL; 125 vdev->barmap[bar] = NULL;
124 } 126 }
125 127
128 vdev->needs_reset = true;
129
126 /* 130 /*
127 * If we have saved state, restore it. If we can reset the device, 131 * If we have saved state, restore it. If we can reset the device,
128 * even better. Resetting with current state seems better than 132 * even better. Resetting with current state seems better than
@@ -154,11 +158,15 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)
154 if (ret) 158 if (ret)
155 pr_warn("%s: Failed to reset device %s (%d)\n", 159 pr_warn("%s: Failed to reset device %s (%d)\n",
156 __func__, dev_name(&pdev->dev), ret); 160 __func__, dev_name(&pdev->dev), ret);
161 else
162 vdev->needs_reset = false;
157 } 163 }
158 164
159 pci_restore_state(pdev); 165 pci_restore_state(pdev);
160out: 166out:
161 pci_disable_device(pdev); 167 pci_disable_device(pdev);
168
169 vfio_pci_try_bus_reset(vdev);
162} 170}
163 171
164static void vfio_pci_release(void *device_data) 172static void vfio_pci_release(void *device_data)
@@ -923,6 +931,110 @@ static struct pci_driver vfio_pci_driver = {
923 .err_handler = &vfio_err_handlers, 931 .err_handler = &vfio_err_handlers,
924}; 932};
925 933
934/*
935 * Test whether a reset is necessary and possible. We mark devices as
936 * needs_reset when they are released, but don't have a function-local reset
937 * available. If any of these exist in the affected devices, we want to do
938 * a bus/slot reset. We also need all of the affected devices to be unused,
939 * so we abort if any device has a non-zero refcnt. driver_lock prevents a
940 * device from being opened during the scan or unbound from vfio-pci.
941 */
942static int vfio_pci_test_bus_reset(struct pci_dev *pdev, void *data)
943{
944 bool *needs_reset = data;
945 struct pci_driver *pci_drv = ACCESS_ONCE(pdev->driver);
946 int ret = -EBUSY;
947
948 if (pci_drv == &vfio_pci_driver) {
949 struct vfio_device *device;
950 struct vfio_pci_device *vdev;
951
952 device = vfio_device_get_from_dev(&pdev->dev);
953 if (!device)
954 return ret;
955
956 vdev = vfio_device_data(device);
957 if (vdev) {
958 if (vdev->needs_reset)
959 *needs_reset = true;
960
961 if (!vdev->refcnt)
962 ret = 0;
963 }
964
965 vfio_device_put(device);
966 }
967
968 /*
969 * TODO: vfio-core considers groups to be viable even if some devices
970 * are attached to known drivers, like pci-stub or pcieport. We can't
971 * freeze devices from being unbound to those drivers like we can
972 * here though, so it would be racy to test for them. We also can't
973 * use device_lock() to prevent changes as that would interfere with
974 * PCI-core taking device_lock during bus reset. For now, we require
975 * devices to be bound to vfio-pci to get a bus/slot reset on release.
976 */
977
978 return ret;
979}
980
981/* Clear needs_reset on all affected devices after successful bus/slot reset */
982static int vfio_pci_clear_needs_reset(struct pci_dev *pdev, void *data)
983{
984 struct pci_driver *pci_drv = ACCESS_ONCE(pdev->driver);
985
986 if (pci_drv == &vfio_pci_driver) {
987 struct vfio_device *device;
988 struct vfio_pci_device *vdev;
989
990 device = vfio_device_get_from_dev(&pdev->dev);
991 if (!device)
992 return 0;
993
994 vdev = vfio_device_data(device);
995 if (vdev)
996 vdev->needs_reset = false;
997
998 vfio_device_put(device);
999 }
1000
1001 return 0;
1002}
1003
1004/*
1005 * Attempt to do a bus/slot reset if there are devices affected by a reset for
1006 * this device that are needs_reset and all of the affected devices are unused
1007 * (!refcnt). Callers of this function are required to hold driver_lock such
1008 * that devices can not be unbound from vfio-pci or opened by a user while we
1009 * test for and perform a bus/slot reset.
1010 */
1011static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev)
1012{
1013 bool needs_reset = false, slot = false;
1014 int ret;
1015
1016 if (!pci_probe_reset_slot(vdev->pdev->slot))
1017 slot = true;
1018 else if (pci_probe_reset_bus(vdev->pdev->bus))
1019 return;
1020
1021 if (vfio_pci_for_each_slot_or_bus(vdev->pdev,
1022 vfio_pci_test_bus_reset,
1023 &needs_reset, slot) || !needs_reset)
1024 return;
1025
1026 if (slot)
1027 ret = pci_try_reset_slot(vdev->pdev->slot);
1028 else
1029 ret = pci_try_reset_bus(vdev->pdev->bus);
1030
1031 if (ret)
1032 return;
1033
1034 vfio_pci_for_each_slot_or_bus(vdev->pdev,
1035 vfio_pci_clear_needs_reset, NULL, slot);
1036}
1037
926static void __exit vfio_pci_cleanup(void) 1038static void __exit vfio_pci_cleanup(void)
927{ 1039{
928 pci_unregister_driver(&vfio_pci_driver); 1040 pci_unregister_driver(&vfio_pci_driver);