All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-10 18:39 Ashok Raj
  2017-05-10 18:39 ` [PATCH 2/2] iommu/vt-d: Helper function to query if a pasid has any active users Ashok Raj
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Ashok Raj @ 2017-05-10 18:39 UTC (permalink / raw)
  To: Bjorn Helgaas, Joerg Roedel, linux-pci
  Cc: CQ Tang, Jean-Phillipe Brucker, David Woodhouse, iommu, Ashok Raj

From: CQ Tang <cq.tang@intel.com>

Requires: https://patchwork.kernel.org/patch/9593891

After a FLR, pci-states need to be restored. This patch saves PASID features
and PRI reqs cached.

Cc: Jean-Phillipe Brucker <jean-philippe.brucker@arm.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: iommu@lists.linux-foundation.org

Signed-off-by: CQ Tang <cq.tang@intel.com>
Signed-off-by: Ashok Raj <ashok.raj@intel.com>
---
 drivers/pci/ats.c       | 65 +++++++++++++++++++++++++++++++++++++------------
 drivers/pci/pci.c       |  3 +++
 include/linux/pci-ats.h | 10 ++++++++
 include/linux/pci.h     |  6 +++++
 4 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index 2126497..a769955 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -160,17 +160,16 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
 	if (!pos)
 		return -EINVAL;
 
-	pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
 	pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status);
-	if ((control & PCI_PRI_CTRL_ENABLE) ||
-	    !(status & PCI_PRI_STATUS_STOPPED))
+	if (!(status & PCI_PRI_STATUS_STOPPED))
 		return -EBUSY;
 
 	pci_read_config_dword(pdev, pos + PCI_PRI_MAX_REQ, &max_requests);
 	reqs = min(max_requests, reqs);
+	pdev->pri_reqs_alloc = reqs;
 	pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs);
 
-	control |= PCI_PRI_CTRL_ENABLE;
+	control = PCI_PRI_CTRL_ENABLE;
 	pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
 
 	pdev->pri_enabled = 1;
@@ -206,6 +205,29 @@ void pci_disable_pri(struct pci_dev *pdev)
 EXPORT_SYMBOL_GPL(pci_disable_pri);
 
 /**
+ * pci_restore_pri_state - Restore PRI
+ * @pdev: PCI device structure
+ *
+ */
+void pci_restore_pri_state(struct pci_dev *pdev)
+{
+   u16 control = PCI_PRI_CTRL_ENABLE;
+   u32 reqs = pdev->pri_reqs_alloc;
+   int pos;
+
+   pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
+   if (!pos)
+       return;
+
+   if (!pdev->pri_enabled)
+       return;
+
+   pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs);
+   pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
+}
+EXPORT_SYMBOL_GPL(pci_restore_pri_state);
+
+/**
  * pci_reset_pri - Resets device's PRI state
  * @pdev: PCI device structure
  *
@@ -224,12 +246,7 @@ int pci_reset_pri(struct pci_dev *pdev)
 	if (!pos)
 		return -EINVAL;
 
-	pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
-	if (control & PCI_PRI_CTRL_ENABLE)
-		return -EBUSY;
-
-	control |= PCI_PRI_CTRL_RESET;
-
+	control = PCI_PRI_CTRL_RESET;
 	pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
 
 	return 0;
@@ -259,12 +276,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
 	if (!pos)
 		return -EINVAL;
 
-	pci_read_config_word(pdev, pos + PCI_PASID_CTRL, &control);
 	pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported);
-
-	if (control & PCI_PASID_CTRL_ENABLE)
-		return -EINVAL;
-
 	supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV;
 
 	/* User wants to enable anything unsupported? */
@@ -272,6 +284,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
 		return -EINVAL;
 
 	control = PCI_PASID_CTRL_ENABLE | features;
+	pdev->pasid_features = features;
 
 	pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
 
@@ -305,6 +318,28 @@ void pci_disable_pasid(struct pci_dev *pdev)
 EXPORT_SYMBOL_GPL(pci_disable_pasid);
 
 /**
+ * pci_restore_pasid_state - Restore PASID capabilities.
+ * @pdev: PCI device structure
+ *
+ */
+void pci_restore_pasid_state(struct pci_dev *pdev)
+{
+   u16 control;
+   int pos;
+
+   pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
+   if (!pos)
+       return;
+
+   if (!pdev->pasid_enabled)
+       return;
+
+   control = PCI_PASID_CTRL_ENABLE | pdev->pasid_features;
+   pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
+}
+EXPORT_SYMBOL_GPL(pci_restore_pasid_state);
+
+/**
  * pci_pasid_features - Check which PASID features are supported
  * @pdev: PCI device structure
  *
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 7904d02..c9a6510 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -28,6 +28,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/pci_hotplug.h>
 #include <linux/vmalloc.h>
+#include <linux/pci-ats.h>
 #include <asm/setup.h>
 #include <asm/dma.h>
 #include <linux/aer.h>
@@ -1171,6 +1172,8 @@ void pci_restore_state(struct pci_dev *dev)
 
 	/* PCI Express register must be restored first */
 	pci_restore_pcie_state(dev);
+	pci_restore_pasid_state(dev);
+	pci_restore_pri_state(dev);
 	pci_restore_ats_state(dev);
 	pci_restore_vc_state(dev);
 
diff --git a/include/linux/pci-ats.h b/include/linux/pci-ats.h
index 57e0b82..782fb8e 100644
--- a/include/linux/pci-ats.h
+++ b/include/linux/pci-ats.h
@@ -7,6 +7,7 @@
 
 int pci_enable_pri(struct pci_dev *pdev, u32 reqs);
 void pci_disable_pri(struct pci_dev *pdev);
+void pci_restore_pri_state(struct pci_dev *pdev);
 int pci_reset_pri(struct pci_dev *pdev);
 
 #else /* CONFIG_PCI_PRI */
@@ -20,6 +21,10 @@ static inline void pci_disable_pri(struct pci_dev *pdev)
 {
 }
 
+static inline void pci_restore_pri_state(struct pci_dev *pdev)
+{
+}
+
 static inline int pci_reset_pri(struct pci_dev *pdev)
 {
 	return -ENODEV;
@@ -31,6 +36,7 @@ static inline int pci_reset_pri(struct pci_dev *pdev)
 
 int pci_enable_pasid(struct pci_dev *pdev, int features);
 void pci_disable_pasid(struct pci_dev *pdev);
+void pci_restore_pasid_state(struct pci_dev *pdev);
 int pci_pasid_features(struct pci_dev *pdev);
 int pci_max_pasids(struct pci_dev *pdev);
 
@@ -45,6 +51,10 @@ static inline void pci_disable_pasid(struct pci_dev *pdev)
 {
 }
 
+static inline void pci_restore_pasid_state(struct pci_dev *pdev)
+{
+}
+
 static inline int pci_pasid_features(struct pci_dev *pdev)
 {
 	return -EINVAL;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index bee980e..1ddb8e0 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -395,6 +395,12 @@ struct pci_dev {
 	u8		ats_stu;	/* ATS Smallest Translation Unit */
 	atomic_t	ats_ref_cnt;	/* number of VFs with ATS enabled */
 #endif
+#ifdef CONFIG_PCI_PRI
+	u32		pri_reqs_alloc; /* Number of PRI requests allocated */
+#endif
+#ifdef CONFIG_PCI_PASID
+	u16		pasid_features;
+#endif
 	phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */
 	size_t romlen; /* Length of ROM if it's not from the BAR */
 	char *driver_override; /* Driver name to force a match */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-10 18:28 Ashok Raj
  2017-05-10 18:28 ` [PATCH 2/2] iommu/vt-d: Helper function to query if a pasid has any active users Ashok Raj
  0 siblings, 1 reply; 14+ messages in thread
