[PATCH 1/1] iommu/arm-smmu: Add support for qcom,smmu-500 variant

2018-03-06 Thread Vivek Gautam
Qualcomm's arm-smmu 500 implementation supports runtime pm
so enable the same.

Signed-off-by: Vivek Gautam 
---

 Based on iommu/arm-smmu pm runtime support series [1]:
 [PATCH v8 0/5] iommu/arm-smmu: Add runtime pm/sleep support
 
 Tested on sdm845 with necessary support to enable the smmu
 and with necessary user.

 [1] https://lkml.org/lkml/2018/3/2/325

 Documentation/devicetree/bindings/iommu/arm,smmu.txt | 14 ++
 drivers/iommu/arm-smmu.c |  8 
 2 files changed, 22 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 6ea27bd4f785..0b5c6d2a9865 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -18,6 +18,7 @@ conditions.
 "arm,mmu-500"
 "cavium,smmu-v2"
 "qcom,-smmu-v2", "qcom,smmu-v2"
+"qcom,-smmu-500", "qcom,smmu-500"
 
   depending on the particular implementation and/or the
   version of the architecture implemented.
@@ -30,6 +31,10 @@ conditions.
   An example string would be -
   "qcom,msm8996-smmu-v2", "qcom,smmu-v2".
 
+  "qcom,smmu-500" is arm,mmu-500 implementation that supports
+  efficient power management by supporting smmu's state
+  retention.
+
 - reg   : Base address and size of the SMMU.
 
 - #global-interrupts : The number of global interrupts exposed by the
@@ -179,3 +184,12 @@ conditions.
 <&mmcc SMMU_MDP_AHB_CLK>;
clock-names = "bus", "iface";
};
+
+   smmu5: iommu {
+   compatible = "qcom,sdm845-smmu-500", "qcom,smmu-500";
+   reg = <0x1500 0x8>;
+   #iommu-cells = <2>;
+   #global-interrupts = <1>;
+
+   ...
+   };
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 7a96c924ae22..7f52456c6b25 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2008,6 +2008,12 @@ static const char * const qcom_smmuv2_clks[] = {
"bus", "iface",
 };
 
+static const struct arm_smmu_match_data qcom_smmu500 = {
+   .version = ARM_SMMU_V2,
+   .model = ARM_MMU500,
+   .rpm_supported = true,
+};
+
 static const struct arm_smmu_match_data qcom_smmuv2 = {
.version = ARM_SMMU_V2,
.model = QCOM_SMMUV2,
@@ -2024,6 +2030,7 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,mmu-500", .data = &arm_mmu500 },
{ .compatible = "cavium,smmu-v2", .data = &cavium_smmuv2 },
{ .compatible = "qcom,smmu-v2", .data = &qcom_smmuv2 },
+   { .compatible = "qcom,smmu-500", .data = &qcom_smmu500 },
{ },
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
@@ -2394,6 +2401,7 @@ IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401");
 IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500");
 IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2");
 IOMMU_OF_DECLARE(qcom_smmuv2, "qcom,smmu-v2");
+IOMMU_OF_DECLARE(qcom_smmu500, "qcom,smmu-500");
 
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
 MODULE_AUTHOR("Will Deacon ");
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH v7 13/14] iommu/rockchip: Add runtime PM support

2018-03-06 Thread Tomasz Figa
On Tue, Mar 6, 2018 at 7:07 PM, Tomasz Figa  wrote:
> Hi Jeffy,
>
> It looks like I missed some details of how runtime PM enable works
> before, so we might be able to simplify things. Sorry for not getting
> things right earlier.
>
> On Tue, Mar 6, 2018 at 12:27 PM, Jeffy Chen  wrote:
>> When the power domain is powered off, the IOMMU cannot be accessed and
>> register programming must be deferred until the power domain becomes
>> enabled.
>>
>> Add runtime PM support, and use runtime PM device link from IOMMU to
>> master to startup and shutdown IOMMU.
>>
>> Signed-off-by: Jeffy Chen 
>> ---
>>
>> Changes in v7:
>> Add WARN_ON in irq isr, and modify iommu archdata comment.
>>
>> Changes in v6: None
>> Changes in v5:
>> Avoid race about pm_runtime_get_if_in_use() and pm_runtime_enabled().
>>
>> Changes in v4: None
>> Changes in v3:
>> Only call startup() and shutdown() when iommu attached.
>> Remove pm_mutex.
>> Check runtime PM disabled.
>> Check pm_runtime in rk_iommu_irq().
>>
>> Changes in v2: None
>>
>>  drivers/iommu/rockchip-iommu.c | 189 
>> -
>>  1 file changed, 148 insertions(+), 41 deletions(-)
>>
>> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
>> index 2448a0528e39..db08978203f7 100644
>> --- a/drivers/iommu/rockchip-iommu.c
>> +++ b/drivers/iommu/rockchip-iommu.c
>> @@ -22,6 +22,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>
>> @@ -105,7 +106,14 @@ struct rk_iommu {
>> struct iommu_domain *domain; /* domain to which iommu is attached */
>>  };
>>
>> +/**
>> + * struct rk_iommudata - iommu archdata of master device.
>> + * @link:  device link with runtime PM integration from the master
>> + * (consumer) to the IOMMU (supplier).
>> + * @iommu: IOMMU of the master device.
>> + */
>>  struct rk_iommudata {
>> +   struct device_link *link;
>> struct rk_iommu *iommu;
>>  };
>>
>> @@ -518,7 +526,13 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
>> u32 int_status;
>> dma_addr_t iova;
>> irqreturn_t ret = IRQ_NONE;
>> -   int i;
>> +   bool need_runtime_put;
>> +   int i, err;
>> +
>> +   err = pm_runtime_get_if_in_use(iommu->dev);
>> +   if (WARN_ON(err <= 0 && err != -EINVAL))
>> +   return ret;
>> +   need_runtime_put = err > 0;
>
> Actually, for our purposes, we can assume that runtime PM enable
> status can be only changed by the driver itself. Looking at the LXR,
> PM core also calls __pm_runtime_disable() before calling
> .suspend_late() callback and pm_runtime_enable() after calling
> .resume_early() callback, but we should be able to ignore this,
> because we handle things in .suspend() callback in this driver.
>
> With this assumption in mind, all we need to do here is:
>
> if (WARN_ON(!pm_runtime_get_if_in_use(iommu->dev)))
> return 0;
>
>>
>> WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
>>
>> @@ -570,6 +584,9 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
>>
>> clk_bulk_disable(iommu->num_clocks, iommu->clocks);
>>
>> +   if (need_runtime_put)
>> +   pm_runtime_put(iommu->dev);
>
> if (pm_runtime_enabled())
> pm_runtime_put(iommu->dev);

Actually, we don't even need this pm_runtime_enabled() check and can
always call pm_runtime_put(), because at this point we would be only
in either of cases:
1) runtime PM compiled in and enabled, so we got the enable count and
need to put it,
2) runtime PM not compiled in, so pm_runtime_put() is a no-op.

