Skip to content

Commit

Permalink
PCI/ATS: Cache PASID Capability offset
Browse files Browse the repository at this point in the history
Previously each PASID interface searched for the PASID Capability.  Cache
the capability offset the first time we use it instead of searching each
time.

[bhelgaas: commit log, reorder patch to later, call pci_pasid_init() from
pci_init_capabilities()]
Link: https://lore.kernel.org/r/4957778959fa34eab3e8b3065d1951989c61cb0f.1567029860.git.sathyanarayanan.kuppuswamy@linux.intel.com
Link: https://lore.kernel.org/r/20190905193146.90250-6-helgaas@kernel.org
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
  • Loading branch information
Kuppuswamy Sathyanarayanan authored and Bjorn Helgaas committed Oct 15, 2019
1 parent c065190 commit 751035b
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 21 deletions.
42 changes: 21 additions & 21 deletions drivers/pci/ats.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,11 @@ EXPORT_SYMBOL_GPL(pci_prg_resp_pasid_required);
#endif /* CONFIG_PCI_PRI */

#ifdef CONFIG_PCI_PASID
void pci_pasid_init(struct pci_dev *pdev)
{
pdev->pasid_cap = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
}

/**
* pci_enable_pasid - Enable the PASID capability
* @pdev: PCI device structure
Expand All @@ -334,7 +339,7 @@ EXPORT_SYMBOL_GPL(pci_prg_resp_pasid_required);
int pci_enable_pasid(struct pci_dev *pdev, int features)
{
u16 control, supported;
int pos;
int pasid = pdev->pasid_cap;

/*
* VFs must not implement the PASID Capability, but if a PF
Expand All @@ -352,11 +357,10 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
if (!pdev->eetlp_prefix_path)
return -EINVAL;

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
if (!pos)
if (!pasid)
return -EINVAL;

pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported);
pci_read_config_word(pdev, pasid + PCI_PASID_CAP, &supported);
supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV;

/* User wants to enable anything unsupported? */
Expand All @@ -366,7 +370,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
control = PCI_PASID_CTRL_ENABLE | features;
pdev->pasid_features = features;

pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
pci_write_config_word(pdev, pasid + PCI_PASID_CTRL, control);

pdev->pasid_enabled = 1;

Expand All @@ -381,7 +385,7 @@ EXPORT_SYMBOL_GPL(pci_enable_pasid);
void pci_disable_pasid(struct pci_dev *pdev)
{
u16 control = 0;
int pos;
int pasid = pdev->pasid_cap;

/* VFs share the PF PASID configuration */
if (pdev->is_virtfn)
Expand All @@ -390,11 +394,10 @@ void pci_disable_pasid(struct pci_dev *pdev)
if (WARN_ON(!pdev->pasid_enabled))
return;

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
if (!pos)
if (!pasid)
return;

pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
pci_write_config_word(pdev, pasid + PCI_PASID_CTRL, control);

pdev->pasid_enabled = 0;
}
Expand All @@ -407,20 +410,19 @@ EXPORT_SYMBOL_GPL(pci_disable_pasid);
void pci_restore_pasid_state(struct pci_dev *pdev)
{
u16 control;
int pos;
int pasid = pdev->pasid_cap;

if (pdev->is_virtfn)
return;

if (!pdev->pasid_enabled)
return;

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
if (!pos)
if (!pasid)
return;

control = PCI_PASID_CTRL_ENABLE | pdev->pasid_features;
pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
pci_write_config_word(pdev, pasid + PCI_PASID_CTRL, control);
}
EXPORT_SYMBOL_GPL(pci_restore_pasid_state);

Expand All @@ -437,16 +439,15 @@ EXPORT_SYMBOL_GPL(pci_restore_pasid_state);
int pci_pasid_features(struct pci_dev *pdev)
{
u16 supported;
int pos;
int pasid = pdev->pasid_cap;

if (pdev->is_virtfn)
pdev = pci_physfn(pdev);

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
if (!pos)
if (!pasid)
return -EINVAL;

pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported);
pci_read_config_word(pdev, pasid + PCI_PASID_CAP, &supported);

supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV;

Expand All @@ -466,16 +467,15 @@ EXPORT_SYMBOL_GPL(pci_pasid_features);
int pci_max_pasids(struct pci_dev *pdev)
{
u16 supported;
int pos;
int pasid = pdev->pasid_cap;

if (pdev->is_virtfn)
pdev = pci_physfn(pdev);

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
if (!pos)
if (!pasid)
return -EINVAL;

pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported);
pci_read_config_word(pdev, pasid + PCI_PASID_CAP, &supported);

supported = (supported & PASID_NUMBER_MASK) >> PASID_NUMBER_SHIFT;

Expand Down
6 changes: 6 additions & 0 deletions drivers/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,12 @@ void pci_pri_init(struct pci_dev *dev);
static inline void pci_pri_init(struct pci_dev *dev) { }
#endif

#ifdef CONFIG_PCI_PASID
void pci_pasid_init(struct pci_dev *dev);
#else
static inline void pci_pasid_init(struct pci_dev *dev) { }
#endif

#ifdef CONFIG_PCI_IOV
int pci_iov_init(struct pci_dev *dev);
void pci_iov_release(struct pci_dev *dev);
Expand Down
3 changes: 3 additions & 0 deletions drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -2327,6 +2327,9 @@ static void pci_init_capabilities(struct pci_dev *dev)
/* Page Request Interface */
pci_pri_init(dev);

/* Process Address Space ID */
pci_pasid_init(dev);

/* Enable ACS P2P upstream forwarding */
pci_enable_acs(dev);

Expand Down
1 change: 1 addition & 0 deletions include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ struct pci_dev {
u32 pri_reqs_alloc; /* Number of PRI requests allocated */
#endif
#ifdef CONFIG_PCI_PASID
u16 pasid_cap; /* PASID Capability offset */
u16 pasid_features;
#endif
#ifdef CONFIG_PCI_P2PDMA
Expand Down

0 comments on commit 751035b

Please sign in to comment.