* [PATCH 1/1] iommu/vt-d: Support page request in scalable mode
@ 2019-01-11 5:04 Lu Baolu
2019-01-11 11:29 ` Joerg Roedel
0 siblings, 1 reply; 2+ messages in thread
From: Lu Baolu @ 2019-01-11 5:04 UTC (permalink / raw)
To: Joerg Roedel, David Woodhouse
Cc: ashok.raj, iommu, linux-kernel, Jacob Pan, Liu Yi L, Kevin Tian,
Lu Baolu
From: Jacob Pan <jacob.jun.pan@linux.intel.com>
VT-d Rev3.0 has made a few changes to the page request interface,
1. widened PRQ descriptor from 128 bits to 256 bits;
2. removed streaming response type;
3. introduced private data that requires page response even the
request is not last request in group (LPIG).
This is a supplement to commit 1c4f88b7f1f92 ("iommu/vt-d: Shared
virtual address in scalable mode") and makes the svm code compliant
with VT-d Rev3.0.
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Liu Yi L <yi.l.liu@intel.com>
Cc: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
Fixes: 1c4f88b7f1f92 ("iommu/vt-d: Shared virtual address in scalable mode")
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
drivers/iommu/intel-svm.c | 77 ++++++++++++++++++++++---------------
include/linux/intel-iommu.h | 21 +++++-----
include/linux/intel-svm.h | 2 +-
3 files changed, 55 insertions(+), 45 deletions(-)
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index a2a2aa4439aa..79add5716552 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -470,20 +470,31 @@ EXPORT_SYMBOL_GPL(intel_svm_is_pasid_valid);
/* Page request queue descriptor */
struct page_req_dsc {
- u64 srr:1;
- u64 bof:1;
- u64 pasid_present:1;
- u64 lpig:1;
- u64 pasid:20;
- u64 bus:8;
- u64 private:23;
- u64 prg_index:9;
- u64 rd_req:1;
- u64 wr_req:1;
- u64 exe_req:1;
- u64 priv_req:1;
- u64 devfn:8;
- u64 addr:52;
+ union {
+ struct {
+ u64 type:8;
+ u64 pasid_present:1;
+ u64 priv_data_present:1;
+ u64 rsvd:6;
+ u64 rid:16;
+ u64 pasid:20;
+ u64 exe_req:1;
+ u64 pm_req:1;
+ u64 rsvd2:10;
+ };
+ u64 qw_0;
+ };
+ union {
+ struct {
+ u64 rd_req:1;
+ u64 wr_req:1;
+ u64 lpig:1;
+ u64 prg_index:9;
+ u64 addr:52;
+ };
+ u64 qw_1;
+ };
+ u64 priv_data[2];
};
#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x10)
@@ -596,7 +607,7 @@ static irqreturn_t prq_event_thread(int irq, void *d)
/* Accounting for major/minor faults? */
rcu_read_lock();
list_for_each_entry_rcu(sdev, &svm->devs, list) {
- if (sdev->sid == PCI_DEVID(req->bus, req->devfn))
+ if (sdev->sid == req->rid)
break;
}
/* Other devices can go away, but the drivers are not permitted
@@ -609,33 +620,35 @@ static irqreturn_t prq_event_thread(int irq, void *d)
if (sdev && sdev->ops && sdev->ops->fault_cb) {
int rwxp = (req->rd_req << 3) | (req->wr_req << 2) |
- (req->exe_req << 1) | (req->priv_req);
- sdev->ops->fault_cb(sdev->dev, req->pasid, req->addr, req->private, rwxp, result);
+ (req->exe_req << 1) | (req->pm_req);
+ sdev->ops->fault_cb(sdev->dev, req->pasid, req->addr,
+ req->priv_data, rwxp, result);
}
/* We get here in the error case where the PASID lookup failed,
and these can be NULL. Do not use them below this point! */
sdev = NULL;
svm = NULL;
no_pasid:
- if (req->lpig) {
- /* Page Group Response */
+ if (req->lpig || req->priv_data_present) {
+ /*
+ * Per VT-d spec. v3.0 ch7.7, system software must
+ * respond with page group response if private data
+ * is present (PDP) or last page in group (LPIG) bit
+ * is set. This is an additional VT-d feature beyond
+ * PCI ATS spec.
+ */
resp.qw0 = QI_PGRP_PASID(req->pasid) |
- QI_PGRP_DID((req->bus << 8) | req->devfn) |
+ QI_PGRP_DID(req->rid) |
QI_PGRP_PASID_P(req->pasid_present) |
+ QI_PGRP_PDP(req->pasid_present) |
+ QI_PGRP_RESP_CODE(result) |
QI_PGRP_RESP_TYPE;
resp.qw1 = QI_PGRP_IDX(req->prg_index) |
- QI_PGRP_PRIV(req->private) |
- QI_PGRP_RESP_CODE(result);
- } else if (req->srr) {
- /* Page Stream Response */
- resp.qw0 = QI_PSTRM_IDX(req->prg_index) |
- QI_PSTRM_PRIV(req->private) |
- QI_PSTRM_BUS(req->bus) |
- QI_PSTRM_PASID(req->pasid) |
- QI_PSTRM_RESP_TYPE;
- resp.qw1 = QI_PSTRM_ADDR(address) |
- QI_PSTRM_DEVFN(req->devfn) |
- QI_PSTRM_RESP_CODE(result);
+ QI_PGRP_LPIG(req->lpig);
+
+ if (req->priv_data_present)
+ memcpy(&resp.qw2, req->priv_data,
+ sizeof(req->priv_data));
}
resp.qw2 = 0;
resp.qw3 = 0;
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 0605f3bf6e79..fa364de9db18 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -374,20 +374,17 @@ enum {
#define QI_DEV_EIOTLB_PFSID(pfsid) (((u64)(pfsid & 0xf) << 12) | ((u64)(pfsid & 0xfff) << 52))
#define QI_DEV_EIOTLB_MAX_INVS 32
-#define QI_PGRP_IDX(idx) (((u64)(idx)) << 55)
-#define QI_PGRP_PRIV(priv) (((u64)(priv)) << 32)
-#define QI_PGRP_RESP_CODE(res) ((u64)(res))
-#define QI_PGRP_PASID(pasid) (((u64)(pasid)) << 32)
-#define QI_PGRP_DID(did) (((u64)(did)) << 16)
+/* Page group response descriptor QW0 */
#define QI_PGRP_PASID_P(p) (((u64)(p)) << 4)
+#define QI_PGRP_PDP(p) (((u64)(p)) << 5)
+#define QI_PGRP_RESP_CODE(res) (((u64)(res)) << 12)
+#define QI_PGRP_DID(rid) (((u64)(rid)) << 16)
+#define QI_PGRP_PASID(pasid) (((u64)(pasid)) << 32)
+
+/* Page group response descriptor QW1 */
+#define QI_PGRP_LPIG(x) (((u64)(x)) << 2)
+#define QI_PGRP_IDX(idx) (((u64)(idx)) << 3)
-#define QI_PSTRM_ADDR(addr) (((u64)(addr)) & VTD_PAGE_MASK)
-#define QI_PSTRM_DEVFN(devfn) (((u64)(devfn)) << 4)
-#define QI_PSTRM_RESP_CODE(res) ((u64)(res))
-#define QI_PSTRM_IDX(idx) (((u64)(idx)) << 55)
-#define QI_PSTRM_PRIV(priv) (((u64)(priv)) << 32)
-#define QI_PSTRM_BUS(bus) (((u64)(bus)) << 24)
-#define QI_PSTRM_PASID(pasid) (((u64)(pasid)) << 4)
#define QI_RESP_SUCCESS 0x0
#define QI_RESP_INVALID 0x1
diff --git a/include/linux/intel-svm.h b/include/linux/intel-svm.h
index 99bc5b3ae26e..e3f76315ca4d 100644
--- a/include/linux/intel-svm.h
+++ b/include/linux/intel-svm.h
@@ -20,7 +20,7 @@ struct device;
struct svm_dev_ops {
void (*fault_cb)(struct device *dev, int pasid, u64 address,
- u32 private, int rwxp, int response);
+ void *private, int rwxp, int response);
};
/* Values for rxwp in fault_cb callback */
--
2.17.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 1/1] iommu/vt-d: Support page request in scalable mode
2019-01-11 5:04 [PATCH 1/1] iommu/vt-d: Support page request in scalable mode Lu Baolu
@ 2019-01-11 11:29 ` Joerg Roedel
0 siblings, 0 replies; 2+ messages in thread
From: Joerg Roedel @ 2019-01-11 11:29 UTC (permalink / raw)
To: Lu Baolu
Cc: David Woodhouse, ashok.raj, iommu, linux-kernel, Jacob Pan,
Liu Yi L, Kevin Tian
On Fri, Jan 11, 2019 at 01:04:57PM +0800, Lu Baolu wrote:
> From: Jacob Pan <jacob.jun.pan@linux.intel.com>
>
> VT-d Rev3.0 has made a few changes to the page request interface,
>
> 1. widened PRQ descriptor from 128 bits to 256 bits;
> 2. removed streaming response type;
> 3. introduced private data that requires page response even the
> request is not last request in group (LPIG).
>
> This is a supplement to commit 1c4f88b7f1f92 ("iommu/vt-d: Shared
> virtual address in scalable mode") and makes the svm code compliant
> with VT-d Rev3.0.
>
> Cc: Ashok Raj <ashok.raj@intel.com>
> Cc: Liu Yi L <yi.l.liu@intel.com>
> Cc: Kevin Tian <kevin.tian@intel.com>
> Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
> Fixes: 1c4f88b7f1f92 ("iommu/vt-d: Shared virtual address in scalable mode")
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Applied for v5.1, thanks.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-01-11 11:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-11 5:04 [PATCH 1/1] iommu/vt-d: Support page request in scalable mode Lu Baolu
2019-01-11 11:29 ` Joerg Roedel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox