Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+171 -26
+6
drivers/vfio/Kconfig
··· 8 8 depends on VFIO && SPAPR_TCE_IOMMU 9 9 default n 10 10 11 + config VFIO_SPAPR_EEH 12 + tristate 13 + depends on EEH && VFIO_IOMMU_SPAPR_TCE 14 + default n 15 + 11 16 menuconfig VFIO 12 17 tristate "VFIO Non-Privileged userspace driver framework" 13 18 depends on IOMMU_API 14 19 select VFIO_IOMMU_TYPE1 if X86 15 20 select VFIO_IOMMU_SPAPR_TCE if (PPC_POWERNV || PPC_PSERIES) 21 + select VFIO_SPAPR_EEH if (PPC_POWERNV || PPC_PSERIES) 16 22 select ANON_INODES 17 23 help 18 24 VFIO provides a framework for secure userspace device drivers.
+1 -1
drivers/vfio/Makefile
··· 1 1 obj-$(CONFIG_VFIO) += vfio.o 2 2 obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o 3 3 obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o 4 - obj-$(CONFIG_EEH) += vfio_spapr_eeh.o 4 + obj-$(CONFIG_VFIO_SPAPR_EEH) += vfio_spapr_eeh.o 5 5 obj-$(CONFIG_VFIO_PCI) += pci/
+144 -19
drivers/vfio/pci/vfio_pci.c
··· 37 37 MODULE_PARM_DESC(nointxmask, 38 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 40 + static DEFINE_MUTEX(driver_lock); 41 + 42 + static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev); 43 + 40 44 static int vfio_pci_enable(struct vfio_pci_device *vdev) 41 45 { 42 46 struct pci_dev *pdev = vdev->pdev; 43 47 int ret; 44 48 u16 cmd; 45 49 u8 msix_pos; 50 + 51 + /* Don't allow our initial saved state to include busmaster */ 52 + pci_clear_master(pdev); 46 53 47 54 ret = pci_enable_device(pdev); 48 55 if (ret) ··· 106 99 struct pci_dev *pdev = vdev->pdev; 107 100 int bar; 108 101 109 - pci_disable_device(pdev); 102 + /* Stop the device from further DMA */ 103 + pci_clear_master(pdev); 110 104 111 105 vfio_pci_set_irqs_ioctl(vdev, VFIO_IRQ_SET_DATA_NONE | 112 106 VFIO_IRQ_SET_ACTION_TRIGGER, ··· 125 117 vdev->barmap[bar] = NULL; 126 118 } 127 119 120 + vdev->needs_reset = true; 121 + 128 122 /* 129 123 * If we have saved state, restore it. If we can reset the device, 130 124 * even better. Resetting with current state seems better than ··· 138 128 __func__, dev_name(&pdev->dev)); 139 129 140 130 if (!vdev->reset_works) 141 - return; 131 + goto out; 142 132 143 133 pci_save_state(pdev); 144 134 } ··· 158 148 if (ret) 159 149 pr_warn("%s: Failed to reset device %s (%d)\n", 160 150 __func__, dev_name(&pdev->dev), ret); 151 + else 152 + vdev->needs_reset = false; 161 153 } 162 154 163 155 pci_restore_state(pdev); 156 + out: 157 + pci_disable_device(pdev); 158 + 159 + vfio_pci_try_bus_reset(vdev); 164 160 } 165 161 166 162 static void vfio_pci_release(void *device_data) 167 163 { 168 164 struct vfio_pci_device *vdev = device_data; 169 165 170 - if (atomic_dec_and_test(&vdev->refcnt)) { 166 + mutex_lock(&driver_lock); 167 + 168 + if (!(--vdev->refcnt)) { 171 169 vfio_spapr_pci_eeh_release(vdev->pdev); 172 170 vfio_pci_disable(vdev); 173 171 } 172 + 173 + mutex_unlock(&driver_lock); 174 174 175 175 module_put(THIS_MODULE); 176 176 } ··· 188 168 static int vfio_pci_open(void *device_data) 189 169 { 190 170 struct vfio_pci_device *vdev = device_data; 191 - int ret; 171 + int ret = 0; 192 172 193 173 if (!try_module_get(THIS_MODULE)) 194 174 return -ENODEV; 195 175 196 - if (atomic_inc_return(&vdev->refcnt) == 1) { 176 + mutex_lock(&driver_lock); 177 + 178 + if (!vdev->refcnt) { 197 179 ret = vfio_pci_enable(vdev); 198 180 if (ret) 199 181 goto error; 200 182 201 - ret = vfio_spapr_pci_eeh_open(vdev->pdev); 202 - if (ret) { 203 - vfio_pci_disable(vdev); 204 - goto error; 205 - } 183 + vfio_spapr_pci_eeh_open(vdev->pdev); 206 184 } 207 - 208 - return 0; 185 + vdev->refcnt++; 209 186 error: 210 - module_put(THIS_MODULE); 187 + mutex_unlock(&driver_lock); 188 + if (ret) 189 + module_put(THIS_MODULE); 211 190 return ret; 212 191 } 213 192 ··· 862 843 vdev->irq_type = VFIO_PCI_NUM_IRQS; 863 844 mutex_init(&vdev->igate); 864 845 spin_lock_init(&vdev->irqlock); 865 - atomic_set(&vdev->refcnt, 0); 866 846 867 847 ret = vfio_add_group_dev(&pdev->dev, &vfio_pci_ops, vdev); 868 848 if (ret) { ··· 876 858 { 877 859 struct vfio_pci_device *vdev; 878 860 879 - vdev = vfio_del_group_dev(&pdev->dev); 880 - if (!vdev) 881 - return; 861 + mutex_lock(&driver_lock); 882 862 883 - iommu_group_put(pdev->dev.iommu_group); 884 - kfree(vdev); 863 + vdev = vfio_del_group_dev(&pdev->dev); 864 + if (vdev) { 865 + iommu_group_put(pdev->dev.iommu_group); 866 + kfree(vdev); 867 + } 868 + 869 + mutex_unlock(&driver_lock); 885 870 } 886 871 887 872 static pci_ers_result_t vfio_pci_aer_err_detected(struct pci_dev *pdev, ··· 926 905 .remove = vfio_pci_remove, 927 906 .err_handler = &vfio_err_handlers, 928 907 }; 908 + 909 + /* 910 + * Test whether a reset is necessary and possible. We mark devices as 911 + * needs_reset when they are released, but don't have a function-local reset 912 + * available. If any of these exist in the affected devices, we want to do 913 + * a bus/slot reset. We also need all of the affected devices to be unused, 914 + * so we abort if any device has a non-zero refcnt. driver_lock prevents a 915 + * device from being opened during the scan or unbound from vfio-pci. 916 + */ 917 + static int vfio_pci_test_bus_reset(struct pci_dev *pdev, void *data) 918 + { 919 + bool *needs_reset = data; 920 + struct pci_driver *pci_drv = ACCESS_ONCE(pdev->driver); 921 + int ret = -EBUSY; 922 + 923 + if (pci_drv == &vfio_pci_driver) { 924 + struct vfio_device *device; 925 + struct vfio_pci_device *vdev; 926 + 927 + device = vfio_device_get_from_dev(&pdev->dev); 928 + if (!device) 929 + return ret; 930 + 931 + vdev = vfio_device_data(device); 932 + if (vdev) { 933 + if (vdev->needs_reset) 934 + *needs_reset = true; 935 + 936 + if (!vdev->refcnt) 937 + ret = 0; 938 + } 939 + 940 + vfio_device_put(device); 941 + } 942 + 943 + /* 944 + * TODO: vfio-core considers groups to be viable even if some devices 945 + * are attached to known drivers, like pci-stub or pcieport. We can't 946 + * freeze devices from being unbound to those drivers like we can 947 + * here though, so it would be racy to test for them. We also can't 948 + * use device_lock() to prevent changes as that would interfere with 949 + * PCI-core taking device_lock during bus reset. For now, we require 950 + * devices to be bound to vfio-pci to get a bus/slot reset on release. 951 + */ 952 + 953 + return ret; 954 + } 955 + 956 + /* Clear needs_reset on all affected devices after successful bus/slot reset */ 957 + static int vfio_pci_clear_needs_reset(struct pci_dev *pdev, void *data) 958 + { 959 + struct pci_driver *pci_drv = ACCESS_ONCE(pdev->driver); 960 + 961 + if (pci_drv == &vfio_pci_driver) { 962 + struct vfio_device *device; 963 + struct vfio_pci_device *vdev; 964 + 965 + device = vfio_device_get_from_dev(&pdev->dev); 966 + if (!device) 967 + return 0; 968 + 969 + vdev = vfio_device_data(device); 970 + if (vdev) 971 + vdev->needs_reset = false; 972 + 973 + vfio_device_put(device); 974 + } 975 + 976 + return 0; 977 + } 978 + 979 + /* 980 + * Attempt to do a bus/slot reset if there are devices affected by a reset for 981 + * this device that are needs_reset and all of the affected devices are unused 982 + * (!refcnt). Callers of this function are required to hold driver_lock such 983 + * that devices can not be unbound from vfio-pci or opened by a user while we 984 + * test for and perform a bus/slot reset. 985 + */ 986 + static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev) 987 + { 988 + bool needs_reset = false, slot = false; 989 + int ret; 990 + 991 + if (!pci_probe_reset_slot(vdev->pdev->slot)) 992 + slot = true; 993 + else if (pci_probe_reset_bus(vdev->pdev->bus)) 994 + return; 995 + 996 + if (vfio_pci_for_each_slot_or_bus(vdev->pdev, 997 + vfio_pci_test_bus_reset, 998 + &needs_reset, slot) || !needs_reset) 999 + return; 1000 + 1001 + if (slot) 1002 + ret = pci_try_reset_slot(vdev->pdev->slot); 1003 + else 1004 + ret = pci_try_reset_bus(vdev->pdev->bus); 1005 + 1006 + if (ret) 1007 + return; 1008 + 1009 + vfio_pci_for_each_slot_or_bus(vdev->pdev, 1010 + vfio_pci_clear_needs_reset, NULL, slot); 1011 + } 929 1012 930 1013 static void __exit vfio_pci_cleanup(void) 931 1014 {
+2 -1
drivers/vfio/pci/vfio_pci_private.h
··· 54 54 bool extended_caps; 55 55 bool bardirty; 56 56 bool has_vga; 57 + bool needs_reset; 57 58 struct pci_saved_state *pci_saved_state; 58 - atomic_t refcnt; 59 + int refcnt; 59 60 struct eventfd_ctx *err_trigger; 60 61 }; 61 62
+15 -2
drivers/vfio/vfio_spapr_eeh.c
··· 9 9 * published by the Free Software Foundation. 10 10 */ 11 11 12 + #include <linux/module.h> 12 13 #include <linux/uaccess.h> 13 14 #include <linux/vfio.h> 14 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 21 /* We might build address mapping here for "fast" path later */ 17 - int vfio_spapr_pci_eeh_open(struct pci_dev *pdev) 22 + void vfio_spapr_pci_eeh_open(struct pci_dev *pdev) 18 23 { 19 - return eeh_dev_open(pdev); 24 + eeh_dev_open(pdev); 20 25 } 26 + EXPORT_SYMBOL_GPL(vfio_spapr_pci_eeh_open); 21 27 22 28 void vfio_spapr_pci_eeh_release(struct pci_dev *pdev) 23 29 { 24 30 eeh_dev_release(pdev); 25 31 } 32 + EXPORT_SYMBOL_GPL(vfio_spapr_pci_eeh_release); 26 33 27 34 long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, 28 35 unsigned int cmd, unsigned long arg) ··· 92 85 93 86 return ret; 94 87 } 88 + EXPORT_SYMBOL(vfio_spapr_iommu_eeh_ioctl); 89 + 90 + MODULE_VERSION(DRIVER_VERSION); 91 + MODULE_LICENSE("GPL v2"); 92 + MODULE_AUTHOR(DRIVER_AUTHOR); 93 + MODULE_DESCRIPTION(DRIVER_DESC);
+3 -3
include/linux/vfio.h
··· 98 98 extern long vfio_external_check_extension(struct vfio_group *group, 99 99 unsigned long arg); 100 100 101 + struct pci_dev; 101 102 #ifdef CONFIG_EEH 102 - extern int vfio_spapr_pci_eeh_open(struct pci_dev *pdev); 103 + extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev); 103 104 extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev); 104 105 extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, 105 106 unsigned int cmd, 106 107 unsigned long arg); 107 108 #else 108 - static inline int vfio_spapr_pci_eeh_open(struct pci_dev *pdev) 109 + static inline void vfio_spapr_pci_eeh_open(struct pci_dev *pdev) 109 110 { 110 - return 0; 111 111 } 112 112 113 113 static inline void vfio_spapr_pci_eeh_release(struct pci_dev *pdev)