History

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

Pull VFIO updates from Alex Williamson: - enable support for bus reset on device release - fixes for EEH support * tag 'vfio-v3.17-rc1' of git://github.com/awilliam/linux-vfio: drivers/vfio: Enable VFIO if EEH is not supported drivers/vfio: Allow EEH to be built as module drivers/vfio: Fix EEH build error vfio-pci: Attempt bus/slot reset on release vfio-pci: Use mutex around open, release, and remove vfio-pci: Release devices with BusMaster disabled

Linus Torvalds committed 12 years ago

Commit cc8a44c2 parents 4dacb91 9b936c96 files · +170 −25Browse files

Unified · Split

6 files
  1. drivers/vfio/Kconfig +6 −0
  2. drivers/vfio/Makefile +1 −1
  3. drivers/vfio/pci/vfio_pci.c +143 −18
  4. drivers/vfio/pci/vfio_pci_private.h +2 −1
  5. drivers/vfio/vfio_spapr_eeh.c +15 −2
  6. include/linux/vfio.h +3 −3
drivers/vfio/Kconfig+6−0
@@ -8,11 +8,17 @@ config VFIO_IOMMU_SPAPR_TCE · 7 unmodified lines
8 depends on VFIO && SPAPR_TCE_IOMMU8 depends on VFIO && SPAPR_TCE_IOMMU
9 default n9 default n
10 10
11config VFIO_SPAPR_EEH
12 tristate
13 depends on EEH && VFIO_IOMMU_SPAPR_TCE
14 default n
15
11menuconfig VFIO16menuconfig VFIO
12 tristate "VFIO Non-Privileged userspace driver framework"17 tristate "VFIO Non-Privileged userspace driver framework"
13 depends on IOMMU_API18 depends on IOMMU_API
14 select VFIO_IOMMU_TYPE1 if X8619 select VFIO_IOMMU_TYPE1 if X86
15 select VFIO_IOMMU_SPAPR_TCE if (PPC_POWERNV || PPC_PSERIES)20 select VFIO_IOMMU_SPAPR_TCE if (PPC_POWERNV || PPC_PSERIES)
21 select VFIO_SPAPR_EEH if (PPC_POWERNV || PPC_PSERIES)
16 select ANON_INODES22 select ANON_INODES
17 help23 help
18 VFIO provides a framework for secure userspace device drivers.24 VFIO provides a framework for secure userspace device drivers.
drivers/vfio/Makefile+1−1
@@ -1,5 +1,5 @@
1obj-$(CONFIG_VFIO) += vfio.o1obj-$(CONFIG_VFIO) += vfio.o
2obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o2obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o
3obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o3obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o
4obj-$(CONFIG_EEH) += vfio_spapr_eeh.o4obj-$(CONFIG_VFIO_SPAPR_EEH) += vfio_spapr_eeh.o
5obj-$(CONFIG_VFIO_PCI) += pci/5obj-$(CONFIG_VFIO_PCI) += pci/
drivers/vfio/pci/vfio_pci.c+143−18
@@ -37,6 +37,10 @@ module_param_named(nointxmask, nointxmask, bool, S_IRUGO | S_IWUSR); · 36 unmodified lines
37MODULE_PARM_DESC(nointxmask,37MODULE_PARM_DESC(nointxmask,
38 "Disable support for PCI 2.3 style INTx masking. If this resolves problems for specific devices, report lspci -vvvxxx to linux-pci@vger.kernel.org so the device can be fixed automatically via the broken_intx_masking flag.");38 "Disable support for PCI 2.3 style INTx masking. If this resolves problems for specific devices, report lspci -vvvxxx to linux-pci@vger.kernel.org so the device can be fixed automatically via the broken_intx_masking flag.");
39 39
40static DEFINE_MUTEX(driver_lock);
41
42static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev);
43
40static int vfio_pci_enable(struct vfio_pci_device *vdev)44static int vfio_pci_enable(struct vfio_pci_device *vdev)
41{45{
42 struct pci_dev *pdev = vdev->pdev;46 struct pci_dev *pdev = vdev->pdev;
@@ -44,6 +48,9 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev) · 1 unmodified line
44 u16 cmd;48 u16 cmd;
45 u8 msix_pos;49 u8 msix_pos;
46 50
51 /* Don't allow our initial saved state to include busmaster */
52 pci_clear_master(pdev);
53
47 ret = pci_enable_device(pdev);54 ret = pci_enable_device(pdev);
48 if (ret)55 if (ret)
49 return ret;56 return ret;
@@ -99,7 +106,8 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) · 49 unmodified lines
99 struct pci_dev *pdev = vdev->pdev;106 struct pci_dev *pdev = vdev->pdev;
100 int bar;107 int bar;
101 108
102 pci_disable_device(pdev);109 /* Stop the device from further DMA */
110 pci_clear_master(pdev);
103 111
104 vfio_pci_set_irqs_ioctl(vdev, VFIO_IRQ_SET_DATA_NONE |112 vfio_pci_set_irqs_ioctl(vdev, VFIO_IRQ_SET_DATA_NONE |
105 VFIO_IRQ_SET_ACTION_TRIGGER,113 VFIO_IRQ_SET_ACTION_TRIGGER,
@@ -117,6 +125,8 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) · 11 unmodified lines
117 vdev->barmap[bar] = NULL;125 vdev->barmap[bar] = NULL;
118 }126 }
119 127
128 vdev->needs_reset = true;
129
120 /*130 /*
121 * 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,
122 * even better. Resetting with current state seems better than132 * even better. Resetting with current state seems better than
@@ -128,7 +138,7 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) · 5 unmodified lines
128 __func__, dev_name(&pdev->dev));138 __func__, dev_name(&pdev->dev));
129 139
130 if (!vdev->reset_works)140 if (!vdev->reset_works)
131 return;141 goto out;
132 142
133 pci_save_state(pdev);143 pci_save_state(pdev);
134 }144 }
@@ -148,46 +158,55 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) · 13 unmodified lines
148 if (ret)158 if (ret)
149 pr_warn("%s: Failed to reset device %s (%d)\n",159 pr_warn("%s: Failed to reset device %s (%d)\n",
150 __func__, dev_name(&pdev->dev), ret);160 __func__, dev_name(&pdev->dev), ret);
161 else
162 vdev->needs_reset = false;
151 }163 }
152 164
153 pci_restore_state(pdev);165 pci_restore_state(pdev);
166out:
167 pci_disable_device(pdev);
168
169 vfio_pci_try_bus_reset(vdev);
154}170}
155 171
156static void vfio_pci_release(void *device_data)172static void vfio_pci_release(void *device_data)
157{173{
158 struct vfio_pci_device *vdev = device_data;174 struct vfio_pci_device *vdev = device_data;
159 175
160 if (atomic_dec_and_test(&vdev->refcnt)) {176 mutex_lock(&driver_lock);
177
178 if (!(--vdev->refcnt)) {
161 vfio_spapr_pci_eeh_release(vdev->pdev);179 vfio_spapr_pci_eeh_release(vdev->pdev);
162 vfio_pci_disable(vdev);180 vfio_pci_disable(vdev);
163 }181 }
164 182
183 mutex_unlock(&driver_lock);
184
165 module_put(THIS_MODULE);185 module_put(THIS_MODULE);
166}186}
167 187
168static int vfio_pci_open(void *device_data)188static int vfio_pci_open(void *device_data)
169{189{
170 struct vfio_pci_device *vdev = device_data;190 struct vfio_pci_device *vdev = device_data;
171 int ret;191 int ret = 0;
172 192
173 if (!try_module_get(THIS_MODULE))193 if (!try_module_get(THIS_MODULE))
174 return -ENODEV;194 return -ENODEV;
175 195
176 if (atomic_inc_return(&vdev->refcnt) == 1) {196 mutex_lock(&driver_lock);
197
198 if (!vdev->refcnt) {
177 ret = vfio_pci_enable(vdev);199 ret = vfio_pci_enable(vdev);
178 if (ret)200 if (ret)
179 goto error;201 goto error;
180 202
181 ret = vfio_spapr_pci_eeh_open(vdev->pdev);203 vfio_spapr_pci_eeh_open(vdev->pdev);
182 if (ret) {
183 vfio_pci_disable(vdev);
184 goto error;
185 }
186 }204 }
187 205 vdev->refcnt++;
188 return 0;
189error:206error:
190 module_put(THIS_MODULE);207 mutex_unlock(&driver_lock);
208 if (ret)
209 module_put(THIS_MODULE);
191 return ret;210 return ret;
192}211}
193 212
@@ -843,7 +862,6 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 649 unmodified lines
843 vdev->irq_type = VFIO_PCI_NUM_IRQS;862 vdev->irq_type = VFIO_PCI_NUM_IRQS;
844 mutex_init(&vdev->igate);863 mutex_init(&vdev->igate);
845 spin_lock_init(&vdev->irqlock);864 spin_lock_init(&vdev->irqlock);
846 atomic_set(&vdev->refcnt, 0);
847 865
848 ret = vfio_add_group_dev(&pdev->dev, &vfio_pci_ops, vdev);866 ret = vfio_add_group_dev(&pdev->dev, &vfio_pci_ops, vdev);
849 if (ret) {867 if (ret) {
@@ -858,12 +876,15 @@ static void vfio_pci_remove(struct pci_dev *pdev) · 8 unmodified lines
858{876{
859 struct vfio_pci_device *vdev;877 struct vfio_pci_device *vdev;
860 878
879 mutex_lock(&driver_lock);
880
861 vdev = vfio_del_group_dev(&pdev->dev);881 vdev = vfio_del_group_dev(&pdev->dev);
862 if (!vdev)882 if (vdev) {
863 return;883 iommu_group_put(pdev->dev.iommu_group);
884 kfree(vdev);
885 }
864 886
865 iommu_group_put(pdev->dev.iommu_group);887 mutex_unlock(&driver_lock);
866 kfree(vdev);
867}888}
868 889
869static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,890static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev,
@@ -906,6 +927,110 @@ static struct pci_driver vfio_pci_driver = { · 36 unmodified lines
906 .err_handler = &vfio_err_handlers,927 .err_handler = &vfio_err_handlers,
907};928};
908 929
930/*
931 * Test whether a reset is necessary and possible. We mark devices as
932 * needs_reset when they are released, but don't have a function-local reset
933 * available. If any of these exist in the affected devices, we want to do
934 * a bus/slot reset. We also need all of the affected devices to be unused,
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 */
938static 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
977/* Clear needs_reset on all affected devices after successful bus/slot reset */
978static int vfio_pci_clear_needs_reset(struct pci_dev *pdev, void *data)
979{
980 struct pci_driver *pci_drv = ACCESS_ONCE(pdev->driver);
981
982 if (pci_drv == &vfio_pci_driver) {
983 struct vfio_device *device;
984 struct vfio_pci_device *vdev;
985
986 device = vfio_device_get_from_dev(&pdev->dev);
987 if (!device)
988 return 0;
989
990 vdev = vfio_device_data(device);
991 if (vdev)
992 vdev->needs_reset = false;
993
994 vfio_device_put(device);
995 }
996
997 return 0;
998}
999
1000/*
1001 * 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
1003 * (!refcnt). Callers of this function are required to hold driver_lock such
1004 * that devices can not be unbound from vfio-pci or opened by a user while we
1005 * test for and perform a bus/slot reset.
1006 */
1007static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev)
1008{
1009 bool needs_reset = false, slot = false;
1010 int ret;
1011
1012 if (!pci_probe_reset_slot(vdev->pdev->slot))
1013 slot = true;
1014 else if (pci_probe_reset_bus(vdev->pdev->bus))
1015 return;
1016
1017 if (vfio_pci_for_each_slot_or_bus(vdev->pdev,
1018 vfio_pci_test_bus_reset,
1019 &needs_reset, slot) || !needs_reset)
1020 return;
1021
1022 if (slot)
1023 ret = pci_try_reset_slot(vdev->pdev->slot);
1024 else
1025 ret = pci_try_reset_bus(vdev->pdev->bus);
1026
1027 if (ret)
1028 return;
1029
1030 vfio_pci_for_each_slot_or_bus(vdev->pdev,
1031 vfio_pci_clear_needs_reset, NULL, slot);
1032}
1033
909static void __exit vfio_pci_cleanup(void)1034static void __exit vfio_pci_cleanup(void)
910{1035{
911 pci_unregister_driver(&vfio_pci_driver);1036 pci_unregister_driver(&vfio_pci_driver);
drivers/vfio/pci/vfio_pci_private.h+2−1
@@ -54,8 +54,9 @@ struct vfio_pci_device { · 53 unmodified lines
54 bool extended_caps;54 bool extended_caps;
55 bool bardirty;55 bool bardirty;
56 bool has_vga;56 bool has_vga;
57 bool needs_reset;
57 struct pci_saved_state *pci_saved_state;58 struct pci_saved_state *pci_saved_state;
58 atomic_t refcnt;59 int refcnt;
59 struct eventfd_ctx *err_trigger;60 struct eventfd_ctx *err_trigger;
60};61};
61 62
drivers/vfio/vfio_spapr_eeh.c+15−2
@@ -9,20 +9,27 @@ · 8 unmodified lines
9 * published by the Free Software Foundation.9 * published by the Free Software Foundation.
10 */10 */
11 11
12#include <linux/module.h>
12#include <linux/uaccess.h>13#include <linux/uaccess.h>
13#include <linux/vfio.h>14#include <linux/vfio.h>
14#include <asm/eeh.h>15#include <asm/eeh.h>
15 16
17#define DRIVER_VERSION "0.1"
18#define DRIVER_AUTHOR "Gavin Shan, IBM Corporation"
19#define DRIVER_DESC "VFIO IOMMU SPAPR EEH"
20
16/* We might build address mapping here for "fast" path later */21/* We might build address mapping here for "fast" path later */
17int vfio_spapr_pci_eeh_open(struct pci_dev *pdev)22void vfio_spapr_pci_eeh_open(struct pci_dev *pdev)
18{23{
19 return eeh_dev_open(pdev);24 eeh_dev_open(pdev);
20}25}
26EXPORT_SYMBOL_GPL(vfio_spapr_pci_eeh_open);
21 27
22void vfio_spapr_pci_eeh_release(struct pci_dev *pdev)28void vfio_spapr_pci_eeh_release(struct pci_dev *pdev)
23{29{
24 eeh_dev_release(pdev);30 eeh_dev_release(pdev);
25}31}
32EXPORT_SYMBOL_GPL(vfio_spapr_pci_eeh_release);
26 33
27long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,34long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
28 unsigned int cmd, unsigned long arg)35 unsigned int cmd, unsigned long arg)
@@ -85,3 +92,9 @@ long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, · 56 unmodified lines
85 92
86 return ret;93 return ret;
87}94}
95EXPORT_SYMBOL(vfio_spapr_iommu_eeh_ioctl);
96
97MODULE_VERSION(DRIVER_VERSION);
98MODULE_LICENSE("GPL v2");
99MODULE_AUTHOR(DRIVER_AUTHOR);
100MODULE_DESCRIPTION(DRIVER_DESC);
include/linux/vfio.h+3−3
@@ -98,16 +98,16 @@ extern int vfio_external_user_iommu_id(struct vfio_group *group); · 97 unmodified lines
98extern long vfio_external_check_extension(struct vfio_group *group,98extern long vfio_external_check_extension(struct vfio_group *group,
99 unsigned long arg);99 unsigned long arg);
100 100
101struct pci_dev;
101#ifdef CONFIG_EEH102#ifdef CONFIG_EEH
102extern int vfio_spapr_pci_eeh_open(struct pci_dev *pdev);103extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev);
103extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev);104extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev);
104extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,105extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
105 unsigned int cmd,106 unsigned int cmd,
106 unsigned long arg);107 unsigned long arg);
107#else108#else
108static inline int vfio_spapr_pci_eeh_open(struct pci_dev *pdev)109static inline void vfio_spapr_pci_eeh_open(struct pci_dev *pdev)
109{110{
110 return 0;
111}111}
112 112
113static inline void vfio_spapr_pci_eeh_release(struct pci_dev *pdev)113static inline void vfio_spapr_pci_eeh_release(struct pci_dev *pdev)