Re: use generic DMA mapping code in powerpc V4

2019-01-15 Thread Christian Zigotzky
Next step: 21074ef03c0816ae158721a78cabe9035938 (powerpc/dma: use 
the generic direct mapping bypass)


git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a

git checkout 21074ef03c0816ae158721a78cabe9035938

I was able to compile the kernel for the AmigaOne X1000 (Nemo board with 
PA Semi PA6T-1682M SoC). It boots but the PA Semi onboard ethernet 
doesn't work.


dmesg:

[   12.698063] pasemi_mac :00:14.3 enp0s20f3: renamed from eth0
[   16.516966] IPv6: ADDRCONF(NETDEV_UP): enp0s20f3: link is not ready
[   16.521025] pci :00:1a.0: overflow 0x00026a587802+1646 of DMA 
mask  bus mask 0
[   16.521047] WARNING: CPU: 0 PID: 2318 at kernel/dma/direct.c:43 
.dma_direct_map_page+0x11c/0x200

[   16.521049] Modules linked in:
[   16.521056] CPU: 0 PID: 2318 Comm: NetworkManager Not tainted 
5.0.0-rc2-2_A-EON_AmigaOne_X1000_Nemo-54576-g21074ef-dirty #1
[   16.521059] NIP:  c010395c LR: c0103a30 CTR: 

[   16.521062] REGS: c0026a1a29a0 TRAP: 0700   Not tainted 
(5.0.0-rc2-2_A-EON_AmigaOne_X1000_Nemo-54576-g21074ef-dirty)
[   16.521064] MSR:  9202b032   CR: 
22002442  XER: 2000

[   16.521074] IRQMASK: 0
   GPR00: c0103a30 c0026a1a2c30 
c1923f00 0052
   GPR04: c0026f206778 c0026f20d458 
c1ab1178 7063693a30303030
   GPR08: 0007  
 0010
   GPR12: 3a30303a31612e30 c1b1 
00a79020 00ace140
   GPR16: fffdd958  
 c0026be92220
   GPR20:  c0026a47 
 
   GPR24: 0800 c0026a1c 
c0026bc69280 c0026a1c
   GPR28: c00277b1f588 066e 
c0026d3c68b0 0802

[   16.52] NIP [c010395c] .dma_direct_map_page+0x11c/0x200
[   16.521114] LR [c0103a30] .dma_direct_map_page+0x1f0/0x200
[   16.521116] Call Trace:
[   16.521120] [c0026a1a2c30] [c0103a30] 
.dma_direct_map_page+0x1f0/0x200 (unreliable)
[   16.521126] [c0026a1a2cd0] [c099b84c] 
.pasemi_mac_replenish_rx_ring+0x12c/0x2a0
[   16.521131] [c0026a1a2da0] [c099dcc4] 
.pasemi_mac_open+0x384/0x7c0

[   16.521137] [c0026a1a2e40] [c0c6f4e4] .__dev_open+0x134/0x1e0
[   16.521142] [c0026a1a2ee0] [c0c6fa4c] 
.__dev_change_flags+0x1bc/0x210
[   16.521147] [c0026a1a2f90] [c0c6fae8] 
.dev_change_flags+0x48/0xa0

[   16.521153] [c0026a1a3030] [c0c8c8ec] .do_setlink+0x3dc/0xf60
[   16.521158] [c0026a1a31b0] [c0c8dde4] 
.__rtnl_newlink+0x5e4/0x900

[   16.521163] [c0026a1a35f0] [c0c8e16c] .rtnl_newlink+0x6c/0xb0
[   16.521167] [c0026a1a3680] [c0c89898] 
.rtnetlink_rcv_msg+0x2e8/0x3d0
[   16.521172] [c0026a1a3760] [c0cc0ff0] 
.netlink_rcv_skb+0x120/0x170
[   16.521177] [c0026a1a3820] [c0c87378] 
.rtnetlink_rcv+0x28/0x40
[   16.521181] [c0026a1a38a0] [c0cc0458] 
.netlink_unicast+0x208/0x2f0
[   16.521186] [c0026a1a3950] [c0cc0a08] 
.netlink_sendmsg+0x348/0x460

[   16.521190] [c0026a1a3a30] [c0c387d4] .sock_sendmsg+0x44/0x70
[   16.521195] [c0026a1a3ab0] [c0c3a7fc] 
.___sys_sendmsg+0x30c/0x320
[   16.521199] [c0026a1a3ca0] [c0c3c414] 
.__sys_sendmsg+0x74/0xf0
[   16.521204] [c0026a1a3d90] [c0cb4e00] 
.__se_compat_sys_sendmsg+0x40/0x60

[   16.521210] [c0026a1a3e20] [c000a21c] system_call+0x5c/0x70
[   16.521212] Instruction dump:
[   16.521215] 6000 f8610070 3d20 6129fffe 79290020 e8e7 
7fa74840 409d00b8
[   16.521222] 3d420001 892acb59 2f89 419e00b8 <0fe0> 382100a0 
3860 e8010010

[   16.521231] ---[ end trace 2129e4121bbdd0e9 ]---

I wasn't able to compile it for the AmigaOne X5000 (Cyrus+ board with 
Qoriq P5020 SoC). Error message:


CALL    scripts/checksyscalls.sh
  CHK include/generated/compile.h
  CC  arch/powerpc/sysdev/fsl_pci.o
arch/powerpc/sysdev/fsl_pci.c: In function 'fsl_pci_dma_set_mask':
arch/powerpc/sysdev/fsl_pci.c:142:21: error: 'dma_nommu_ops' undeclared 
(first use in this function)

   set_dma_ops(dev, _nommu_ops);
 ^
arch/powerpc/sysdev/fsl_pci.c:142:21: note: each undeclared identifier 
is reported only once for each function it appears in
scripts/Makefile.build:276: recipe for target 
'arch/powerpc/sysdev/fsl_pci.o' failed

make[2]: *** [arch/powerpc/sysdev/fsl_pci.o] Error 1
scripts/Makefile.build:492: recipe for target 'arch/powerpc/sysdev' failed
make[1]: *** [arch/powerpc/sysdev] Error 2
Makefile:1049: recipe for target 'arch/powerpc' failed
make: *** [arch/powerpc] Error 2

-- Christian


On 15 January 2019 at 09:49AM, Christian Zigotzky wrote:
Next step: 63a6e350e037a21e9a88c8b710129bea7049a80f 

[PATCH 1/3] swiotlb: Introduce swiotlb_max_mapping_size()

2019-01-15 Thread Joerg Roedel
From: Joerg Roedel 

The function returns the maximum size that can be remapped
by the SWIOTLB implementation. This function will be later
exposed to users through the DMA-API.

Signed-off-by: Joerg Roedel 
---
 include/linux/swiotlb.h | 5 +
 kernel/dma/swiotlb.c| 5 +
 2 files changed, 10 insertions(+)

diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 7c007ed7505f..ceb623321f38 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -62,6 +62,7 @@ extern void swiotlb_tbl_sync_single(struct device *hwdev,
 
 extern int
 swiotlb_dma_supported(struct device *hwdev, u64 mask);
+extern size_t swiotlb_max_mapping_size(struct device *dev);
 
 #ifdef CONFIG_SWIOTLB
 extern enum swiotlb_force swiotlb_force;
@@ -95,6 +96,10 @@ static inline unsigned int swiotlb_max_segment(void)
 {
return 0;
 }
+static inline size_t swiotlb_max_mapping_size(struct device *dev)
+{
+   return SIZE_MAX;
+}
 #endif /* CONFIG_SWIOTLB */
 
 extern void swiotlb_print_info(void);
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index d6361776dc5c..c950b3e9f683 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -660,3 +660,8 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask)
 {
return __phys_to_dma(hwdev, io_tlb_end - 1) <= mask;
 }
+
+size_t swiotlb_max_mapping_size(struct device *dev)
+{
+   return ((size_t)1 << IO_TLB_SHIFT) * IO_TLB_SEGSIZE;
+}
-- 
2.17.1

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


[PATCH 3/3] virtio-blk: Consider dma_max_mapping_size() for maximum segment size

2019-01-15 Thread Joerg Roedel
From: Joerg Roedel 

Segments can't be larger than the maximum DMA mapping size
supported on the platform. Take that into account when
setting the maximum segment size for a block device.

Signed-off-by: Joerg Roedel 
---
 drivers/block/virtio_blk.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index b16a887bbd02..6193962a7fec 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -723,7 +723,7 @@ static int virtblk_probe(struct virtio_device *vdev)
struct request_queue *q;
int err, index;
 
-   u32 v, blk_size, sg_elems, opt_io_size;
+   u32 v, blk_size, max_size, sg_elems, opt_io_size;
u16 min_io_size;
u8 physical_block_exp, alignment_offset;
 
@@ -826,14 +826,16 @@ static int virtblk_probe(struct virtio_device *vdev)
/* No real sector limit. */
blk_queue_max_hw_sectors(q, -1U);
 
+   max_size = dma_max_mapping_size(>dev);
+
/* Host can optionally specify maximum segment size and number of
 * segments. */
err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SIZE_MAX,
   struct virtio_blk_config, size_max, );
if (!err)
-   blk_queue_max_segment_size(q, v);
-   else
-   blk_queue_max_segment_size(q, -1U);
+   max_size = min(max_size, v);
+
+   blk_queue_max_segment_size(q, max_size);
 
/* Host can optionally specify the block size of the device */
err = virtio_cread_feature(vdev, VIRTIO_BLK_F_BLK_SIZE,
-- 
2.17.1

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


[PATCH 2/3] dma: Introduce dma_max_mapping_size()

2019-01-15 Thread Joerg Roedel
From: Joerg Roedel 

The function returns the maximum size that can be mapped
using DMA-API functions. The patch also adds the
implementation for direct DMA and a new dma_map_ops pointer
so that other implementations can expose their limit.

Signed-off-by: Joerg Roedel 
---
 include/linux/dma-mapping.h | 16 
 kernel/dma/direct.c | 10 ++
 2 files changed, 26 insertions(+)

diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f6ded992c183..a3ca8a71a704 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -130,6 +130,7 @@ struct dma_map_ops {
enum dma_data_direction direction);
int (*dma_supported)(struct device *dev, u64 mask);
u64 (*get_required_mask)(struct device *dev);
+   size_t (*max_mapping_size)(struct device *dev);
 };
 
 #define DMA_MAPPING_ERROR  (~(dma_addr_t)0)
@@ -257,6 +258,8 @@ static inline void dma_direct_sync_sg_for_cpu(struct device 
*dev,
 }
 #endif
 
+size_t dma_direct_max_mapping_size(struct device *dev);
+
 #ifdef CONFIG_HAS_DMA
 #include 
 
@@ -440,6 +443,19 @@ static inline int dma_mapping_error(struct device *dev, 
dma_addr_t dma_addr)
return 0;
 }
 
+static inline size_t dma_max_mapping_size(struct device *dev)
+{
+   const struct dma_map_ops *ops = get_dma_ops(dev);
+   size_t size = SIZE_MAX;
+
+   if (dma_is_direct(ops))
+   size = dma_direct_max_mapping_size(dev);
+   else if (ops && ops->max_mapping_size)
+   size = ops->max_mapping_size(dev);
+
+   return size;
+}
+
 void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t flag, unsigned long attrs);
 void dma_free_attrs(struct device *dev, size_t size, void *cpu_addr,
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 355d16acee6d..84917e1003c4 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -380,3 +380,13 @@ int dma_direct_supported(struct device *dev, u64 mask)
 */
return mask >= __phys_to_dma(dev, min_mask);
 }
+
+size_t dma_direct_max_mapping_size(struct device *dev)
+{
+   /*
+* Return the minimum of the direct DMA limit and the SWIOTLB limit.
+* Since direct DMA has no limit, it is fine to just return the SWIOTLB
+* limit.
+*/
+   return swiotlb_max_mapping_size(dev);
+}
-- 
2.17.1

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


