Re: [PATCH 4/6] iommu/qcom: Add support for AArch64 IOMMU pagetables

2022-06-02 Thread Rob Herring
On Fri, May 27, 2022 at 11:28:59PM +0200, Konrad Dybcio wrote:
> From: AngeloGioacchino Del Regno 
> 
> Some IOMMUs associated with some TZ firmwares may support switching
> to the AArch64 pagetable format by sending a "set pagetable format"
> scm command indicating the IOMMU secure ID and the context number
> to switch.
> 
> Add a DT property "qcom,use-aarch64-pagetables" for this driver to
> send this command to the secure world and to switch the pagetable
> format to benefit of the ARM64 IOMMU pagetables, where possible.
> 
> Note that, even though the command should be valid to switch each
> context, the property is made global because:
> 1. It doesn't make too much sense to switch only one or two
>context(s) to AA64 instead of just the entire thing
> 2. Some IOMMUs will go crazy and produce spectacular results when
>trying to mix up the pagetables on a per-context basis.
> 
> Signed-off-by: AngeloGioacchino Del Regno 
> 
> Signed-off-by: Marijn Suijten 
> Signed-off-by: Konrad Dybcio 
> ---
>  .../devicetree/bindings/iommu/qcom,iommu.txt  |  2 +

Bindings should be separate patch.

As you are making multiple changes, please convert this to DT schema 
first.

>  drivers/iommu/arm/arm-smmu/qcom_iommu.c   | 54 +++
>  2 files changed, 47 insertions(+), 9 deletions(-)
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 4/6] iommu/qcom: Add support for AArch64 IOMMU pagetables

2022-05-27 Thread kernel test robot
Hi Konrad,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on joro-iommu/next]
[also build test WARNING on v5.18 next-20220527]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/intel-lab-lkp/linux/commits/Konrad-Dybcio/iommu-qcom-Use-the-asid-read-from-device-tree-if-specified/20220528-062952
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
config: arc-allyesconfig 
(https://download.01.org/0day-ci/archive/20220528/202205280904.vsncfpph-...@intel.com/config)
compiler: arceb-elf-gcc (GCC) 11.3.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/0744f7d6ebfff8d6854a24d0f95f8e58885b5212
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Konrad-Dybcio/iommu-qcom-Use-the-asid-read-from-device-tree-if-specified/20220528-062952
git checkout 0744f7d6ebfff8d6854a24d0f95f8e58885b5212
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 
O=build_dir ARCH=arc SHELL=/bin/bash drivers/iommu/arm/arm-smmu/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   drivers/iommu/arm/arm-smmu/qcom_iommu.c: In function 
'qcom_iommu_tlb_inv_range_nosync':
>> drivers/iommu/arm/arm-smmu/qcom_iommu.c:174:58: warning: left shift count >= 
>> width of type [-Wshift-count-overflow]
 174 | iova |= (unsigned long)ctx->asid << 48;
 |  ^~


vim +174 drivers/iommu/arm/arm-smmu/qcom_iommu.c

   157  
   158  static void qcom_iommu_tlb_inv_range_nosync(unsigned long iova, size_t 
size,
   159  size_t granule, bool leaf, 
void *cookie)
   160  {
   161  struct qcom_iommu_domain *qcom_domain = cookie;
   162  struct iommu_fwspec *fwspec = qcom_domain->fwspec;
   163  unsigned i, reg;
   164  
   165  reg = leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA;
   166  
   167  for (i = 0; i < fwspec->num_ids; i++) {
   168  struct qcom_iommu_dev *qcom_iommu = qcom_domain->iommu;
   169  struct qcom_iommu_ctx *ctx = to_ctx(qcom_domain, 
fwspec->ids[i]);
   170  size_t s = size;
   171  
   172  if (qcom_iommu->use_aarch64_pt) {
   173  iova >>= 12;
 > 174  iova |= (unsigned long)ctx->asid << 48;
   175  } else {
   176  iova &= (1UL << 12) - 1UL;
   177  iova |= ctx->asid;
   178  }
   179  do {
   180  iommu_writel(ctx, reg, iova);
   181  iova += granule;
   182  } while (s -= granule);
   183  }
   184  }
   185  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 4/6] iommu/qcom: Add support for AArch64 IOMMU pagetables

2022-05-27 Thread Konrad Dybcio
From: AngeloGioacchino Del Regno 

Some IOMMUs associated with some TZ firmwares may support switching
to the AArch64 pagetable format by sending a "set pagetable format"
scm command indicating the IOMMU secure ID and the context number
to switch.

Add a DT property "qcom,use-aarch64-pagetables" for this driver to
send this command to the secure world and to switch the pagetable
format to benefit of the ARM64 IOMMU pagetables, where possible.