>
>> +
>> return ret;
>>  }
>>
>> @@ -611,10 +628,20 @@ static void rk_iommu_zap_iova(struct rk_iommu_domain 
>> *rk_domain,
>> spin_lock_irqsave(&rk_domain->iommus_lock, flags);
>> list_for_each(pos, &rk_domain->iommus) {
>> struct rk_iommu *iommu;
>> +   int ret;
>> +
>> iommu = list_entry(pos, struct rk_iommu, node);
>> -   WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
>> -   rk_iommu_zap_lines(iommu, iova, size);
>> -   clk_bulk_disable(iommu->num_clocks, iommu->clocks);
>> +
>> +   /* Only zap TLBs of IOMMUs that are powered on. */
>> +   ret = pm_runtime_get_if_in_use(iommu->dev);
>> +   if (ret > 0 || ret == -EINVAL) {
>
> if (pm_runtime_get_if_in_use(iommu->dev)) {
>
>> +   WARN_ON(clk_bulk_enable(iommu->num_clocks,
>> +   iommu->clocks));
>> +   rk_iommu_zap_lines(iommu, iova, size);
>> +   clk_bulk_disable(iommu->num_clocks, iommu->clocks);
>
> if (pm_runtime_enabled(iommu->dev))
> pm_runtime_put(iommu->dev);

Same here.

Best regards,
Tomasz
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/m

Re: [PATCH v7 13/14] iommu/rockchip: Add runtime PM support

2018-03-06 Thread JeffyChen

Hi Tomasz,

Thanks for your reply.

On 03/06/2018 06:07 PM, Tomasz Figa wrote:

Hi Jeffy,

It looks like I missed some details of how runtime PM enable works
before, so we might be able to simplify things. Sorry for not getting
things right earlier


hmm, right, the enable state should be the same during those functions. 
will do it in the next version.

.


On Tue, Mar 6, 2018 at 12:27 PM, Jeffy Chen  wrote:

When the power domain is powered off, the IOMMU cannot be accessed and
register programming must be deferred until the power domain becomes
enabled.

Add runtime PM support, and use runtime PM device link from IOMMU to
master to startup and shutdown IOMMU.

Signed-off-by: Jeffy Chen 
---

Changes in v7:
Add WARN_ON in irq isr, and modify iommu archdata comment.

Changes in v6: None
Changes in v5:
Avoid race about pm_runtime_get_if_in_use() and pm_runtime_enabled().

Changes in v4: None
Changes in v3:
Only call startup() and shutdown() when iommu attached.
Remove pm_mutex.
Check runtime PM disabled.
Check pm_runtime in rk_iommu_irq().

Changes in v2: None

  drivers/iommu/rockchip-iommu.c | 189 -
  1 file changed, 148 insertions(+), 41 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 2448a0528e39..db08978203f7 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -22,6 +22,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 

@@ -105,7 +106,14 @@ struct rk_iommu {
 struct iommu_domain *domain; /* domain to which iommu is attached */
  };

+/**
+ * struct rk_iommudata - iommu archdata of master device.
+ * @link:  device link with runtime PM integration from the master
+ * (consumer) to the IOMMU (supplier).
+ * @iommu: IOMMU of the master device.
+ */
  struct rk_iommudata {
+   struct device_link *link;
 struct rk_iommu *iommu;
  };

@@ -518,7 +526,13 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
 u32 int_status;
 dma_addr_t iova;
 irqreturn_t ret = IRQ_NONE;
-   int i;
+   bool need_runtime_put;
+   int i, err;
+
+   err = pm_runtime_get_if_in_use(iommu->dev);
+   if (WARN_ON(err <= 0 && err != -EINVAL))
+   return ret;
+   need_runtime_put = err > 0;


Actually, for our purposes, we can assume that runtime PM enable
status can be only changed by the driver itself. Looking at the LXR,
PM core also calls __pm_runtime_disable() before calling
.suspend_late() callback and pm_runtime_enable() after calling
.resume_early() callback, but we should be able to ignore this,
because we handle things in .suspend() callback in this driver.

With this assumption in mind, all we need to do here is:

if (WARN_ON(!pm_runtime_get_if_in_use(iommu->dev)))
 return 0;



 WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));

@@ -570,6 +584,9 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)

 clk_bulk_disable(iommu->num_clocks, iommu->clocks);

+   if (need_runtime_put)
+   pm_runtime_put(iommu->dev);


if (pm_runtime_enabled())
 pm_runtime_put(iommu->dev);


+
 return ret;
  }

