road blocks for using dma-iommu on more than arm64
Robin Murphy
robin.murphy at arm.com
Mon Oct 2 17:48:20 UTC 2017
On 02/10/17 17:31, Christoph Hellwig wrote:
> On Mon, Oct 02, 2017 at 03:56:14PM +0100, Robin Murphy wrote:
>> IIRC, dmabounce has to stay because it handles non-contiguous DMA masks,
>> thanks to a StrongARM hardware erratum where the DMA controller could
>> only access every other megabyte of memory (or something like that).
>
> Isn't that exactly the problem that xen-swiotlb solves?
As far as I can see, not quite - swiotlb-xen appears to handle buffers
which span non-contiguous host pages, but still assumes that DMA masks
are of the full DMA_BIT_MASK() form such that checks like "addr <= mask"
work. I suppose we *could* try just making the SWIOTLB users themselves
robust against incomplete masks (e.g. [2]) if they need to be, but I'm
not sure whether that would actually work in practice.
FWIW, I could have sworn I had an old mail from Russell about this but
that seems to have vanished - after a bit more digging it's actually
about avoiding a particular address line on the SA-1111 as documented in
[1], and set up in sa1111_configure_smc() (arch/arm/common/sa1111.c).
Robin.
[1] https://wwwcip.informatik.uni-erlangen.de/~simigern/jornada-7xx/docs/sa1111-errata.pdf
[2]
diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
index 0df756b24863..8db96d714517 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -66,10 +66,13 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
+ dma_addr_t mask;
+
if (!dev->dma_mask)
return false;
- return addr + size - 1 <= *dev->dma_mask;
+ mask = *dev->dma_mask;
+ return !(addr + size - 1 & ~mask) && (size - 1 <= mask ^ (mask + 1));
}
static inline void dma_mark_clean(void *addr, size_t size)
More information about the iommu
mailing list