Thread (8 messages) 8 messages, 4 authors, 2017-01-10
STALE3435d

[PATCH] virtio_mmio: Set DMA masks appropriately

From: arnd@arndb.de (Arnd Bergmann)
Date: 2017-01-10 14:10:42

On Tuesday, January 10, 2017 1:44:37 PM CET Robin Murphy wrote:
On 10/01/17 13:15, Arnd Bergmann wrote:
quoted
On Tuesday, January 10, 2017 12:26:01 PM CET Robin Murphy wrote:
quoted
@@ -548,6 +550,14 @@ static int virtio_mmio_probe(struct platform_device *pdev)
        if (vm_dev->version == 1)
                writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE);
 
+       rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+       if (rc)
+               rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
You don't seem to do anything different when 64-bit DMA is unsupported.
How do you prevent the use of kernel buffers that are above the first 4G
here?
That's the token "give up and rely on SWIOTLB/IOMMU" point, which as we
already know won't necessarily work very well (because it's already the
situation without this patch), but is still arguably better than
nothing. As I've just replied elsewhere, I personally hate this idiom,
but it's the done thing given the current DMA mask API.
Ah, I think I understand now. This is actually unrelated to SWIOTLB, which
should always succeed, but it is used on some architectures (x86, and
sparc in particular) to control whether the iommu is allowed to hand
out IOVA above 32-bit. Sorry for assuming in my earlier mail that all
IOMMUs only do 32-bit VA addressing in the dma-mapping API.

The related case on PowerPC is that DMA_BIT_MASK(64) has a special
meaning of bypassing the IOMMU entirely to optimize for performance.
Again that should not fail, but it will switch the dma_map_ops between
iommu and direct, using the IOMMU only when the device can't address
the entire space.
quoted
quoted
+       else if (vm_dev->version == 1)
+               dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32 + PAGE_SHIFT));
Why is this limitation only for the coherent mask?
AIUI, the "32-bit pointers to pages" limitation of legacy virtio only
applies to the location of the vring itself, which is allocated via
dma_alloc_coherent - the descriptors themselves hold full 64-bit
addresses pointing at the actual data, which is mapped using streaming
DMA. It relies on the API guarantee that if we've managed to set a
64-bit streaming mask, then setting a smaller coherent mask cannot fail
(DMA-API-HOWTO.txt:257)

This is merely an amalgamation of the logic already in place for
virtio-pci, I just skimped on duplicating all the rationale (I know
there's a mail thread somewhere I could probably dig up).
Ok, got it.

	Arnd
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help