summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-08-04 01:25:14 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2017-08-04 01:25:14 +0300
commit869c058fbe741cadff09647c68dbeae7d012f52d (patch)
treeb54246c6abcca7ed0f8de92d92ff3bafaeb539ac
parent995d03ae266d3f3bec8844d01b6c3ded19b9cc1c (diff)
parent796b755066dd6254bfb6388fec901631e868d1c7 (diff)
downloadlinux-869c058fbe741cadff09647c68dbeae7d012f52d.tar.xz
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
-rw-r--r--drivers/vfio/pci/vfio_pci.c9
-rw-r--r--drivers/vfio/pci/vfio_pci_config.c13
-rw-r--r--include/linux/vfio.h4
3 files changed, 19 insertions, 7 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 063c1ce6fa42..f041b1a6cf66 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -226,7 +226,14 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
if (ret)
return ret;
- vdev->reset_works = (pci_reset_function(pdev) == 0);
+ /* If reset fails because of the device lock, fail this path entirely */
+ ret = pci_try_reset_function(pdev);
+ if (ret == -EAGAIN) {
+ pci_disable_device(pdev);
+ return ret;
+ }
+
+ vdev->reset_works = !ret;
pci_save_state(pdev);
vdev->pci_saved_state = pci_store_saved_state(pdev);
if (!vdev->pci_saved_state)
diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
index 330a57024cbc..5628fe114347 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -839,7 +839,7 @@ static int vfio_exp_config_write(struct vfio_pci_device *vdev, int pos,
/* Permissions for PCI Express capability */
static int __init init_pci_cap_exp_perm(struct perm_bits *perm)
{
- /* Alloc larger of two possible sizes */
+ /* Alloc largest of possible sizes */
if (alloc_perm_bits(perm, PCI_CAP_EXP_ENDPOINT_SIZEOF_V2))
return -ENOMEM;
@@ -1243,11 +1243,16 @@ static int vfio_cap_len(struct vfio_pci_device *vdev, u8 cap, u8 pos)
vdev->extended_caps = (dword != 0);
}
- /* length based on version */
- if ((pcie_caps_reg(pdev) & PCI_EXP_FLAGS_VERS) == 1)
+ /* length based on version and type */
+ if ((pcie_caps_reg(pdev) & PCI_EXP_FLAGS_VERS) == 1) {
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END)
+ return 0xc; /* "All Devices" only, no link */
return PCI_CAP_EXP_ENDPOINT_SIZEOF_V1;
- else
+ } else {
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END)
+ return 0x2c; /* No link */
return PCI_CAP_EXP_ENDPOINT_SIZEOF_V2;
+ }
case PCI_CAP_ID_HT:
ret = pci_read_config_byte(pdev, pos + 3, &byte);
if (ret)
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 586809abb273..a47b985341d1 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -152,7 +152,7 @@ extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr,
size_t *data_size);
struct pci_dev;
-#ifdef CONFIG_EEH
+#if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH)
extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev);
extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev);
extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
@@ -173,7 +173,7 @@ static inline long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
{
return -ENOTTY;
}
-#endif /* CONFIG_EEH */
+#endif /* CONFIG_VFIO_SPAPR_EEH */
/*
* IRQfd - generic