Re: [PATCH v5 08/23] iommu/vt-d: support flushing more translation cache types

2018-05-17 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.17-rc5 next-20180516]
[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/20180512-114854
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
config: x86_64-rhel-7.2 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   drivers/iommu/dmar.c: In function 'qi_flush_dev_eiotlb':
>> drivers/iommu/dmar.c:1382:12: warning: 'desc.high' is used uninitialized in 
>> this function [-Wuninitialized]
 desc.high |= QI_DEV_EIOTLB_GLOB(granu);
   ^~

vim +1382 drivers/iommu/dmar.c

  1374  
  1375  void qi_flush_dev_eiotlb(struct intel_iommu *iommu, u16 sid,
  1376  u32 pasid,  u16 qdep, u64 addr, unsigned size, u64 
granu)
  1377  {
  1378  struct qi_desc desc;
  1379  
  1380  desc.low = QI_DEV_EIOTLB_PASID(pasid) | QI_DEV_EIOTLB_SID(sid) |
  1381  QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE;
> 1382  desc.high |= QI_DEV_EIOTLB_GLOB(granu);
  1383  
  1384  /* If S bit is 0, we only flush a single page. If S bit is set,
  1385   * The least significant zero bit indicates the size. VT-d spec
  1386   * 6.5.2.6
  1387   */
  1388  if (!size)
  1389  desc.high = QI_DEV_EIOTLB_ADDR(addr) & 
~QI_DEV_EIOTLB_SIZE;
  1390  else {
  1391  unsigned long mask = 1UL << (VTD_PAGE_SHIFT + size);
  1392  
  1393  desc.high = QI_DEV_EIOTLB_ADDR(addr & ~mask) | 
QI_DEV_EIOTLB_SIZE;
  1394  }
  1395  qi_submit_sync(, iommu);
  1396  }
  1397  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH v5 08/23] iommu/vt-d: support flushing more translation cache types

2018-05-14 Thread Jacob Pan
On Mon, 14 May 2018 10:18:44 +0800
Lu Baolu  wrote:

