diff options
| -rw-r--r-- | drivers/vhost/vsock.c | 13 | ||||
| -rw-r--r-- | drivers/virtio/virtio_mmio.c | 20 | ||||
| -rw-r--r-- | drivers/virtio/virtio_ring.c | 7 |
3 files changed, 35 insertions, 5 deletions
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index bbbf588540ed..ce5e63d2c66a 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c | |||
| @@ -373,6 +373,7 @@ static void vhost_vsock_handle_rx_kick(struct vhost_work *work) | |||
| 373 | 373 | ||
| 374 | static int vhost_vsock_start(struct vhost_vsock *vsock) | 374 | static int vhost_vsock_start(struct vhost_vsock *vsock) |
| 375 | { | 375 | { |
| 376 | struct vhost_virtqueue *vq; | ||
| 376 | size_t i; | 377 | size_t i; |
| 377 | int ret; | 378 | int ret; |
| 378 | 379 | ||
| @@ -383,19 +384,20 @@ static int vhost_vsock_start(struct vhost_vsock *vsock) | |||
| 383 | goto err; | 384 | goto err; |
| 384 | 385 | ||
| 385 | for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { | 386 | for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { |
| 386 | struct vhost_virtqueue *vq = &vsock->vqs[i]; | 387 | vq = &vsock->vqs[i]; |
| 387 | 388 | ||
| 388 | mutex_lock(&vq->mutex); | 389 | mutex_lock(&vq->mutex); |
| 389 | 390 | ||
| 390 | if (!vhost_vq_access_ok(vq)) { | 391 | if (!vhost_vq_access_ok(vq)) { |
| 391 | ret = -EFAULT; | 392 | ret = -EFAULT; |
| 392 | mutex_unlock(&vq->mutex); | ||
| 393 | goto err_vq; | 393 | goto err_vq; |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | if (!vq->private_data) { | 396 | if (!vq->private_data) { |
| 397 | vq->private_data = vsock; | 397 | vq->private_data = vsock; |
| 398 | vhost_vq_init_access(vq); | 398 | ret = vhost_vq_init_access(vq); |
| 399 | if (ret) | ||
| 400 | goto err_vq; | ||
| 399 | } | 401 | } |
| 400 | 402 | ||
| 401 | mutex_unlock(&vq->mutex); | 403 | mutex_unlock(&vq->mutex); |
| @@ -405,8 +407,11 @@ static int vhost_vsock_start(struct vhost_vsock *vsock) | |||
| 405 | return 0; | 407 | return 0; |
| 406 | 408 | ||
| 407 | err_vq: | 409 | err_vq: |
| 410 | vq->private_data = NULL; | ||
| 411 | mutex_unlock(&vq->mutex); | ||
| 412 | |||
| 408 | for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { | 413 | for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { |
| 409 | struct vhost_virtqueue *vq = &vsock->vqs[i]; | 414 | vq = &vsock->vqs[i]; |
| 410 | 415 | ||
| 411 | mutex_lock(&vq->mutex); | 416 | mutex_lock(&vq->mutex); |
| 412 | vq->private_data = NULL; | 417 | vq->private_data = NULL; |
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index d47a2fcef818..c71fde5fe835 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> |
| @@ -498,6 +499,7 @@ static int virtio_mmio_probe(struct platform_device *pdev) | |||
| 498 | struct virtio_mmio_device *vm_dev; | 499 | struct virtio_mmio_device *vm_dev; |
| 499 | struct resource *mem; | 500 | struct resource *mem; |
| 500 | unsigned long magic; | 501 | unsigned long magic; |
| 502 | int rc; | ||
| 501 | 503 | ||
| 502 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 504 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 503 | if (!mem) | 505 | if (!mem) |
| @@ -547,9 +549,25 @@ static int virtio_mmio_probe(struct platform_device *pdev) | |||
| 547 | } | 549 | } |
| 548 | vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); | 550 | vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); |
| 549 | 551 | ||
| 550 | if (vm_dev->version == 1) | 552 | if (vm_dev->version == 1) { |
| 551 | writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE); | 553 | writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE); |
| 552 | 554 | ||
| 555 | rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)); | ||
| 556 | /* | ||
| 557 | * In the legacy case, ensure our coherently-allocated virtio | ||
| 558 | * ring will be at an address expressable as a 32-bit PFN. | ||
| 559 | */ | ||
| 560 | if (!rc) | ||
| 561 | dma_set_coherent_mask(&pdev->dev, | ||
| 562 | DMA_BIT_MASK(32 + PAGE_SHIFT)); | ||
| 563 | } else { | ||
| 564 | rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); | ||
| 565 | } | ||
| 566 | if (rc) | ||
| 567 | rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); | ||
| 568 | if (rc) | ||
| 569 | dev_warn(&pdev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.\n"); | ||
| 570 | |||
| 553 | platform_set_drvdata(pdev, vm_dev); | 571 | platform_set_drvdata(pdev, vm_dev); |
| 554 | 572 | ||
| 555 | return register_virtio_device(&vm_dev->vdev); | 573 | return register_virtio_device(&vm_dev->vdev); |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 409aeaa49246..7e38ed79c3fc 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
| @@ -159,6 +159,13 @@ static bool vring_use_dma_api(struct virtio_device *vdev) | |||
| 159 | if (xen_domain()) | 159 | if (xen_domain()) |
| 160 | return true; | 160 | return true; |
| 161 | 161 | ||
| 162 | /* | ||
| 163 | * On ARM-based machines, the DMA ops will do the right thing, | ||
| 164 | * so always use them with legacy devices. | ||
| 165 | */ | ||
| 166 | if (IS_ENABLED(CONFIG_ARM) || IS_ENABLED(CONFIG_ARM64)) | ||
| 167 | return !virtio_has_feature(vdev, VIRTIO_F_VERSION_1); | ||
| 168 | |||
| 162 | return false; | 169 | return false; |
| 163 | } | 170 | } |
| 164 | 171 | ||