Note that, even though the command should be valid to switch each
context, the property is made global because:
1. It doesn't make too much sense to switch only one or two
   context(s) to AA64 instead of just the entire thing
2. Some IOMMUs will go crazy and produce spectacular results when
   trying to mix up the pagetables on a per-context basis.

Signed-off-by: AngeloGioacchino Del Regno 

Signed-off-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
 .../devicetree/bindings/iommu/qcom,iommu.txt  |  2 +
 drivers/iommu/arm/arm-smmu/qcom_iommu.c   | 54 +++
 2 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt 
b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt
index ba0b77889f02..72ae0595efff 100644
--- a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt
@@ -47,6 +47,8 @@ to non-secure vs secure interrupt line.
  secure lines.  (Ie. if the iommu contains secure
  context banks)
 - qcom,ctx-num : The number associated to the context bank
+- qcom,use-aarch64-pagetables : Switch to AArch64 pagetable format on all
+contexts declared in this IOMMU
 
 
 ** Examples:
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c 
b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 129e322f56a6..530aa92bf6a1 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -52,6 +52,7 @@ struct qcom_iommu_dev {
void __iomem*local_base;
u32  sec_id;
u8   num_ctxs;
+   bool use_aarch64_pt;
struct qcom_iommu_ctx   *ctxs[];   /* indexed by asid-1 */
 };
 
