]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
virtio: Allocate bounce buffers for devices with VIRTIO_F_IOMMU_PLATFORM
authorWill Deacon <willdeacon@google.com>
Wed, 29 Mar 2023 14:24:59 +0000 (22:24 +0800)
committerTom Rini <trini@konsulko.com>
Tue, 25 Apr 2023 15:53:15 +0000 (11:53 -0400)
In preparation for bouncing virtio data for devices advertising the
VIRTIO_F_IOMMU_PLATFORM feature, allocate an array of bounce buffer
structures in the vring, one per descriptor.

Signed-off-by: Will Deacon <willdeacon@google.com>
[ Paul: pick from the Android tree. Rebase to the upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
Cc: Bin Meng <bmeng.cn@gmail.com>
Link: https://android.googlesource.com/platform/external/u-boot/+/3e052749e7c50c4c1a6014e645ae3b9be3710c07
Reviewed-by: Simon Glass <sjg@chromium.org>
drivers/virtio/virtio_ring.c
include/virtio_ring.h

index 1bd19add758b8b81bba571db4bd6c250acc38933..de75786ca767f50b15daea9fddccad9161827c17 100644 (file)
@@ -6,6 +6,7 @@
  * virtio ring implementation
  */
 
+#include <bouncebuf.h>
 #include <common.h>
 #include <dm.h>
 #include <log.h>
@@ -292,6 +293,7 @@ struct virtqueue *vring_create_virtqueue(unsigned int index, unsigned int num,
        struct udevice *vdev = uc_priv->vdev;
        struct virtqueue *vq;
        void *queue = NULL;
+       struct bounce_buffer *bbs = NULL;
        struct vring vring;
 
        /* We assume num is a power of 2 */
@@ -320,17 +322,29 @@ struct virtqueue *vring_create_virtqueue(unsigned int index, unsigned int num,
                return NULL;
 
        memset(queue, 0, vring_size(num, vring_align));
-       vring_init(&vring, num, queue, vring_align);
 
-       vq = __vring_new_virtqueue(index, vring, udev);
-       if (!vq) {
-               virtio_free_pages(vdev, queue, DIV_ROUND_UP(vring.size, PAGE_SIZE));
-               return NULL;
+       if (virtio_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
+               bbs = calloc(num, sizeof(*bbs));
+               if (!bbs)
+                       goto err_free_queue;
        }
+
+       vring_init(&vring, num, queue, vring_align, bbs);
+
+       vq = __vring_new_virtqueue(index, vring, udev);
+       if (!vq)
+               goto err_free_bbs;
+
        debug("(%s): created vring @ %p for vq @ %p with num %u\n", udev->name,
              queue, vq, num);
 
        return vq;
+
+err_free_bbs:
+       free(bbs);
+err_free_queue:
+       virtio_free_pages(vdev, queue, DIV_ROUND_UP(vring.size, PAGE_SIZE));
+       return NULL;
 }
 
 void vring_del_virtqueue(struct virtqueue *vq)
@@ -339,6 +353,7 @@ void vring_del_virtqueue(struct virtqueue *vq)
                          DIV_ROUND_UP(vq->vring.size, PAGE_SIZE));
        free(vq->vring_desc_shadow);
        list_del(&vq->list);
+       free(vq->vring.bouncebufs);
        free(vq);
 }
 
index 8f8a55c7bd3e006a5eabe57d0e16f7871355ec6e..e8e91044a272f976bd1bd23da0f44c1e96519061 100644 (file)
@@ -87,6 +87,7 @@ struct vring_used {
 struct vring {
        unsigned int num;
        size_t size;
+       struct bounce_buffer *bouncebufs;
        struct vring_desc *desc;
        struct vring_avail *avail;
        struct vring_used *used;
@@ -146,10 +147,12 @@ static inline unsigned int vring_size(unsigned int num, unsigned long align)
 }
 
 static inline void vring_init(struct vring *vr, unsigned int num, void *p,
-                             unsigned long align)
+                             unsigned long align,
+                             struct bounce_buffer *bouncebufs)
 {
        vr->num = num;
        vr->size = vring_size(num, align);
+       vr->bouncebufs = bouncebufs;
        vr->desc = p;
        vr->avail = p + num * sizeof(struct vring_desc);
        vr->used = (void *)(((uintptr_t)&vr->avail->ring[num] +