Re: [PATCH 37/37] vfio: Add support for Shared Virtual Addressing

2018-02-27 Thread Sinan Kaya
On 2/12/2018 1:33 PM, Jean-Philippe Brucker wrote:
> Add two new ioctl for VFIO containers. VFIO_IOMMU_BIND_PROCESS creates a
> bond between a container and a process address space, identified by a
> device-specific ID named PASID. This allows the device to target DMA
> transactions at the process virtual addresses without a need for mapping
> and unmapping buffers explicitly in the IOMMU. The process page tables are
> shared with the IOMMU, and mechanisms such as PCI ATS/PRI are used to
> handle faults. VFIO_IOMMU_UNBIND_PROCESS removes a bond created with
> VFIO_IOMMU_BIND_PROCESS.
> 
> Signed-off-by: Jean-Philippe Brucker 
> ---
>  drivers/vfio/vfio_iommu_type1.c | 399 
> 
>  include/uapi/linux/vfio.h   |  76 
>  2 files changed, 475 insertions(+)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index e30e29ae4819..cac066f0026b 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -30,6 +30,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -60,6 +61,7 @@ MODULE_PARM_DESC(disable_hugepages,
>  
>  struct vfio_iommu {
>   struct list_headdomain_list;
> + struct list_headmm_list;
>   struct vfio_domain  *external_domain; /* domain for external user */
>   struct mutexlock;
>   struct rb_root  dma_list;
> @@ -90,6 +92,15 @@ struct vfio_dma {
>  struct vfio_group {
>   struct iommu_group  *iommu_group;
>   struct list_headnext;
> + boolsva_enabled;
> +};
> +
> +struct vfio_mm {
> +#define VFIO_PASID_INVALID   (-1)
> + spinlock_t  lock;
> + int pasid;
> + struct mm_struct*mm;
> + struct list_headnext;
>  };
>  
>  /*
> @@ -1117,6 +1128,157 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
>   return 0;
>  }
>  
> +static int vfio_iommu_mm_exit(struct device *dev, int pasid, void *data)
> +{
> + struct vfio_mm *vfio_mm = data;
> +
> + /*
> +  * The mm_exit callback cannot block, so we can't take the iommu mutex
> +  * and remove this vfio_mm from the list. Hopefully the SVA code will
> +  * relax its locking requirement in the future.
> +  *
> +  * We mostly care about attach_group, which will attempt to replay all
> +  * binds in this container. Ensure that it doesn't touch this defunct mm
> +  * struct, by clearing the pointer. The structure will be freed when the
> +  * group is removed from the container.
> +  */
> + spin_lock(_mm->lock);
> + vfio_mm->mm = NULL;
> + spin_unlock(_mm->lock);
> +
> + return 0;
> +}
> +
> +static int vfio_iommu_sva_init(struct device *dev, void *data)
> +{

data is not getting used.

> +
> + int ret;
> +
> + ret = iommu_sva_device_init(dev, IOMMU_SVA_FEAT_PASID |
> + IOMMU_SVA_FEAT_IOPF, 0);
> + if (ret)
> + return ret;
> +
> + return iommu_register_mm_exit_handler(dev, vfio_iommu_mm_exit);
> +}
> +
> +static int vfio_iommu_sva_shutdown(struct device *dev, void *data)
> +{
> + iommu_sva_device_shutdown(dev);
> + iommu_unregister_mm_exit_handler(dev);
> +
> + return 0;
> +}
> +
> +static int vfio_iommu_bind_group(struct vfio_iommu *iommu,
> +  struct vfio_group *group,
> +  struct vfio_mm *vfio_mm)
> +{
> + int ret;
> + int pasid;
> +
> + if (!group->sva_enabled) {
> + ret = iommu_group_for_each_dev(group->iommu_group, NULL,
> +vfio_iommu_sva_init);
> + if (ret)
> + return ret;
> +
> + group->sva_enabled = true;
> + }
> +
> + ret = iommu_sva_bind_group(group->iommu_group, vfio_mm->mm, ,
> +IOMMU_SVA_FEAT_PASID | IOMMU_SVA_FEAT_IOPF,
> +vfio_mm);
> + if (ret)
> + return ret;

don't you need to clean up the work done by vfio_iommu_sva_init() here.

> +
> + if (WARN_ON(vfio_mm->pasid != VFIO_PASID_INVALID && pasid !=
> + vfio_mm->pasid))
> + return -EFAULT;
> +
> + vfio_mm->pasid = pasid;
> +
> + return 0;
> +}
> +
> +static void vfio_iommu_unbind_group(struct vfio_group *group,
> + struct vfio_mm *vfio_mm)
> +{
> + iommu_sva_unbind_group(group->iommu_group, vfio_mm->pasid);
> +}
> +
> +static void vfio_iommu_unbind(struct vfio_iommu *iommu,
> +   struct vfio_mm *vfio_mm)
> +{
> + struct vfio_group *group;
> + struct vfio_domain *domain;
> +
> + list_for_each_entry(domain, >domain_list, next)
> + list_for_each_entry(group, >group_list, next)
> + vfio_iommu_unbind_group(group, 

Re: [PATCH 16/37] iommu: Add generic PASID table library

2018-02-27 Thread Jacob Pan
On Mon, 12 Feb 2018 18:33:31 +
Jean-Philippe Brucker  wrote:

> Add a small API within the IOMMU subsystem to handle different
> formats of PASID tables. It uses the same principle as io-pgtable:
> 
> * The IOMMU driver registers a PASID table with some invalidation
>   callbacks.
> * The pasid-table lib allocates a set of tables of the right format,
> and returns an iommu_pasid_table_ops structure.
> * The IOMMU driver allocates entries and writes them using the
> provided ops.
> * The pasid-table lib calls the IOMMU driver back for invalidation
> when necessary.
> * The IOMMU driver unregisters the ops which frees the tables when
>   finished.
> 
> An example user will be Arm SMMU in a subsequent patch.
> 
> Signed-off-by: Jean-Philippe Brucker 
> ---
>  drivers/iommu/Kconfig   |   8 +++
>  drivers/iommu/Makefile  |   1 +
>  drivers/iommu/iommu-pasid.c |  53 +
>  drivers/iommu/iommu-pasid.h | 142
>  4 files changed, 204
> insertions(+) create mode 100644 drivers/iommu/iommu-pasid.c
>  create mode 100644 drivers/iommu/iommu-pasid.h
> 
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index e751bb9958ba..8add90ba9b75 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -60,6 +60,14 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
>  
>  endmenu
>  
> +menu "Generic PASID table support"
> +
> +# Selected by the actual PASID table implementations
> +config IOMMU_PASID_TABLE
> + bool
> +
> +endmenu
> +
>  config IOMMU_IOVA
>   tristate
>  
> diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
> index f4324e29035e..338e59c93131 100644
> --- a/drivers/iommu/Makefile
> +++ b/drivers/iommu/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_IOMMU_FAULT) += io-pgfault.o
>  obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
>  obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
>  obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
> +obj-$(CONFIG_IOMMU_PASID_TABLE) += iommu-pasid.o
>  obj-$(CONFIG_IOMMU_IOVA) += iova.o
>  obj-$(CONFIG_OF_IOMMU)   += of_iommu.o
>  obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
> diff --git a/drivers/iommu/iommu-pasid.c b/drivers/iommu/iommu-pasid.c
> new file mode 100644
> index ..6b21d369d514
> --- /dev/null
> +++ b/drivers/iommu/iommu-pasid.c
> @@ -0,0 +1,53 @@
> +/*
> + * PASID table management for the IOMMU
> + *
> + * Copyright (C) 2018 ARM Ltd.
> + * Author: Jean-Philippe Brucker 
> + *
> + * SPDX-License-Identifier: GPL-2.0
> + */
> +
> +#include 
> +
> +#include "iommu-pasid.h"
> +
> +static const struct iommu_pasid_init_fns *
> +pasid_table_init_fns[PASID_TABLE_NUM_FMTS] = {
> +};
> +
> +struct iommu_pasid_table_ops *
> +iommu_alloc_pasid_ops(enum iommu_pasid_table_fmt fmt,
> +   struct iommu_pasid_table_cfg *cfg, void
> *cookie) +{
I guess you don't need to pass in cookie here.
> + struct iommu_pasid_table *table;
> + const struct iommu_pasid_init_fns *fns;
> +
> + if (fmt >= PASID_TABLE_NUM_FMTS)
> + return NULL;
> +
> + fns = pasid_table_init_fns[fmt];
> + if (!fns)
> + return NULL;
> +
> + table = fns->alloc(cfg, cookie);
> + if (!table)
> + return NULL;
> +
> + table->fmt = fmt;
> + table->cookie = cookie;
> + table->cfg = *cfg;
> +
the ops is already IOMMU model specific, why do you need to pass cfg
back?
> + return >ops;
If there is no common code that uses these ops, I don't see the benefit
of having these APIs. Or the plan is to consolidate even further such
that referene to pasid table can be attached at per iommu_domain etc,
but that would be model specific choice.

Jacob 
> +}
> +
> +void iommu_free_pasid_ops(struct iommu_pasid_table_ops *ops)
> +{
> + struct iommu_pasid_table *table;
> +
> + if (!ops)
> + return;
> +
> + table = container_of(ops, struct iommu_pasid_table, ops);
> + iommu_pasid_flush_all(table);
> + pasid_table_init_fns[table->fmt]->free(table);
> +}
> diff --git a/drivers/iommu/iommu-pasid.h b/drivers/iommu/iommu-pasid.h
> new file mode 100644
> index ..40a27d35c1e0
> --- /dev/null
> +++ b/drivers/iommu/iommu-pasid.h
> @@ -0,0 +1,142 @@
> +/*
> + * PASID table management for the IOMMU
> + *
> + * Copyright (C) 2017 ARM Ltd.
> + * Author: Jean-Philippe Brucker 
> + *
> + * SPDX-License-Identifier: GPL-2.0
> + */
> +#ifndef __IOMMU_PASID_H
> +#define __IOMMU_PASID_H
> +
> +#include 
> +#include "io-pgtable.h"
> +
> +struct mm_struct;
> +
> +enum iommu_pasid_table_fmt {
> + PASID_TABLE_NUM_FMTS,
> +};
> +
> +/**
> + * iommu_pasid_entry - Entry of a PASID table
> + *
> + * @token:   architecture-specific data needed to uniquely
> identify the
> + *   entry. Most notably used for TLB invalidation
> + */
> +struct iommu_pasid_entry {
> + u64 

Re: [PATCH v5 08/13] iommu/rockchip: Control clocks needed to access the IOMMU

2018-02-27 Thread Robin Murphy

On 23/02/18 10:24, JeffyChen wrote:

Hi guys,

On 02/01/2018 07:19 PM, JeffyChen wrote:



diff --git
a/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
index 2098f7732264..33dd853359fa 100644
--- a/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt
@@ -14,6 +14,13 @@ Required properties:
  "single-master" device, and needs no
additional information
  to associate with its master device.  See:

Documentation/devicetree/bindings/iommu/iommu.txt
+Optional properties:
+- clocks : A list of master clocks requires for the IOMMU to be
accessible
+   by the host CPU. The number of clocks depends on the
master
+   block and might as well be zero. See [1] for generic 
clock

+   bindings description.


Hardware blocks don't have a variable number of clock connections.


I think you underestimate the imagination of hardware designers. :)


Learned long ago to never do that. If there are 2 ways to do
something, they will find a 3rd way.


For Rockchip IOMMU, there is a set of clocks, which all need to be
enabled for IOMMU register access to succeed. The clocks are not
directly fed to the IOMMU, but they are needed for the various buses
and intermediate blocks on the way to the IOMMU to work.


The binding should describe the clock connections, not what clocks a
driver needs (currently). It sounds like a lack of managing bus clocks
to me.

In any case, the binding must be written so it can be verified. If you
can have any number of clocks with any names, there's no point in
documenting.


the rockchip IOMMU is part of the master block in hardware, so it needs
to control the master's power domain and some of the master's clocks
when access it's registers.

and the number of clocks needed here, might be different between each
IOMMUs(according to which master block it belongs), it's a little like
our power domain:
https://elixir.free-electrons.com/linux/latest/source/arch/arm64/boot/dts/rockchip/rk3399.dtsi#L935 




i'm not sure how to describe this correctly, is it ok use something like
"the same as it's master block"?


would it make sense to add a property to specify the master who owns the 
iommu, and we can get all clocks(only some of those clocks are actually 
needed) from it in the of_xlate()? and we can also reuse the clock-names 
of that master to build clk_bulk_data and log errors in clk_bulk_get.


I'm inclined to agree with Rob here - if we're to add anything to the 
binding, it should only be whatever clock inputs are defined for the 
IOMMU IP block itself. If Linux doesn't properly handle the interconnect 
clock hierarchy external to a particular integration, that's a separate 
issue and it's not the binding's problem.


I actually quite like the hack of "borrowing" the clocks from 
dev->of_node in of_xlate() - you shouldn't need any DT changes for that, 
because you already know that each IOMMU instance only has the one 
master device anyway.


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

Re: [PATCH 1/4] iommu: Add virtio-iommu driver

2018-02-27 Thread Michael S. Tsirkin
On Thu, Feb 22, 2018 at 11:04:30AM +, Jean-Philippe Brucker wrote:
> On 21/02/18 20:12, kbuild test robot wrote:
> [...]
> > config: arm64-allmodconfig (attached as .config)
> [...]
> >aarch64-linux-gnu-ld: arch/arm64/kernel/head.o: relocation 
> > R_AARCH64_ABS32 against `_kernel_offset_le_lo32' can not be used when 
> > making a shared object
> >arch/arm64/kernel/head.o: In function `kimage_vaddr':
> >(.idmap.text+0x0): dangerous relocation: unsupported relocation
> 
> Is this related?
> 
> >arch/arm64/kernel/head.o: In function `__primary_switch':
> >(.idmap.text+0x340): dangerous relocation: unsupported relocation
> >(.idmap.text+0x348): dangerous relocation: unsupported relocation
> >drivers/iommu/virtio-iommu.o: In function `viommu_probe':
> >virtio-iommu.c:(.text+0xbdc): undefined reference to 
> > `virtio_check_driver_offered_feature'
> >virtio-iommu.c:(.text+0xcfc): undefined reference to 
> > `virtio_check_driver_offered_feature'
> >virtio-iommu.c:(.text+0xe10): undefined reference to 
> > `virtio_check_driver_offered_feature'
> >drivers/iommu/virtio-iommu.o: In function `viommu_send_reqs_sync':
> >virtio-iommu.c:(.text+0x130c): undefined reference to `virtqueue_add_sgs'
> >virtio-iommu.c:(.text+0x1398): undefined reference to `virtqueue_kick'
> >virtio-iommu.c:(.text+0x14d4): undefined reference to `virtqueue_get_buf'
> >drivers/iommu/virtio-iommu.o: In function `virtio_iommu_drv_init':
> >virtio-iommu.c:(.init.text+0x1c): undefined reference to 
> > `register_virtio_driver'
> >drivers/iommu/virtio-iommu.o: In function `virtio_iommu_drv_exit':
> >>> virtio-iommu.c:(.exit.text+0x14): undefined reference to 
> >>> `unregister_virtio_driver'
> 
> Right. At the moment CONFIG_VIRTIO_IOMMU is a bool instead of tristate,
> because the IOMMU subsystem isn't entirely ready to have IOMMU drivers
> built as modules. In addition to exporting symbols it would also needs to
> hold off probing endpoints behind the IOMMU until the IOMMU driver is
> loaded. At the moment (I think) it gives up once userspace is reached (see
> of_iommu_driver_present).
> 
> The above report is due to VIRTIO=m and VIRTIO_IOMMU=y. To solve it we could:
> 
> a) Allow VIRTIO_IOMMU to be built as module by exporting a dozen IOMMU
> symbols. It would be a lie. The driver wouldn't be usable because of the
> probe issue discussed above, but it would build.
> 
> b) Actually make any IOMMU driver work as module. Whilst it would
> certainly be a nice feature, it's a bigger problem and I don't think it
> has its place in this series.
> 
> c) Make VIRTIO_IOMMU depend on VIRTIO_MMIO=y instead of VIRTIO_MMIO, which
> I think is the sanest for now (and does work), even though distro kernels
> probably all have VIRTIO=m.
> 
> I prefer doing c) now and experiment with b) once I got some time.
> 
> Thanks,
> Jean

It kind of means it's a toy for now though. So fine as long
as it's out of tree.

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


Re: [PATCH v2 4/4] iommu/arm-smmu-v3: Support 52-bit virtual address

2018-02-27 Thread Robin Murphy

On 26/02/18 18:05, Will Deacon wrote:

On Thu, Dec 14, 2017 at 04:58:53PM +, Robin Murphy wrote:

Stage 1 input addresses are effectively 64-bit in SMMUv3 anyway, so
really all that's involved is letting io-pgtable know the appropriate
upper bound for T0SZ.

Tested-by: Nate Watterson 
Signed-off-by: Robin Murphy 
---

v2: No change

  drivers/iommu/arm-smmu-v3.c | 8 
  1 file changed, 8 insertions(+)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index c9c4e6132e27..7059a0805bd1 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -102,6 +102,7 @@
  #define IDR5_OAS_44_BIT   (4 << IDR5_OAS_SHIFT)
  #define IDR5_OAS_48_BIT   (5 << IDR5_OAS_SHIFT)
  #define IDR5_OAS_52_BIT   (6 << IDR5_OAS_SHIFT)
+#define IDR5_VAX   (1 << 10)


I think this is actually a two-bit field, so we should check the whole
thing.


Yes, I either overlooked that or took a cheeky shortcut; will fix.

  
  #define ARM_SMMU_CR0			0x20

  #define CR0_CMDQEN(1 << 3)
@@ -604,6 +605,7 @@ struct arm_smmu_device {
  #define ARM_SMMU_FEAT_STALLS  (1 << 11)
  #define ARM_SMMU_FEAT_HYP (1 << 12)
  #define ARM_SMMU_FEAT_STALL_FORCE (1 << 13)
+#define ARM_SMMU_FEAT_VAX  (1 << 14)
u32 features;
  
  #define ARM_SMMU_OPT_SKIP_PREFETCH	(1 << 0)

@@ -1656,6 +1658,8 @@ static int arm_smmu_domain_finalise(struct iommu_domain 
*domain)
switch (smmu_domain->stage) {
case ARM_SMMU_DOMAIN_S1:
ias = VA_BITS;
+   if (VA_BITS > 48 && !(smmu->features & ARM_SMMU_FEAT_VAX))


nit, but I'd rather the if condition was checking ias instead of VA_BITS.


+   ias = 48;
oas = smmu->ias;


Should we also be sanitising the oas here if the SMMU doesn't support 64k
pages? It looks like the ias/oas sanitisation isn't cleanly split between
the pgtable code and the SMMU driver.


Right, based on my previous argument it would be cleaner to set 48/52 
here based on the SMMU features, then constrain to VA_BITS in 
io-pgtable; I think I was more focused on minimising the diff initially.


Robin.
___
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-02-27 Thread Robin Murphy

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? :/

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.



+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.



  static bool selftest_running = false;
  
  static dma_addr_t __arm_lpae_dma_addr(void *pages)

@@ -287,7 +302,7 @@ static void __arm_lpae_init_pte(struct arm_lpae_io_pgtable 
*data,
pte |= ARM_LPAE_PTE_TYPE_BLOCK;
  
  	pte |= ARM_LPAE_PTE_AF | ARM_LPAE_PTE_SH_IS;

-   pte |= pfn_to_iopte(paddr >> data->pg_shift, data);
+   pte |= paddr_to_iopte(paddr, data);
  
  	__arm_lpae_set_pte(ptep, pte, >iop.cfg);

  }
@@ -528,7 +543,7 @@ static int arm_lpae_split_blk_unmap(struct 
arm_lpae_io_pgtable *data,
if (size == split_sz)
unmap_idx = ARM_LPAE_LVL_IDX(iova, lvl, data);
  
-	blk_paddr = iopte_to_pfn(blk_pte, data) << data->pg_shift;

+   blk_paddr = iopte_to_paddr(blk_pte, data);
pte = iopte_prot(blk_pte);
  
  	for (i = 0; i < tablesz / sizeof(pte); i++, blk_paddr += split_sz) {

@@ -652,12 +667,13 @@ static phys_addr_t arm_lpae_iova_to_phys(struct 
io_pgtable_ops *ops,
  
  found_translation:

iova &= (ARM_LPAE_BLOCK_SIZE(lvl, data) - 1);
-   return ((phys_addr_t)iopte_to_pfn(pte,data) << data->pg_shift) | iova;
+   return iopte_to_paddr(pte, data) | iova;
  }
  
  static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)

  {
-   unsigned long granule;
+   unsigned long granule, page_sizes;
+   unsigned int max_addr_bits = 48;
  
  	/*

 * We need to restrict the supported page sizes to match the
@@ -677,17 +693,24 @@ static void arm_lpae_restrict_pgsizes(struct 
io_pgtable_cfg *cfg)
  
  	switch (granule) {

case SZ_4K:
-   cfg->pgsize_bitmap &= (SZ_4K | SZ_2M | SZ_1G);
+   page_sizes = (SZ_4K | SZ_2M | SZ_1G);
break;
case SZ_16K:
-   cfg->pgsize_bitmap &= (SZ_16K | SZ_32M);
+   page_sizes = (SZ_16K | SZ_32M);
break;
case SZ_64K:
-   cfg->pgsize_bitmap &= (SZ_64K | SZ_512M);
+   max_addr_bits = 52;
+   page_sizes = (SZ_64K | SZ_512M);
+   if (cfg->oas > 48)
+   page_sizes |= 1ULL << 42; /* 4TB */
break;
default:
-   cfg->pgsize_bitmap = 0;
+   page_sizes = 0;
}
+
+   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 

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

2018-02-27 Thread Robin Murphy

Hi Will,

On 26/02/18 18:04, Will Deacon wrote:

Hi Robin,

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 ;)


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


Re: [PATCH 0/8] R-Car M3-N: Enable EtherAVB device node

2018-02-27 Thread jacopo mondi
Hi Geert,

On Mon, Feb 26, 2018 at 07:28:47PM +0100, Geert Uytterhoeven wrote:
> Hi Jacopo,
>
> On Mon, Feb 26, 2018 at 6:57 PM, Jacopo Mondi  
> wrote:
> >   as discussed with you Sergei and Geert, in order to enable EtherAVB for
> > R8A77965 we first wanted to make the phy-mode "rgmii-txid" a board specific
> > property for all other SoCs.
>
> Thanks for your series!
>
> > This series adds  the phy-mode property to salvator-common.dtsi and reset 
> > the
> > one for R8A77965/R8A7796/R8A77995 to "rgmii".
>
> I forgot that r8a7795.dtsi and r8a7796.dtsi are used for the ULCB boards, too.
> So to avoid regressions, you need to make a similar change to ulcb.dtsi like 
> you
> made for salvator-common.dtsi.
>
> In addition, r8a77995.dtsi is only used for the Draak board.
> So you have to update r8a7795-draak.dtsi first, too.

Of course! I forgot about ULCB (and had a patch for Draak I lost while
rebasing :/ )
>
> > Then, in order to enable EtherAVB for R-Car M3-N, iommu nodes had to be 
> > added
> > as they are referenced by the "avb" device node (CC the iommu list for the
> > series for that reason).
>
> I don't think we need the iommu properties and nodes at this early stage.
> Ethernet works fine without them. Simon, do you agree?

I'll wait for Simon reply and then resend, possibly without iommu and
ULCB and Draak patches!

Thanks
   j

>
> P.S. scripts/dtc/dtx_diff is a great tool to compare DTBs before and after 
> your
>   changes. It would have revealed the changes for ULCB and Draak.
>
> 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: Question on IOMMU indentity mapping for intel-iommu

2018-02-27 Thread David Woodhouse
On Mon, 2018-02-26 at 15:01 -0800, Alexander Duyck wrote:
> I am interested in adding a new memory mapping option that
> establishes
> one identity-mapped region for all DMA_TO_DEVICE mappings and creates
> a new dynamic mapping for any DMA_FROM_DEVICE and DMA_BIDIRECTIONAL
> mappings. My thought is it should allow for a compromise between
> security and performance (in the case of networking) in that many of
> the server NICs drivers these days are running with mostly pinned or
> resused paged for Rx. By using an identity mapping for the Tx packets
> we should be able to significantly cut down on the IOMMU overhead for
> the device. The other advantage if this works is that we could use
> this to possibly do something like dirty page tracking in the case of
> a emulated version of the IOMMU.
> 
> I was originally thinking I could get away with just reusing the
> identity mapping code but it looks like that would end up merging
> everything into one domain if I am understanding correctly. Do I have
> that right?
> 
> Would I be correct in assuming that I will need to have a separate
> domain per device, each domain containing the 1 TO_DEVICE identity
> mapped region, and then whatever other mappings are needed to handle
> the FROM and BIDIRECTIONAL mappings?

In the normal model where we explicitly map every RX and TX buffer, you
have a domain device anyway; that's not a new requirement for your
model.

It sounds like an interesting idea; I agree that it's a reasonable
compromise between security and performance. The device can *read* all
of memory, but it can't write anywhere that isn't explicitly mapped.

In addition, we're mapping buffers for RX some time in advance of them
being needed (replenishing the tail of the RX ring), where the latency
of the map operation hopefully shouldn't be quite so much of an issue.
While packets for TX can go straight to the device with no latency.
Overall, I think it might work really well.

You don't want the existing identity mapping code; that will give you a
RW mapping which you don't want — you really do want read-only or this
whole exercise is pointless, right? And you're right, it would have put
the domain into the single identity domain.

You could probably start by mocking this up with the IOMMU API. Create
a domain with the 1:1 read-only mapping of all memory, add your device
to it, and then do your writeable mappings on top (at IOVAs higher than
the top of physical memory). That's probably a quick way to assess
performance and prove the concept (although you don't get deferred
unmap of RX packets that way, which might mess things up a bit).

When we expose this through the DMA API, I'd quite like this *not* to
be Intel-specific. It could reasonably live in a higher layer and be
usable with all kinds of IOMMU implementations.

smime.p7s
Description: S/MIME cryptographic signature
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH 0/8] R-Car M3-N: Enable EtherAVB device node

2018-02-27 Thread Simon Horman
On Tue, Feb 27, 2018 at 09:28:38AM +0100, jacopo mondi wrote:
> Hi Geert,
> 
> On Mon, Feb 26, 2018 at 07:28:47PM +0100, Geert Uytterhoeven wrote:
> > Hi Jacopo,
> >
> > On Mon, Feb 26, 2018 at 6:57 PM, Jacopo Mondi  
> > wrote:
> > >   as discussed with you Sergei and Geert, in order to enable EtherAVB for
> > > R8A77965 we first wanted to make the phy-mode "rgmii-txid" a board 
> > > specific
> > > property for all other SoCs.
> >
> > Thanks for your series!
> >
> > > This series adds  the phy-mode property to salvator-common.dtsi and reset 
> > > the
> > > one for R8A77965/R8A7796/R8A77995 to "rgmii".
> >
> > I forgot that r8a7795.dtsi and r8a7796.dtsi are used for the ULCB boards, 
> > too.
> > So to avoid regressions, you need to make a similar change to ulcb.dtsi 
> > like you
> > made for salvator-common.dtsi.
> >
> > In addition, r8a77995.dtsi is only used for the Draak board.
> > So you have to update r8a7795-draak.dtsi first, too.
> 
> Of course! I forgot about ULCB (and had a patch for Draak I lost while
> rebasing :/ )
> >
> > > Then, in order to enable EtherAVB for R-Car M3-N, iommu nodes had to be 
> > > added
> > > as they are referenced by the "avb" device node (CC the iommu list for the
> > > series for that reason).
> >
> > I don't think we need the iommu properties and nodes at this early stage.
> > Ethernet works fine without them. Simon, do you agree?
> 
> I'll wait for Simon reply and then resend, possibly without iommu and
> ULCB and Draak patches!

I don't feel strongly about this but I don't think iommu is a strict
dependency of enabling Ethernet and I think its good not to include extra
dependencies - if it was me I'd try to get Ethernet accepted then follow-up
on iommu.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu