diff options
Diffstat (limited to 'src/venus/vkr_cs.h')
-rw-r--r-- | src/venus/vkr_cs.h | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/src/venus/vkr_cs.h b/src/venus/vkr_cs.h index d39474ca..4e2daa6b 100644 --- a/src/venus/vkr_cs.h +++ b/src/venus/vkr_cs.h @@ -8,7 +8,12 @@ #include "vkr_common.h" -#define VKR_CS_DECODER_TEMP_POOL_MAX_SIZE (64u * 1024 * 1024) +/* This is to avoid integer overflows and to catch bogus allocations (e.g., + * the guest driver encodes an uninitialized value). In practice, the largest + * allocations we've seen are from vkGetPipelineCacheData and are dozens of + * MBs. + */ +#define VKR_CS_DECODER_TEMP_POOL_MAX_SIZE (1u * 1024 * 1024 * 1024) struct iovec; @@ -16,6 +21,7 @@ struct vkr_cs_encoder { bool *fatal_error; struct { + const struct vkr_resource_attachment *attachment; const struct iovec *iov; int iov_count; size_t offset; @@ -39,6 +45,14 @@ struct vkr_cs_decoder_saved_state { uint8_t *pool_reset_to; }; +/* + * We usually need many small allocations during decoding. Those allocations + * are suballocated from the temp pool. + * + * After a command is decoded, vkr_cs_decoder_reset_temp_pool is called to + * reset pool->cur. After an entire command stream is decoded, + * vkr_cs_decoder_gc_temp_pool is called to garbage collect pool->buffers. + */ struct vkr_cs_decoder_temp_pool { uint8_t **buffers; uint32_t buffer_count; @@ -52,7 +66,7 @@ struct vkr_cs_decoder_temp_pool { }; struct vkr_cs_decoder { - const struct util_hash_table_u64 *object_table; + const struct hash_table *object_table; bool fatal_error; struct vkr_cs_decoder_temp_pool temp_pool; @@ -79,8 +93,7 @@ vkr_cs_encoder_set_fatal(const struct vkr_cs_encoder *enc) void vkr_cs_encoder_set_stream(struct vkr_cs_encoder *enc, - const struct iovec *iov, - int iov_count, + const struct vkr_resource_attachment *att, size_t offset, size_t size); @@ -112,8 +125,7 @@ vkr_cs_encoder_write(struct vkr_cs_encoder *enc, } void -vkr_cs_decoder_init(struct vkr_cs_decoder *dec, - const struct util_hash_table_u64 *object_table); +vkr_cs_decoder_init(struct vkr_cs_decoder *dec, const struct hash_table *object_table); void vkr_cs_decoder_fini(struct vkr_cs_decoder *dec); @@ -161,6 +173,7 @@ vkr_cs_decoder_peek_internal(const struct vkr_cs_decoder *dec, assert(val_size <= size); if (unlikely(size > (size_t)(dec->end - dec->cur))) { + vkr_log("failed to peek %zu bytes", size); vkr_cs_decoder_set_fatal(dec); memset(val, 0, val_size); return false; @@ -197,9 +210,16 @@ vkr_cs_decoder_lookup_object(const struct vkr_cs_decoder *dec, if (!id) return NULL; - obj = util_hash_table_get_u64((struct util_hash_table_u64 *)dec->object_table, id); - if (!obj || obj->type != type) + const struct hash_entry *entry = + _mesa_hash_table_search((struct hash_table *)dec->object_table, &id); + obj = likely(entry) ? entry->data : NULL; + if (unlikely(!obj || obj->type != type)) { + if (obj) + vkr_log("object %" PRIu64 " has type %d, not %d", id, obj->type, type); + else + vkr_log("failed to look up object %" PRIu64, id); vkr_cs_decoder_set_fatal(dec); + } return obj; } @@ -221,6 +241,7 @@ vkr_cs_decoder_alloc_temp(struct vkr_cs_decoder *dec, size_t size) if (unlikely(size > (size_t)(pool->end - pool->cur))) { if (!vkr_cs_decoder_alloc_temp_internal(dec, size)) { + vkr_log("failed to suballocate %zu bytes from the temp pool", size); vkr_cs_decoder_set_fatal(dec); return NULL; } @@ -229,7 +250,7 @@ vkr_cs_decoder_alloc_temp(struct vkr_cs_decoder *dec, size_t size) /* align to 64-bit after we know size is at most * VKR_CS_DECODER_TEMP_POOL_MAX_SIZE and cannot overflow */ - size = (size + 7) & ~7; + size = align64(size, 8); assert(size <= (size_t)(pool->end - pool->cur)); void *ptr = pool->cur; |