From: Ashok Raj @ 2017-05-10 18:28 UTC (permalink / raw)
  To: Bjorn Helgaas, Joerg Roedel, linux-pci
  Cc: CQ Tang, Jean-Phillipe Brucker, David Woodhouse, iommu, Ashok Raj

From: CQ Tang <cq.tang@intel.com>

Requires: https://patchwork.kernel.org/patch/9593891


After a FLR, pci-states need to be restored. This patch saves PASID features
and PRI reqs cached.

Cc: Jean-Phillipe Brucker <jean-philippe.brucker@arm.com>
Cc: David Woodhouse <dwm2@infradead.org>
Cc: iommu@lists.linux-foundation.org

Signed-off-by: CQ Tang <cq.tang@intel.com>
Signed-off-by: Ashok Raj <ashok.raj@intel.com>
---
 drivers/pci/ats.c       | 65 +++++++++++++++++++++++++++++++++++++------------
 drivers/pci/pci.c       |  3 +++
 include/linux/pci-ats.h | 10 ++++++++
 include/linux/pci.h     |  6 +++++
 4 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index 2126497..a769955 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -160,17 +160,16 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
 	if (!pos)
 		return -EINVAL;
 
-	pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
 	pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status);
-	if ((control & PCI_PRI_CTRL_ENABLE) ||
-	    !(status & PCI_PRI_STATUS_STOPPED))
+	if (!(status & PCI_PRI_STATUS_STOPPED))
 		return -EBUSY;
 
 	pci_read_config_dword(pdev, pos + PCI_PRI_MAX_REQ, &max_requests);
 	reqs = min(max_requests, reqs);
