diff options
author | Ryan Neph <ryanneph@google.com> | 2023-09-15 17:06:57 -0700 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2023-09-18 23:09:58 +0000 |
commit | d584798ca648e44aa9b6a089d9d6ecb244415d53 (patch) | |
tree | 616829b83e55b59241735aeccbb30c1de1ee83f1 | |
parent | baa5528131c3c110d241bd4b5c25160fab19952a (diff) |
vkr: validate queueCount at device creation
Signed-off-by: Ryan Neph <ryanneph@google.com>
Part-of: <https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/1239>
-rw-r--r-- | src/venus/vkr_device.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/venus/vkr_device.c b/src/venus/vkr_device.c index c6a77b7..4e9a6da 100644 --- a/src/venus/vkr_device.c +++ b/src/venus/vkr_device.c @@ -84,6 +84,46 @@ vkr_dispatch_vkCreateDevice(struct vn_dispatch_context *dispatch, struct vkr_physical_device *physical_dev = vkr_physical_device_from_handle(args->physicalDevice); + /* there can be at most two members sharing a queueFamilyIndex (one + * protected-capable, one not), in which case their summed queueCount must + * be <= the family's VkQueueFamilyProperties::queueCount. + */ + { + uint32_t *counts = + malloc(sizeof(uint32_t) * physical_dev->queue_family_property_count); + if (!counts) { + args->ret = VK_ERROR_OUT_OF_HOST_MEMORY; + return; + } + memset(counts, 0, sizeof(uint32_t) * physical_dev->queue_family_property_count); + + args->ret = VK_SUCCESS; + for (uint32_t i = 0; i < args->pCreateInfo->queueCreateInfoCount; i++) { + const uint32_t queue_family_index = + args->pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex; + const uint32_t queue_count = args->pCreateInfo->pQueueCreateInfos[i].queueCount; + + if (queue_family_index >= physical_dev->queue_family_property_count) { + args->ret = VK_ERROR_UNKNOWN; + break; + } + + const VkQueueFamilyProperties *queue_family_properties = + &physical_dev->queue_family_properties[queue_family_index]; + + if (queue_family_properties->queueCount - counts[queue_family_index] < + queue_count) { + args->ret = VK_ERROR_UNKNOWN; + break; + } + counts[queue_family_index] += queue_count; + } + + free(counts); + if (args->ret != VK_SUCCESS) + return; + } + /* append extensions for our own use */ const char **exts = NULL; uint32_t ext_count = args->pCreateInfo->enabledExtensionCount; |