> Hi,
> 
> On 05/12/2018 04:54 AM, Jacob Pan wrote:
> > When Shared Virtual Memory is exposed to a guest via vIOMMU,
> > extended IOTLB invalidation may be passed down from outside IOMMU
> > subsystems. This patch adds invalidation functions that can be used
> > for additional translation cache types.
> >
> > Signed-off-by: Jacob Pan 
> > ---
> >  drivers/iommu/dmar.c| 44
> > 
> > include/linux/intel-iommu.h | 21 +++-- 2 files
> > changed, 63 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
> > index 7852678..0b5b052 100644
> > --- a/drivers/iommu/dmar.c
> > +++ b/drivers/iommu/dmar.c
> > @@ -1339,6 +1339,18 @@ void qi_flush_iotlb(struct intel_iommu
> > *iommu, u16 did, u64 addr, qi_submit_sync(, iommu);
> >  }
> >  
> > +void qi_flush_eiotlb(struct intel_iommu *iommu, u16 did, u64 addr,
> > u32 pasid,
> > +   unsigned int size_order, u64 granu, bool global)  
> 
> Alignment should match open parenthesis.
> 
> > +{
> > +   struct qi_desc desc;
> > +
> > +   desc.low = QI_EIOTLB_PASID(pasid) | QI_EIOTLB_DID(did) |
> > +   QI_EIOTLB_GRAN(granu) | QI_EIOTLB_TYPE;
> > +   desc.high = QI_EIOTLB_ADDR(addr) | QI_EIOTLB_GL(global) |
> > +   QI_EIOTLB_IH(0) | QI_EIOTLB_AM(size_order);
> > +   qi_submit_sync(, iommu);
> > +}
> > +
> >  void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16
> > pfsid, u16 qdep, u64 addr, unsigned mask)
> >  {
> > @@ -1360,6 +1372,38 @@ void qi_flush_dev_iotlb(struct intel_iommu
> > *iommu, u16 sid, u16 pfsid, qi_submit_sync(, iommu);
> >  }
> >  
> > +void qi_flush_dev_eiotlb(struct intel_iommu *iommu, u16 sid,
> > +   u32 pasid,  u16 qdep, u64 addr, unsigned size, u64
> > granu)  
> 
> Ditto.
> 
> > +{
> > +   struct qi_desc desc;
> > +
> > +   desc.low = QI_DEV_EIOTLB_PASID(pasid) |
> > QI_DEV_EIOTLB_SID(sid) |
> > +   QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE;  
> 
> Have you forgotten PFSID, or I missed anything here?
you are right, missed pfsid in this case.
> 
>  [...]  
> 
> Best regards,
> Lu Baolu

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


Re: [PATCH v5 08/23] iommu/vt-d: support flushing more translation cache types

2018-05-13 Thread Lu Baolu
Hi,

On 05/12/2018 04:54 AM, Jacob Pan wrote:
> When Shared Virtual Memory is exposed to a guest via vIOMMU, extended
> IOTLB invalidation may be passed down from outside IOMMU subsystems.
> This patch adds invalidation functions that can be used for additional
> translation cache types.
>
> Signed-off-by: Jacob Pan 
> ---
>  drivers/iommu/dmar.c| 44 
>  include/linux/intel-iommu.h | 21 +++--
>  2 files changed, 63 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
> index 7852678..0b5b052 100644
> --- a/drivers/iommu/dmar.c
> +++ b/drivers/iommu/dmar.c
> @@ -1339,6 +1339,18 @@ void qi_flush_iotlb(struct intel_iommu *iommu, u16 
> did, u64 addr,
>   qi_submit_sync(, iommu);
>  }
>  
> +void qi_flush_eiotlb(struct intel_iommu *iommu, u16 did, u64 addr, u32 pasid,
> + unsigned int size_order, u64 granu, bool global)

Alignment should match open parenthesis.

> +{
> + struct qi_desc desc;
> +
> + desc.low = QI_EIOTLB_PASID(pasid) | QI_EIOTLB_DID(did) |
> + QI_EIOTLB_GRAN(granu) | QI_EIOTLB_TYPE;
> + desc.high = QI_EIOTLB_ADDR(addr) | QI_EIOTLB_GL(global) |
> + QI_EIOTLB_IH(0) | QI_EIOTLB_AM(size_order);
> + qi_submit_sync(, iommu);
> +}
> +
>  void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
>   u16 qdep, u64 addr, unsigned mask)
>  {
> @@ -1360,6 +1372,38 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 
> sid, u16 pfsid,
>   qi_submit_sync(, iommu);
>  }
>  
> +void qi_flush_dev_eiotlb(struct intel_iommu *iommu, u16 sid,
> + u32 pasid,  u16 qdep, u64 addr, unsigned size, u64 granu)

Ditto.

> +{
> + struct qi_desc desc;
> +
> + desc.low = QI_DEV_EIOTLB_PASID(pasid) | QI_DEV_EIOTLB_SID(sid) |
> + QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE;

Have you forgotten PFSID, or I missed anything here?

> + desc.high |= QI_DEV_EIOTLB_GLOB(granu);
> +
> + /* If S bit is 0, we only flush a single page. If S bit is set,
> +  * The least significant zero bit indicates the size. VT-d spec
> +  * 6.5.2.6
> +  */
> + if (!size)
> + desc.high = QI_DEV_EIOTLB_ADDR(addr) & ~QI_DEV_EIOTLB_SIZE;
> + else {
> + unsigned long mask = 1UL << (VTD_PAGE_SHIFT + size);
> +
> + desc.high = QI_DEV_EIOTLB_ADDR(addr & ~mask) | 
> QI_DEV_EIOTLB_SIZE;
> + }
> + qi_submit_sync(, iommu);
> +}
> +
> +void qi_flush_pasid(struct intel_iommu *iommu, u16 did, u64 granu, int pasid)
> +{
> + struct qi_desc desc;
> +
> + desc.high = 0;
> + desc.low = QI_PC_TYPE | QI_PC_DID(did) | QI_PC_GRAN(granu) | 
> QI_PC_PASID(pasid);
> +
> + qi_submit_sync(, iommu);
> +}
>  /*
>   * Disable Queued Invalidation interface.
>   */
> diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
> index 678a0f4..5ac0c28 100644
> --- a/include/linux/intel-iommu.h
> +++ b/include/linux/intel-iommu.h
> @@ -262,6 +262,10 @@ enum {
>  #define QI_PGRP_RESP_TYPE0x9
>  #define QI_PSTRM_RESP_TYPE   0xa
>  
> +#define QI_DID(did)  (((u64)did & 0x) << 16)
> +#define QI_DID_MASK  GENMASK(31, 16)
> +#define QI_TYPE_MASK GENMASK(3, 0)
> +
>  #define QI_IEC_SELECTIVE (((u64)1) << 4)
>  #define QI_IEC_IIDEX(idx)(((u64)(idx & 0x) << 32))
>  #define QI_IEC_IM(m) (((u64)(m & 0x1f) << 27))
> @@ -293,8 +297,9 @@ enum {
>  #define QI_PC_DID(did)   (((u64)did) << 16)
>  #define QI_PC_GRAN(gran) (((u64)gran) << 4)
>  
> -#define QI_PC_ALL_PASIDS (QI_PC_TYPE | QI_PC_GRAN(0))
> -#define QI_PC_PASID_SEL  (QI_PC_TYPE | QI_PC_GRAN(1))
> +/* PASID cache invalidation granu */
> +#define QI_PC_ALL_PASIDS 0
> +#define QI_PC_PASID_SEL  1
>  
>  #define QI_EIOTLB_ADDR(addr) ((u64)(addr) & VTD_PAGE_MASK)
>  #define QI_EIOTLB_GL(gl) (((u64)gl) << 7)
> @@ -304,6 +309,10 @@ enum {
>  #define QI_EIOTLB_DID(did)   (((u64)did) << 16)
>  #define QI_EIOTLB_GRAN(gran) (((u64)gran) << 4)
>  
> +/* QI Dev-IOTLB inv granu */
> +#define QI_DEV_IOTLB_GRAN_ALL1
> +#define QI_DEV_IOTLB_GRAN_PASID_SEL  0
> +
>  #define QI_DEV_EIOTLB_ADDR(a)((u64)(a) & VTD_PAGE_MASK)
>  #define QI_DEV_EIOTLB_SIZE   (((u64)1) << 11)
>  #define QI_DEV_EIOTLB_GLOB(g)((u64)g)
> @@ -332,6 +341,7 @@ enum {
>  #define QI_RESP_INVALID  0x1
>  #define QI_RESP_FAILURE  0xf
>  
> +/* QI EIOTLB inv granu */
>  #define QI_GRAN_ALL_ALL  0
>  #define QI_GRAN_NONG_ALL 1
>  #define QI_GRAN_NONG_PASID   2
> @@ -504,8 +514,15 @@ extern void qi_flush_context(struct intel_iommu *iommu, 
> u16 did, u16 sid,
>u8 fm, u64 type);
>  extern void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
> unsigned int size_order, u64 

[PATCH v5 08/23] iommu/vt-d: support flushing more translation cache types

2018-05-11 Thread Jacob Pan
When Shared Virtual Memory is exposed to a guest via vIOMMU, extended
IOTLB invalidation may be passed down from outside IOMMU subsystems.
This patch adds invalidation functions that can be used for additional
translation cache types.

Signed-off-by: Jacob Pan 
---
 drivers/iommu/dmar.c| 44 
 include/linux/intel-iommu.h | 21 +++--
 2 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 7852678..0b5b052 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -1339,6 +1339,18 @@ void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, 
u64 addr,
qi_submit_sync(, iommu);
 }
 
+void qi_flush_eiotlb(struct intel_iommu *iommu, u16 did, u64 addr, u32 pasid,
+   unsigned int size_order, u64 granu, bool global)
+{
+   struct qi_desc desc;
+
+   desc.low = QI_EIOTLB_PASID(pasid) | QI_EIOTLB_DID(did) |
+   QI_EIOTLB_GRAN(granu) | QI_EIOTLB_TYPE;
+   desc.high = QI_EIOTLB_ADDR(addr) | QI_EIOTLB_GL(global) |
+   QI_EIOTLB_IH(0) | QI_EIOTLB_AM(size_order);
+   qi_submit_sync(, iommu);
+}
+
 void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
u16 qdep, u64 addr, unsigned mask)
 {
@@ -1360,6 +1372,38 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 
sid, u16 pfsid,
qi_submit_sync(, iommu);
 }
 
+void qi_flush_dev_eiotlb(struct intel_iommu *iommu, u16 sid,
+   u32 pasid,  u16 qdep, u64 addr, unsigned size, u64 granu)
+{
+   struct qi_desc desc;
+
+   desc.low = QI_DEV_EIOTLB_PASID(pasid) | QI_DEV_EIOTLB_SID(sid) |
+   QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE;
+   desc.high |= QI_DEV_EIOTLB_GLOB(granu);
+
+   /* If S bit is 0, we only flush a single page. If S bit is set,
+* The least significant zero bit indicates the size. VT-d spec
+* 6.5.2.6
+*/
+   if (!size)
+   desc.high = QI_DEV_EIOTLB_ADDR(addr) & ~QI_DEV_EIOTLB_SIZE;
+   else {
+   unsigned long mask = 1UL << (VTD_PAGE_SHIFT + size);
+
+   desc.high = QI_DEV_EIOTLB_ADDR(addr & ~mask) | 
QI_DEV_EIOTLB_SIZE;
+   }
+   qi_submit_sync(, iommu);
+}
+
+void qi_flush_pasid(struct intel_iommu *iommu, u16 did, u64 granu, int pasid)
+{
+   struct qi_desc desc;
+
+   desc.high = 0;
+   desc.low = QI_PC_TYPE | QI_PC_DID(did) | QI_PC_GRAN(granu) | 
QI_PC_PASID(pasid);
+
+   qi_submit_sync(, iommu);
+}
 /*
  * Disable Queued Invalidation interface.
  */
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 678a0f4..5ac0c28 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -262,6 +262,10 @@ enum {
 #define QI_PGRP_RESP_TYPE  0x9
 #define QI_PSTRM_RESP_TYPE 0xa
 
+#define QI_DID(did)(((u64)did & 0x) << 16)
+#define QI_DID_MASKGENMASK(31, 16)
+#define QI_TYPE_MASK   GENMASK(3, 0)
+
 #define QI_IEC_SELECTIVE   (((u64)1) << 4)
 #define QI_IEC_IIDEX(idx)  (((u64)(idx & 0x) << 32))
 #define QI_IEC_IM(m)   (((u64)(m & 0x1f) << 27))
@@ -293,8 +297,9 @@ enum {
 #define QI_PC_DID(did) (((u64)did) << 16)
 #define QI_PC_GRAN(gran)   (((u64)gran) << 4)
 
-#define QI_PC_ALL_PASIDS   (QI_PC_TYPE | QI_PC_GRAN(0))
-#define QI_PC_PASID_SEL(QI_PC_TYPE | QI_PC_GRAN(1))
+/* PASID cache invalidation granu */
+#define QI_PC_ALL_PASIDS   0
+#define QI_PC_PASID_SEL1
 
 #define QI_EIOTLB_ADDR(addr)   ((u64)(addr) & VTD_PAGE_MASK)
 #define QI_EIOTLB_GL(gl)   (((u64)gl) << 7)
@@ -304,6 +309,10 @@ enum {
 #define QI_EIOTLB_DID(did) (((u64)did) << 16)
 #define QI_EIOTLB_GRAN(gran)   (((u64)gran) << 4)
 
+/* QI Dev-IOTLB inv granu */
+#define QI_DEV_IOTLB_GRAN_ALL  1
+#define QI_DEV_IOTLB_GRAN_PASID_SEL0
+
 #define QI_DEV_EIOTLB_ADDR(a)  ((u64)(a) & VTD_PAGE_MASK)
 #define QI_DEV_EIOTLB_SIZE (((u64)1) << 11)
 #define QI_DEV_EIOTLB_GLOB(g)  ((u64)g)
@@ -332,6 +341,7 @@ enum {
 #define QI_RESP_INVALID0x1
 #define QI_RESP_FAILURE0xf
 
+/* QI EIOTLB inv granu */
 #define QI_GRAN_ALL_ALL0
 #define QI_GRAN_NONG_ALL   1
 #define QI_GRAN_NONG_PASID 2
@@ -504,8 +514,15 @@ extern void qi_flush_context(struct intel_iommu *iommu, 
u16 did, u16 sid,
 u8 fm, u64 type);
 extern void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
  unsigned int size_order, u64 type);
+extern void qi_flush_eiotlb(struct intel_iommu *iommu, u16 did, u64 addr,
+   u32 pasid, unsigned int size_order, u64 type, bool 
global);
 extern void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
u16 qdep, u64 addr, unsigned mask);
+
+extern void