+	pdev->pri_reqs_alloc = reqs;
 	pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs);
 
-	control |= PCI_PRI_CTRL_ENABLE;
+	control = PCI_PRI_CTRL_ENABLE;
 	pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
 
 	pdev->pri_enabled = 1;
@@ -206,6 +205,29 @@ void pci_disable_pri(struct pci_dev *pdev)
 EXPORT_SYMBOL_GPL(pci_disable_pri);
 
 /**
+ * pci_restore_pri_state - Restore PRI
+ * @pdev: PCI device structure
+ *
+ */
+void pci_restore_pri_state(struct pci_dev *pdev)
+{
+   u16 control = PCI_PRI_CTRL_ENABLE;
+   u32 reqs = pdev->pri_reqs_alloc;
+   int pos;
+
+   pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
+   if (!pos)
+       return;
+
+   if (!pdev->pri_enabled)
+       return;
+
+   pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs);
+   pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
+}
+EXPORT_SYMBOL_GPL(pci_restore_pri_state);
+
+/**
  * pci_reset_pri - Resets device's PRI state
  * @pdev: PCI device structure
  *
@@ -224,12 +246,7 @@ int pci_reset_pri(struct pci_dev *pdev)
 	if (!pos)
 		return -EINVAL;
 
-	pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
-	if (control & PCI_PRI_CTRL_ENABLE)
-		return -EBUSY;
-
-	control |= PCI_PRI_CTRL_RESET;
-
+	control = PCI_PRI_CTRL_RESET;
 	pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
 
 	return 0;
@@ -259,12 +276,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
 	if (!pos)
 		return -EINVAL;
 
-	pci_read_config_word(pdev, pos + PCI_PASID_CTRL, &control);
 	pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported);
-
-	if (control & PCI_PASID_CTRL_ENABLE)
-		return -EINVAL;
-
 	supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV;
 
 	/* User wants to enable anything unsupported? */
@@ -272,6 +284,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
 		return -EINVAL;
 
 	control = PCI_PASID_CTRL_ENABLE | features;
+	pdev->pasid_features = features;
 
 	pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
 
@@ -305,6 +318,28 @@ void pci_disable_pasid(struct pci_dev *pdev)
 EXPORT_SYMBOL_GPL(pci_disable_pasid);
 
 /**
+ * pci_restore_pasid_state - Restore PASID capabilities.
+ * @pdev: PCI device structure
+ *
+ */
+void pci_restore_pasid_state(struct pci_dev *pdev)
+{
+   u16 control;
+   int pos;
+
+   pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
+   if (!pos)
+       return;
+
+   if (!pdev->pasid_enabled)
+       return;
+
+   control = PCI_PASID_CTRL_ENABLE | pdev->pasid_features;
+   pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
+}
+EXPORT_SYMBOL_GPL(pci_restore_pasid_state);
+
+/**
  * pci_pasid_features - Check which PASID features are supported
  * @pdev: PCI device structure
  *
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 7904d02..c9a6510 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -28,6 +28,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/pci_hotplug.h>
 #include <linux/vmalloc.h>
+#include <linux/pci-ats.h>
 #include <asm/setup.h>
 #include <asm/dma.h>
 #include <linux/aer.h>
@@ -1171,6 +1172,8 @@ void pci_restore_state(struct pci_dev *dev)
 
 	/* PCI Express register must be restored first */
 	pci_restore_pcie_state(dev);
