diff --git a/src/venus/vkr_ring.c b/src/venus/vkr_ring.c index 33424e6..223ff84 100644 --- a/src/venus/vkr_ring.c +++ b/src/venus/vkr_ring.c @@ -9,6 +9,7 @@ #include #include "virgl_context.h" +#include "vrend_iov.h" enum vkr_ring_status_flag { VKR_RING_STATUS_IDLE = 1u << 0, @@ -56,7 +57,6 @@ vkr_ring_read_buffer(struct vkr_ring *ring, void *data, size_t size) struct vkr_ring * vkr_ring_create(const struct vkr_ring_layout *layout, - void *shared, struct virgl_context *ctx, uint64_t idle_timeout) { @@ -67,8 +67,11 @@ vkr_ring_create(const struct vkr_ring_layout *layout, if (!ring) return NULL; + ring->resource = layout->resource; + + uint8_t *shared = layout->resource->iov[0].iov_base; #define ring_attach_shared(member) \ - ring->shared.member = (void *)((uint8_t *)shared + layout->member.begin) + ring->shared.member = (void *)(shared + layout->member.begin) ring_attach_shared(head); ring_attach_shared(tail); ring_attach_shared(status); diff --git a/src/venus/vkr_ring.h b/src/venus/vkr_ring.h index d14d641..6cd0050 100644 --- a/src/venus/vkr_ring.h +++ b/src/venus/vkr_ring.h @@ -8,8 +8,12 @@ #include "vkr_common.h" -/* the layout of a ring in a virgl_resource */ +/* The layout of a ring in a virgl_resource. This is parsed and discarded by + * vkr_ring_create. + */ struct vkr_ring_layout { + struct virgl_resource *resource; + struct vkr_region head; struct vkr_region tail; struct vkr_region status; @@ -35,6 +39,7 @@ struct vkr_ring { vkr_object_id id; struct list_head head; + struct virgl_resource *resource; struct vkr_ring_shared shared; uint32_t buffer_size; uint32_t buffer_mask; @@ -55,7 +60,6 @@ struct vkr_ring { struct vkr_ring * vkr_ring_create(const struct vkr_ring_layout *layout, - void *shared, struct virgl_context *ctx, uint64_t idle_timeout); diff --git a/src/venus/vkr_transport.c b/src/venus/vkr_transport.c index c4b35d2..1a872a0 100644 --- a/src/venus/vkr_transport.c +++ b/src/venus/vkr_transport.c @@ -153,10 +153,13 @@ lookup_ring(struct vkr_context *ctx, uint64_t ring_id) } static bool -vkr_ring_layout_init(struct vkr_ring_layout *layout, const VkRingCreateInfoMESA *info) +vkr_ring_layout_init(struct vkr_ring_layout *layout, + struct virgl_resource *res, + const VkRingCreateInfoMESA *info) { /* clang-format off */ *layout = (struct vkr_ring_layout){ + .resource = res, .head = VKR_REGION_INIT(info->offset + info->headOffset, sizeof(uint32_t)), .tail = VKR_REGION_INIT(info->offset + info->tailOffset, sizeof(uint32_t)), .status = VKR_REGION_INIT(info->offset + info->statusOffset, sizeof(uint32_t)), @@ -174,6 +177,15 @@ vkr_ring_layout_init(struct vkr_ring_layout *layout, const VkRingCreateInfoMESA }; /* clang-format on */ + if (res->iov_count != 1) { + vkr_log("no scatter-gather support for ring buffers (TODO)"); + return false; + } + + const struct vkr_region res_size = VKR_REGION_INIT(0, res->iov[0].iov_len); + if (!vkr_region_is_valid(&res_region) || !vkr_region_is_within(&res_region, &res_size)) + return false; + for (size_t i = 0; i < ARRAY_SIZE(regions); i++) { const struct vkr_region *region = regions[i]; @@ -224,8 +236,6 @@ vkr_dispatch_vkCreateRingMESA(struct vn_dispatch_context *dispatch, struct vkr_context *ctx = dispatch->data; const VkRingCreateInfoMESA *info = args->pCreateInfo; const struct vkr_resource_attachment *att; - uint8_t *shared; - size_t size; struct vkr_ring *ring; att = util_hash_table_get(ctx->resource_table, uintptr_to_pointer(info->resourceId)); @@ -234,28 +244,14 @@ vkr_dispatch_vkCreateRingMESA(struct vn_dispatch_context *dispatch, return; } - /* TODO support scatter-gather or require logically contiguous resources */ - if (att->resource->iov_count != 1) { - vkr_log("no scatter-gather support for ring buffers (TODO)"); - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - - shared = att->resource->iov[0].iov_base; - size = att->resource->iov[0].iov_len; - if (info->offset > size || info->size > size - info->offset) { - vkr_cs_decoder_set_fatal(&ctx->decoder); - return; - } - struct vkr_ring_layout layout; - if (!vkr_ring_layout_init(&layout, info)) { + if (!vkr_ring_layout_init(&layout, att->resource, info)) { vkr_log("vkCreateRingMESA supplied with invalid buffer layout parameters"); vkr_cs_decoder_set_fatal(&ctx->decoder); return; } - ring = vkr_ring_create(&layout, shared, &ctx->base, info->idleTimeout); + ring = vkr_ring_create(&layout, &ctx->base, info->idleTimeout); if (!ring) { vkr_cs_decoder_set_fatal(&ctx->decoder); return;