* [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; 8+ 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] 8+ 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 [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes Ashok Raj @ 2017-05-10 18:28 ` Ashok Raj 0 siblings, 0 replies; 8+ 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] 8+ messages in thread
* [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes.
@ 2017-05-10 18:39 Ashok Raj
[not found] ` <1494441543-8216-1-git-send-email-ashok.raj-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 8+ 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] 8+ messages in thread[parent not found: <1494441543-8216-1-git-send-email-ashok.raj-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>]
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes. [not found] ` <1494441543-8216-1-git-send-email-ashok.raj-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> @ 2017-05-11 10:50 ` Jean-Philippe Brucker [not found] ` <aa916e13-063f-3b25-34a5-b1a24200e021-5wv7dgnIgG8@public.gmane.org> 2017-05-23 20:33 ` Bjorn Helgaas 1 sibling, 1 reply; 8+ 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] 8+ messages in thread
[parent not found: <aa916e13-063f-3b25-34a5-b1a24200e021-5wv7dgnIgG8@public.gmane.org>]
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes. [not found] ` <aa916e13-063f-3b25-34a5-b1a24200e021-5wv7dgnIgG8@public.gmane.org> @ 2017-05-25 13:19 ` Raj, Ashok 2017-05-30 16:31 ` Raj, Ashok 1 sibling, 0 replies; 8+ 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] 8+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes. [not found] ` <aa916e13-063f-3b25-34a5-b1a24200e021-5wv7dgnIgG8@public.gmane.org> 2017-05-25 13:19 ` Raj, Ashok @ 2017-05-30 16:31 ` Raj, Ashok 1 sibling, 0 replies; 8+ 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] 8+ messages in thread
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes. [not found] ` <1494441543-8216-1-git-send-email-ashok.raj-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> 2017-05-11 10:50 ` Jean-Philippe Brucker @ 2017-05-23 20:33 ` Bjorn Helgaas [not found] ` <20170523203322.GA15055-1RhO1Y9PlrlHTL0Zs8A6p5iNqAH0jzoTYJqu5kTmcBRl57MIdRCFDg@public.gmane.org> 1 sibling, 1 reply; 8+ 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] 8+ messages in thread
[parent not found: <20170523203322.GA15055-1RhO1Y9PlrlHTL0Zs8A6p5iNqAH0jzoTYJqu5kTmcBRl57MIdRCFDg@public.gmane.org>]
* Re: [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes. [not found] ` <20170523203322.GA15055-1RhO1Y9PlrlHTL0Zs8A6p5iNqAH0jzoTYJqu5kTmcBRl57MIdRCFDg@public.gmane.org> @ 2017-05-24 21:21 ` Bjorn Helgaas 0 siblings, 0 replies; 8+ 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] 8+ messages in thread
end of thread, other threads:[~2017-05-30 16:31 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-10 18:28 [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes 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
-- strict thread matches above, loose matches on Subject: below --
2017-05-10 18:39 [PATCH 1/2] PCI: Save properties required to handle FLR for replay purposes Ashok Raj
[not found] ` <1494441543-8216-1-git-send-email-ashok.raj-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-05-11 10:50 ` Jean-Philippe Brucker
[not found] ` <aa916e13-063f-3b25-34a5-b1a24200e021-5wv7dgnIgG8@public.gmane.org>
2017-05-25 13:19 ` Raj, Ashok
2017-05-30 16:31 ` Raj, Ashok
2017-05-23 20:33 ` Bjorn Helgaas
[not found] ` <20170523203322.GA15055-1RhO1Y9PlrlHTL0Zs8A6p5iNqAH0jzoTYJqu5kTmcBRl57MIdRCFDg@public.gmane.org>
2017-05-24 21:21 ` Bjorn Helgaas
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).