diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-11 06:49:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-11 06:49:24 -0400 |
commit | 27a9716bc80448f7e98fb1fb316daba241a4c539 (patch) | |
tree | d9a82dc1e1eddd1ff2a27d558149ad8323975134 /drivers/vfio/pci | |
parent | e98d6e7f7625ed60c7bc1d39aeb2375ed3918fd5 (diff) | |
parent | 93899a679fd6b2534b5c297d9316bae039ebcbe1 (diff) |
Merge tag 'vfio-v3.18-rc1' of git://github.com/awilliam/linux-vfio
Pull VFIO updates from Alex Williamson:
- Nested IOMMU extension to type1 (Will Deacon)
- Restore MSIx message before enabling (Gavin Shan)
- Fix remove path locking (Alex Williamson)
* tag 'vfio-v3.18-rc1' of git://github.com/awilliam/linux-vfio:
vfio-pci: Fix remove path locking
drivers/vfio: Export vfio_spapr_iommu_eeh_ioctl() with GPL
vfio/pci: Restore MSIx message prior to enabling
PCI: Export MSI message relevant functions
vfio/iommu_type1: add new VFIO_TYPE1_NESTING_IOMMU IOMMU type
iommu: introduce domain attribute for nesting IOMMUs
Diffstat (limited to 'drivers/vfio/pci')
-rw-r--r-- | drivers/vfio/pci/vfio_pci.c | 136 | ||||
-rw-r--r-- | drivers/vfio/pci/vfio_pci_intrs.c | 15 |
2 files changed, 72 insertions, 79 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index f7825332a325..9558da3f06a0 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c | |||
@@ -876,15 +876,11 @@ static void vfio_pci_remove(struct pci_dev *pdev) | |||
876 | { | 876 | { |
877 | struct vfio_pci_device *vdev; | 877 | struct vfio_pci_device *vdev; |
878 | 878 | ||
879 | mutex_lock(&driver_lock); | ||
880 | |||
881 | vdev = vfio_del_group_dev(&pdev->dev); | 879 | vdev = vfio_del_group_dev(&pdev->dev); |
882 | if (vdev) { | 880 | if (vdev) { |
883 | iommu_group_put(pdev->dev.iommu_group); | 881 | iommu_group_put(pdev->dev.iommu_group); |
884 | kfree(vdev); | 882 | kfree(vdev); |
885 | } | 883 | } |
886 | |||
887 | mutex_unlock(&driver_lock); | ||
888 | } | 884 | } |
889 | 885 | ||
890 | static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev, | 886 | static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev, |
@@ -927,108 +923,90 @@ static struct pci_driver vfio_pci_driver = { | |||
927 | .err_handler = &vfio_err_handlers, | 923 | .err_handler = &vfio_err_handlers, |
928 | }; | 924 | }; |
929 | 925 | ||
930 | /* | 926 | struct vfio_devices { |
931 | * Test whether a reset is necessary and possible. We mark devices as | 927 | struct vfio_device **devices; |
932 | * needs_reset when they are released, but don't have a function-local reset | 928 | int cur_index; |
933 | * available. If any of these exist in the affected devices, we want to do | 929 | int max_index; |
934 | * a bus/slot reset. We also need all of the affected devices to be unused, | 930 | }; |
935 | * so we abort if any device has a non-zero refcnt. driver_lock prevents a | ||
936 | * device from being opened during the scan or unbound from vfio-pci. | ||
937 | */ | ||
938 | static int vfio_pci_test_bus_reset(struct pci_dev *pdev, void *data) | ||
939 | { | ||
940 | bool *needs_reset = data; | ||
941 | struct pci_driver *pci_drv = ACCESS_ONCE(pdev->driver); | ||
942 | int ret = -EBUSY; | ||
943 | |||
944 | if (pci_drv == &vfio_pci_driver) { | ||
945 | struct vfio_device *device; | ||
946 | struct vfio_pci_device *vdev; | ||
947 | |||
948 | device = vfio_device_get_from_dev(&pdev->dev); | ||
949 | if (!device) | ||
950 | return ret; | ||
951 | |||
952 | vdev = vfio_device_data(device); | ||
953 | if (vdev) { | ||
954 | if (vdev->needs_reset) | ||
955 | *needs_reset = true; | ||
956 | |||
957 | if (!vdev->refcnt) | ||
958 | ret = 0; | ||
959 | } | ||
960 | |||
961 | vfio_device_put(device); | ||
962 | } | ||
963 | |||
964 | /* | ||
965 | * TODO: vfio-core considers groups to be viable even if some devices | ||
966 | * are attached to known drivers, like pci-stub or pcieport. We can't | ||
967 | * freeze devices from being unbound to those drivers like we can | ||
968 | * here though, so it would be racy to test for them. We also can't | ||
969 | * use device_lock() to prevent changes as that would interfere with | ||
970 | * PCI-core taking device_lock during bus reset. For now, we require | ||
971 | * devices to be bound to vfio-pci to get a bus/slot reset on release. | ||
972 | */ | ||
973 | |||
974 | return ret; | ||
975 | } | ||
976 | 931 | ||
977 | /* Clear needs_reset on all affected devices after successful bus/slot reset */ | 932 | static int vfio_pci_get_devs(struct pci_dev *pdev, void *data) |
978 | static int vfio_pci_clear_needs_reset(struct pci_dev *pdev, void *data) | ||
979 | { | 933 | { |
934 | struct vfio_devices *devs = data; | ||
980 | struct pci_driver *pci_drv = ACCESS_ONCE(pdev->driver); | 935 | struct pci_driver *pci_drv = ACCESS_ONCE(pdev->driver); |
981 | 936 | ||
982 | if (pci_drv == &vfio_pci_driver) { | 937 | if (pci_drv != &vfio_pci_driver) |
983 | struct vfio_device *device; | 938 | return -EBUSY; |
984 | struct vfio_pci_device *vdev; | ||
985 | 939 | ||
986 | device = vfio_device_get_from_dev(&pdev->dev); | 940 | if (devs->cur_index == devs->max_index) |
987 | if (!device) | 941 | return -ENOSPC; |
988 | return 0; | ||
989 | 942 | ||
990 | vdev = vfio_device_data(device); | 943 | devs->devices[devs->cur_index] = vfio_device_get_from_dev(&pdev->dev); |
991 | if (vdev) | 944 | if (!devs->devices[devs->cur_index]) |
992 | vdev->needs_reset = false; | 945 | return -EINVAL; |
993 | |||
994 | vfio_device_put(device); | ||
995 | } | ||
996 | 946 | ||
947 | devs->cur_index++; | ||
997 | return 0; | 948 | return 0; |
998 | } | 949 | } |
999 | 950 | ||
1000 | /* | 951 | /* |
1001 | * Attempt to do a bus/slot reset if there are devices affected by a reset for | 952 | * Attempt to do a bus/slot reset if there are devices affected by a reset for |
1002 | * this device that are needs_reset and all of the affected devices are unused | 953 | * this device that are needs_reset and all of the affected devices are unused |
1003 | * (!refcnt). Callers of this function are required to hold driver_lock such | 954 | * (!refcnt). Callers are required to hold driver_lock when calling this to |
1004 | * that devices can not be unbound from vfio-pci or opened by a user while we | 955 | * prevent device opens and concurrent bus reset attempts. We prevent device |
1005 | * test for and perform a bus/slot reset. | 956 | * unbinds by acquiring and holding a reference to the vfio_device. |
957 | * | ||
958 | * NB: vfio-core considers a group to be viable even if some devices are | ||
959 | * bound to drivers like pci-stub or pcieport. Here we require all devices | ||
960 | * to be bound to vfio_pci since that's the only way we can be sure they | ||
961 | * stay put. | ||
1006 | */ | 962 | */ |
1007 | static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev) | 963 | static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev) |
1008 | { | 964 | { |
965 | struct vfio_devices devs = { .cur_index = 0 }; | ||
966 | int i = 0, ret = -EINVAL; | ||
1009 | bool needs_reset = false, slot = false; | 967 | bool needs_reset = false, slot = false; |
1010 | int ret; | 968 | struct vfio_pci_device *tmp; |
1011 | 969 | ||
1012 | if (!pci_probe_reset_slot(vdev->pdev->slot)) | 970 | if (!pci_probe_reset_slot(vdev->pdev->slot)) |
1013 | slot = true; | 971 | slot = true; |
1014 | else if (pci_probe_reset_bus(vdev->pdev->bus)) | 972 | else if (pci_probe_reset_bus(vdev->pdev->bus)) |
1015 | return; | 973 | return; |
1016 | 974 | ||
1017 | if (vfio_pci_for_each_slot_or_bus(vdev->pdev, | 975 | if (vfio_pci_for_each_slot_or_bus(vdev->pdev, vfio_pci_count_devs, |
1018 | vfio_pci_test_bus_reset, | 976 | &i, slot) || !i) |
1019 | &needs_reset, slot) || !needs_reset) | ||
1020 | return; | 977 | return; |
1021 | 978 | ||
1022 | if (slot) | 979 | devs.max_index = i; |
1023 | ret = pci_try_reset_slot(vdev->pdev->slot); | 980 | devs.devices = kcalloc(i, sizeof(struct vfio_device *), GFP_KERNEL); |
1024 | else | 981 | if (!devs.devices) |
1025 | ret = pci_try_reset_bus(vdev->pdev->bus); | ||
1026 | |||
1027 | if (ret) | ||
1028 | return; | 982 | return; |
1029 | 983 | ||
1030 | vfio_pci_for_each_slot_or_bus(vdev->pdev, | 984 | if (vfio_pci_for_each_slot_or_bus(vdev->pdev, |
1031 | vfio_pci_clear_needs_reset, NULL, slot); | 985 | vfio_pci_get_devs, &devs, slot)) |
986 | goto put_devs; | ||
987 | |||
988 | for (i = 0; i < devs.cur_index; i++) { | ||
989 | tmp = vfio_device_data(devs.devices[i]); | ||
990 | if (tmp->needs_reset) | ||
991 | needs_reset = true; | ||
992 | if (tmp->refcnt) | ||
993 | goto put_devs; | ||
994 | } | ||
995 | |||
996 | if (needs_reset) | ||
997 | ret = slot ? pci_try_reset_slot(vdev->pdev->slot) : | ||
998 | pci_try_reset_bus(vdev->pdev->bus); | ||
999 | |||
1000 | put_devs: | ||
1001 | for (i = 0; i < devs.cur_index; i++) { | ||
1002 | if (!ret) { | ||
1003 | tmp = vfio_device_data(devs.devices[i]); | ||
1004 | tmp->needs_reset = false; | ||
1005 | } | ||
1006 | vfio_device_put(devs.devices[i]); | ||
1007 | } | ||
1008 | |||
1009 | kfree(devs.devices); | ||
1032 | } | 1010 | } |
1033 | 1011 | ||
1034 | static void __exit vfio_pci_cleanup(void) | 1012 | static void __exit vfio_pci_cleanup(void) |
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index 9dd49c9839ac..553212f037c3 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/eventfd.h> | 18 | #include <linux/eventfd.h> |
19 | #include <linux/msi.h> | ||
19 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
20 | #include <linux/file.h> | 21 | #include <linux/file.h> |
21 | #include <linux/poll.h> | 22 | #include <linux/poll.h> |
@@ -548,6 +549,20 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev, | |||
548 | return PTR_ERR(trigger); | 549 | return PTR_ERR(trigger); |
549 | } | 550 | } |
550 | 551 | ||
552 | /* | ||
553 | * The MSIx vector table resides in device memory which may be cleared | ||
554 | * via backdoor resets. We don't allow direct access to the vector | ||
555 | * table so even if a userspace driver attempts to save/restore around | ||
556 | * such a reset it would be unsuccessful. To avoid this, restore the | ||
557 | * cached value of the message prior to enabling. | ||
558 | */ | ||
559 | if (msix) { | ||
560 | struct msi_msg msg; | ||
561 | |||
562 | get_cached_msi_msg(irq, &msg); | ||
563 | write_msi_msg(irq, &msg); | ||
564 | } | ||
565 | |||
551 | ret = request_irq(irq, vfio_msihandler, 0, | 566 | ret = request_irq(irq, vfio_msihandler, 0, |
552 | vdev->ctx[vector].name, trigger); | 567 | vdev->ctx[vector].name, trigger); |
553 | if (ret) { | 568 | if (ret) { |