* [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 2/2] iommu/vt-d: Helper function to query if a pasid has any active users
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 ` Ashok Raj
2017-05-17 12:59 ` Joerg Roedel
2017-05-11 10:50 ` Jean-Philippe Brucker
2017-05-23 20:33 ` Bjorn Helgaas
2 siblings, 1 reply; 14+ messages in thread
From: Ashok Raj @ 2017-05-10 18:39 UTC (permalink / raw)
To: Joerg Roedel, linux-kernel
Cc: CQ Tang, linux-pci, Jean-Phillipe Brucker, iommu, Ashok Raj
From: CQ Tang <cq.tang@intel.com>
A driver would need to know if there are any active references to a
a PASID before cleaning up its resources. This function helps check
if there are any active users of a PASID before it can perform any
recovery on that device.
To: Joerg Roedel <joro@8bytes.org>
To: linux-kernel@vger.kernel.org
To: David Woodhouse <dwmw2@infradead.org>
Cc: Jean-Phillipe Brucker <jean-philippe.brucker@arm.com>
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/iommu/intel-svm.c | 30 ++++++++++++++++++++++++++++++
include/linux/intel-svm.h | 20 ++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index 23c4276..f167c0d 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -489,6 +489,36 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
}
EXPORT_SYMBOL_GPL(intel_svm_unbind_mm);
+int intel_svm_is_pasid_valid(struct device *dev, int pasid)
+{
+ struct intel_iommu *iommu;
+ struct intel_svm *svm;
+ int ret = -EINVAL;
+
+ mutex_lock(&pasid_mutex);
+ iommu = intel_svm_device_to_iommu(dev);
+ if (!iommu || !iommu->pasid_table)
+ goto out;
+
+ svm = idr_find(&iommu->pasid_idr, pasid);
+ if (!svm)
+ goto out;
+
+ /* init_mm is used in this case */
+ if (!svm->mm)
+ ret = 1;
+ else if (atomic_read(&svm->mm->mm_users) > 0)
+ ret = 1;
+ else
+ ret = 0;
+
+ out:
+ mutex_unlock(&pasid_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(intel_svm_is_pasid_valid);
+
/* Page request queue descriptor */
struct page_req_dsc {
u64 srr:1;
diff --git a/include/linux/intel-svm.h b/include/linux/intel-svm.h
index 3c25794..99bc5b3 100644
--- a/include/linux/intel-svm.h
+++ b/include/linux/intel-svm.h
@@ -102,6 +102,21 @@ extern int intel_svm_bind_mm(struct device *dev, int *pasid, int flags,
*/
extern int intel_svm_unbind_mm(struct device *dev, int pasid);
+/**
+ * intel_svm_is_pasid_valid() - check if pasid is valid
+ * @dev: Device for which PASID was allocated
+ * @pasid: PASID value to be checked
+ *
+ * This function checks if the specified pasid is still valid. A
+ * valid pasid means the backing mm is still having a valid user.
+ * For kernel callers init_mm is always valid. for other mm, if mm->mm_users
+ * is non-zero, it is valid.
+ *
+ * returns -EINVAL if invalid pasid, 0 if pasid ref count is invalid
+ * 1 if pasid is valid.
+ */
+extern int intel_svm_is_pasid_valid(struct device *dev, int pasid);
+
#else /* CONFIG_INTEL_IOMMU_SVM */
static inline int intel_svm_bind_mm(struct device *dev, int *pasid,
@@ -114,6 +129,11 @@ static inline int intel_svm_unbind_mm(struct device *dev, int pasid)
{
BUG();
}
+
+static int intel_svm_is_pasid_valid(struct device *dev, int pasid)
+{
+ return -EINVAL;
+}
#endif /* CONFIG_INTEL_IOMMU_SVM */
#define intel_svm_available(dev) (!intel_svm_bind_mm((dev), NULL, 0, NULL))
--
2.7.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] iommu/vt-d: Helper function to query if a pasid has any active users
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
0 siblings, 0 replies; 14+ messages in thread
From: Joerg Roedel @ 2017-05-17 12:59 UTC (permalink / raw)
To: Ashok Raj; +Cc: linux-kernel, CQ Tang, linux-pci, Jean-Phillipe Brucker, iommu
On Wed, May 10, 2017 at 11:39:03AM -0700, Ashok Raj wrote:
> From: CQ Tang <cq.tang@intel.com>
>
> A driver would need to know if there are any active references to a
> a PASID before cleaning up its resources. This function helps check
> if there are any active users of a PASID before it can perform any
> recovery on that device.
>
> To: Joerg Roedel <joro@8bytes.org>
> To: linux-kernel@vger.kernel.org
> To: David Woodhouse <dwmw2@infradead.org>
> Cc: Jean-Phillipe Brucker <jean-philippe.brucker@arm.com>
> 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/iommu/intel-svm.c | 30 ++++++++++++++++++++++++++++++
> include/linux/intel-svm.h | 20 ++++++++++++++++++++
> 2 files changed, 50 insertions(+)
Applied, thanks.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-11 10:50 ` Jean-Philippe Brucker
0 siblings, 0 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-11 10:50 UTC (permalink / raw)
To: Ashok Raj, Bjorn Helgaas, Joerg Roedel, linux-pci
Cc: CQ Tang, David Woodhouse, iommu
Hi,
On 10/05/17 19:39, Ashok Raj wrote:
> From: CQ Tang <cq.tang@intel.com>
>
> Requires: https://patchwork.kernel.org/patch/9593891
Since your series is likely to go in much earlier than my SVM mess, maybe
you could carry that PCI patch along with it? Or I could resend it on its
own if you prefer.
I'm planning to resend the SVM series in a few weeks but it still won't
make it into mainline since it hasn't run on hardware.
Thanks,
Jean-Philippe
> 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 */
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-11 10:50 ` Jean-Philippe Brucker
0 siblings, 0 replies; 14+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-11 10:50 UTC (permalink / raw)
To: Ashok Raj, Bjorn Helgaas, Joerg Roedel, linux-pci-u79uwXL29TY76Z2rM5mHXA
Cc: David Woodhouse, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Hi,
On 10/05/17 19:39, Ashok Raj wrote:
> From: CQ Tang <cq.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>
> Requires: https://patchwork.kernel.org/patch/9593891
Since your series is likely to go in much earlier than my SVM mess, maybe
you could carry that PCI patch along with it? Or I could resend it on its
own if you prefer.
I'm planning to resend the SVM series in a few weeks but it still won't
make it into mainline since it hasn't run on hardware.
Thanks,
Jean-Philippe
> 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-5wv7dgnIgG8@public.gmane.org>
> Cc: David Woodhouse <dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
> Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
>
> Signed-off-by: CQ Tang <cq.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Ashok Raj <ashok.raj-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> ---
> 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 */
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-25 13:19 ` Raj, Ashok
0 siblings, 0 replies; 14+ messages in thread
From: Raj, Ashok @ 2017-05-25 13:19 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: Bjorn Helgaas, Joerg Roedel, linux-pci, CQ Tang, David Woodhouse,
iommu, ashok.raj
Hi Jean
On Thu, May 11, 2017 at 11:50:24AM +0100, Jean-Philippe Brucker wrote:
> Hi,
>
> On 10/05/17 19:39, Ashok Raj wrote:
> > From: CQ Tang <cq.tang@intel.com>
> >
> > Requires: https://patchwork.kernel.org/patch/9593891
>
> Since your series is likely to go in much earlier than my SVM mess, maybe
> you could carry that PCI patch along with it? Or I could resend it on its
> own if you prefer.
CQ has tested your patch along with this. In fact the original patch had
exactly what you had in this patch. But i split since i noticed you caught
part of our change.
Since Joerg already has your version, it might be easy to just pick
your patch and ours and commit separately.
Cheers,
Ashok
>
> I'm planning to resend the SVM series in a few weeks but it still won't
> make it into mainline since it hasn't run on hardware.
>
> Thanks,
> Jean-Philippe
>
> > 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 */
> >
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-25 13:19 ` Raj, Ashok
0 siblings, 0 replies; 14+ messages in thread
From: Raj, Ashok @ 2017-05-25 13:19 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Bjorn Helgaas,
David Woodhouse
Hi Jean
On Thu, May 11, 2017 at 11:50:24AM +0100, Jean-Philippe Brucker wrote:
> Hi,
>
> On 10/05/17 19:39, Ashok Raj wrote:
> > From: CQ Tang <cq.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> >
> > Requires: https://patchwork.kernel.org/patch/9593891
>
> Since your series is likely to go in much earlier than my SVM mess, maybe
> you could carry that PCI patch along with it? Or I could resend it on its
> own if you prefer.
CQ has tested your patch along with this. In fact the original patch had
exactly what you had in this patch. But i split since i noticed you caught
part of our change.
Since Joerg already has your version, it might be easy to just pick
your patch and ours and commit separately.
Cheers,
Ashok
>
> I'm planning to resend the SVM series in a few weeks but it still won't
> make it into mainline since it hasn't run on hardware.
>
> Thanks,
> Jean-Philippe
>
> > 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-5wv7dgnIgG8@public.gmane.org>
> > Cc: David Woodhouse <dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
> > Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
> >
> > Signed-off-by: CQ Tang <cq.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> > Signed-off-by: Ashok Raj <ashok.raj-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> > ---
> > 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 */
> >
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-30 16:31 ` Raj, Ashok
0 siblings, 0 replies; 14+ messages in thread
From: Raj, Ashok @ 2017-05-30 16:31 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: Bjorn Helgaas, Joerg Roedel, linux-pci, CQ Tang, David Woodhouse,
iommu, ashok.raj
On Thu, May 11, 2017 at 11:50:24AM +0100, Jean-Philippe Brucker wrote:
> Hi,
>
> On 10/05/17 19:39, Ashok Raj wrote:
> > From: CQ Tang <cq.tang@intel.com>
> >
> > Requires: https://patchwork.kernel.org/patch/9593891
>
> Since your series is likely to go in much earlier than my SVM mess, maybe
> you could carry that PCI patch along with it? Or I could resend it on its
> own if you prefer.
I have send the 2 patches to the list, so we can get them in before the long
SVM series gets in.
>
> I'm planning to resend the SVM series in a few weeks but it still won't
> make it into mainline since it hasn't run on hardware.
>
> Thanks,
> Jean-Philippe
>
Cheers,
Ashok
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-30 16:31 ` Raj, Ashok
0 siblings, 0 replies; 14+ messages in thread
From: Raj, Ashok @ 2017-05-30 16:31 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Bjorn Helgaas,
David Woodhouse
On Thu, May 11, 2017 at 11:50:24AM +0100, Jean-Philippe Brucker wrote:
> Hi,
>
> On 10/05/17 19:39, Ashok Raj wrote:
> > From: CQ Tang <cq.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> >
> > Requires: https://patchwork.kernel.org/patch/9593891
>
> Since your series is likely to go in much earlier than my SVM mess, maybe
> you could carry that PCI patch along with it? Or I could resend it on its
> own if you prefer.
I have send the 2 patches to the list, so we can get them in before the long
SVM series gets in.
>
> I'm planning to resend the SVM series in a few weeks but it still won't
> make it into mainline since it hasn't run on hardware.
>
> Thanks,
> Jean-Philippe
>
Cheers,
Ashok
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-23 20:33 ` Bjorn Helgaas
0 siblings, 0 replies; 14+ messages in thread
From: Bjorn Helgaas @ 2017-05-23 20:33 UTC (permalink / raw)
To: Ashok Raj
Cc: Bjorn Helgaas, Joerg Roedel, linux-pci, CQ Tang,
Jean-Phillipe Brucker, David Woodhouse, iommu
On Wed, May 10, 2017 at 11:39:02AM -0700, Ashok Raj wrote:
> From: CQ Tang <cq.tang@intel.com>
>
> Requires: https://patchwork.kernel.org/patch/9593891
I'm not sure what the status of the patch above is. I acked it, but it's
part of a 30-patch IOMMU series, so I expect it to be merged via an IOMMU
tree.
In any case, it's not in v4.12-rc1, so I can't apply *this* patch yet.
> 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 [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-23 20:33 ` Bjorn Helgaas
0 siblings, 0 replies; 14+ messages in thread
From: Bjorn Helgaas @ 2017-05-23 20:33 UTC (permalink / raw)
To: Ashok Raj
Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Bjorn Helgaas,
David Woodhouse
On Wed, May 10, 2017 at 11:39:02AM -0700, Ashok Raj wrote:
> From: CQ Tang <cq.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>
> Requires: https://patchwork.kernel.org/patch/9593891
I'm not sure what the status of the patch above is. I acked it, but it's
part of a 30-patch IOMMU series, so I expect it to be merged via an IOMMU
tree.
In any case, it's not in v4.12-rc1, so I can't apply *this* patch yet.
> 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-5wv7dgnIgG8@public.gmane.org>
> Cc: David Woodhouse <dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
> Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
>
> Signed-off-by: CQ Tang <cq.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Ashok Raj <ashok.raj-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> ---
> 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 [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-24 21:21 ` Bjorn Helgaas
0 siblings, 0 replies; 14+ messages in thread
From: Bjorn Helgaas @ 2017-05-24 21:21 UTC (permalink / raw)
To: Ashok Raj
Cc: Bjorn Helgaas, Joerg Roedel, linux-pci, CQ Tang,
Jean-Phillipe Brucker, David Woodhouse, iommu
On Tue, May 23, 2017 at 03:33:22PM -0500, Bjorn Helgaas wrote:
> On Wed, May 10, 2017 at 11:39:02AM -0700, Ashok Raj wrote:
> > From: CQ Tang <cq.tang@intel.com>
> >
> > Requires: https://patchwork.kernel.org/patch/9593891
>
> I'm not sure what the status of the patch above is. I acked it, but it's
> part of a 30-patch IOMMU series, so I expect it to be merged via an IOMMU
> tree.
>
> In any case, it's not in v4.12-rc1, so I can't apply *this* patch yet.
Ashok or CQ, would you mind reposting this when the patch it depends
on has been merged? I'm going to drop it from patchwork for now since
I can't do anything with it, and that means it will completely
disappear from my to-do list.
Bjorn
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-24 21:21 ` Bjorn Helgaas
0 siblings, 0 replies; 14+ messages in thread
From: Bjorn Helgaas @ 2017-05-24 21:21 UTC (permalink / raw)
To: Ashok Raj
Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Bjorn Helgaas,
David Woodhouse
On Tue, May 23, 2017 at 03:33:22PM -0500, Bjorn Helgaas wrote:
> On Wed, May 10, 2017 at 11:39:02AM -0700, Ashok Raj wrote:
> > From: CQ Tang <cq.tang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> >
> > Requires: https://patchwork.kernel.org/patch/9593891
>
> I'm not sure what the status of the patch above is. I acked it, but it's
> part of a 30-patch IOMMU series, so I expect it to be merged via an IOMMU
> tree.
>
> In any case, it's not in v4.12-rc1, so I can't apply *this* patch yet.
Ashok or CQ, would you mind reposting this when the patch it depends
on has been merged? I'm going to drop it from patchwork for now since
I can't do anything with it, and that means it will completely
disappear from my to-do list.
Bjorn
^ permalink raw reply [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
* [PATCH 2/2] iommu/vt-d: Helper function to query if a pasid has any active users
2017-05-10 18:28 Ashok Raj
@ 2017-05-10 18:28 ` Ashok Raj
0 siblings, 0 replies; 14+ messages in thread
From: Ashok Raj @ 2017-05-10 18:28 UTC (permalink / raw)
To: Joerg Roedel, linux-kernel
Cc: CQ Tang, linux-pci, Jean-Phillipe Brucker, iommu, Ashok Raj
From: CQ Tang <cq.tang@intel.com>
A driver would need to know if there are any active references to a
a PASID before cleaning up its resources. This function helps check
if there are any active users of a PASID before it can perform any
recovery on that device.
To: Joerg Roedel <joro@8bytes.org>
To: linux-kernel@vger.kernel.org
To: David Woodhouse <dwm2@infradead.org>
Cc: Jean-Phillipe Brucker <jean-philippe.brucker@arm.com>
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/iommu/intel-svm.c | 30 ++++++++++++++++++++++++++++++
include/linux/intel-svm.h | 20 ++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index 23c4276..f167c0d 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -489,6 +489,36 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
}
EXPORT_SYMBOL_GPL(intel_svm_unbind_mm);
+int intel_svm_is_pasid_valid(struct device *dev, int pasid)
+{
+ struct intel_iommu *iommu;
+ struct intel_svm *svm;
+ int ret = -EINVAL;
+
+ mutex_lock(&pasid_mutex);
+ iommu = intel_svm_device_to_iommu(dev);
+ if (!iommu || !iommu->pasid_table)
+ goto out;
+
+ svm = idr_find(&iommu->pasid_idr, pasid);
+ if (!svm)
+ goto out;
+
+ /* init_mm is used in this case */
+ if (!svm->mm)
+ ret = 1;
+ else if (atomic_read(&svm->mm->mm_users) > 0)
+ ret = 1;
+ else
+ ret = 0;
+
+ out:
+ mutex_unlock(&pasid_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(intel_svm_is_pasid_valid);
+
/* Page request queue descriptor */
struct page_req_dsc {
u64 srr:1;
diff --git a/include/linux/intel-svm.h b/include/linux/intel-svm.h
index 3c25794..99bc5b3 100644
--- a/include/linux/intel-svm.h
+++ b/include/linux/intel-svm.h
@@ -102,6 +102,21 @@ extern int intel_svm_bind_mm(struct device *dev, int *pasid, int flags,
*/
extern int intel_svm_unbind_mm(struct device *dev, int pasid);
+/**
+ * intel_svm_is_pasid_valid() - check if pasid is valid
+ * @dev: Device for which PASID was allocated
+ * @pasid: PASID value to be checked
+ *
+ * This function checks if the specified pasid is still valid. A
+ * valid pasid means the backing mm is still having a valid user.
+ * For kernel callers init_mm is always valid. for other mm, if mm->mm_users
+ * is non-zero, it is valid.
+ *
+ * returns -EINVAL if invalid pasid, 0 if pasid ref count is invalid
+ * 1 if pasid is valid.
+ */
+extern int intel_svm_is_pasid_valid(struct device *dev, int pasid);
+
#else /* CONFIG_INTEL_IOMMU_SVM */
static inline int intel_svm_bind_mm(struct device *dev, int *pasid,
@@ -114,6 +129,11 @@ static inline int intel_svm_unbind_mm(struct device *dev, int pasid)
{
BUG();
}
+
+static int intel_svm_is_pasid_valid(struct device *dev, int pasid)
+{
+ return -EINVAL;
+}
#endif /* CONFIG_INTEL_IOMMU_SVM */
#define intel_svm_available(dev) (!intel_svm_bind_mm((dev), NULL, 0, NULL))
--
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.