aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/vfio/Kconfig6
-rw-r--r--drivers/vfio/Makefile2
-rw-r--r--drivers/vfio/pci/vfio_pci.c161
-rw-r--r--drivers/vfio/pci/vfio_pci_private.h3
-rw-r--r--drivers/vfio/vfio_spapr_eeh.c17
-rw-r--r--include/linux/vfio.h6
6 files changed, 170 insertions, 25 deletions
diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
index af7b204b9215..d8c57636b9ce 100644
--- a/drivers/vfio/Kconfig
+++ b/drivers/vfio/Kconfig
@@ -8,11 +8,17 @@ config VFIO_IOMMU_SPAPR_TCE
8 depends on VFIO && SPAPR_TCE_IOMMU 8 depends on VFIO && SPAPR_TCE_IOMMU
9 default n 9 default n
10 10
11config VFIO_SPAPR_EEH
12 tristate
13 depends on EEH && VFIO_IOMMU_SPAPR_TCE
14 default n
15
11menuconfig VFIO 16menuconfig VFIO
12 tristate "VFIO Non-Privileged userspace driver framework" 17 tristate "VFIO Non-Privileged userspace driver framework"
13 depends on IOMMU_API 18 depends on IOMMU_API
14 select VFIO_IOMMU_TYPE1 if X86 19 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_INODES 22 select ANON_INODES
17 help 23 help
18 VFIO provides a framework for secure userspace device drivers. 24 VFIO provides a framework for secure userspace device drivers.
diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile
index 50e30bc75e85..0b035b12600a 100644
--- a/drivers/vfio/Makefile
+++ b/drivers/vfio/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_VFIO) += vfio.o 1obj-$(CONFIG_VFIO) += vfio.o
2obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o 2obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o
3obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o 3obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o
4obj-$(CONFIG_EEH) += vfio_spapr_eeh.o 4obj-$(CONFIG_VFIO_SPAPR_EEH) += vfio_spapr_eeh.o
5obj-$(CONFIG_VFIO_PCI) += pci/ 5obj-$(CONFIG_VFIO_PCI) += pci/
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index e2ee80f36e3e..f7825332a325 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -37,6 +37,10 @@ module_param_named(nointxmask, nointxmask, bool, S_IRUGO | S_IWUSR);
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)
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)
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)
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 than 132 * even better. Resetting with current state seems better than
@@ -128,7 +138,7 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)
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)
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)
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)
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 = {
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);
diff --git a/drivers/vfio/pci/vfio_pci_private.h b/drivers/vfio/pci/vfio_pci_private.h
index 9c6d5d0f3b02..671c17a6e6d0 100644
--- a/drivers/vfio/pci/vfio_pci_private.h
+++ b/drivers/vfio/pci/vfio_pci_private.h
@@ -54,8 +54,9 @@ struct vfio_pci_device {
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
diff --git a/drivers/vfio/vfio_spapr_eeh.c b/drivers/vfio/vfio_spapr_eeh.c
index f834b4ce1431..86dfceb9201f 100644
--- a/drivers/vfio/vfio_spapr_eeh.c
+++ b/drivers/vfio/vfio_spapr_eeh.c
@@ -9,20 +9,27 @@
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,
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);
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 25a0fbd4b998..d3204115f15d 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -98,16 +98,16 @@ extern int vfio_external_user_iommu_id(struct vfio_group *group);
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_EEH 102#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#else 108#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)