@@ -611,10 +628,20 @@ static void rk_iommu_zap_iova(struct rk_iommu_domain 
*rk_domain,
 spin_lock_irqsave(&rk_domain->iommus_lock, flags);
 list_for_each(pos, &rk_domain->iommus) {
 struct rk_iommu *iommu;
+   int ret;
+
 iommu = list_entry(pos, struct rk_iommu, node);
-   WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
-   rk_iommu_zap_lines(iommu, iova, size);
-   clk_bulk_disable(iommu->num_clocks, iommu->clocks);
+
+   /* Only zap TLBs of IOMMUs that are powered on. */
+   ret = pm_runtime_get_if_in_use(iommu->dev);
+   if (ret > 0 || ret == -EINVAL) {


if (pm_runtime_get_if_in_use(iommu->dev)) {


+   WARN_ON(clk_bulk_enable(iommu->num_clocks,
+   iommu->clocks));
+   rk_iommu_zap_lines(iommu, iova, size);
+   clk_bulk_disable(iommu->num_clocks, iommu->clocks);


 if (pm_runtime_enabled(iommu->dev))
 pm_runtime_put(iommu->dev);

And so on, in other places.

Really sorry for the confusion before.

Best regards,
Tomasz






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


[PATCH] iommu/vt-d: fix usage of force parameter in intel_ir_reconfigure_irte()

2018-03-06 Thread Jagannathan Raman
It was noticed that the IRTE configured for guest OS kernel
was over-written while the guest was running. As a result,
vt-d Posted Interrupts configured for the guest are not being
delivered directly, and instead bounces off the host. Every
interrupt delivery takes a VM Exit.

It was noticed that the following stack is doing the over-write:
[  147.463177]  modify_irte+0x171/0x1f0
[  147.463405]  intel_ir_set_affinity+0x5c/0x80
[  147.463641]  msi_domain_set_affinity+0x32/0x90
[  147.463881]  irq_do_set_affinity+0x37/0xd0
[  147.464125]  irq_set_affinity_locked+0x9d/0xb0
[  147.464374]  __irq_set_affinity+0x42/0x70
[  147.464627]  write_irq_affinity.isra.5+0xe1/0x110
[  147.464895]  proc_reg_write+0x38/0x70
[  147.465150]  __vfs_write+0x36/0x180
[  147.465408]  ? handle_mm_fault+0xdf/0x200
[  147.465671]  ? _cond_resched+0x15/0x30
[  147.465936]  vfs_write+0xad/0x1a0
[  147.466204]  SyS_write+0x52/0xc0
[  147.466472]  do_syscall_64+0x74/0x1a0
[  147.466744]  entry_SYSCALL_64_after_hwframe+0x3d/0xa2

reversing the sense of force check in intel_ir_reconfigure_irte()
restores proper posted interrupt functionality

Signed-off-by: Jagannathan Raman 
---
 Hi Thomas,

 I noticed that you added intel_ir_reconfigure_irte() with the
 following commit:
 d491bdff888e ("iommu/vt-d: Reevaluate vector configuration on
 activate()")

 Could you please confirm the usage of "force" parameter in
 intel_ir_reconfigure_irte()?

 drivers/iommu/intel_irq_remapping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/intel_irq_remapping.c 
b/drivers/iommu/intel_irq_remapping.c
index 66f69af..3062a15 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -1136,7 +1136,7 @@ static void intel_ir_reconfigure_irte(struct irq_data 
*irqd, bool force)
irte->dest_id = IRTE_DEST(cfg->dest_apicid);
 
/* Update the hardware only if the interrupt is in remapped mode. */
-   if (!force || ir_data->irq_2_iommu.mode == IRQ_REMAPPING)
+   if (force || ir_data->irq_2_iommu.mode == IRQ_REMAPPING)
modify_irte(&ir_data->irq_2_iommu, irte);
 }
 
-- 
1.8.3.1

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


RE: [PATCH 1/3] dt-bindings: iommu: ipmmu-vmsa: Add device tree support for r8a774[35]

2018-03-06 Thread Fabrizio Castro
Dear All,

I am very sorry to bother you, do you know who is supposed to take this patch?

Thanks,
Fab

> -Original Message-
> From: Biju Das [mailto:biju@bp.renesas.com]
> Sent: 24 January 2018 15:42
> To: Joerg Roedel ; Laurent Pinchart 
> ; Geert Uytterhoeven
> 
> Cc: Simon Horman ; Magnus Damm ; 
> Chris Paterson
> ; Fabrizio Castro 
> ; iommu@lists.linux-foundation.org; linux-
> renesas-...@vger.kernel.org; Biju Das 
> Subject: [PATCH 1/3] dt-bindings: iommu: ipmmu-vmsa: Add device tree support 
> for r8a774[35]
>
> Document r8a774[35] specific compatible strings. The Renesas RZ/G1[ME]
> (r8a774[35]) IPMMU are identical to the R-Car Gen2 family.
>
> Signed-off-by: Biju Das 
> Reviewed-by: Chris Paterson 
> ---
>  Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
> b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
> index 857df92..7d300af 100644
> --- a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
> +++ b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
> @@ -11,12 +11,15 @@ Required Properties:
>  the device is compatible with the R-Car Gen2 VMSA-compatible IPMMU.
>
>  - "renesas,ipmmu-r8a73a4" for the R8A73A4 (R-Mobile APE6) IPMMU.
> +- "renesas,ipmmu-r8a7743" for the R8A7743 (RZ/G1M) IPMMU.
> +- "renesas,ipmmu-r8a7745" for the R8A7745 (RZ/G1E) IPMMU.
>  - "renesas,ipmmu-r8a7790" for the R8A7790 (R-Car H2) IPMMU.
>  - "renesas,ipmmu-r8a7791" for the R8A7791 (R-Car M2-W) IPMMU.
>  - "renesas,ipmmu-r8a7793" for the R8A7793 (R-Car M2-N) IPMMU.
>  - "renesas,ipmmu-r8a7794" for the R8A7794 (R-Car E2) IPMMU.
>  - "renesas,ipmmu-r8a7795" for the R8A7795 (R-Car H3) IPMMU.
> -- "renesas,ipmmu-vmsa" for generic R-Car Gen2 VMSA-compatible IPMMU.
> +- "renesas,ipmmu-vmsa" for generic R-Car Gen2 or RZ/G1 VMSA-compatible
> +   IPMMU.
>
>- reg: Base address and size of the IPMMU registers.
>- interrupts: Specifiers for the MMU fault interrupts. For instances that
> --
> 2.7.4




Renesas Electronics Europe Ltd, Dukes Meadow, Millboard Road, Bourne End, 
Buckinghamshire, SL8 5FH, UK. Registered in England & Wales under Registered 
No. 04586709.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 2/4] iommu/io-pgtable-arm: Support 52-bit physical address

2018-03-06 Thread Will Deacon
Hey Robin,

On Tue, Feb 27, 2018 at 01:49:14PM +, Robin Murphy wrote:
> On 26/02/18 18:05, Will Deacon wrote:
> >On Thu, Dec 14, 2017 at 04:58:51PM +, Robin Murphy wrote:
> >>Bring io-pgtable-arm in line with the ARMv8.2-LPA feature allowing
> >>52-bit physical addresses when using the 64KB translation granule.
> >>This will be supported by SMMUv3.1.
> >>
> >>Tested-by: Nate Watterson 
> >>Signed-off-by: Robin Murphy 
> >>---
> >>
> >>v2: Fix TCR_PS/TCR_IPS copy-paste error
> >>
> >>  drivers/iommu/io-pgtable-arm.c | 65 
> >> ++
> >>  1 file changed, 47 insertions(+), 18 deletions(-)
> >
> >[...]
> >
> >>@@ -203,6 +199,25 @@ struct arm_lpae_io_pgtable {
> >>  typedef u64 arm_lpae_iopte;
> >>+static arm_lpae_iopte paddr_to_iopte(phys_addr_t paddr,
> >>+struct arm_lpae_io_pgtable *data)
> >>+{
> >>+   arm_lpae_iopte pte = paddr;
> >>+
> >>+   /* Of the bits which overlap, either 51:48 or 15:12 are always RES0 */
> >>+   return (pte | (pte >> 36)) & ARM_LPAE_PTE_ADDR_MASK;
> >>+}
> >
> >I don't particularly like relying on properties of the paddr for correct
> >construction of the pte here. The existing macro doesn't have this
> >limitation. I suspect it's all fine at the moment because we only use TTBR0,
> >but I'd rather not bake that in if we can avoid it.
> 
> What's the relevance of TTBR0 to physical addresses? :/

Good point! I clearly got confused here.

> Note that by this point paddr has been validated against cfg->oas by
> arm_lpae_map(), and validated to be granule-aligned by iommu_map(), so it
> really can't be wrong under reasonable conditions.

Fair enough, but I still think this would be a bit more readable written
along the lines of:

arm_lpae_iopte pte_hi, pte_lo = 0;

pte_hi = paddr & GENMASK(47, data->pg_shift);
if (data->pg_shift == 16) {
pte_lo = paddr & GENMASK(ARM_LPAE_MAX_ADDR_BITS - 1, 48);
pte_lo >>= (48 - 12);
}

return pte_hi | pte_lo;

Ok, we don't squeeze every last cycle out of it, but I find it much more
readable. Is it just me? The magic numbers could be #defined and/or
derived if necessary.

> >>+static phys_addr_t iopte_to_paddr(arm_lpae_iopte pte,
> >>+ struct arm_lpae_io_pgtable *data)
> >>+{
> >>+   phys_addr_t paddr = pte & ARM_LPAE_PTE_ADDR_MASK;
> >>+   phys_addr_t paddr_hi = paddr & (ARM_LPAE_GRANULE(data) - 1);
> >>+
> >>+   /* paddr_hi spans nothing for 4K granule, and only RES0 bits for 16K */
> >>+   return (paddr ^ paddr_hi) | (paddr_hi << 36);
> >
> >Why do we need xor here?
> 
> Because "(paddr ^ paddr_hi)" is more concise than "(paddr &
> ~(phys_addr_t)(ARM_LPAE_GRANULE(data) - 1)" or variants thereof. It's
> potentially a teeny bit more efficient too, I think, but it's mostly about
> the readability.

I don't think the bit-twiddling is super readable, to be honest. Again,
something like:

phys_addr_t paddr_lo, paddr_hi = 0;

paddr_lo = pte & GENMASK(47, data->pg_shift);
if (data->pg_shift == 16) {
paddr_hi = pte & GENMASK(15, 12);
paddr_hi <<= (48 - 12);
}

return paddr_hi | paddr_lo;

but I've not even compiled this stuff...

> >>+   cfg->pgsize_bitmap &= page_sizes;
> >>+   cfg->ias = min(cfg->ias, max_addr_bits);
> >>+   cfg->oas = min(cfg->oas, max_addr_bits);
> >
> >I don't think we should be writing to the ias/oas fields here, at least
> >now without auditing the drivers and updating the comments about the
> >io-pgtable API. For example, the SMMUv3 driver uses its own ias local
> >variable to initialise the domain geometry, and won't pick up any changes
> >made here.
> 
> As you've discovered, the driver thing is indeed true. More generally,
> though, we've always adjusted cfg->pgsize_bitmap here, so I don't see why
> other fields should be treated differently - I've always assumed the cfg
> which the driver passes in here just represents its total maximum
> capabilities, from which it's io-pgtable's job to pick an appropriate
> configuration.

Can you update the the header file with a comment to that effect, please?

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


Re: [PATCH 1/3] dt-bindings: iommu: ipmmu-vmsa: Add device tree support for r8a774[35]

2018-03-06 Thread Geert Uytterhoeven
Hi Fabrizio,

On Tue, Mar 6, 2018 at 5:55 PM, Fabrizio Castro
 wrote:
> I am very sorry to bother you, do you know who is supposed to take this patch?

Jörg is the IOMMU maintainer, so I assume he's the one.

>> -Original Message-
>> From: Biju Das [mailto:biju@bp.renesas.com]
>> Sent: 24 January 2018 15:42
>> To: Joerg Roedel ; Laurent Pinchart 
>> ; Geert Uytterhoeven
>> 
>> Cc: Simon Horman ; Magnus Damm ; 
>> Chris Paterson
>> ; Fabrizio Castro 
>> ; iommu@lists.linux-foundation.org; linux-
>> renesas-...@vger.kernel.org; Biju Das 
>> Subject: [PATCH 1/3] dt-bindings: iommu: ipmmu-vmsa: Add device tree support 
>> for r8a774[35]
>>
>> Document r8a774[35] specific compatible strings. The Renesas RZ/G1[ME]
>> (r8a774[35]) IPMMU are identical to the R-Car Gen2 family.
>>
>> Signed-off-by: Biju Das 
>> Reviewed-by: Chris Paterson 
>> ---
>>  Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt | 5 -
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
>> b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
>> index 857df92..7d300af 100644
>> --- a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
>> +++ b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
>> @@ -11,12 +11,15 @@ Required Properties:
>>  the device is compatible with the R-Car Gen2 VMSA-compatible IPMMU.
>>
>>  - "renesas,ipmmu-r8a73a4" for the R8A73A4 (R-Mobile APE6) IPMMU.
>> +- "renesas,ipmmu-r8a7743" for the R8A7743 (RZ/G1M) IPMMU.
>> +- "renesas,ipmmu-r8a7745" for the R8A7745 (RZ/G1E) IPMMU.
>>  - "renesas,ipmmu-r8a7790" for the R8A7790 (R-Car H2) IPMMU.
>>  - "renesas,ipmmu-r8a7791" for the R8A7791 (R-Car M2-W) IPMMU.
>>  - "renesas,ipmmu-r8a7793" for the R8A7793 (R-Car M2-N) IPMMU.
>>  - "renesas,ipmmu-r8a7794" for the R8A7794 (R-Car E2) IPMMU.
>>  - "renesas,ipmmu-r8a7795" for the R8A7795 (R-Car H3) IPMMU.
>> -- "renesas,ipmmu-vmsa" for generic R-Car Gen2 VMSA-compatible IPMMU.
>> +- "renesas,ipmmu-vmsa" for generic R-Car Gen2 or RZ/G1 VMSA-compatible
>> +   IPMMU.
>>
>>- reg: Base address and size of the IPMMU registers.
>>- interrupts: Specifiers for the MMU fault interrupts. For instances that
>> --
>> 2.7.4

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH v2 1/4] iommu/arm-smmu-v3: Clean up address masking

2018-03-06 Thread Will Deacon
Hi Robin,

On Tue, Feb 27, 2018 at 01:28:31PM +, Robin Murphy wrote:
> On 26/02/18 18:04, Will Deacon wrote:
> >On Thu, Dec 14, 2017 at 04:58:50PM +, Robin Murphy wrote:
> >>Before trying to add the SMMUv3.1 support for 52-bit addresses, make
> >>things bearable by cleaning up the various address mask definitions to
> >>use GENMASK_ULL() consistently. The fact that doing so reveals (and
> >>fixes) a latent off-by-one in Q_BASE_ADDR_MASK only goes to show what a
> >>jolly good idea it is...
> >>
> >>Tested-by: Nate Watterson 
> >>Signed-off-by: Robin Murphy 
> >>---
> >>
> >>v2: Clean up one more now-unnecessary linewrap
> >>
> >>  drivers/iommu/arm-smmu-v3.c | 53 
> >> ++---
> >>  1 file changed, 21 insertions(+), 32 deletions(-)
> >
> >Whilst I agree that using GENMASK is better, this patch does mean that the
> >driver is (more) inconsistent with its _MASK terminology in that you can't
> >generally tell whether a definition that ends in _MASK is shifted or not,
> >and this isn't even consistent for fields within the same register.
> 
> The apparently slightly-less-than-obvious internal consistency is that every
> mask used for an *address field* is now in-place, while other types of field
> are still handled as inconsistently as they were before. It should also be
> the case that every x_MASK without a corresponding x_SHIFT defined next to
> it is unshifted.
> 
> Either way it's certainly no *worse* than the current situation where
> address masks sometimes have a nonzero shift, sometimes have zero bits at
> the bottom and a shift of 0, and sometimes have no shift defined at all.
> 
> Thinking about it some more, the address masks should only ever be needed
> when *extracting* an address from a register/structure word, or validating
> them in the context of an address *before* inserting into a field - if we
> can't trust input to be correct then just silently masking off bits probably
> isn't the best idea either way - so IMHO there is plenty of contextual
> disambiguation too.
> 
> >Should we be using GENMASK/BIT for all fields instead and removing all of
> >the _SHIFT definitions?
> 
> I'm all aboard using BIT() consistently for single-bit boolean fields, but
> for multi-bit fields in general we do have to keep an explicit shift defined
> *somewhere* in order to make sensible use of the value, i.e. either:
> 
>   val = (reg >> 22) & 0x1f;
>   reg = (val & 0x1f) << 22;
> 
> or:
>   val = (reg & 0x07c0) >> 22;
>   reg = (val << 22) & 0x07c0;
> 
> [ but ideally not this mess we currently have in some places:
> 
>   val = (reg & 0x1f << 22) >> 22;
> ]
> 
> Again, I'd gladly clean everything up to at least be self-consistent (and
> line up more with how we did things in SMMUv2) if you think it's worthwhile.
> Although I guess that means I'd get the job of fixing up future stable
> backport conflicts too ;)

I reckon it would be worth the cleanup since you're in the area. I don't
mind keeping the SHITF definitions where they're needed, but using BIT and
GENMASK wherever we can.

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


Re: [PATCH 07/37] iommu: Add a page fault handler

2018-03-06 Thread okaya

On 2018-03-06 05:46, Jean-Philippe Brucker wrote:

On 05/03/18 21:53, Sinan Kaya wrote:

On 2/12/2018 1:33 PM, Jean-Philippe Brucker wrote:

+static struct workqueue_struct *iommu_fault_queue;


Is there anyway we can make this fault queue per struct device?
Since this is common code, I think it needs some care.


I don't think it's better, the workqueue struct seems large. Maybe 
having

one wq per IOMMU is a good compromise?


Yes, one per iommu sounds reasonable.


As said in my other reply for this
patch, doing so isn't completely straightforward. I'll consider adding 
an

iommu pointer to the iommu_param struct attached to each device.

Thanks,
Jean
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" 
in

the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


Re: [RFC 3/5] dt-bindings: arm-smmu: Add reserved-msi-region

2018-03-06 Thread Robin Murphy

On 06/03/18 04:59, Jitendra Bhivare wrote:

iPROC SoC has a special device window to treat GICv3 ITS MSI.


Ugh, really? After preferably printing out 100 copies of the SBSA, 
binding them all together and dropping the lot onto the hardware 
designers from a great height, could you clarify what exactly the 
special behaviour is here?


Robin.


Current code maps MSI to IOVA space. Add SMMU node property to use
direct mappings for MSI region.

This property is read and reserved when arm_smmu_get_resv_regions
gets called.

Signed-off-by: Jitendra Bhivare 
---
  Documentation/devicetree/bindings/iommu/arm,smmu.txt | 12 
  1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce..13fa2b9 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -71,6 +71,15 @@ conditions.
or using stream matching with #iommu-cells = <2>, and
may be ignored if present in such cases.
  
+- reserved-msi-region: MSI region to be reserved with specific prot in IOVA

+ space for direct mapping. The region is specified in tuple
+ of (busno,prot,bus_addr,size).
+
+- #region-address-cells: specifies number of cells needed to encode bus_addr
+
+- #region-size-cells: specifies number of cells needed to encode size
+
+
  ** Deprecated properties:
  
  - mmu-masters (deprecated in favour of the generic "iommus" binding) :

@@ -95,6 +104,9 @@ conditions.
   <0 36 4>,
   <0 37 4>;
  #iommu-cells = <1>;
+   #region-address-cells = <1>;
+   #region-size-cells = <1>;
+   reserved-msi-region = <0x0 0x1a 0x63c3000 0x8000>;
  };
  
  /* device with two stream IDs, 0 and 7 */



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


Re: [RFC 2/5] dt-bindings: brcm: Add reserved-dma-region for iPROC

2018-03-06 Thread Robin Murphy

On 06/03/18 04:59, Jitendra Bhivare wrote:

With SoC wide DMA mask of 40-bit, the mappings for entire IOVA space can't
be specified in the PAXBv2 PCIe RC of SoC. The holes in IOVA space needs to
be reserved to prevent any IOVA allocations in those spaces.


Can you clarify why? If this is the PCI inbound window thing again, let 
me say once again that "dma-ranges" is the appropriate way for DT to 
describe the hardware.


Robin.


reserved-dma-region property is added to specify the ranges which should
never be mapped and given to devices sitting behind.

Reviewed-by: Ray Jui 
Reviewed-by: Vikram Prakash 
Reviewed-by: Scott Branden 
Signed-off-by: Jitendra Bhivare 
---
  Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt 
b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
index b8e48b4..3be0fe3 100644
--- a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
@@ -30,6 +30,9 @@ Optional properties:
  - dma-ranges: Some PAXB-based root complexes do not have inbound mapping done
by the ASIC after power on reset.  In this case, SW is required to configure
  the mapping, based on inbound memory regions specified by this property.
+- reserved-dma-region: PAXBv2 with IOMMU enabled cannot provide mappings for
+  entire IOVA space specified by DMA mask. Hence this is used to reserve the
+  gaps in dma-ranges.
  
  - brcm,pcie-ob: Some iProc SoCs do not have the outbound address mapping done

  by the ASIC after power on reset. In this case, SW needs to configure it


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


Re: [RFC 1/5] dt-bindings: iommu: Add reserved-dma-region for IOMMU device

2018-03-06 Thread Robin Murphy

On 06/03/18 04:59, Jitendra Bhivare wrote:

Certain regions in IO virtual address space may need to be reserved to be
not used for devices configured behind IOMMU.

Add documentation of the property to allow such regions to be specified in
DT to be reserved using IOMMU_RESV_RESERVED type.


That sounds like software policy; DT is for describing hardware.


Reviewed-by: Ray Jui 
Reviewed-by: Vikram Prakash 
Reviewed-by: Scott Branden 
Signed-off-by: Jitendra Bhivare 
---
  Documentation/devicetree/bindings/iommu/iommu.txt | 17 +
  1 file changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/iommu.txt 
b/Documentation/devicetree/bindings/iommu/iommu.txt
index 5a8b462..5a58ef2 100644
--- a/Documentation/devicetree/bindings/iommu/iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/iommu.txt
@@ -98,6 +98,20 @@ requirements of that use-case haven't been fully determined 
yet. Implementing
  this is therefore not recommended without further discussion and extension of
  this binding.
  
+Optional properties:

+
+- reserved-dma-region: This specifies DMA region to be reserved with specific
+  prot in IOVA space. It is in tuples of (busno,prot,bus_addr,size).


What do busno and prot actually mean, and what are valid values for them?

Robin.


+- #region-address-cells: specifies number of cells needed to encode bus_addr
+
+- #region-size-cells: specifies number of cells needed to encode size
+
+Notes:
+==
+This can be applied to IOMMU master node or to children (such as PCI host
+bridges) on the bus behind IOMMU.
+
  
  Examples:

  =
@@ -173,6 +187,9 @@ Multiple-master IOMMU with configurable DMA window:
 * master (i.e. the I/O virtual address space).
 */
#iommu-cells = <4>;
+   #region-address-cells = <2>;
+   #region-size-cells = <2>;
+   reserved-dma-region = <0x0 0x0 0x04 0x0 0x04 0x0>;
};
  
  		master {



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


Re: [PATCH 07/37] iommu: Add a page fault handler

2018-03-06 Thread Jean-Philippe Brucker
On 05/03/18 21:53, Sinan Kaya wrote:
> On 2/12/2018 1:33 PM, Jean-Philippe Brucker wrote:
>> +static struct workqueue_struct *iommu_fault_queue;
> 
> Is there anyway we can make this fault queue per struct device?
> Since this is common code, I think it needs some care.

I don't think it's better, the workqueue struct seems large. Maybe having
one wq per IOMMU is a good compromise? As said in my other reply for this
patch, doing so isn't completely straightforward. I'll consider adding an
iommu pointer to the iommu_param struct attached to each device.

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


Re: [PATCH 03/37] iommu/sva: Manage process address spaces

2018-03-06 Thread Jean-Philippe Brucker
On 05/03/18 15:28, Sinan Kaya wrote:
> On 2/12/2018 1:33 PM, Jean-Philippe Brucker wrote:
>> +static void io_mm_free(struct io_mm *io_mm)
>> +{
>> +struct mm_struct *mm;
>> +void (*release)(struct io_mm *);
>> +
>> +release = io_mm->release;
>> +mm = io_mm->mm;
>> +
>> +release(io_mm);
> 
> Is there any reason why you can't call iommu->release()
> here directly? Why do you need the release local variable?

I think I can remove the local variable

Thanks,
Jean

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


Re: [PATCH 07/37] iommu: Add a page fault handler

2018-03-06 Thread Jean-Philippe Brucker
On 05/03/18 21:44, Sinan Kaya wrote:
> On 2/12/2018 1:33 PM, Jean-Philippe Brucker wrote:
>> +static int iommu_queue_fault(struct iommu_domain *domain, struct device 
>> *dev,
>> + struct iommu_fault_event *evt)
>> +{
>> +struct iommu_fault_group *group;
>> +struct iommu_fault_context *fault, *next;
>> +
>> +if (!iommu_fault_queue)
>> +return -ENOSYS;
>> +
>> +if (!evt->last_req) {
>> +fault = kzalloc(sizeof(*fault), GFP_KERNEL);
>> +if (!fault)
>> +return -ENOMEM;
>> +
>> +fault->evt = *evt;
>> +fault->dev = dev;
>> +
>> +/* Non-last request of a group. Postpone until the last one */
>> +spin_lock(&iommu_partial_faults_lock);
>> +list_add_tail(&fault->head, &iommu_partial_faults);
>> +spin_unlock(&iommu_partial_faults_lock);
>> +
>> +return IOMMU_PAGE_RESP_HANDLED;
>> +}
>> +
>> +group = kzalloc(sizeof(*group), GFP_KERNEL);
>> +if (!group)
>> +return -ENOMEM;
> 
> Release the requests in iommu_partial_faults here.

We move these requests to the group->faults list (which btw should use
list_move instead of the current list_del+list_add) and we release them in
iommu_fault_handle_group()

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


Re: [PATCH v7 13/14] iommu/rockchip: Add runtime PM support

2018-03-06 Thread Tomasz Figa
Hi Jeffy,

It looks like I missed some details of how runtime PM enable works
before, so we might be able to simplify things. Sorry for not getting
things right earlier.

On Tue, Mar 6, 2018 at 12:27 PM, Jeffy Chen  wrote:
> When the power domain is powered off, the IOMMU cannot be accessed and
> register programming must be deferred until the power domain becomes
> enabled.
>
> Add runtime PM support, and use runtime PM device link from IOMMU to
> master to startup and shutdown IOMMU.
>
> Signed-off-by: Jeffy Chen 
> ---
>
> Changes in v7:
> Add WARN_ON in irq isr, and modify iommu archdata comment.
>
> Changes in v6: None
> Changes in v5:
> Avoid race about pm_runtime_get_if_in_use() and pm_runtime_enabled().
>
> Changes in v4: None
> Changes in v3:
> Only call startup() and shutdown() when iommu attached.
> Remove pm_mutex.
> Check runtime PM disabled.
> Check pm_runtime in rk_iommu_irq().
>
> Changes in v2: None
>
>  drivers/iommu/rockchip-iommu.c | 189 
> -
>  1 file changed, 148 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> index 2448a0528e39..db08978203f7 100644
> --- a/drivers/iommu/rockchip-iommu.c
> +++ b/drivers/iommu/rockchip-iommu.c
> @@ -22,6 +22,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>
> @@ -105,7 +106,14 @@ struct rk_iommu {
> struct iommu_domain *domain; /* domain to which iommu is attached */
>  };
>
> +/**
> + * struct rk_iommudata - iommu archdata of master device.
> + * @link:  device link with runtime PM integration from the master
> + * (consumer) to the IOMMU (supplier).
> + * @iommu: IOMMU of the master device.
> + */
>  struct rk_iommudata {
> +   struct device_link *link;
> struct rk_iommu *iommu;
>  };
>
> @@ -518,7 +526,13 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
> u32 int_status;
> dma_addr_t iova;
> irqreturn_t ret = IRQ_NONE;
> -   int i;
> +   bool need_runtime_put;
> +   int i, err;
> +
> +   err = pm_runtime_get_if_in_use(iommu->dev);
> +   if (WARN_ON(err <= 0 && err != -EINVAL))
> +   return ret;
> +   need_runtime_put = err > 0;

Actually, for our purposes, we can assume that runtime PM enable
status can be only changed by the driver itself. Looking at the LXR,
PM core also calls __pm_runtime_disable() before calling
.suspend_late() callback and pm_runtime_enable() after calling
.resume_early() callback, but we should be able to ignore this,
because we handle things in .suspend() callback in this driver.

With this assumption in mind, all we need to do here is:

if (WARN_ON(!pm_runtime_get_if_in_use(iommu->dev)))
return 0;

>
> WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
>
> @@ -570,6 +584,9 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
>
> clk_bulk_disable(iommu->num_clocks, iommu->clocks);
>
> +   if (need_runtime_put)
> +   pm_runtime_put(iommu->dev);

if (pm_runtime_enabled())
pm_runtime_put(iommu->dev);

> +
> return ret;
>  }
>
> @@ -611,10 +628,20 @@ static void rk_iommu_zap_iova(struct rk_iommu_domain 
> *rk_domain,
> spin_lock_irqsave(&rk_domain->iommus_lock, flags);
> list_for_each(pos, &rk_domain->iommus) {
> struct rk_iommu *iommu;
> +   int ret;
> +
> iommu = list_entry(pos, struct rk_iommu, node);
> -   WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks));
> -   rk_iommu_zap_lines(iommu, iova, size);
> -   clk_bulk_disable(iommu->num_clocks, iommu->clocks);
> +
> +   /* Only zap TLBs of IOMMUs that are powered on. */
> +   ret = pm_runtime_get_if_in_use(iommu->dev);
> +   if (ret > 0 || ret == -EINVAL) {

if (pm_runtime_get_if_in_use(iommu->dev)) {

> +   WARN_ON(clk_bulk_enable(iommu->num_clocks,
> +   iommu->clocks));
> +   rk_iommu_zap_lines(iommu, iova, size);
> +   clk_bulk_disable(iommu->num_clocks, iommu->clocks);

if (pm_runtime_enabled(iommu->dev))
pm_runtime_put(iommu->dev);

And so on, in other places.

Really sorry for the confusion before.

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


[RFC 5/5] iommu/arm-smmu: Allow direct mapping for MSI region

2018-03-06 Thread Jitendra Bhivare via iommu
Current ARM SMMU virtualizes MSI addresses to IOVA space.

In iProc SoCs, MSI needs to be steered. Allow reserving MSI address range
using DT node entry as direct region.

Signed-off-by: Jitendra Bhivare 
---
 drivers/iommu/arm-smmu.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 78d4c6b..7b34980 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1533,8 +1533,11 @@ static int arm_smmu_of_xlate(struct device *dev, struct 
of_phandle_args *args)
 static void arm_smmu_get_resv_regions(struct device *dev,
  struct list_head *head)
 {
+   struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+   struct arm_smmu_device *smmu = fwspec_smmu(fwspec);
struct iommu_resv_region *region;
-   int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
+   struct of_iommu_resv_region of_region;
+   int index = 0, prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
 
region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
 prot, IOMMU_RESV_SW_MSI);
@@ -1543,6 +1546,15 @@ static void arm_smmu_get_resv_regions(struct device *dev,
 
list_add_tail(®ion->list, head);
 
+   if (!of_get_resv_region(smmu->dev->of_node, "msi", &index,
+   &of_region)) {
+   region = iommu_alloc_resv_region(of_region.bus_addr,
+of_region.size,
+of_region.prot,
+IOMMU_RESV_DIRECT);
+   if (region)
+   list_add_tail(®ion->list, head);
+   }
iommu_dma_get_resv_regions(dev, head);
 }
 
-- 
2.7.4

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


[RFC 0/5] DT property to reserve IOMMU regions

2018-03-06 Thread Jitendra Bhivare via iommu
ARM SoCs need a way to reserve IOMMU regions. Some address ranges used 
by devices sitting behind IOMMU are treated specially. To prevent these
ranges from getting mapped in IOVA space, use the existing framework and
code to reserve the ranges using DT properties.

This patch set is created against 4.15-rc7.

Jitendra Bhivare (5):
  dt-bindings: iommu: Add reserved-dma-region for IOMMU device
  dt-bindings: brcm: Add reserved-dma-region for iPROC
  dt-bindings: arm-smmu: Add reserved-msi-region
  iommu/of: Reserve IOMMU DMA regions using DT
  iommu/arm-smmu: Allow direct mapping for MSI region

 .../devicetree/bindings/iommu/arm,smmu.txt |  12 +++
 Documentation/devicetree/bindings/iommu/iommu.txt  |  17 
 .../devicetree/bindings/pci/brcm,iproc-pcie.txt|   3 +
 drivers/iommu/arm-smmu.c   |  14 ++-
 drivers/iommu/dma-iommu.c  |   6 ++
 drivers/iommu/of_iommu.c   | 100 +++--
 include/linux/iommu.h  |   3 +
 include/linux/of_iommu.h   |  25 --
 8 files changed, 126 insertions(+), 54 deletions(-)

-- 
2.7.4

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


[RFC 2/5] dt-bindings: brcm: Add reserved-dma-region for iPROC

2018-03-06 Thread Jitendra Bhivare via iommu
With SoC wide DMA mask of 40-bit, the mappings for entire IOVA space can't
be specified in the PAXBv2 PCIe RC of SoC. The holes in IOVA space needs to
be reserved to prevent any IOVA allocations in those spaces.

reserved-dma-region property is added to specify the ranges which should
never be mapped and given to devices sitting behind.

Reviewed-by: Ray Jui 
Reviewed-by: Vikram Prakash 
Reviewed-by: Scott Branden 
Signed-off-by: Jitendra Bhivare 
---
 Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt 
b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
index b8e48b4..3be0fe3 100644
--- a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
@@ -30,6 +30,9 @@ Optional properties:
 - dma-ranges: Some PAXB-based root complexes do not have inbound mapping done
   by the ASIC after power on reset.  In this case, SW is required to configure
 the mapping, based on inbound memory regions specified by this property.
+- reserved-dma-region: PAXBv2 with IOMMU enabled cannot provide mappings for
+  entire IOVA space specified by DMA mask. Hence this is used to reserve the
+  gaps in dma-ranges.
 
 - brcm,pcie-ob: Some iProc SoCs do not have the outbound address mapping done
 by the ASIC after power on reset. In this case, SW needs to configure it
-- 
2.7.4

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


[RFC 4/5] iommu/of: Reserve IOMMU DMA regions using DT

2018-03-06 Thread Jitendra Bhivare via iommu
iPROC SoC provides restricted windows to access sparsed memory as per ARM
memory map to the devices sitting behind IOMMU. The windows cover enough
DDR space but not the entire 40-bit 1TB space used by IOMMU code as per
the DMA mask set.

Current IOMMU code does not provide a hook to reserve these holes. Use
defined but unused of_get_dma_window to get reserved DMA regions from DT.

To reserve the regions for IOVA allocation, ranges can be specified in DT
as . These regions are marked as
IOMMU_RESV_RESERVED when device behind SMMU gets added and
arm_smmu_get_resv_regions gets called.

This provision is also used in reserving region for GICv3 ITS using
IOMMU_RESV_DIRECT as it falls in special device window.

Reviewed-by: Scott Branden 
Signed-off-by: Jitendra Bhivare 
---
 drivers/iommu/dma-iommu.c |   6 +++
 drivers/iommu/of_iommu.c  | 100 --
 include/linux/iommu.h |   3 ++
 include/linux/of_iommu.h  |  25 +---
 4 files changed, 81 insertions(+), 53 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 25914d3..433d427 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -173,6 +174,7 @@ void iommu_dma_get_resv_regions(struct device *dev, struct 
list_head *list)
 {
struct pci_host_bridge *bridge;
struct resource_entry *window;
+   struct device_node *np;
 
if (!dev_is_pci(dev))
return;
@@ -195,6 +197,10 @@ void iommu_dma_get_resv_regions(struct device *dev, struct 
list_head *list)
 
list_add_tail(®ion->list, list);
}
+   /* check platform device representing bridge for reserved DMA windows */
+   np = bridge->dev.parent->of_node;
+   if (np)
+   of_iommu_resv_dma_regions(np, list);
 }
 EXPORT_SYMBOL(iommu_dma_get_resv_regions);
 
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 50947eb..cebcbaa 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -31,72 +31,78 @@ static const struct of_device_id __iommu_of_table_sentinel
__used __section(__iommu_of_table_end);
 
 /**
- * of_get_dma_window - Parse *dma-window property and returns 0 if found.
+ * of_get_resv_region - Parse reserved-*-region property and returns 0 if 
found.
  *
  * @dn: device node
- * @prefix: prefix for property name if any
+ * @region: region for property name if any
  * @index: index to start to parse
- * @busno: Returns busno if supported. Otherwise pass NULL
- * @addr: Returns address that DMA starts
- * @size: Returns the range that DMA can handle
+ * @of_region: returns read of_iommu_resv_region 
  *
- * This supports different formats flexibly. "prefix" can be
- * configured if any. "busno" and "index" are optionally
- * specified. Set 0(or NULL) if not used.
+ * This supports different formats using "region" configured if any.
  */
-int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
- unsigned long *busno, dma_addr_t *addr, size_t *size)
+int of_get_resv_region(struct device_node *dn, const char *region, int *index,
+ struct of_iommu_resv_region *of_region)
 {
-   const __be32 *dma_window, *end;
-   int bytes, cur_index = 0;
-   char propname[NAME_MAX], addrname[NAME_MAX], sizename[NAME_MAX];
+   char propname[NAME_MAX];
+   int na, ns, len, pos;
+   const __be32 *prop;
 
-   if (!dn || !addr || !size)
+   if (!dn || !of_region || !index)
return -EINVAL;
 
-   if (!prefix)
-   prefix = "";
+   if (!region)
+   region = "";
 
-   snprintf(propname, sizeof(propname), "%sdma-window", prefix);
-   snprintf(addrname, sizeof(addrname), "%s#dma-address-cells", prefix);
-   snprintf(sizename, sizeof(sizename), "%s#dma-size-cells", prefix);
+   prop = of_get_property(dn, "#region-address-cells", NULL);
+   na = prop ? be32_to_cpup(prop) : of_n_addr_cells(dn);
+   prop = of_get_property(dn, "#region-size-cells", NULL);
+   ns = prop ? be32_to_cpup(prop) : of_n_size_cells(dn);
 
-   dma_window = of_get_property(dn, propname, &bytes);
-   if (!dma_window)
-   return -ENODEV;
-   end = dma_window + bytes / sizeof(*dma_window);
+   snprintf(propname, sizeof(propname), "reserved-%s-region", region);
+   prop = of_get_property(dn, propname, &len);
+   if (!prop)
+   return -ENOENT;
 
-   while (dma_window < end) {
-   u32 cells;
-   const void *prop;
-
-   /* busno is one cell if supported */
-   if (busno)
-   *busno = be32_to_cpup(dma_window++);
+   len /= sizeof(*prop);
+   pos = *index;
+   /* prot and busno takes one cell each */
+   if (pos >= len || (len - pos) % (na + ns + 2))
+   ret

[RFC 3/5] dt-bindings: arm-smmu: Add reserved-msi-region

2018-03-06 Thread Jitendra Bhivare via iommu
iPROC SoC has a special device window to treat GICv3 ITS MSI.

Current code maps MSI to IOVA space. Add SMMU node property to use
direct mappings for MSI region.

This property is read and reserved when arm_smmu_get_resv_regions
gets called.

Signed-off-by: Jitendra Bhivare 
---
 Documentation/devicetree/bindings/iommu/arm,smmu.txt | 12 
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce..13fa2b9 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -71,6 +71,15 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- reserved-msi-region: MSI region to be reserved with specific prot in IOVA
+ space for direct mapping. The region is specified in tuple
+ of (busno,prot,bus_addr,size).
+
+- #region-address-cells: specifies number of cells needed to encode bus_addr
+
+- #region-size-cells: specifies number of cells needed to encode size
+
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -95,6 +104,9 @@ conditions.
  <0 36 4>,
  <0 37 4>;
 #iommu-cells = <1>;
+   #region-address-cells = <1>;
+   #region-size-cells = <1>;
+   reserved-msi-region = <0x0 0x1a 0x63c3000 0x8000>;
 };
 
 /* device with two stream IDs, 0 and 7 */
-- 
2.7.4

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


[RFC 1/5] dt-bindings: iommu: Add reserved-dma-region for IOMMU device

2018-03-06 Thread Jitendra Bhivare via iommu
Certain regions in IO virtual address space may need to be reserved to be
not used for devices configured behind IOMMU.

Add documentation of the property to allow such regions to be specified in
DT to be reserved using IOMMU_RESV_RESERVED type.

Reviewed-by: Ray Jui 
Reviewed-by: Vikram Prakash 
Reviewed-by: Scott Branden 
Signed-off-by: Jitendra Bhivare 
---
 Documentation/devicetree/bindings/iommu/iommu.txt | 17 +
 1 file changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/iommu.txt 
b/Documentation/devicetree/bindings/iommu/iommu.txt
index 5a8b462..5a58ef2 100644
--- a/Documentation/devicetree/bindings/iommu/iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/iommu.txt
@@ -98,6 +98,20 @@ requirements of that use-case haven't been fully determined 
yet. Implementing
 this is therefore not recommended without further discussion and extension of
 this binding.
 
+Optional properties:
+
+- reserved-dma-region: This specifies DMA region to be reserved with specific
+  prot in IOVA space. It is in tuples of (busno,prot,bus_addr,size).
+
+- #region-address-cells: specifies number of cells needed to encode bus_addr
+
+- #region-size-cells: specifies number of cells needed to encode size
+
+Notes:
+==
+This can be applied to IOMMU master node or to children (such as PCI host
+bridges) on the bus behind IOMMU.
+
 
 Examples:
 =
@@ -173,6 +187,9 @@ Multiple-master IOMMU with configurable DMA window:
 * master (i.e. the I/O virtual address space).
 */
#iommu-cells = <4>;
+   #region-address-cells = <2>;
+   #region-size-cells = <2>;
+   reserved-dma-region = <0x0 0x0 0x04 0x0 0x04 0x0>;
};
 
master {
-- 
2.7.4

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