Skip to content

Commit

Permalink
PCI/ATS: Handle sharing of PF PRI Capability with all VFs
Browse files Browse the repository at this point in the history
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: Ashok 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.org
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Keith Busch <keith.busch@intel.com>
  • Loading branch information
Kuppuswamy Sathyanarayanan authored and Bjorn Helgaas committed Oct 15, 2019
1 parent 8cbb8a9 commit 9bf49e3
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions drivers/pci/ats.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -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;
Expand Down

0 comments on commit 9bf49e3

Please sign in to comment.