aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2017-01-10 12:51:17 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-01 02:33:13 -0500
commit776050a9b55e17b72b5684794b9580d72e920e17 (patch)
treed59368fb4c8390177a238be8cab07a8829c9fab7
parent143a9ad4e68cc5c210e6e99e910d6b77cc8a9ec5 (diff)
virtio_mmio: Set DMA masks appropriately
commit f7f6634d23830ff74335734fbdb28ea109c1f349 upstream. Once DMA API usage is enabled, it becomes apparent that virtio-mmio is inadvertently relying on the default 32-bit DMA mask, which leads to problems like rapidly exhausting SWIOTLB bounce buffers. Ensure that we set the appropriate 64-bit DMA mask whenever possible, with the coherent mask suitably limited for the legacy vring as per a0be1db4304f ("virtio_pci: Limit DMA mask to 44 bits for legacy virtio devices"). Cc: Andy Lutomirski <luto@kernel.org> Cc: Michael S. Tsirkin <mst@redhat.com> Reported-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Fixes: b42111382f0e ("virtio_mmio: Use the DMA API if enabled") Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/virtio/virtio_mmio.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 48bfea91dbca..50840984fbfa 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -59,6 +59,7 @@
59#define pr_fmt(fmt) "virtio-mmio: " fmt 59#define pr_fmt(fmt) "virtio-mmio: " fmt
60 60
61#include <linux/acpi.h> 61#include <linux/acpi.h>
62#include <linux/dma-mapping.h>
62#include <linux/highmem.h> 63#include <linux/highmem.h>
63#include <linux/interrupt.h> 64#include <linux/interrupt.h>
64#include <linux/io.h> 65#include <linux/io.h>
@@ -497,6 +498,7 @@ static int virtio_mmio_probe(struct platform_device *pdev)
497 struct virtio_mmio_device *vm_dev; 498 struct virtio_mmio_device *vm_dev;
498 struct resource *mem; 499 struct resource *mem;
499 unsigned long magic; 500 unsigned long magic;
501 int rc;
500 502
501 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 503 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
502 if (!mem) 504 if (!mem)
@@ -545,9 +547,25 @@ static int virtio_mmio_probe(struct platform_device *pdev)
545 } 547 }
546 vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); 548 vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
547 549
548 if (vm_dev->version == 1) 550 if (vm_dev->version == 1) {
549 writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE); 551 writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE);
550 552
553 rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
554 /*
555 * In the legacy case, ensure our coherently-allocated virtio
556 * ring will be at an address expressable as a 32-bit PFN.
557 */
558 if (!rc)
559 dma_set_coherent_mask(&pdev->dev,
560 DMA_BIT_MASK(32 + PAGE_SHIFT));
561 } else {
562 rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
563 }
564 if (rc)
565 rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
566 if (rc)
567 dev_warn(&pdev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.\n");
568
551 platform_set_drvdata(pdev, vm_dev); 569 platform_set_drvdata(pdev, vm_dev);
552 570
553 return register_virtio_device(&vm_dev->vdev); 571 return register_virtio_device(&vm_dev->vdev);