Thread (30 messages) 30 messages, 5 authors, 2020-02-05

Re: [PATCH 2/2] arm: use swiotlb for bounce buffer on LPAE configs

From: Christoph Hellwig <hch@lst.de>
Date: 2020-01-09 14:49:24
Also in: linux-iommu, lkml

On Wed, Jan 08, 2020 at 03:20:07PM +0000, Robin Murphy wrote:
quoted
The problem - I think - is that the DMA_BIT_MASK(32) from
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)) is treated as physical
address along the call path so the dma_pfn_offset is applied to it and
the check will fail, saying that DMA_BIT_MASK(32) can not be supported.
But that's the thing - in isolation, that is entirely correct. Considering 
ZONE_DMA32 for simplicity, in general the zone is expected to cover the 
physical address range 0x0000_0000 - 0xffff_ffff (because DMA offsets are 
relatively rare), and a device with a dma_pfn_offset of more than 
(0x1_0000_0000 >> PAGE_SHIFT) *cannot* support that range with any mask, 
because the DMA address itself would have to be negative.
Note that ZONE_DMA32 is irrelevant in this particular case, as we are
talking about arm32.  But with ZONE_DMA instead this roughly makes sense.
The problem is that platforms with esoteric memory maps have no right thing 
to do. If the base of RAM is at at 0x1_0000_0000 or higher, the "correct" 
ZONE_DMA32 would be empty while ZONE_NORMAL above it would not, and last 
time I looked that makes the page allocator break badly. So the standard 
bodge on such platforms is to make ZONE_DMA32 cover not the first 4GB of 
*PA space*, but the first 4GB of *RAM*, wherever that happens to be. That 
then brings different problems - now the page allocator is happy and 
successfully returns GFP_DMA32 allocations from the range 0x8_0000_0000 - 
0x8_ffff_ffff that are utterly useless to 32-bit devices with zero 
dma_pfn_offset - see the AMD Seattle SoC for the prime example of that. If 
on the other hand all devices are guaranteed to have a dma_pfn_offset that 
puts the base of RAM at DMA address 0 then GFP_DMA32 allocations do end up 
working as expected, but now the original assumption of where ZONE_DMA32 
actually is is broken, so generic code unaware of the 
platform/architecture-specific bodge will be misled - that's the case 
you're running into.

Having thought this far, if there's a non-hacky way to reach in and grab 
ZONE_DMA{32} such that dma_direct_supported() could use zone_end_pfn() 
instead of trying to assume either way, that might be the most robust 
general solution.
zone_dma_bits is our somewhat ugly way to try to poke into this
information, although the way it is done right now sucks pretty badly.

The patch I sent to Peter in December was trying to convey that
information in a way similar to what the arm32 legacy dma code does, but
it didn't work, so I'll need to find some time to sit down and figure out
why.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help