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

Merge tag 'vfio-v4.13-rc4' of git://github.com/awilliam/linux-vfio

Pull VFIO fixes from Alex Williamson:

- SPAPR/EEH config build fix (Murilo Opsfelder Araujo)

- Fix possible device lock deadlock (Alex Williamson)

- Correctly size integrated endpoint PCIe capabilities (Alex
Williamson)

* tag 'vfio-v4.13-rc4' of git://github.com/awilliam/linux-vfio:
vfio/pci: Fix handling of RC integrated endpoint PCIe capability size
vfio/pci: Use pci_try_reset_function() on initial open
include/linux/vfio.h: Guard powerpc-specific functions with CONFIG_VFIO_SPAPR_EEH

+19 -7
+8 -1
drivers/vfio/pci/vfio_pci.c
··· 226 226 if (ret) 227 227 return ret; 228 228 229 - vdev->reset_works = (pci_reset_function(pdev) == 0); 229 + /* If reset fails because of the device lock, fail this path entirely */ 230 + ret = pci_try_reset_function(pdev); 231 + if (ret == -EAGAIN) { 232 + pci_disable_device(pdev); 233 + return ret; 234 + } 235 + 236 + vdev->reset_works = !ret; 230 237 pci_save_state(pdev); 231 238 vdev->pci_saved_state = pci_store_saved_state(pdev); 232 239 if (!vdev->pci_saved_state)
+9 -4
drivers/vfio/pci/vfio_pci_config.c
··· 839 839 /* Permissions for PCI Express capability */ 840 840 static int __init init_pci_cap_exp_perm(struct perm_bits *perm) 841 841 { 842 - /* Alloc larger of two possible sizes */ 842 + /* Alloc largest of possible sizes */ 843 843 if (alloc_perm_bits(perm, PCI_CAP_EXP_ENDPOINT_SIZEOF_V2)) 844 844 return -ENOMEM; 845 845 ··· 1243 1243 vdev->extended_caps = (dword != 0); 1244 1244 } 1245 1245 1246 - /* length based on version */ 1247 - if ((pcie_caps_reg(pdev) & PCI_EXP_FLAGS_VERS) == 1) 1246 + /* length based on version and type */ 1247 + if ((pcie_caps_reg(pdev) & PCI_EXP_FLAGS_VERS) == 1) { 1248 + if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END) 1249 + return 0xc; /* "All Devices" only, no link */ 1248 1250 return PCI_CAP_EXP_ENDPOINT_SIZEOF_V1; 1249 - else 1251 + } else { 1252 + if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END) 1253 + return 0x2c; /* No link */ 1250 1254 return PCI_CAP_EXP_ENDPOINT_SIZEOF_V2; 1255 + } 1251 1256 case PCI_CAP_ID_HT: 1252 1257 ret = pci_read_config_byte(pdev, pos + 3, &byte); 1253 1258 if (ret)
+2 -2
include/linux/vfio.h
··· 152 152 size_t *data_size); 153 153 154 154 struct pci_dev; 155 - #ifdef CONFIG_EEH 155 + #if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) 156 156 extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev); 157 157 extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev); 158 158 extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, ··· 173 173 { 174 174 return -ENOTTY; 175 175 } 176 - #endif /* CONFIG_EEH */ 176 + #endif /* CONFIG_VFIO_SPAPR_EEH */ 177 177 178 178 /* 179 179 * IRQfd - generic