From 2183cc1f55e228e4070a68deb97c619671658b23 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 18 Aug 2022 11:20:25 +0000 Subject: [PATCH] ANDROID: virtio_balloon: Do not translate reported pages through DMA API The free-page reporting and hinting queues do not pass arrays of page addresses (like the basic inflate queue) but instead pass the free page ranges as buffers. This does not work well with DMA API: The host wants to know the GPA, not an IOVA. For these two virtqueues, disable DMA API and pass through buffers untranslated. Change-Id: Ic08cf0e2aa092944bac0a6dfc8004c766a7eb3af Bug: 357781595 Signed-off-by: Keir Fraser --- drivers/virtio/virtio_balloon.c | 8 ++++++-- drivers/virtio/virtio_ring.c | 10 ++++++++++ include/linux/virtio.h | 2 ++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index b36d2803674e..a5c59fff242a 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -634,11 +634,15 @@ static int init_vqs(struct virtio_balloon *vb) virtqueue_kick(vb->stats_vq); } - if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) + if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { vb->free_page_vq = vqs[VIRTIO_BALLOON_VQ_FREE_PAGE]; + virtqueue_disable_dma_api_for_buffers(vb->free_page_vq); + } - if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_REPORTING)) + if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_REPORTING)) { vb->reporting_vq = vqs[VIRTIO_BALLOON_VQ_REPORTING]; + virtqueue_disable_dma_api_for_buffers(vb->reporting_vq); + } return 0; } diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 98374ed7c577..9a6a53e5e7cd 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -3246,5 +3246,15 @@ void virtqueue_dma_sync_single_range_for_device(struct virtqueue *_vq, } EXPORT_SYMBOL_GPL(virtqueue_dma_sync_single_range_for_device); +/* + * Prevents use of DMA API for buffers passed via the specified virtqueue. + * DMA API may still be used for the vrings themselves. + */ +void virtqueue_disable_dma_api_for_buffers(struct virtqueue *vq) +{ + to_vvq(vq)->use_dma_api = false; +} +EXPORT_SYMBOL_GPL(virtqueue_disable_dma_api_for_buffers); + MODULE_DESCRIPTION("Virtio ring implementation"); MODULE_LICENSE("GPL"); diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 306137a15d07..2a401ae330c1 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -104,6 +104,8 @@ int virtqueue_resize(struct virtqueue *vq, u32 num, int virtqueue_reset(struct virtqueue *vq, void (*recycle)(struct virtqueue *vq, void *buf)); +void virtqueue_disable_dma_api_for_buffers(struct virtqueue *vq); + struct virtio_admin_cmd { __le16 opcode; __le16 group_type;