Re: [RFC v2] iommu/vt-d: Allow iommu_domain_alloc to allocate IOMMU_DOMAIN_DMA

2019-01-15 Thread James Sewart via iommu
Hey Jacob,

> On 7 Jan 2019, at 20:04, Jacob Pan  wrote:
> 
> On Wed, 5 Dec 2018 17:19:35 +
> James Sewart  wrote:
> 
>> Hey,
>> 
>> There exists an issue in the logic used to determine domain
>> association with devices. Currently the driver uses
>> find_or_alloc_domain to either reuse an existing domain or allocate a
>> new one if one isn’t found. Domains should be shared between all
>> members of an IOMMU group as this is the minimum granularity that we
>> can guarantee address space isolation.
>> 
>> The intel IOMMU driver exposes pci_device_group in intel_iommu_ops as
>> the function to call to determine the group of a device, this is
>> implemented in the generic IOMMU code and checks: dma aliases,
>> upstream pcie switch ACS, pci aliases, and pci function aliases. The
>> find_or_alloc_domain code currently only uses dma aliases to
>> determine if a domain is shared. This causes a disconnect between
>> IOMMU groups and domains. We have observed devices under a pcie
>> switch each having their own domain but assigned the same group.
>> 
>> One solution would be to fix the logic in find_or_alloc_domain to add 
>> checks for the other conditions that a device may share a domain.
>> However, this duplicates code which the generic IOMMU code
>> implements. Instead this issue can be fixed by allowing the
>> allocation of default_domain on the IOMMU group. This is not
>> currently supported as the intel driver does not allow allocation of
>> domain type IOMMU_DOMAIN_DMA.
>> 
>> Allowing allocation of DMA domains has the effect that the
>> default_domain is non NULL and is attached to a device when
>> initialising. This delegates the handling of domains to the generic
>> IOMMU code. Once this is implemented it is possible to remove the
>> lazy allocation of domains entirely.
>> 
> This can also consolidate the domain storage, i.e. move domain from
> device_domain_info to iommu_group.

The plan was to have a patchset that first added the functionality below, 
making use of the group domain storage but keeping the lazy allocation. 
Then subsequent patches that remove the lazy allocation. To also remove 
the device_domain_info it looks like some of the information there might 
need moving into the domain?

>> This patch implements DMA and identity domains to be allocated for 
>> external management. As it isn’t known which device will be attached
>> to a domain, the dma domain is not initialised at alloc time. Instead
>> it is allocated when attached. As we may lose RMRR mappings when
>> attaching a device to a new domain, we also ensure these are mapped
>> at attach time.
>> 
>> This will likely conflict with the work done for auxiliary domains by 
>> Baolu but the code to accommodate won’t change much.
>> 
>> I had also started on a patch to remove find_or_alloc_domain and
>> various functions that call it but had issues with edge cases such as 
>> iommu_prepare_isa that is doing domain operations at IOMMU init time.
>> 
>> Cheers,
>> James.
>> 
>> 
>> ---
>> drivers/iommu/intel-iommu.c | 159
>> +--- 1 file changed, 110
>> insertions(+), 49 deletions(-)
>> 
>> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
>> index 41a4b8808802..6437cb2e9b22 100644
>> --- a/drivers/iommu/intel-iommu.c
>> +++ b/drivers/iommu/intel-iommu.c
>> @@ -351,6 +351,14 @@ static int hw_pass_through = 1;
>> /* si_domain contains mulitple devices */
>> #define DOMAIN_FLAG_STATIC_IDENTITY  (1 << 1)
>> 
>> +/* Domain managed externally, don't cleanup if it isn't attached
>> + * to any devices. */
>> +#define DOMAIN_FLAG_NO_CLEANUP  (1 << 2)
>> +
> the name NO_CLEANUP is a little counter intuitive to me, should it be
> called UNINITIALISED?

I don’t think uninitialised is accurate, the domain may be initialised. It 
is used to distinguish between domains allocated by the external API, 
which we shouldn’t automatically cleanup, and domains allocated internally, 
which should. I agree a better name could be found.

