summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Deacon <willdeacon@google.com>2023-03-29 17:24:59 +0300
committerTom Rini <trini@konsulko.com>2023-04-25 18:53:15 +0300
commit37e53db38bdbeb58732e36d1efcdf58f6ce3a138 (patch)
tree002470ae9aa56f198e0ab28dfceb4929f9b155b7
parenta15d67e01abee6f091a4bcde22fd5e0649590944 (diff)
downloadu-boot-37e53db38bdbeb58732e36d1efcdf58f6ce3a138.tar.xz
virtio: Allocate bounce buffers for devices with VIRTIO_F_IOMMU_PLATFORM
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>
-rw-r--r--drivers/virtio/virtio_ring.c25
-rw-r--r--include/virtio_ring.h5
2 files changed, 24 insertions, 6 deletions
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 1bd19add75..de75786ca7 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -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);
}
diff --git a/include/virtio_ring.h b/include/virtio_ring.h
index 8f8a55c7bd..e8e91044a2 100644
--- a/include/virtio_ring.h
+++ b/include/virtio_ring.h
@@ -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] +