[PATCH v4 20/22] iommu/vt-d: add intel iommu page response function

2018-04-16 Thread Jacob Pan
This patch adds page response support for Intel VT-d.
Generic response data is taken from the IOMMU API
then parsed into VT-d specific response descriptor format.

Signed-off-by: Jacob Pan 
---
 drivers/iommu/intel-iommu.c | 47 +
 include/linux/intel-iommu.h |  3 +++
 2 files changed, 50 insertions(+)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a6ea67d..38f76d4 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5142,6 +5142,52 @@ static int intel_iommu_sva_invalidate(struct 
iommu_domain *domain,
return ret;
 }
 
+static int intel_iommu_page_response(struct device *dev, struct 
page_response_msg *msg)
+{
+   struct qi_desc resp;
+   struct intel_iommu *iommu;
+   struct pci_dev *pdev;
+   u8 bus, devfn;
+   u16 rid;
+   u64 desc;
+
+   pdev = to_pci_dev(dev);
+   iommu = device_to_iommu(dev, , );
+   if (!iommu) {
+   dev_err(dev, "No IOMMU for device to unbind PASID table\n");
+   return -ENODEV;
+   }
+
+   pci_dev_get(pdev);
+   rid = ((u16)bus << 8) | devfn;
+   /* Iommu private data contains  preserved page request descriptor, so we
+* inspect the SRR bit for response type then queue response with only
+* the private data [54:32].
+*/
+   desc = msg->private_data;
+   if (desc & QI_PRQ_SRR) {
+   /* Page Stream Response */
+   resp.low = QI_PSTRM_IDX(msg->page_req_group_id) |
+   (desc & QI_PRQ_PRIV) | 
QI_PSTRM_BUS(PCI_BUS_NUM(pdev->bus->number)) |
+   QI_PSTRM_PASID(msg->pasid) | QI_PSTRM_RESP_TYPE;
+   resp.high = QI_PSTRM_ADDR(msg->addr) | 
QI_PSTRM_DEVFN(pdev->devfn & 0xff) |
+   QI_PSTRM_RESP_CODE(msg->resp_code);
+   } else {
+   /* Page Group Response */
+   resp.low = QI_PGRP_PASID(msg->pasid) |
+   QI_PGRP_DID(rid) |
+   QI_PGRP_PASID_P(msg->pasid_present) |
+   QI_PGRP_RESP_TYPE;
+   resp.high = QI_PGRP_IDX(msg->page_req_group_id) |
+   (desc & QI_PRQ_PRIV) | 
QI_PGRP_RESP_CODE(msg->resp_code);
+
+   }
+   qi_submit_sync(, iommu);
+   pci_dev_put(pdev);
+
+   return 0;
+}
+
 static int intel_iommu_map(struct iommu_domain *domain,
   unsigned long iova, phys_addr_t hpa,
   size_t size, int iommu_prot)
@@ -5568,6 +5614,7 @@ const struct iommu_ops intel_iommu_ops = {
.bind_pasid_table   = intel_iommu_bind_pasid_table,
.unbind_pasid_table = intel_iommu_unbind_pasid_table,
.sva_invalidate = intel_iommu_sva_invalidate,
+   .page_response  = intel_iommu_page_response,
 #endif
.map= intel_iommu_map,
.unmap  = intel_iommu_unmap,
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index dbe8c93..ed2883a 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -337,6 +337,9 @@ enum {
 #define QI_PSTRM_BUS(bus)  (((u64)(bus)) << 24)
 #define QI_PSTRM_PASID(pasid)  (((u64)(pasid)) << 4)
 
+#define QI_PRQ_SRR BIT_ULL(0)
+#define QI_PRQ_PRIVGENMASK_ULL(54, 32)
+
 #define QI_RESP_SUCCESS0x0
 #define QI_RESP_INVALID0x1
 #define QI_RESP_FAILURE0xf
-- 
2.7.4

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 20/22] iommu/vt-d: add intel iommu page response function

2018-03-24 Thread kbuild test robot
Hi Jacob,

I love your patch! Perhaps something to improve:

[auto build test WARNING on iommu/next]
[also build test WARNING on v4.16-rc6 next-20180323]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Jacob-Pan/IOMMU-and-VT-d-driver-support-for-Shared-Virtual-Address-SVA/20180325-024555
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   drivers/iommu/intel-iommu.c:500:5: sparse: symbol 'intel_iommu_gfx_mapped' 
was not declared. Should it be static?
   drivers/iommu/intel-iommu.c:3066:41: sparse: incorrect type in argument 1 
(different address spaces) @@expected void volatile [noderef] *addr 
@@got ile [noderef] *addr @@
   drivers/iommu/intel-iommu.c:3066:41:expected void volatile [noderef] 
*addr
   drivers/iommu/intel-iommu.c:3066:41:got struct context_entry *old_ce
>> drivers/iommu/intel-iommu.c:5198:5: sparse: symbol 
>> 'intel_iommu_page_response' was not declared. Should it be static?
>> drivers/iommu/intel-iommu.c:5224:48: sparse: right shift by bigger than 
>> source value

Please review and possibly fold the followup patch.

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v4 20/22] iommu/vt-d: add intel iommu page response function