+	pci_restore_pasid_state(dev);
+	pci_restore_pri_state(dev);
 	pci_restore_ats_state(dev);
 	pci_restore_vc_state(dev);
 
diff --git a/include/linux/pci-ats.h b/include/linux/pci-ats.h
index 57e0b82..782fb8e 100644
--- a/include/linux/pci-ats.h
+++ b/include/linux/pci-ats.h
@@ -7,6 +7,7 @@
 
 int pci_enable_pri(struct pci_dev *pdev, u32 reqs);
 void pci_disable_pri(struct pci_dev *pdev);
+void pci_restore_pri_state(struct pci_dev *pdev);
 int pci_reset_pri(struct pci_dev *pdev);
 
 #else /* CONFIG_PCI_PRI */
@@ -20,6 +21,10 @@ static inline void pci_disable_pri(struct pci_dev *pdev)
 {
 }
 
+static inline void pci_restore_pri_state(struct pci_dev *pdev)
+{
+}
+
 static inline int pci_reset_pri(struct pci_dev *pdev)
 {
 	return -ENODEV;
@@ -31,6 +36,7 @@ static inline int pci_reset_pri(struct pci_dev *pdev)
 
 int pci_enable_pasid(struct pci_dev *pdev, int features);
 void pci_disable_pasid(struct pci_dev *pdev);
+void pci_restore_pasid_state(struct pci_dev *pdev);
 int pci_pasid_features(struct pci_dev *pdev);
 int pci_max_pasids(struct pci_dev *pdev);
 
@@ -45,6 +51,10 @@ static inline void pci_disable_pasid(struct pci_dev *pdev)
 {
 }
 
+static inline void pci_restore_pasid_state(struct pci_dev *pdev)
+{
+}
+
 static inline int pci_pasid_features(struct pci_dev *pdev)
 {
 	return -EINVAL;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index bee980e..1ddb8e0 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -395,6 +395,12 @@ struct pci_dev {
 	u8		ats_stu;	/* ATS Smallest Translation Unit */
 	atomic_t	ats_ref_cnt;	/* number of VFs with ATS enabled */
 #endif
+#ifdef CONFIG_PCI_PRI
+	u32		pri_reqs_alloc; /* Number of PRI requests allocated */
+#endif
+#ifdef CONFIG_PCI_PASID
+	u16		pasid_features;
+#endif
 	phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */
 	size_t romlen; /* Length of ROM if it's not from the BAR */
 	char *driver_override; /* Driver name to force a match */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2017-05-30 17:43 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-10 18:39 [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes Ashok Raj
2017-05-10 18:39 ` [PATCH 2/2] iommu/vt-d: Helper function to query if a pasid has any active users Ashok Raj
2017-05-17 12:59   ` Joerg Roedel
2017-05-11 10:50 ` [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes Jean-Philippe Brucker
2017-05-11 10:50   ` Jean-Philippe Brucker
2017-05-25 13:19   ` Raj, Ashok
2017-05-25 13:19     ` Raj, Ashok
2017-05-30 16:31   ` Raj, Ashok
2017-05-30 16:31     ` Raj, Ashok
2017-05-23 20:33 ` Bjorn Helgaas
2017-05-23 20:33   ` Bjorn Helgaas
2017-05-24 21:21   ` Bjorn Helgaas
2017-05-24 21:21     ` Bjorn Helgaas
  -- strict thread matches above, loose matches on Subject: below --
2017-05-10 18:28 Ashok Raj
2017-05-10 18:28 ` [PATCH 2/2] iommu/vt-d: Helper function to query if a pasid has any active users Ashok Raj

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.