>> +/* Set after domain initialisation. Used when allocating dma domains
>> to
>> + * defer domain initialisation until it is attached to a device */
>> +#define DOMAIN_FLAG_INITIALISED (1 << 4)
>> +
>> #define for_each_domain_iommu(idx, domain)   \
>>  for (idx = 0; idx < g_num_of_iommus; idx++) \
>>  if (domain->iommu_refcnt[idx])
>> @@ -624,6 +632,16 @@ static inline int domain_type_is_vm_or_si(struct
>> dmar_domain *domain) DOMAIN_FLAG_STATIC_IDENTITY);
>> }
>> 
>> +static inline int domain_managed_externally(struct dmar_domain
>> *domain) +{
>> +return domain->flags & DOMAIN_FLAG_NO_CLEANUP;
>> +}
>> +
>> +static inline int domain_is_initialised(struct dmar_domain *domain)
>> +{
>> +return domain->flags & DOMAIN_FLAG_INITIALISED;
>> +}
>> +
>> static inline int domain_pfn_supported(struct dmar_domain *domain,
>> unsigned long pfn)
>> {
>> @@ -1717,7 +1735,7 @@ static void 

Re: [PATCH 1/3] swiotlb: Export maximum allocation size

2019-01-15 Thread Christoph Hellwig
On Mon, Jan 14, 2019 at 04:59:27PM -0500, Michael S. Tsirkin wrote:
> On Mon, Jan 14, 2019 at 03:49:07PM -0500, Konrad Rzeszutek Wilk wrote:
> > On Fri, Jan 11, 2019 at 10:12:31AM +0100, Joerg Roedel wrote:
> > > On Thu, Jan 10, 2019 at 12:02:05PM -0500, Konrad Rzeszutek Wilk wrote:
> > > > Why not use swiotlb_nr_tbl ? That is how drivers/gpu/drm use to figure 
> > > > if they
> > > > need to limit the size of pages.
> > > 
> > > That function just exports the overall size of the swiotlb aperture, no?
> > > What I need here is the maximum size for a single mapping.
> > 
> > Yes. The other drivers just assumed that if there is SWIOTLB they would use
> > the smaller size by default (as in they knew the limitation).
> > 
> > But I agree it would be better to have something smarter - and also convert 
> > the
> > DRM drivers to piggy back on this.
> > 
> > Or alternatively we could make SWIOTLB handle bigger sizes..
> 
> 
> Just a thought: is it a good idea to teach blk_queue_max_segment_size
> to get the dma size? This will help us find other devices
> possibly missing this check.

Yes, we should.  Both the existing DMA size communicated through dma_params
which is set by the driver, and this new DMA-ops exposed one which needs
to be added.  I'm working on some preliminary patches for the first part,
as I think I introduced a bug related to that in the SCSI layer in 5.0..
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: use generic DMA mapping code in powerpc V4

2019-01-15 Thread Christian Zigotzky

On 15 January 2019 at 2:35PM, Christoph Hellwig wrote:

On Tue, Jan 15, 2019 at 11:55:25AM +0100, Christian Zigotzky wrote:

Next step: 21074ef03c0816ae158721a78cabe9035938 (powerpc/dma: use the
generic direct mapping bypass)

git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a

git checkout 21074ef03c0816ae158721a78cabe9035938

I was able to compile the kernel for the AmigaOne X1000 (Nemo board with PA
Semi PA6T-1682M SoC). It boots but the PA Semi onboard ethernet doesn't
work.

Thanks.  But we are exactly missing the steps that are relevant.  I've
pushed a fixed up powerpc-dma.6 tree, which will only change starting from
the first commit that didn't link.

The first commit that changed from the old one is this one:

http://git.infradead.org/users/hch/misc.git/commitdiff/257002094bc5935dd63207a380d9698ab81f0775

which was that one that your compile failed on first.

Thanks again for all your work!

Thank you! I tried the commit 240d7ecd7f6fa62e074e8a835e620047954f0b28 
(powerpc/dma: use the dma-direct allocator for coherent platforms) again.


git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a

git checkout 240d7ecd7f6fa62e074e8a835e620047954f0b28

I modified the 'dma.c' patch because of the undefined references to 
'__dma_nommu_free_coherent' and '__dma_nommu_alloc_coherent':


---

@@ -163,8 +99,13 @@ static inline void dma_nommu_sync_single(struct 
device *dev,

 #endif

 const struct dma_map_ops dma_nommu_ops = {
+   .alloc  = dma_direct_alloc,
+   .free   = dma_direct_free,
    .map_sg = dma_nommu_map_sg,
    .unmap_sg   = dma_nommu_unmap_sg,
    .dma_supported  = dma_direct_supported,

---

The X1000 boots and the PASEMI onboard ethernet works! X5000 (P5020 
board): U-Boot loads the kernel and the dtb file. Then the kernel starts 
but it doesn't find any hard disks (partitions).


-- Christian

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

[PATCH v7 1/7] dt-bindings: virtio-mmio: Add IOMMU description

2019-01-15 Thread Jean-Philippe Brucker
The nature of a virtio-mmio node is discovered by the virtio driver at
probe time. However the DMA relation between devices must be described
statically. When a virtio-mmio node is a virtio-iommu device, it needs an
"#iommu-cells" property as specified by bindings/iommu/iommu.txt.

Otherwise, the virtio-mmio device may perform DMA through an IOMMU, which
requires an "iommus" property. Describe these requirements in the
device-tree bindings documentation.

Reviewed-by: Rob Herring 
Reviewed-by: Eric Auger 
Signed-off-by: Jean-Philippe Brucker 
---
 .../devicetree/bindings/virtio/mmio.txt   | 30 +++
 1 file changed, 30 insertions(+)

diff --git a/Documentation/devicetree/bindings/virtio/mmio.txt 
b/Documentation/devicetree/bindings/virtio/mmio.txt
index 5069c1b8e193..21af30fbb81f 100644
--- a/Documentation/devicetree/bindings/virtio/mmio.txt
+++ b/Documentation/devicetree/bindings/virtio/mmio.txt
@@ -8,10 +8,40 @@ Required properties:
 - reg: control registers base address and size including configuration 
space
 - interrupts:  interrupt generated by the device
 
+Required properties for virtio-iommu:
+
+- #iommu-cells:When the node corresponds to a virtio-iommu device, it 
is
+   linked to DMA masters using the "iommus" or "iommu-map"
+   properties [1][2]. #iommu-cells specifies the size of the
+   "iommus" property. For virtio-iommu #iommu-cells must be
+   1, each cell describing a single endpoint ID.
+
+Optional properties:
+
+- iommus:  If the device accesses memory through an IOMMU, it should
+   have an "iommus" property [1]. Since virtio-iommu itself
+   does not access memory through an IOMMU, the "virtio,mmio"
+   node cannot have both an "#iommu-cells" and an "iommus"
+   property.
+
 Example:
 
virtio_block@3000 {
compatible = "virtio,mmio";
reg = <0x3000 0x100>;
interrupts = <41>;
+
+   /* Device has endpoint ID 23 */
+   iommus = < 23>
}
+
+   viommu: iommu@3100 {
+   compatible = "virtio,mmio";
+   reg = <0x3100 0x100>;
+   interrupts = <42>;
+
+   #iommu-cells = <1>
+   }
+
+[1] Documentation/devicetree/bindings/iommu/iommu.txt
+[2] Documentation/devicetree/bindings/pci/pci-iommu.txt
-- 
2.19.1

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


[PATCH v7 2/7] dt-bindings: virtio: Add virtio-pci-iommu node

2019-01-15 Thread Jean-Philippe Brucker
Some systems implement virtio-iommu as a PCI endpoint. The operating
system needs to discover the relationship between IOMMU and masters long
before the PCI endpoint gets probed. Add a PCI child node to describe the
virtio-iommu device.

The virtio-pci-iommu is conceptually split between a PCI programming
interface and a translation component on the parent bus. The latter
doesn't have a node in the device tree. The virtio-pci-iommu node
describes both, by linking the PCI endpoint to "iommus" property of DMA
master nodes and to "iommu-map" properties of bus nodes.

Reviewed-by: Rob Herring 
Reviewed-by: Eric Auger 
Signed-off-by: Jean-Philippe Brucker 
---
 .../devicetree/bindings/virtio/iommu.txt  | 66 +++
 1 file changed, 66 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/virtio/iommu.txt

diff --git a/Documentation/devicetree/bindings/virtio/iommu.txt 
b/Documentation/devicetree/bindings/virtio/iommu.txt
new file mode 100644
index ..2407fea0651c
--- /dev/null
+++ b/Documentation/devicetree/bindings/virtio/iommu.txt
@@ -0,0 +1,66 @@
+* virtio IOMMU PCI device
+
+When virtio-iommu uses the PCI transport, its programming interface is
+discovered dynamically by the PCI probing infrastructure. However the
+device tree statically describes the relation between IOMMU and DMA
+masters. Therefore, the PCI root complex that hosts the virtio-iommu
+contains a child node representing the IOMMU device explicitly.
+
+Required properties:
+
+- compatible:  Should be "virtio,pci-iommu"
+- reg: PCI address of the IOMMU. As defined in the PCI Bus
+   Binding reference [1], the reg property is a five-cell
+   address encoded as (phys.hi phys.mid phys.lo size.hi
+   size.lo). phys.hi should contain the device's BDF as
+   0b  dfff . The other cells
+   should be zero.
+- #iommu-cells:Each platform DMA master managed by the IOMMU is 
assigned
+   an endpoint ID, described by the "iommus" property [2].
+   For virtio-iommu, #iommu-cells must be 1.
+
+Notes:
+
+- DMA from the IOMMU device isn't managed by another IOMMU. Therefore the
+  virtio-iommu node doesn't have an "iommus" property, and is omitted from
+  the iommu-map property of the root complex.
+
+Example:
+
+pcie@1000 {
+   compatible = "pci-host-ecam-generic";
+   ...
+
+   /* The IOMMU programming interface uses slot 00:01.0 */
+   iommu0: iommu@0008 {
+   compatible = "virtio,pci-iommu";
+   reg = <0x0800 0 0 0 0>;
+   #iommu-cells = <1>;
+   };
+
+   /*
+* The IOMMU manages all functions in this PCI domain except
+* itself. Omit BDF 00:01.0.
+*/
+   iommu-map = <0x0  0x0 0x8>
+   <0x9  0x9 0xfff7>;
+};
+
+pcie@2000 {
+   compatible = "pci-host-ecam-generic";
+   ...
+   /*
+* The IOMMU also manages all functions from this domain,
+* with endpoint IDs 0x1 - 0x1
+*/
+   iommu-map = <0x0  0x1 0x1>;
+};
+
+ethernet@fe001000 {
+   ...
+   /* The IOMMU manages this platform device with endpoint ID 0x2 */
+   iommus = < 0x2>;
+};
+
+[1] Documentation/devicetree/bindings/pci/pci.txt
+[2] Documentation/devicetree/bindings/iommu/iommu.txt
-- 
2.19.1

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


[PATCH v7 0/7] Add virtio-iommu driver

2019-01-15 Thread Jean-Philippe Brucker
Implement the virtio-iommu driver, following specification v0.9 [1].

This is a simple rebase onto Linux v5.0-rc2. We now use the
dev_iommu_fwspec_get() helper introduced in v5.0 instead of accessing
dev->iommu_fwspec, but there aren't any functional change from v6 [2].

Our current goal for virtio-iommu is to get a paravirtual IOMMU working
on Arm, and enable device assignment to guest userspace. In this
use-case the mappings are static, and don't require optimal performance,
so this series tries to keep things simple. However there is plenty more
to do for features and optimizations, and having this base in v5.1 would
be good. Given that most of the changes are to drivers/iommu, I believe
the driver and future changes should go via the IOMMU tree.

You can find Linux driver and kvmtool device on v0.9.2 branches [3],
module and x86 support on virtio-iommu/devel. Also tested with Eric's
QEMU device [4]. Please note that the series depends on Robin's
probe-deferral fix [5], which will hopefully land in v5.0.

[1] Virtio-iommu specification v0.9, sources and pdf
git://linux-arm.org/virtio-iommu.git virtio-iommu/v0.9
http://jpbrucker.net/virtio-iommu/spec/v0.9/virtio-iommu-v0.9.pdf

[2] [PATCH v6 0/7] Add virtio-iommu driver
https://lists.linuxfoundation.org/pipermail/iommu/2018-December/032127.html

[3] git://linux-arm.org/linux-jpb.git virtio-iommu/v0.9.2
git://linux-arm.org/kvmtool-jpb.git virtio-iommu/v0.9.2

[4] [RFC v9 00/17] VIRTIO-IOMMU device
https://www.mail-archive.com/qemu-devel@nongnu.org/msg575578.html

[5] [PATCH] iommu/of: Fix probe-deferral
https://www.spinics.net/lists/arm-kernel/msg698371.html

Jean-Philippe Brucker (7):
  dt-bindings: virtio-mmio: Add IOMMU description
  dt-bindings: virtio: Add virtio-pci-iommu node
  of: Allow the iommu-map property to omit untranslated devices
  PCI: OF: Initialize dev->fwnode appropriately
  iommu: Add virtio-iommu driver
  iommu/virtio: Add probe request
  iommu/virtio: Add event queue

 .../devicetree/bindings/virtio/iommu.txt  |   66 +
 .../devicetree/bindings/virtio/mmio.txt   |   30 +
 MAINTAINERS   |7 +
 drivers/iommu/Kconfig |   11 +
 drivers/iommu/Makefile|1 +
 drivers/iommu/virtio-iommu.c  | 1158 +
 drivers/of/base.c |   10 +-
 drivers/pci/of.c  |7 +
 include/uapi/linux/virtio_ids.h   |1 +
 include/uapi/linux/virtio_iommu.h |  161 +++
 10 files changed, 1449 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/virtio/iommu.txt
 create mode 100644 drivers/iommu/virtio-iommu.c
 create mode 100644 include/uapi/linux/virtio_iommu.h

-- 
2.19.1

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


[PATCH v7 6/7] iommu/virtio: Add probe request

2019-01-15 Thread Jean-Philippe Brucker
When the device offers the probe feature, send a probe request for each
device managed by the IOMMU. Extract RESV_MEM information. When we
encounter a MSI doorbell region, set it up as a IOMMU_RESV_MSI region.
This will tell other subsystems that there is no need to map the MSI
doorbell in the virtio-iommu, because MSIs bypass it.

Tested-by: Bharat Bhushan 
Tested-by: Eric Auger 
Reviewed-by: Eric Auger 
Signed-off-by: Jean-Philippe Brucker 
---
 drivers/iommu/virtio-iommu.c  | 157 --
 include/uapi/linux/virtio_iommu.h |  36 +++
 2 files changed, 187 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 6fa012cd727e..5e194493a531 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -46,6 +46,7 @@ struct viommu_dev {
struct iommu_domain_geometrygeometry;
u64 pgsize_bitmap;
u8  domain_bits;
+   u32 probe_size;
 };
 
 struct viommu_mapping {
@@ -67,8 +68,10 @@ struct viommu_domain {
 };
 
 struct viommu_endpoint {
+   struct device   *dev;
struct viommu_dev   *viommu;
struct viommu_domain*vdomain;
+   struct list_headresv_regions;
 };
 
 struct viommu_request {
@@ -119,6 +122,9 @@ static off_t viommu_get_write_desc_offset(struct viommu_dev 
*viommu,
 {
size_t tail_size = sizeof(struct virtio_iommu_req_tail);
 
+   if (req->type == VIRTIO_IOMMU_T_PROBE)
+   return len - viommu->probe_size - tail_size;
+
return len - tail_size;
 }
 
@@ -393,6 +399,110 @@ static int viommu_replay_mappings(struct viommu_domain 
*vdomain)
return ret;
 }
 
+static int viommu_add_resv_mem(struct viommu_endpoint *vdev,
+  struct virtio_iommu_probe_resv_mem *mem,
+  size_t len)
+{
+   size_t size;
+   u64 start64, end64;
+   phys_addr_t start, end;
+   struct iommu_resv_region *region = NULL;
+   unsigned long prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
+
+   start = start64 = le64_to_cpu(mem->start);
+   end = end64 = le64_to_cpu(mem->end);
+   size = end64 - start64 + 1;
+
+   /* Catch any overflow, including the unlikely end64 - start64 + 1 = 0 */
+   if (start != start64 || end != end64 || size < end64 - start64)
+   return -EOVERFLOW;
+
+   if (len < sizeof(*mem))
+   return -EINVAL;
+
+   switch (mem->subtype) {
+   default:
+   dev_warn(vdev->dev, "unknown resv mem subtype 0x%x\n",
+mem->subtype);
+   /* Fall-through */
+   case VIRTIO_IOMMU_RESV_MEM_T_RESERVED:
+   region = iommu_alloc_resv_region(start, size, 0,
+IOMMU_RESV_RESERVED);
+   break;
+   case VIRTIO_IOMMU_RESV_MEM_T_MSI:
+   region = iommu_alloc_resv_region(start, size, prot,
+IOMMU_RESV_MSI);
+   break;
+   }
+   if (!region)
+   return -ENOMEM;
+
+   list_add(>resv_regions, >list);
+   return 0;
+}
+
+static int viommu_probe_endpoint(struct viommu_dev *viommu, struct device *dev)
+{
+   int ret;
+   u16 type, len;
+   size_t cur = 0;
+   size_t probe_len;
+   struct virtio_iommu_req_probe *probe;
+   struct virtio_iommu_probe_property *prop;
+   struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+   struct viommu_endpoint *vdev = fwspec->iommu_priv;
+
+   if (!fwspec->num_ids)
+   return -EINVAL;
+
+   probe_len = sizeof(*probe) + viommu->probe_size +
+   sizeof(struct virtio_iommu_req_tail);
+   probe = kzalloc(probe_len, GFP_KERNEL);
+   if (!probe)
+   return -ENOMEM;
+
+   probe->head.type = VIRTIO_IOMMU_T_PROBE;
+   /*
+* For now, assume that properties of an endpoint that outputs multiple
+* IDs are consistent. Only probe the first one.
+*/
+   probe->endpoint = cpu_to_le32(fwspec->ids[0]);
+
+   ret = viommu_send_req_sync(viommu, probe, probe_len);
+   if (ret)
+   goto out_free;
+
+   prop = (void *)probe->properties;
+   type = le16_to_cpu(prop->type) & VIRTIO_IOMMU_PROBE_T_MASK;
+
+   while (type != VIRTIO_IOMMU_PROBE_T_NONE &&
+  cur < viommu->probe_size) {
+   len = le16_to_cpu(prop->length) + sizeof(*prop);
+
+   switch (type) {
+   case VIRTIO_IOMMU_PROBE_T_RESV_MEM:
+   ret = viommu_add_resv_mem(vdev, (void *)prop, len);
+   break;
+   default:
+   dev_err(dev, "unknown viommu prop 0x%x\n", type);
+   }
+
+   if (ret)
+  

[PATCH v7 5/7] iommu: Add virtio-iommu driver

2019-01-15 Thread Jean-Philippe Brucker
The virtio IOMMU is a para-virtualized device, allowing to send IOMMU
requests such as map/unmap over virtio transport without emulating page
tables. This implementation handles ATTACH, DETACH, MAP and UNMAP
requests.

The bulk of the code transforms calls coming from the IOMMU API into
corresponding virtio requests. Mappings are kept in an interval tree
instead of page tables. A little more work is required for modular and x86
support, so for the moment the driver depends on CONFIG_VIRTIO=y and
CONFIG_ARM64.

Tested-by: Bharat Bhushan 
Tested-by: Eric Auger 
Reviewed-by: Eric Auger 
Signed-off-by: Jean-Philippe Brucker 
---
 MAINTAINERS   |   7 +
 drivers/iommu/Kconfig |  11 +
 drivers/iommu/Makefile|   1 +
 drivers/iommu/virtio-iommu.c  | 916 ++
 include/uapi/linux/virtio_ids.h   |   1 +
 include/uapi/linux/virtio_iommu.h | 106 
 6 files changed, 1042 insertions(+)
 create mode 100644 drivers/iommu/virtio-iommu.c
 create mode 100644 include/uapi/linux/virtio_iommu.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 4d04cebb4a71..1ef06a1e0525 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16274,6 +16274,13 @@ S: Maintained
 F: drivers/virtio/virtio_input.c
 F: include/uapi/linux/virtio_input.h
 
+VIRTIO IOMMU DRIVER
+M: Jean-Philippe Brucker 
+L: virtualizat...@lists.linux-foundation.org
+S: Maintained
+F: drivers/iommu/virtio-iommu.c
+F: include/uapi/linux/virtio_iommu.h
+
 VIRTUAL BOX GUEST DEVICE DRIVER
 M: Hans de Goede 
 M: Arnd Bergmann 
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index d9a25715650e..d507fd754214 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -435,4 +435,15 @@ config QCOM_IOMMU
help
  Support for IOMMU on certain Qualcomm SoCs.
 
+config VIRTIO_IOMMU
+   bool "Virtio IOMMU driver"
+   depends on VIRTIO=y
+   depends on ARM64
+   select IOMMU_API
+   select INTERVAL_TREE
+   help
+ Para-virtualised IOMMU driver with virtio.
+
+ Say Y here if you intend to run this kernel as a guest.
+
 endif # IOMMU_SUPPORT
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index a158a68c8ea8..48d831a39281 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -32,3 +32,4 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
 obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
 obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
 obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
+obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
new file mode 100644
index ..6fa012cd727e
--- /dev/null
+++ b/drivers/iommu/virtio-iommu.c
@@ -0,0 +1,916 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Virtio driver for the paravirtualized IOMMU
+ *
+ * Copyright (C) 2018 Arm Limited
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#define MSI_IOVA_BASE  0x800
+#define MSI_IOVA_LENGTH0x10
+
+#define VIOMMU_REQUEST_VQ  0
+#define VIOMMU_NR_VQS  1
+
+struct viommu_dev {
+   struct iommu_device iommu;
+   struct device   *dev;
+   struct virtio_device*vdev;
+
+   struct ida  domain_ids;
+
+   struct virtqueue*vqs[VIOMMU_NR_VQS];
+   spinlock_t  request_lock;
+   struct list_headrequests;
+
+   /* Device configuration */
+   struct iommu_domain_geometrygeometry;
+   u64 pgsize_bitmap;
+   u8  domain_bits;
+};
+
+struct viommu_mapping {
+   phys_addr_t paddr;
+   struct interval_tree_node   iova;
+   u32 flags;
+};
+
+struct viommu_domain {
+   struct iommu_domain domain;
+   struct viommu_dev   *viommu;
+   struct mutexmutex; /* protects viommu pointer */
+   unsigned intid;
+
+   spinlock_t  mappings_lock;
+   struct rb_root_cached   mappings;
+
+   unsigned long   nr_endpoints;
+};
+
+struct viommu_endpoint {
+   struct viommu_dev   *viommu;
+   struct viommu_domain*vdomain;
+};
+
+struct viommu_request {
+   struct list_headlist;
+   void*writeback;
+   unsigned intwrite_offset;
+   unsigned intlen;
+   charbuf[];
+};
+
+#define to_viommu_domain(domain)   \
+   container_of(domain, struct viommu_domain, 

[PATCH v7 7/7] iommu/virtio: Add event queue

2019-01-15 Thread Jean-Philippe Brucker
The event queue offers a way for the device to report access faults from
endpoints. It is implemented on virtqueue #1. Whenever the host needs to
signal a fault, it fills one of the buffers offered by the guest and
interrupts it.

Tested-by: Bharat Bhushan 
Tested-by: Eric Auger 
Reviewed-by: Eric Auger 
Signed-off-by: Jean-Philippe Brucker 
---
 drivers/iommu/virtio-iommu.c  | 115 +++---
 include/uapi/linux/virtio_iommu.h |  19 +
 2 files changed, 125 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 5e194493a531..4620dd221ffd 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -29,7 +29,8 @@
 #define MSI_IOVA_LENGTH0x10
 
 #define VIOMMU_REQUEST_VQ  0
-#define VIOMMU_NR_VQS  1
+#define VIOMMU_EVENT_VQ1
+#define VIOMMU_NR_VQS  2
 
 struct viommu_dev {
struct iommu_device iommu;
@@ -41,6 +42,7 @@ struct viommu_dev {
struct virtqueue*vqs[VIOMMU_NR_VQS];
spinlock_t  request_lock;
struct list_headrequests;
+   void*evts;
 
/* Device configuration */
struct iommu_domain_geometrygeometry;
@@ -82,6 +84,15 @@ struct viommu_request {
charbuf[];
 };
 
+#define VIOMMU_FAULT_RESV_MASK 0xff00
+
+struct viommu_event {
+   union {
+   u32 head;
+   struct virtio_iommu_fault fault;
+   };
+};
+
 #define to_viommu_domain(domain)   \
container_of(domain, struct viommu_domain, domain)
 
@@ -503,6 +514,68 @@ static int viommu_probe_endpoint(struct viommu_dev 
*viommu, struct device *dev)
return ret;
 }
 
+static int viommu_fault_handler(struct viommu_dev *viommu,
+   struct virtio_iommu_fault *fault)
+{
+   char *reason_str;
+
+   u8 reason   = fault->reason;
+   u32 flags   = le32_to_cpu(fault->flags);
+   u32 endpoint= le32_to_cpu(fault->endpoint);
+   u64 address = le64_to_cpu(fault->address);
+
+   switch (reason) {
+   case VIRTIO_IOMMU_FAULT_R_DOMAIN:
+   reason_str = "domain";
+   break;
+   case VIRTIO_IOMMU_FAULT_R_MAPPING:
+   reason_str = "page";
+   break;
+   case VIRTIO_IOMMU_FAULT_R_UNKNOWN:
+   default:
+   reason_str = "unknown";
+   break;
+   }
+
+   /* TODO: find EP by ID and report_iommu_fault */
+   if (flags & VIRTIO_IOMMU_FAULT_F_ADDRESS)
+   dev_err_ratelimited(viommu->dev, "%s fault from EP %u at %#llx 
[%s%s%s]\n",
+   reason_str, endpoint, address,
+   flags & VIRTIO_IOMMU_FAULT_F_READ ? "R" : 
"",
+   flags & VIRTIO_IOMMU_FAULT_F_WRITE ? "W" : 
"",
+   flags & VIRTIO_IOMMU_FAULT_F_EXEC ? "X" : 
"");
+   else
+   dev_err_ratelimited(viommu->dev, "%s fault from EP %u\n",
+   reason_str, endpoint);
+   return 0;
+}
+
+static void viommu_event_handler(struct virtqueue *vq)
+{
+   int ret;
+   unsigned int len;
+   struct scatterlist sg[1];
+   struct viommu_event *evt;
+   struct viommu_dev *viommu = vq->vdev->priv;
+
+   while ((evt = virtqueue_get_buf(vq, )) != NULL) {
+   if (len > sizeof(*evt)) {
+   dev_err(viommu->dev,
+   "invalid event buffer (len %u != %zu)\n",
+   len, sizeof(*evt));
+   } else if (!(evt->head & VIOMMU_FAULT_RESV_MASK)) {
+   viommu_fault_handler(viommu, >fault);
+   }
+
+   sg_init_one(sg, evt, sizeof(*evt));
+   ret = virtqueue_add_inbuf(vq, sg, 1, evt, GFP_ATOMIC);
+   if (ret)
+   dev_err(viommu->dev, "could not add event buffer\n");
+   }
+
+   virtqueue_kick(vq);
+}
+
 /* IOMMU API */
 
 static struct iommu_domain *viommu_domain_alloc(unsigned type)
@@ -886,16 +959,35 @@ static struct iommu_ops viommu_ops = {
 static int viommu_init_vqs(struct viommu_dev *viommu)
 {
struct virtio_device *vdev = dev_to_virtio(viommu->dev);
-   const char *name = "request";
-   void *ret;
+   const char *names[] = { "request", "event" };
+   vq_callback_t *callbacks[] = {
+   NULL, /* No async requests */
+   viommu_event_handler,
+   };
 
-   ret = virtio_find_single_vq(vdev, NULL, name);
-   if (IS_ERR(ret)) {
-   dev_err(viommu->dev, "cannot find VQ\n");
-   return PTR_ERR(ret);
-   }
+   return virtio_find_vqs(vdev, VIOMMU_NR_VQS, viommu->vqs, 

[PATCH v7 4/7] PCI: OF: Initialize dev->fwnode appropriately

2019-01-15 Thread Jean-Philippe Brucker
For PCI devices that have an OF node, set the fwnode as well. This way
drivers that rely on fwnode don't need the special case described by
commit f94277af03ea ("of/platform: Initialise dev->fwnode appropriately").

Acked-by: Bjorn Helgaas 
Signed-off-by: Jean-Philippe Brucker 
---
 drivers/pci/of.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 4c4217d0c3f1..c272ecfcd038 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -21,12 +21,15 @@ void pci_set_of_node(struct pci_dev *dev)
return;
dev->dev.of_node = of_pci_find_child_device(dev->bus->dev.of_node,
dev->devfn);
+   if (dev->dev.of_node)
+   dev->dev.fwnode = >dev.of_node->fwnode;
 }
 
 void pci_release_of_node(struct pci_dev *dev)
 {
of_node_put(dev->dev.of_node);
dev->dev.of_node = NULL;
+   dev->dev.fwnode = NULL;
 }
 
 void pci_set_bus_of_node(struct pci_bus *bus)
@@ -35,12 +38,16 @@ void pci_set_bus_of_node(struct pci_bus *bus)
bus->dev.of_node = pcibios_get_phb_of_node(bus);
else
bus->dev.of_node = of_node_get(bus->self->dev.of_node);
+
+   if (bus->dev.of_node)
+   bus->dev.fwnode = >dev.of_node->fwnode;
 }
 
 void pci_release_bus_of_node(struct pci_bus *bus)
 {
of_node_put(bus->dev.of_node);
bus->dev.of_node = NULL;
+   bus->dev.fwnode = NULL;
 }
 
 struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus)
-- 
2.19.1

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


[PATCH v7 3/7] of: Allow the iommu-map property to omit untranslated devices

2019-01-15 Thread Jean-Philippe Brucker
In PCI root complex nodes, the iommu-map property describes the IOMMU that
translates each endpoint. On some platforms, the IOMMU itself is presented
as a PCI endpoint (e.g. AMD IOMMU and virtio-iommu). This isn't supported
by the current OF driver, which expects all endpoints to have an IOMMU.
Allow the iommu-map property to have gaps.

Relaxing of_map_rid() also allows the msi-map property to have gaps, which
is invalid since MSIs always reach an MSI controller. In that case
pci_msi_setup_msi_irqs() will return an error when attempting to find the
device's MSI domain.

Reviewed-by: Rob Herring 
Signed-off-by: Jean-Philippe Brucker 
---
 drivers/of/base.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 5226e898476e..4d12b1cab55f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2293,8 +2293,12 @@ int of_map_rid(struct device_node *np, u32 rid,
return 0;
}
 
-   pr_err("%pOF: Invalid %s translation - no match for rid 0x%x on %pOF\n",
-   np, map_name, rid, target && *target ? *target : NULL);
-   return -EFAULT;
+   pr_info("%pOF: no %s translation for rid 0x%x on %pOF\n", np, map_name,
+   rid, target && *target ? *target : NULL);
+
+   /* Bypasses translation */
+   if (id_out)
+   *id_out = rid;
+   return 0;
 }
 EXPORT_SYMBOL_GPL(of_map_rid);
-- 
2.19.1

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


Re: [PATCH v5 4/8] iommu/vt-d: Aux-domain specific domain attach/detach

2019-01-15 Thread Jonathan Cameron
On Tue, 15 Jan 2019 10:10:21 +0800
Lu Baolu  wrote:

> Hi,
> 
> On 1/14/19 8:26 PM, Jonathan Cameron wrote:
> > On Thu, 10 Jan 2019 11:00:23 +0800
> > Lu Baolu  wrote:
> >   
> >> When multiple domains per device has been enabled by the
> >> device driver, the device will tag the default PASID for
> >> the domain to all DMA traffics out of the subset of this
> >> device; and the IOMMU should translate the DMA requests
> >> in PASID granularity.
> >>
> >> This adds the intel_iommu_aux_attach/detach_device() ops
> >> to support managing PASID granular translation structures
> >> when the device driver has enabled multiple domains per
> >> device.
> >>
> >> Cc: Ashok Raj 
> >> Cc: Jacob Pan 
> >> Cc: Kevin Tian 
> >> Signed-off-by: Sanjay Kumar 
> >> Signed-off-by: Liu Yi L 
> >> Signed-off-by: Lu Baolu   
> > 
> > The following is probably a rather naive review given I don't know
> > the driver or hardware well at all.  Still, it seems like things
> > are a lot less balanced than I'd expect and isn't totally obvious
> > to me why that is.  
> 
> Thank you!

You are welcome.

...

> >> +/*
> >> + * Check whether a @domain could be attached to the @dev through the
> >> + * aux-domain attach/detach APIs.
> >> + */
> >> +static inline bool
> >> +is_aux_domain(struct device *dev, struct iommu_domain *domain)  
> > 
> > I'm finding the distinction between an aux domain capability on
> > a given device and whether one is actually in use to be obscured
> > slightly in the function naming.
> > 
> > This one for example is actually checking if we have a domain
> > that is capable of being enabled for aux domain use, but not
> > yet actually in that mode?
> > 
> > Mind you I'm not sure I have a better answer for the naming.
> > can_aux_domain_be_enabled?  is_unattached_aux_domain?
> > 
> >   
> 
> device aux mode vs. normal mode
> ===
> 
> When we talk about the auxiliary mode (simply aux-mode), it means "the
> device works in aux-mode or normal mode". "normal mode" means that the
> device (and it's corresponding IOMMU) supports only RID (PCI Request ID)
> based DMA translation; while, aux-mode means the the device (and it's
> IOMMU) supports fine-grained DMA translation, like PASID based DMA
> translation with Intel VT-d scalable mode.
> 
> We are adding below APIs to switch a device between these two modes:
> 
> int iommu_dev_enable/disable_feature(dev, IOMMU_DEV_FEAT_AUX)
> 
> And this API (still under discussion) to check which mode the device is
> working in:
> 
> bool iommu_dev_has_feature(dev, IOMMU_DEV_FEAT_AUX)
> 
> aux-domain
> ==
> 
> If a device is working in aux-mode and we are going to attach a domain
> to this device, we say "this domain will be attached to the device in
> aux mode", and simply "aux domain". So a domain is "normal" when it is
> going to attach to a device in normal mode; and is "aux-domain" when it
> is going to attach to a device in aux mode.

Hmm.. OK I guess.  It still feels like there is more need to refer to
the docs than there should be.  Still, your code and I may well never
read it again so I don't mind :)

> 
> >   
> >> +{

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


Re: use generic DMA mapping code in powerpc V4

2019-01-15 Thread Christoph Hellwig
On Tue, Jan 15, 2019 at 11:55:25AM +0100, Christian Zigotzky wrote:
> Next step: 21074ef03c0816ae158721a78cabe9035938 (powerpc/dma: use the 
> generic direct mapping bypass)
>
> git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a
>
> git checkout 21074ef03c0816ae158721a78cabe9035938
>
> I was able to compile the kernel for the AmigaOne X1000 (Nemo board with PA 
> Semi PA6T-1682M SoC). It boots but the PA Semi onboard ethernet doesn't 
> work.

Thanks.  But we are exactly missing the steps that are relevant.  I've
pushed a fixed up powerpc-dma.6 tree, which will only change starting from
the first commit that didn't link.

The first commit that changed from the old one is this one:

http://git.infradead.org/users/hch/misc.git/commitdiff/257002094bc5935dd63207a380d9698ab81f0775

which was that one that your compile failed on first.

Thanks again for all your work!
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 2/3] dma: Introduce dma_max_mapping_size()

2019-01-15 Thread Christoph Hellwig
> +size_t dma_direct_max_mapping_size(struct device *dev)
> +{
> + /*
> +  * Return the minimum of the direct DMA limit and the SWIOTLB limit.
> +  * Since direct DMA has no limit, it is fine to just return the SWIOTLB
> +  * limit.
> +  */
> + return swiotlb_max_mapping_size(dev);

Well, if we don't actually use the swiotlb buffers despite it being
compiled in or even allocated we don't need the limit.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] Revert "ARM: dma-mapping: Set proper DMA ops in arm_iommu_detach_device()"

2019-01-15 Thread Thierry Reding
On Mon, Jan 14, 2019 at 04:38:20PM +, Robin Murphy wrote:
> On 14/01/2019 16:09, Thierry Reding wrote:
> > On Mon, Jan 14, 2019 at 02:22:40PM +0100, Marek Szyprowski wrote:
> > > This reverts commit 1874619a7df4b14b23b14877e705ae15325773e3.
> > > 
> > > That patch broke IOMMU support for devices, which fails to probe for the
> > > first time and use deferred probe approach. When non-NULL dma_ops is set
> > > in arm_iommu_detach_device(), the given device later ignored by
> > > arch_setup_dma_ops() and stays with non-IOMMU dma_ops.
> > > 
> > > Reported-by: Tobias Jakobi 
> > > Fixes: 1874619a7df4 "ARM: dma-mapping: Set proper DMA ops in 
> > > arm_iommu_detach_device()"
> > > Signed-off-by: Marek Szyprowski 
> > > ---
> > >   arch/arm/mm/dma-mapping.c | 12 ++--
> > >   1 file changed, 6 insertions(+), 6 deletions(-)
> > 
> > Can you point out exactly what drivers break because of this change? We
> > need to find a solution that works for everyone. Reverting is only
> > marginally useful because somebody will just end up wanting to revert
> > the revert because a different driver is now broken.
> 
> At first glance, it sounds like what we really want is for
> arch_teardown_iommu_ops() to completely clear any ops that
> arch_setup_dma_ops() installed - does the below suffice?
> 
> Robin.
> 
> ->8-
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index f1e2922e447c..1e3e08a1c456 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -2390,4 +2390,6 @@ void arch_teardown_dma_ops(struct device *dev)
>   return;
> 
>   arm_teardown_iommu_dma_ops(dev);
> + /* Let arch_setup_dma_ops() start again from scratch upon re-probe */
> + set_dma_ops(dev, NULL);
>  }

Seems to work fine on Tegra:

Tested-by: Thierry Reding 


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

Re: use generic DMA mapping code in powerpc V4

2019-01-15 Thread Christoph Hellwig
On Tue, Jan 15, 2019 at 02:56:34PM +0100, Christian Zigotzky wrote:
> On 15 January 2019 at 2:35PM, Christoph Hellwig wrote:
>> On Tue, Jan 15, 2019 at 11:55:25AM +0100, Christian Zigotzky wrote:
>>> Next step: 21074ef03c0816ae158721a78cabe9035938 (powerpc/dma: use the
>>> generic direct mapping bypass)
>>>
>>> git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a
>>>
>>> git checkout 21074ef03c0816ae158721a78cabe9035938
>>>
>>> I was able to compile the kernel for the AmigaOne X1000 (Nemo board with PA
>>> Semi PA6T-1682M SoC). It boots but the PA Semi onboard ethernet doesn't
>>> work.
>> Thanks.  But we are exactly missing the steps that are relevant.  I've
>> pushed a fixed up powerpc-dma.6 tree, which will only change starting from
>> the first commit that didn't link.
>>
>> The first commit that changed from the old one is this one:
>>
>> http://git.infradead.org/users/hch/misc.git/commitdiff/257002094bc5935dd63207a380d9698ab81f0775
>>
>> which was that one that your compile failed on first.
>>
>> Thanks again for all your work!
>>
> Thank you! I tried the commit 240d7ecd7f6fa62e074e8a835e620047954f0b28 
> (powerpc/dma: use the dma-direct allocator for coherent platforms) again.
>
> git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a
>
> git checkout 240d7ecd7f6fa62e074e8a835e620047954f0b28
>
> I modified the 'dma.c' patch because of the undefined references to 
> '__dma_nommu_free_coherent' and '__dma_nommu_alloc_coherent':

So 257002094bc5935dd63207a380d9698ab81f0775 above is the fixed version
for the commit - this switched the ifdef in dma.c around that I had
inverted.  Can you try that one instead?  And then move on with the
commits after it in the updated powerpc-dma.6 branch - they are
identical to the original branch except for carrying this fix forward.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 2/3] dma: Introduce dma_max_mapping_size()

2019-01-15 Thread Joerg Roedel
On Tue, Jan 15, 2019 at 02:37:54PM +0100, Christoph Hellwig wrote:
> > +size_t dma_direct_max_mapping_size(struct device *dev)
> > +{
> > +   /*
> > +* Return the minimum of the direct DMA limit and the SWIOTLB limit.
> > +* Since direct DMA has no limit, it is fine to just return the SWIOTLB
> > +* limit.
> > +*/
> > +   return swiotlb_max_mapping_size(dev);
> 
> Well, if we don't actually use the swiotlb buffers despite it being
> compiled in or even allocated we don't need the limit.

Right, I thought about that too, but didn't find a generic way to check
for all the cases. There are various checks that could be done:

1) Check if SWIOTLB is initialized at all, if not, return
   SIZE_MAX as the limit. This can't be checked from dma-direct
   code right now, but could be easily implemented.

2) Check for swiotlb=force needs to be done.

3) Check whether the device can access all of available RAM. I
   have no idea how to check that in an architecture independent
   way. It also has to take memory hotplug into account as well
   as the DMA mask of the device.

   An easy approximation could be to omit the limit if the
   dma-mask covers all of the physical address bits available
   on the platform. It would require to pass the dma-mask as an
   additional parameter like it is done in dma_supported().

Any better ideas for how to implement 3)?

Regards,

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


[PATCH v2] dma-direct: do not allocate a single page from CMA area

2019-01-15 Thread Nicolin Chen
The addresses within a single page are always contiguous, so it's
not so necessary to allocate one single page from CMA area. Since
the CMA area has a limited predefined size of space, it might run
out of space in some heavy use case, where there might be quite a
lot CMA pages being allocated for single pages.

This patch tries to skip CMA allocations of single pages and lets
them go through normal page allocations unless the allocation has
a DMA_ATTR_FORCE_CONTIGUOUS attribute. This'd save some resources
in the CMA area for further more CMA allocations, and it can also
reduce CMA fragmentations resulted from trivial allocations.

Signed-off-by: Nicolin Chen 
---
Robin/Christoph,

I have some personal priority to submit this patch. I understand
you might have other plan to clean up the code first. Just would
it be possible for you to review and apply this one if it doesn't
conflict too much? Thanks!

Changelog
v1->v2:
 * Added DMA_ATTR_FORCE_CONTIGUOUS flag check so as to enforce
   CMA allocations if callers specified.
 * Added to the commit message the reduction of fragmentations
   suggested by Robin.

 kernel/dma/direct.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 355d16acee6d..5d57f99b2edf 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -109,8 +109,14 @@ struct page *__dma_direct_alloc_pages(struct device *dev, 
size_t size,
gfp |= __dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask,
_mask);
 again:
-   /* CMA can be used only in the context which permits sleeping */
-   if (gfpflags_allow_blocking(gfp)) {
+   /*
+* CMA can be used only in the context which permits sleeping.
+* Since addresses within one PAGE are always contiguous, skip
+* CMA allocation for a single page to save CMA reserved space
+* unless DMA_ATTR_FORCE_CONTIGUOUS is flagged.
+*/
+   if (gfpflags_allow_blocking(gfp) &&
+   (count > 1 || attrs & DMA_ATTR_FORCE_CONTIGUOUS)) {
page = dma_alloc_from_contiguous(dev, count, page_order,
 gfp & __GFP_NOWARN);
if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
-- 
2.17.1

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


Re: [RFC v3 17/21] iommu/smmuv3: Report non recoverable faults

2019-01-15 Thread Auger Eric
Hi Jean,

On 1/11/19 6:46 PM, Jean-Philippe Brucker wrote:
> On 08/01/2019 10:26, Eric Auger wrote:
>> When a stage 1 related fault event is read from the event queue,
>> let's propagate it to potential external fault listeners, ie. users
>> who registered a fault handler.
>>
>> Signed-off-by: Eric Auger 
>> ---
>>  drivers/iommu/arm-smmu-v3.c | 124 
>>  1 file changed, 113 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
>> index 999ee470a2ae..6a711cbbb228 100644
>> --- a/drivers/iommu/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm-smmu-v3.c
>> @@ -168,6 +168,26 @@
>>  #define ARM_SMMU_PRIQ_IRQ_CFG1  0xd8
>>  #define ARM_SMMU_PRIQ_IRQ_CFG2  0xdc
>>  
>> +/* Events */
>> +#define ARM_SMMU_EVT_F_UUT  0x01
>> +#define ARM_SMMU_EVT_C_BAD_STREAMID 0x02
>> +#define ARM_SMMU_EVT_F_STE_FETCH0x03
>> +#define ARM_SMMU_EVT_C_BAD_STE  0x04
>> +#define ARM_SMMU_EVT_F_BAD_ATS_TREQ 0x05
>> +#define ARM_SMMU_EVT_F_STREAM_DISABLED  0x06
>> +#define ARM_SMMU_EVT_F_TRANSL_FORBIDDEN 0x07
>> +#define ARM_SMMU_EVT_C_BAD_SUBSTREAMID  0x08
>> +#define ARM_SMMU_EVT_F_CD_FETCH 0x09
>> +#define ARM_SMMU_EVT_C_BAD_CD   0x0a
>> +#define ARM_SMMU_EVT_F_WALK_EABT0x0b
>> +#define ARM_SMMU_EVT_F_TRANSLATION  0x10
>> +#define ARM_SMMU_EVT_F_ADDR_SIZE0x11
>> +#define ARM_SMMU_EVT_F_ACCESS   0x12
>> +#define ARM_SMMU_EVT_F_PERMISSION   0x13
>> +#define ARM_SMMU_EVT_F_TLB_CONFLICT 0x20
>> +#define ARM_SMMU_EVT_F_CFG_CONFLICT 0x21
>> +#define ARM_SMMU_EVT_E_PAGE_REQUEST 0x24
>> +
>>  /* Common MSI config fields */
>>  #define MSI_CFG0_ADDR_MASK  GENMASK_ULL(51, 2)
>>  #define MSI_CFG2_SH GENMASK(5, 4)
>> @@ -333,6 +353,11 @@
>>  #define EVTQ_MAX_SZ_SHIFT   7
>>  
>>  #define EVTQ_0_ID   GENMASK_ULL(7, 0)
>> +#define EVTQ_0_SUBSTREAMID  GENMASK_ULL(31, 12)
>> +#define EVTQ_0_STREAMID GENMASK_ULL(63, 32)
>> +#define EVTQ_1_S2   GENMASK_ULL(39, 39)
>> +#define EVTQ_1_CLASSGENMASK_ULL(40, 41)
>> +#define EVTQ_3_FETCH_ADDR   GENMASK_ULL(51, 3)
>>  
>>  /* PRI queue */
>>  #define PRIQ_ENT_DWORDS 2
>> @@ -1270,7 +1295,6 @@ static int arm_smmu_init_l2_strtab(struct 
>> arm_smmu_device *smmu, u32 sid)
>>  return 0;
>>  }
>>  
>> -__maybe_unused
>>  static struct arm_smmu_master_data *
>>  arm_smmu_find_master(struct arm_smmu_device *smmu, u32 sid)
>>  {
>> @@ -1296,24 +1320,102 @@ arm_smmu_find_master(struct arm_smmu_device *smmu, 
>> u32 sid)
>>  return master;
>>  }
>>  
>> +static void arm_smmu_report_event(struct arm_smmu_device *smmu, u64 *evt)
>> +{
>> +u64 fetch_addr = FIELD_GET(EVTQ_3_FETCH_ADDR, evt[3]);
>> +u32 sid = FIELD_GET(EVTQ_0_STREAMID, evt[0]);
>> +bool s1 = !FIELD_GET(EVTQ_1_S2, evt[1]);
>> +u8 type = FIELD_GET(EVTQ_0_ID, evt[0]);
>> +struct arm_smmu_master_data *master;
>> +struct iommu_fault_event event;
>> +bool propagate = true;
>> +u64 addr = evt[2];
>> +int i;
>> +
>> +master = arm_smmu_find_master(smmu, sid);
>> +if (WARN_ON(!master))
>> +return;
>> +
>> +event.fault.type = IOMMU_FAULT_DMA_UNRECOV;
>> +
>> +switch (type) {
>> +case ARM_SMMU_EVT_C_BAD_STREAMID:
>> +event.fault.reason = IOMMU_FAULT_REASON_SOURCEID_INVALID;
>> +break;
>> +case ARM_SMMU_EVT_F_STREAM_DISABLED:
>> +case ARM_SMMU_EVT_C_BAD_SUBSTREAMID:
>> +event.fault.reason = IOMMU_FAULT_REASON_PASID_INVALID;
>> +break;
>> +case ARM_SMMU_EVT_F_CD_FETCH:
>> +event.fault.reason = IOMMU_FAULT_REASON_PASID_FETCH;
>> +break;
>> +case ARM_SMMU_EVT_F_WALK_EABT:
>> +event.fault.reason = IOMMU_FAULT_REASON_WALK_EABT;
>> +event.fault.addr = addr;
>> +event.fault.fetch_addr = fetch_addr;
>> +propagate = s1;
>> +break;
>> +case ARM_SMMU_EVT_F_TRANSLATION:
>> +event.fault.reason = IOMMU_FAULT_REASON_PTE_FETCH;
>> +event.fault.addr = addr;
>> +event.fault.fetch_addr = fetch_addr;
>> +propagate = s1;
>> +break;
>> +case ARM_SMMU_EVT_F_PERMISSION:
>> +event.fault.reason = IOMMU_FAULT_REASON_PERMISSION;
>> +event.fault.addr = addr;
>> +propagate = s1;
>> +break;
>> +case ARM_SMMU_EVT_F_ACCESS:
>> +event.fault.reason = IOMMU_FAULT_REASON_ACCESS;
>> +event.fault.addr = addr;
>> +propagate = s1;
>> +break;
>> +case ARM_SMMU_EVT_C_BAD_STE:
>> +event.fault.reason = 
>> IOMMU_FAULT_REASON_BAD_DEVICE_CONTEXT_ENTRY;
>> +break;
>> +case ARM_SMMU_EVT_C_BAD_CD:
>> +event.fault.reason = IOMMU_FAULT_REASON_BAD_PASID_ENTRY;
>> +

Re: [RFC v3 14/21] iommu: introduce device fault data

2019-01-15 Thread Auger Eric
Hi Jean,

On 1/11/19 12:06 PM, Jean-Philippe Brucker wrote:
> On 10/01/2019 18:45, Jacob Pan wrote:
>> On Tue,  8 Jan 2019 11:26:26 +0100
>> Eric Auger  wrote:
>>
>>> From: Jacob Pan 
>>>
>>> Device faults detected by IOMMU can be reported outside IOMMU
>>> subsystem for further processing. This patch intends to provide
>>> a generic device fault data such that device drivers can be
>>> communicated with IOMMU faults without model specific knowledge.
>>>
>>> The proposed format is the result of discussion at:
>>> https://lkml.org/lkml/2017/11/10/291
>>> Part of the code is based on Jean-Philippe Brucker's patchset
>>> (https://patchwork.kernel.org/patch/9989315/).
>>>
>>> The assumption is that model specific IOMMU driver can filter and
>>> handle most of the internal faults if the cause is within IOMMU driver
>>> control. Therefore, the fault reasons can be reported are grouped
>>> and generalized based common specifications such as PCI ATS.
>>>
>>> Signed-off-by: Jacob Pan 
>>> Signed-off-by: Jean-Philippe Brucker 
>>> Signed-off-by: Liu, Yi L 
>>> Signed-off-by: Ashok Raj 
>>> Signed-off-by: Eric Auger 
>>> [moved part of the iommu_fault_event struct in the uapi, enriched
>>>  the fault reasons to be able to map unrecoverable SMMUv3 errors]
>>> ---
>>>  include/linux/iommu.h  | 55 -
>>>  include/uapi/linux/iommu.h | 83
>>> ++ 2 files changed, 136
>>> insertions(+), 2 deletions(-)
>>>
>>> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
>>> index 244c1a3d5989..1dedc2d247c2 100644
>>> --- a/include/linux/iommu.h
>>> +++ b/include/linux/iommu.h
>>> @@ -49,13 +49,17 @@ struct bus_type;
>>>  struct device;
>>>  struct iommu_domain;
>>>  struct notifier_block;
>>> +struct iommu_fault_event;
>>>  
>>>  /* iommu fault flags */
>>> -#define IOMMU_FAULT_READ   0x0
>>> -#define IOMMU_FAULT_WRITE  0x1
>>> +#define IOMMU_FAULT_READ   (1 << 0)
>>> +#define IOMMU_FAULT_WRITE  (1 << 1)
>>> +#define IOMMU_FAULT_EXEC   (1 << 2)
>>> +#define IOMMU_FAULT_PRIV   (1 << 3)
>>>  
>>>  typedef int (*iommu_fault_handler_t)(struct iommu_domain *,
>>> struct device *, unsigned long, int, void *);
>>> +typedef int (*iommu_dev_fault_handler_t)(struct iommu_fault_event *,
>>> void *); 
>>>  struct iommu_domain_geometry {
>>> dma_addr_t aperture_start; /* First address that can be
>>> mapped*/ @@ -255,6 +259,52 @@ struct iommu_device {
>>> struct device *dev;
>>>  };
>>>  
>>> +/**
>>> + * struct iommu_fault_event - Generic per device fault data
>>> + *
>>> + * - PCI and non-PCI devices
>>> + * - Recoverable faults (e.g. page request), information based on
>>> PCI ATS
>>> + * and PASID spec.
>>> + * - Un-recoverable faults of device interest
>>> + * - DMA remapping and IRQ remapping faults
>>> + *
>>> + * @fault: fault descriptor
>>> + * @device_private: if present, uniquely identify device-specific
>>> + *  private data for an individual page request.
>>> + * @iommu_private: used by the IOMMU driver for storing
>>> fault-specific
>>> + * data. Users should not modify this field before
>>> + * sending the fault response.
>>> + */
>>> +struct iommu_fault_event {
>>> +   struct iommu_fault fault;
>>> +   u64 device_private;
>> I think we want to move device_private to uapi since it gets injected
>> into the guest, then returned by guest in case of page response. For
>> VT-d we also need 128 bits of private data. VT-d spec. 7.7.1
> 
> Ah, I didn't notice the format changed in VT-d rev3. On that topic, how
> do we manage future extensions to the iommu_fault struct? Should we add
> ~48 bytes of padding after device_private, along with some flags telling
> which field is valid, or deal with it using a structure version like we
> do for the invalidate and bind structs? In the first case, iommu_fault
> wouldn't fit in a 64-byte cacheline anymore, but I'm not sure we care.
> 
>> For exception tracking (e.g. unanswered page request), I can add timer
>> and list info later when I include PRQ. sounds ok?
>>> +   u64 iommu_private;
> [...]
>>> +/**
>>> + * struct iommu_fault - Generic fault data
>>> + *
>>> + * @type contains fault type
>>> + * @reason fault reasons if relevant outside IOMMU driver.
>>> + * IOMMU driver internal faults are not reported.
>>> + * @addr: tells the offending page address
>>> + * @fetch_addr: tells the address that caused an abort, if any
>>> + * @pasid: contains process address space ID, used in shared virtual
>>> memory
>>> + * @page_req_group_id: page request group index
>>> + * @last_req: last request in a page request group
>>> + * @pasid_valid: indicates if the PRQ has a valid PASID
>>> + * @prot: page access protection flag:
>>> + * IOMMU_FAULT_READ, IOMMU_FAULT_WRITE
>>> + */
>>> +
>>> +struct iommu_fault {
>>> +   __u32   type;   /* enum iommu_fault_type */
>>> +   __u32   reason; /* enum iommu_fault_reason */
>>> +   __u64   

Re: [RFC v3 04/21] vfio: VFIO_IOMMU_SET_PASID_TABLE

2019-01-15 Thread Auger Eric
Hi Alex,

On 1/11/19 11:50 PM, Alex Williamson wrote:
> On Tue,  8 Jan 2019 11:26:16 +0100
> Eric Auger  wrote:
> 
>> From: "Liu, Yi L" 
>>
>> This patch adds VFIO_IOMMU_SET_PASID_TABLE ioctl which aims at
>> passing the virtual iommu guest configuration to the VFIO driver
>> downto to the iommu subsystem.
>>
>> Signed-off-by: Jacob Pan 
>> Signed-off-by: Liu, Yi L 
>> Signed-off-by: Eric Auger 
>>
>> ---
>> v2 -> v3:
>> - s/BIND_PASID_TABLE/SET_PASID_TABLE
>>
>> v1 -> v2:
>> - s/BIND_GUEST_STAGE/BIND_PASID_TABLE
>> - remove the struct device arg
>> ---
>>  drivers/vfio/vfio_iommu_type1.c | 31 +++
>>  include/uapi/linux/vfio.h   |  8 
>>  2 files changed, 39 insertions(+)
>>
>> diff --git a/drivers/vfio/vfio_iommu_type1.c 
>> b/drivers/vfio/vfio_iommu_type1.c
>> index 7651cfb14836..d9dd23f64f00 100644
>> --- a/drivers/vfio/vfio_iommu_type1.c
>> +++ b/drivers/vfio/vfio_iommu_type1.c
>> @@ -1644,6 +1644,24 @@ static int vfio_domains_have_iommu_cache(struct 
>> vfio_iommu *iommu)
>>  return ret;
>>  }
>>  
>> +static int
>> +vfio_set_pasid_table(struct vfio_iommu *iommu,
>> +  struct vfio_iommu_type1_set_pasid_table *ustruct)
>> +{
>> +struct vfio_domain *d;
>> +int ret = 0;
>> +
>> +mutex_lock(>lock);
>> +
>> +list_for_each_entry(d, >domain_list, next) {
>> +ret = iommu_set_pasid_table(d->domain, >config);
>> +if (ret)
>> +break;
>> +}
> 
> There's no unwind on failure here, leaves us in an inconsistent state
> should something go wrong or domains don't have homogeneous PASID
> support.  What's expected to happen if a PASID table is already set for
> a domain, does it replace the old one or return -EBUSY?
Effectively the setting can succeed on one domain and fail on another
one, typically if one underlying SMMU does not support nested while the
others support it.

At the moment setting a new PASID table whereas one is installed does
not return any error in the SMMU code, just overwrite the associated
fields in the stream table entry. This is also the way we turn nested
off (cfg->bypass == true). Needs to be clarified anyway.
> 
>> +mutex_unlock(>lock);
>> +return ret;
>> +}
>> +
>>  static long vfio_iommu_type1_ioctl(void *iommu_data,
>> unsigned int cmd, unsigned long arg)
>>  {
>> @@ -1714,6 +1732,19 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
>>  
>>  return copy_to_user((void __user *)arg, , minsz) ?
>>  -EFAULT : 0;
>> +} else if (cmd == VFIO_IOMMU_SET_PASID_TABLE) {
>> +struct vfio_iommu_type1_set_pasid_table ustruct;
>> +
>> +minsz = offsetofend(struct vfio_iommu_type1_set_pasid_table,
>> +config);
>> +
>> +if (copy_from_user(, (void __user *)arg, minsz))
>> +return -EFAULT;
>> +
>> +if (ustruct.argsz < minsz || ustruct.flags)
>> +return -EINVAL;
>> +
>> +return vfio_set_pasid_table(iommu, );
>>  }
>>  
>>  return -ENOTTY;
>> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
>> index 02bb7ad6e986..0d9f4090c95d 100644
>> --- a/include/uapi/linux/vfio.h
>> +++ b/include/uapi/linux/vfio.h
>> @@ -14,6 +14,7 @@
>>  
>>  #include 
>>  #include 
>> +#include 
>>  
>>  #define VFIO_API_VERSION0
>>  
>> @@ -759,6 +760,13 @@ struct vfio_iommu_type1_dma_unmap {
>>  #define VFIO_IOMMU_ENABLE   _IO(VFIO_TYPE, VFIO_BASE + 15)
>>  #define VFIO_IOMMU_DISABLE  _IO(VFIO_TYPE, VFIO_BASE + 16)
>>  
>> +struct vfio_iommu_type1_set_pasid_table {
>> +__u32   argsz;
>> +__u32   flags;
>> +struct iommu_pasid_table_config config;
>> +};
>> +#define VFIO_IOMMU_SET_PASID_TABLE  _IO(VFIO_TYPE, VFIO_BASE + 22)
> 
> -ENOCOMMENTS  Thanks,
sure

Thanks

Eric
> 
> Alex
> 
>> +
>>  /*  Additional API for SPAPR TCE (Server POWERPC) IOMMU  */
>>  
>>  /*
> 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC v3 18/21] vfio-pci: Add a new VFIO_REGION_TYPE_NESTED region type

2019-01-15 Thread Auger Eric
Hi Alex,

On 1/15/19 12:04 AM, Alex Williamson wrote:
> On Mon, 14 Jan 2019 21:48:06 +0100
> Auger Eric  wrote:
> 
>> Hi Alex,
>>
>> On 1/12/19 12:58 AM, Alex Williamson wrote:
>>> On Tue,  8 Jan 2019 11:26:30 +0100
>>> Eric Auger  wrote:
>>>   
 This patch adds a new 64kB region aiming to report nested mode
 translation faults.

 The region contains a header with the size of the queue,
 the producer and consumer indices and then the actual
 fault queue data. The producer is updated by the kernel while
 the consumer is updated by the userspace.

 Signed-off-by: Eric Auger 

 ---
 ---
  drivers/vfio/pci/vfio_pci.c | 102 +++-
  drivers/vfio/pci/vfio_pci_private.h |   2 +
  include/uapi/linux/vfio.h   |  15 
  3 files changed, 118 insertions(+), 1 deletion(-)

 diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
 index ff60bd1ea587..2ba181ab2edd 100644
 --- a/drivers/vfio/pci/vfio_pci.c
 +++ b/drivers/vfio/pci/vfio_pci.c
 @@ -56,6 +56,11 @@ module_param(disable_idle_d3, bool, S_IRUGO | S_IWUSR);
  MODULE_PARM_DESC(disable_idle_d3,
 "Disable using the PCI D3 low power state for idle, unused 
 devices");
  
 +#define VFIO_FAULT_REGION_SIZE 0x1  
>>>
>>> Why 64K?  
>> For the region to be mmappable with 64kB page size.
> 
> Isn't hard coding 64K just as bad as hard coding 4K?  The kernel knows
> what PAGE_SIZE is after all.  Is there some target number of queue
> entries here that we could round up to a multiple of PAGE_SIZE?
Spec says the queue size has max 2^n events with n <= 19. n is
implementation dependent. In practice the driver uses 2^8 entries, each
entry being 32 bytes so the event queue is 8kB. So depending on the size
of the entry we are going to choose here we may need a queue counting
around the same number of entries.

>  
 +#define VFIO_FAULT_QUEUE_SIZE \
 +  ((VFIO_FAULT_REGION_SIZE - sizeof(struct vfio_fault_region_header)) / \
 +  sizeof(struct iommu_fault))
 +
  static inline bool vfio_vga_disabled(void)
  {
  #ifdef CONFIG_VFIO_PCI_VGA
 @@ -1226,6 +1231,100 @@ static const struct vfio_device_ops vfio_pci_ops = 
 {
  static int vfio_pci_reflck_attach(struct vfio_pci_device *vdev);
  static void vfio_pci_reflck_put(struct vfio_pci_reflck *reflck);
  
 +static size_t
 +vfio_pci_dma_fault_rw(struct vfio_pci_device *vdev, char __user *buf,
 +size_t count, loff_t *ppos, bool iswrite)
 +{
 +  unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) - VFIO_PCI_NUM_REGIONS;
 +  void *base = vdev->region[i].data;
 +  loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
 +
 +  if (pos >= vdev->region[i].size)
 +  return -EINVAL;
 +
 +  count = min(count, (size_t)(vdev->region[i].size - pos));
 +
 +  if (copy_to_user(buf, base + pos, count))
 +  return -EFAULT;
 +
 +  *ppos += count;
 +
 +  return count;
 +}
 +
 +static int vfio_pci_dma_fault_mmap(struct vfio_pci_device *vdev,
 + struct vfio_pci_region *region,
 + struct vm_area_struct *vma)
 +{
 +  u64 phys_len, req_len, pgoff, req_start;
 +  unsigned long long addr;
 +  unsigned int index;
 +
 +  index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
 +
 +  if (vma->vm_end < vma->vm_start)
 +  return -EINVAL;
 +  if ((vma->vm_flags & VM_SHARED) == 0)
 +  return -EINVAL;
 +
 +  phys_len = VFIO_FAULT_REGION_SIZE;
 +
 +  req_len = vma->vm_end - vma->vm_start;
 +  pgoff = vma->vm_pgoff &
 +  ((1U << (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT)) - 1);
 +  req_start = pgoff << PAGE_SHIFT;
 +
 +  if (req_start + req_len > phys_len)
 +  return -EINVAL;
 +
 +  addr = virt_to_phys(vdev->fault_region);
 +  vma->vm_private_data = vdev;
 +  vma->vm_pgoff = (addr >> PAGE_SHIFT) + pgoff;
 +
 +  return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
 + req_len, vma->vm_page_prot);
 +}
 +
 +void vfio_pci_dma_fault_release(struct vfio_pci_device *vdev,
 +  struct vfio_pci_region *region)
 +{
 +}
 +
 +static const struct vfio_pci_regops vfio_pci_dma_fault_regops = {
 +  .rw = vfio_pci_dma_fault_rw,
 +  .mmap   = vfio_pci_dma_fault_mmap,
 +  .release= vfio_pci_dma_fault_release,
 +};
 +
 +static int vfio_pci_init_dma_fault_region(struct vfio_pci_device *vdev)
 +{
 +  u32 flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE |
 +  VFIO_REGION_INFO_FLAG_MMAP;
 +  int ret;
 +
 +  spin_lock_init(>fault_queue_lock);
 +
 +  vdev->fault_region = 

[PATCH v1] iommu/s390: Declare s390 iommu reserved regions

2019-01-15 Thread Pierre Morel
The s390 iommu can only allow DMA transactions between the zPCI device
entries start_dma and end_dma.

Let's declare the regions before start_dma and after end_dma as
reserved regions using the appropriate callback in iommu_ops.

Signed-off-by: Pierre Morel 
---
 drivers/iommu/s390-iommu.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index 22d4db3..5ca91a1 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -363,6 +363,33 @@ void zpci_destroy_iommu(struct zpci_dev *zdev)
iommu_device_sysfs_remove(>iommu_dev);
 }
 
+static void s390_get_resv_regions(struct device *dev, struct list_head *head)
+{
+   struct iommu_resv_region *region;
+   struct zpci_dev *zdev = to_pci_dev(dev)->sysdata;
+
+   region = iommu_alloc_resv_region(0, zdev->start_dma,
+0, IOMMU_RESV_RESERVED);
+   if (!region)
+   return;
+   list_add_tail(>list, head);
+
+   region = iommu_alloc_resv_region(zdev->end_dma + 1,
+~0UL - zdev->end_dma,
+0, IOMMU_RESV_RESERVED);
+   if (!region)
+   return;
+   list_add_tail(>list, head);
+}
+
+static void s390_put_resv_regions(struct device *dev, struct list_head *head)
+{
+   struct iommu_resv_region *entry, *next;
+
+   list_for_each_entry_safe(entry, next, head, list)
+   kfree(entry);
+}
+
 static const struct iommu_ops s390_iommu_ops = {
.capable = s390_iommu_capable,
.domain_alloc = s390_domain_alloc,
@@ -376,6 +403,8 @@ static const struct iommu_ops s390_iommu_ops = {
.remove_device = s390_iommu_remove_device,
.device_group = generic_device_group,
.pgsize_bitmap = S390_IOMMU_PGSIZES,
+   .get_resv_regions = s390_get_resv_regions,
+   .put_resv_regions = s390_put_resv_regions,
 };
 
 static int __init s390_iommu_init(void)
-- 
2.7.4

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


[PATCH v1] iommu/s390: Declare s390 iommu reserved regions

2019-01-15 Thread Pierre Morel
The s390 iommu can only allow DMA transactions between the zPCI device
entries start_dma and end_dma.

Let's declare the regions before start_dma and after end_dma as
reserved regions using the appropriate callback in iommu_ops.

The reserved region may later be retrieved from sysfs or from
the vfio iommu internal interface.

This seems to me related with the work Shameer has started on
vfio_iommu_type1 so I add Alex and Shameer to the CC list.


Pierre Morel (1):
  iommu/s390: Declare s390 iommu reserved regions

 drivers/iommu/s390-iommu.c | 29 +
 1 file changed, 29 insertions(+)

-- 
2.7.4

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


Re: use generic DMA mapping code in powerpc V4

2019-01-15 Thread Christian Zigotzky
Next step: 240d7ecd7f6fa62e074e8a835e620047954f0b28 (powerpc/dma: use 
the dma-direct allocator for coherent platforms)


git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a

git checkout 240d7ecd7f6fa62e074e8a835e620047954f0b28

Link to the Git: 
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/powerpc-dma.6


env LANG=C make CROSS_COMPILE=powerpc-linux-gnu- ARCH=powerpc zImage

Error message:

arch/powerpc/kernel/dma.o:(.data.rel.ro+0x0): undefined reference to 
`__dma_nommu_alloc_coherent'
arch/powerpc/kernel/dma.o:(.data.rel.ro+0x8): undefined reference to 
`__dma_nommu_free_coherent'

Makefile:1027: recipe for target 'vmlinux' failed
make: *** [vmlinux] Error 1

-- Christian


On 12 January 2019 at 7:14PM, Christian Zigotzky wrote:
Next step: 4558b6e1ddf3dcf5a86d6a5d16c2ac1600c7df39 (swiotlb: remove 
swiotlb_dma_supported)


git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a

git checkout 4558b6e1ddf3dcf5a86d6a5d16c2ac1600c7df39

Output:

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. 
Example:


  git checkout -b 

HEAD is now at 4558b6e... swiotlb: remove swiotlb_dma_supported



Link to the Git: 
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/powerpc-dma.6


Results: PASEMI onboard ethernet (X1000) works and the X5000 (P5020 
board) boots. I also successfully tested sound, hardware 3D 
acceleration, Bluetooth, network, booting with a label etc. The 
uImages work also in a virtual e5500 quad-core QEMU machine.


-- Christian


On 11 January 2019 at 03:10AM, Christian Zigotzky wrote:
Next step: 891dcc1072f1fa27a83da920d88daff6ca08fc02 (powerpc/dma: 
remove dma_nommu_dma_supported)


git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a

git checkout 891dcc1072f1fa27a83da920d88daff6ca08fc02

Output:

Note: checking out '891dcc1072f1fa27a83da920d88daff6ca08fc02'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in 
this

state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. 
Example:


git checkout -b 

HEAD is now at 891dcc1... powerpc/dma: remove dma_nommu_dma_supported

---

Link to the Git: 
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/powerpc-dma.6


Results: PASEMI onboard ethernet works and the X5000 (P5020 board) 
boots. I also successfully tested sound, hardware 3D acceleration, 
Bluetooth, network, booting with a label etc. The uImages work also 
in a virtual e5500 quad-core QEMU machine.


-- Christian


On 09 January 2019 at 10:31AM, Christian Zigotzky wrote:
Next step: a64e18ba191ba9102fb174f27d707485ffd9389c (powerpc/dma: 
remove dma_nommu_get_required_mask)


git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a

git checkout a64e18ba191ba9102fb174f27d707485ffd9389c

Link to the Git: 
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/powerpc-dma.6


Results: PASEMI onboard ethernet works and the X5000 (P5020 board) 
boots. I also successfully tested sound, hardware 3D acceleration, 
Bluetooth, network, booting with a label etc. The uImages work also 
in a virtual e5500 quad-core QEMU machine.


-- Christian


On 05 January 2019 at 5:03PM, Christian Zigotzky wrote:
Next step: c446404b041130fbd9d1772d184f24715cf2362f (powerpc/dma: 
remove dma_nommu_mmap_coherent)


git clone git://git.infradead.org/users/hch/misc.git -b 
powerpc-dma.6 a


git checkout c446404b041130fbd9d1772d184f24715cf2362f

Output:

Note: checking out 'c446404b041130fbd9d1772d184f24715cf2362f'.

You are in 'detached HEAD' state. You can look around, make 
experimental
changes and commit them, and you can discard any commits you make 
in this

state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, 
you may
do so (now or later) by using -b with the checkout command again. 
Example:


  git checkout -b 

HEAD is now at c446404... powerpc/dma: remove dma_nommu_mmap_coherent

-

Link to the Git: 
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/powerpc-dma.6


Result: PASEMI onboard ethernet works and the X5000 (P5020 board) 
boots.


-- Christian












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

Re: [PATCH 0/3] Fix virtio-blk issue with SWIOTLB

2019-01-15 Thread Joerg Roedel
On Mon, Jan 14, 2019 at 01:20:45PM -0500, Michael S. Tsirkin wrote:
> Which would be fine especially if we can manage not to introduce a bunch
> of indirect calls all over the place and hurt performance.

Which indirect calls? In case of unset dma_ops the DMA-API functions
call directly into the dma-direct implementation, no indirect calls at
all.

Regards,

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


Re: use generic DMA mapping code in powerpc V4

2019-01-15 Thread Christian Zigotzky
Next step: 63a6e350e037a21e9a88c8b710129bea7049a80f (powerpc/dma: use 
the dma_direct mapping routines)


git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a

git checkout 63a6e350e037a21e9a88c8b710129bea7049a80f

Error message:

arch/powerpc/kernel/dma.o:(.data.rel.ro+0x0): undefined reference to 
`__dma_nommu_alloc_coherent'
arch/powerpc/kernel/dma.o:(.data.rel.ro+0x8): undefined reference to 
`__dma_nommu_free_coherent'

Makefile:1027: recipe for target 'vmlinux' failed
make: *** [vmlinux] Error 1

-- Christian


On 15 January 2019 at 09:07AM, Christian Zigotzky wrote:
Next step: 240d7ecd7f6fa62e074e8a835e620047954f0b28 (powerpc/dma: use 
the dma-direct allocator for coherent platforms)


git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a

git checkout 240d7ecd7f6fa62e074e8a835e620047954f0b28

Link to the Git: 
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/powerpc-dma.6


env LANG=C make CROSS_COMPILE=powerpc-linux-gnu- ARCH=powerpc zImage

Error message:

arch/powerpc/kernel/dma.o:(.data.rel.ro+0x0): undefined reference to 
`__dma_nommu_alloc_coherent'
arch/powerpc/kernel/dma.o:(.data.rel.ro+0x8): undefined reference to 
`__dma_nommu_free_coherent'

Makefile:1027: recipe for target 'vmlinux' failed
make: *** [vmlinux] Error 1

-- Christian


On 12 January 2019 at 7:14PM, Christian Zigotzky wrote:
Next step: 4558b6e1ddf3dcf5a86d6a5d16c2ac1600c7df39 (swiotlb: remove 
swiotlb_dma_supported)


git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a

git checkout 4558b6e1ddf3dcf5a86d6a5d16c2ac1600c7df39

Output:

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in 
this

state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. 
Example:


  git checkout -b 

HEAD is now at 4558b6e... swiotlb: remove swiotlb_dma_supported



Link to the Git: 
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/powerpc-dma.6


Results: PASEMI onboard ethernet (X1000) works and the X5000 (P5020 
board) boots. I also successfully tested sound, hardware 3D 
acceleration, Bluetooth, network, booting with a label etc. The 
uImages work also in a virtual e5500 quad-core QEMU machine.


-- Christian


On 11 January 2019 at 03:10AM, Christian Zigotzky wrote:
Next step: 891dcc1072f1fa27a83da920d88daff6ca08fc02 (powerpc/dma: 
remove dma_nommu_dma_supported)


git clone git://git.infradead.org/users/hch/misc.git -b powerpc-dma.6 a

git checkout 891dcc1072f1fa27a83da920d88daff6ca08fc02

Output:

Note: checking out '891dcc1072f1fa27a83da920d88daff6ca08fc02'.

You are in 'detached HEAD' state. You can look around, make 
experimental
changes and commit them, and you can discard any commits you make in 
this

state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you 
may
do so (now or later) by using -b with the checkout command again. 
Example:


git checkout -b 

HEAD is now at 891dcc1... powerpc/dma: remove dma_nommu_dma_supported

---

Link to the Git: 
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/powerpc-dma.6


Results: PASEMI onboard ethernet works and the X5000 (P5020 board) 
boots. I also successfully tested sound, hardware 3D acceleration, 
Bluetooth, network, booting with a label etc. The uImages work also 
in a virtual e5500 quad-core QEMU machine.


-- Christian


On 09 January 2019 at 10:31AM, Christian Zigotzky wrote:
Next step: a64e18ba191ba9102fb174f27d707485ffd9389c (powerpc/dma: 
remove dma_nommu_get_required_mask)


git clone git://git.infradead.org/users/hch/misc.git -b 
powerpc-dma.6 a


git checkout a64e18ba191ba9102fb174f27d707485ffd9389c

Link to the Git: 
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/powerpc-dma.6


Results: PASEMI onboard ethernet works and the X5000 (P5020 board) 
boots. I also successfully tested sound, hardware 3D acceleration, 
Bluetooth, network, booting with a label etc. The uImages work also 
in a virtual e5500 quad-core QEMU machine.


-- Christian


On 05 January 2019 at 5:03PM, Christian Zigotzky wrote:
Next step: c446404b041130fbd9d1772d184f24715cf2362f (powerpc/dma: 
remove dma_nommu_mmap_coherent)


git clone git://git.infradead.org/users/hch/misc.git -b 
powerpc-dma.6 a


git checkout c446404b041130fbd9d1772d184f24715cf2362f

Output:

Note: checking out 'c446404b041130fbd9d1772d184f24715cf2362f'.

You are in 'detached HEAD' state. You can look around, make 
experimental
changes and commit them, and you can discard any commits you make 
in this

state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, 
you may
do so (now or later) by using -b with the checkout