2018-03-22 Thread Jacob Pan
This patch adds page response support for Intel VT-d.
Generic response data is taken from the IOMMU API
then parsed into VT-d specific response descriptor format.

Signed-off-by: Jacob Pan 
---
 drivers/iommu/intel-iommu.c | 47 +
 include/linux/intel-iommu.h |  3 +++
 2 files changed, 50 insertions(+)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 3229e20..8d73ff0 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5195,6 +5195,52 @@ static int intel_iommu_sva_invalidate(struct 
iommu_domain *domain,
return ret;
 }
 
+int intel_iommu_page_response(struct device *dev, struct page_response_msg 
*msg)
+{
+   struct qi_desc resp;
+   struct intel_iommu *iommu;
+   struct pci_dev *pdev;
+   u8 bus, devfn;
+   u16 rid;
+   u64 desc;
+
+   pdev = to_pci_dev(dev);
+   iommu = device_to_iommu(dev, , );
+   if (!iommu) {
+   dev_err(dev, "No IOMMU for device to unbind PASID table\n");
+   return -ENODEV;
+   }
+
+   pci_dev_get(pdev);
+   rid = ((u16)bus << 8) | devfn;
+   /* Iommu private data contains  preserved page request descriptor, so we
+* inspect the SRR bit for response type then queue response with only
+* the private data [54:32].
+*/
+   desc = msg->private_data;
+   if (desc & QI_PRQ_SRR) {
+   /* Page Stream Response */
+   resp.low = QI_PSTRM_IDX(msg->page_req_group_id) |
+   (desc & QI_PRQ_PRIV) | 
QI_PSTRM_BUS(PCI_BUS_NUM(pdev->bus->number)) |
+   QI_PSTRM_PASID(msg->pasid) | QI_PSTRM_RESP_TYPE;
+   resp.high = QI_PSTRM_ADDR(msg->addr) | 
QI_PSTRM_DEVFN(pdev->devfn & 0xff) |
+   QI_PSTRM_RESP_CODE(msg->resp_code);
+   } else {
+   /* Page Group Response */
+   resp.low = QI_PGRP_PASID(msg->pasid) |
+   QI_PGRP_DID(rid) |
+   QI_PGRP_PASID_P(msg->pasid_present) |
+   QI_PGRP_RESP_TYPE;
+   resp.high = QI_PGRP_IDX(msg->page_req_group_id) |
+   (desc & QI_PRQ_PRIV) | 
QI_PGRP_RESP_CODE(msg->resp_code);
+
+   }
+   qi_submit_sync(, iommu);
+   pci_dev_put(pdev);
+
+   return 0;
+}
+
 static int intel_iommu_map(struct iommu_domain *domain,
   unsigned long iova, phys_addr_t hpa,
   size_t size, int iommu_prot)
@@ -5625,6 +5671,7 @@ const struct iommu_ops intel_iommu_ops = {
.bind_pasid_table   = intel_iommu_bind_pasid_table,
.unbind_pasid_table = intel_iommu_unbind_pasid_table,
.sva_invalidate = intel_iommu_sva_invalidate,
+   .page_response  = intel_iommu_page_response,
 #endif
.map= intel_iommu_map,
.unmap  = intel_iommu_unmap,
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index dacb6cf..d2e1b5c 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -337,6 +337,9 @@ enum {
 #define QI_PSTRM_BUS(bus)  (((u64)(bus)) << 24)
 #define QI_PSTRM_PASID(pasid)  (((u64)(pasid)) << 4)
 
+#define QI_PRQ_SRR BIT_ULL(0)
+#define QI_PRQ_PRIVGENMASK_ULL(54, 32)
+
 #define QI_RESP_SUCCESS0x0
 #define QI_RESP_INVALID0x1
 #define QI_RESP_FAILURE0xf
-- 
2.7.4

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu