PCI/ATS: Cache PASID Capability offset
authorKuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Thu, 5 Sep 2019 19:31:46 +0000 (14:31 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 15 Oct 2019 21:39:10 +0000 (16:39 -0500)
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>
drivers/pci/ats.c
drivers/pci/pci.h
drivers/pci/probe.c
include/linux/pci.h

index c97e862..d5ac808 100644 (file)
@@ -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
@@ -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
@@ -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? */
@@ -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;
 
@@ -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)
@@ -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;
 }
@@ -407,7 +410,7 @@ 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;
@@ -415,12 +418,11 @@ void pci_restore_pasid_state(struct pci_dev *pdev)
        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);
 
@@ -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;
 
@@ -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;
 
index aa08cd3..ae84d28 100644 (file)
@@ -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);
index d145165..df2b778 100644 (file)
@@ -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);
 
index e7770d9..6542100 100644 (file)
@@ -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