@@ -164,11 +165,17 @@ static void qcom_iommu_tlb_inv_range_nosync(unsigned long 
iova, size_t size,
reg = leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA;
 
for (i = 0; i < fwspec->num_ids; i++) {
+   struct qcom_iommu_dev *qcom_iommu = qcom_domain->iommu;
struct qcom_iommu_ctx *ctx = to_ctx(qcom_domain, 
fwspec->ids[i]);
size_t s = size;
 
-   iova = (iova >> 12) << 12;
-   iova |= ctx->asid;
+   if (qcom_iommu->use_aarch64_pt) {
+   iova >>= 12;
+   iova |= (unsigned long)ctx->asid << 48;
+   } else {
+   iova &= (1UL << 12) - 1UL;
+   iova |= ctx->asid;
+   }
do {
iommu_writel(ctx, reg, iova);
iova += granule;
@@ -248,6 +255,8 @@ static int qcom_iommu_init_domain(struct iommu_domain 
*domain,
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct io_pgtable_ops *pgtbl_ops;
struct io_pgtable_cfg pgtbl_cfg;
+   enum io_pgtable_fmt pgtbl_fmt;
+   unsigned long ias, oas;
int i, ret = 0;
u32 reg;
 
@@ -255,10 +264,19 @@ static int qcom_iommu_init_domain(struct iommu_domain 
*domain,
if (qcom_domain->iommu)
goto out_unlock;
 
+   if (qcom_iommu->use_aarch64_pt) {
+   pgtbl_fmt = ARM_64_LPAE_S1;
+   ias = oas = 48;
+   } else {
+   pgtbl_fmt = ARM_32_LPAE_S1;
+   ias = 32;
+   oas = 40;
+   }
+
pgtbl_cfg = (struct io_pgtable_cfg) {
.pgsize_bitmap  = qcom_iommu_ops.pgsize_bitmap,
-   .ias= 32,
-   .oas= 40,
+   .ias= ias,
+   .oas= oas,
.tlb= &qcom_flush_ops,
.iommu_dev  = qcom_iommu->dev,
};
@@ -266,7 +284,7 @@ static int qcom_iommu_init_domain(struct iommu_domain 
*domain,
qcom_domain->iommu = qcom_iommu;
qcom_domain->fwspec = fwspec;
 
-   pgtbl_ops = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &pgtbl_cfg, 
qcom_domain);
+   pgtbl_ops = alloc_io_pgtable_ops(pgtbl_fmt, &pgtbl_cfg, qcom_domain);
if (!pgtbl_ops) {
dev_err(qcom_iommu->dev, "failed to allocate pagetable ops\n");
ret = -ENOMEM;
@@ -280,6 +298,7 @@ static int qcom_iommu_init_domain(struct iommu_domain 
*domain,
 
for (i = 0; i < fwspec->num_ids; i++) {
struct qcom_iommu_ctx *ctx = to_ctx(qcom_domain, 
fwspec->ids[i]);
+   u32 tcr

[PATCH 4/6] iommu/qcom: Add support for AArch64 IOMMU pagetables

2019-09-26 Thread kholk11
From: AngeloGioacchino Del Regno 

Some IOMMUs associated with some TZ firmwares may support switching
to the AArch64 pagetable format by sending a "set pagetable format"
scm command indicating the IOMMU secure ID and the context number
to switch.

Add a DT property "qcom,use-aarch64-pagetables" for this driver to
send this command to the secure world and to switch the pagetable
format to benefit of the ARM64 IOMMU pagetables, where possible.

Note that, even though the command should be valid to switch each
context, the property is made global because:
1. It doesn't make too much sense to switch only one or two
   context(s) to AA64 instead of just the entire thing
2. Some IOMMUs will go crazy and produce spectacular results when
   trying to mix up the pagetables on a per-context basis.

Signed-off-by: AngeloGioacchino Del Regno 
---
 .../devicetree/bindings/iommu/qcom,iommu.txt  |  2 +
 drivers/iommu/qcom_iommu.c| 55 +++
 2 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt 
b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt
index 98102b323196..a4dd76b8c566 100644
--- a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt
@@ -39,6 +39,8 @@ to non-secure vs secure interrupt line.
   - reg: Base address and size of context bank within the iommu
   - interrupts : The context fault irq.
   - qcom,ctx-num   : The number associated to the context bank
+  - qcom,use-aarch64-pagetables : Switch to AArch64 pagetable format on all
+  contexts declared in this IOMMU
 
 ** Optional properties:
 
diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
index 2f31da2e7add..233ef496af27 100644
--- a/drivers/iommu/qcom_iommu.c
+++ b/drivers/iommu/qcom_iommu.c
@@ -48,6 +48,7 @@ struct qcom_iommu_dev {
void __iomem*local_base;
u32  sec_id;
u8   num_ctxs;
+   bool use_aarch64_pt;
struct qcom_iommu_ctx   *ctxs[0];   /* indexed by asid-1 */
 };
 
@@ -153,11 +154,17 @@ static void qcom_iommu_tlb_inv_range_nosync(unsigned long 
iova, size_t size,
reg = leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA;
 
for (i = 0; i < fwspec->num_ids; i++) {
+   struct qcom_iommu_dev *qcom_iommu = to_iommu(fwspec);
struct qcom_iommu_ctx *ctx = to_ctx(fwspec, fwspec->ids[i]);
size_t s = size;
 
-   iova &= ~12UL;
-   iova |= ctx->asid;
+   if (qcom_iommu->use_aarch64_pt) {
+   iova >>= 12;
+   iova |= (u64)ctx->asid << 48;
+   } else {
+   iova &= ~12UL;
+   iova |= ctx->asid;
+   }
do {
iommu_writel(ctx, reg, iova);
iova += granule;
@@ -222,6 +229,8 @@ static int qcom_iommu_init_domain(struct iommu_domain 
*domain,
struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
struct io_pgtable_ops *pgtbl_ops;
struct io_pgtable_cfg pgtbl_cfg;
+   enum io_pgtable_fmt pgtbl_fmt;
+   unsigned long ias, oas;
int i, ret = 0;
u32 reg;
 
@@ -229,16 +238,25 @@ static int qcom_iommu_init_domain(struct iommu_domain 
*domain,
if (qcom_domain->iommu)
goto out_unlock;
 
+   if (qcom_iommu->use_aarch64_pt) {
+   pgtbl_fmt = ARM_64_LPAE_S1;
+   ias = oas = 48;
+   } else {
+   pgtbl_fmt = ARM_32_LPAE_S1;
+   ias = 32;
+   oas = 40;
+   }
+
pgtbl_cfg = (struct io_pgtable_cfg) {
.pgsize_bitmap  = qcom_iommu_ops.pgsize_bitmap,
-   .ias= 32,
-   .oas= 40,
+   .ias= ias,
+   .oas= oas,
.tlb= &qcom_gather_ops,
.iommu_dev  = qcom_iommu->dev,
};
 
qcom_domain->iommu = qcom_iommu;
-   pgtbl_ops = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &pgtbl_cfg, fwspec);
+   pgtbl_ops = alloc_io_pgtable_ops(pgtbl_fmt, &pgtbl_cfg, fwspec);
if (!pgtbl_ops) {
dev_err(qcom_iommu->dev, "failed to allocate pagetable ops\n");
ret = -ENOMEM;
@@ -252,6 +270,7 @@ static int qcom_iommu_init_domain(struct iommu_domain 
*domain,
 
for (i = 0; i < fwspec->num_ids; i++) {
struct qcom_iommu_ctx *ctx = to_ctx(fwspec, fwspec->ids[i]);
+   u32 tcr[2];
 
if (!ctx->secure_init) {
ret = qcom_scm_restore_sec_cfg(qcom_iommu->sec_id, 
ctx->asid);
@@ -264,12 +283,25 @@ static int qcom_iommu_init_domain(struct iommu_domain 
*domain,
 
qcom_iommu_