Commit 9bf49e36 authored by Kuppuswamy Sathyanarayanan's avatar Kuppuswamy Sathyanarayanan Committed by Bjorn Helgaas

PCI/ATS: Handle sharing of PF PRI Capability with all VFs

Per PCIe r5.0, sec 9.3.7.11, VFs must not implement the PRI Capability.  If
the PF implements PRI, it is shared by the VFs.  Since VFs don't have a PRI
Capability, pci_enable_pri() always failed, which caused IOMMU setup to
fail.

Update the PRI interfaces so for VFs they reflect the state of the PF PRI.

[bhelgaas: rebase without pri_cap caching, commit log]
Suggested-by: default avatarAshok Raj <ashok.raj@intel.com>
Link: https://lore.kernel.org/r/b971e31f8695980da8e4a7f93e3b6a3edba3edaa.1567029860.git.sathyanarayanan.kuppuswamy@linux.intel.com
Link: https://lore.kernel.org/r/20190905193146.90250-2-helgaas@kernel.orgSigned-off-by: default avatarKuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Keith Busch <keith.busch@intel.com>
parent 8cbb8a93
......@@ -182,6 +182,17 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
u32 max_requests;
int pos;
/*
* VFs must not implement the PRI Capability. If their PF
* implements PRI, it is shared by the VFs, so if the PF PRI is
* enabled, it is also enabled for the VF.
*/
if (pdev->is_virtfn) {
if (pci_physfn(pdev)->pri_enabled)
return 0;
return -EINVAL;
}
if (WARN_ON(pdev->pri_enabled))
return -EBUSY;
......@@ -218,6 +229,10 @@ void pci_disable_pri(struct pci_dev *pdev)
u16 control;
int pos;
/* VFs share the PF PRI */
if (pdev->is_virtfn)
return;
if (WARN_ON(!pdev->pri_enabled))
return;
......@@ -243,6 +258,9 @@ void pci_restore_pri_state(struct pci_dev *pdev)
u32 reqs = pdev->pri_reqs_alloc;
int pos;
if (pdev->is_virtfn)
return;
if (!pdev->pri_enabled)
return;
......@@ -267,6 +285,9 @@ int pci_reset_pri(struct pci_dev *pdev)
u16 control;
int pos;
if (pdev->is_virtfn)
return 0;
if (WARN_ON(pdev->pri_enabled))
return -EBUSY;
......@@ -293,6 +314,9 @@ int pci_prg_resp_pasid_required(struct pci_dev *pdev)
u16 status;
int pos;
if (pdev->is_virtfn)
pdev = pci_physfn(pdev);
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
if (!pos)
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment