virtgpu: set blob_id when creating blob resources

Setting the blob_id is necessary to prevent a race where the cmds for
two concurrent CREATE_BLOB ioctls get swapped.

BUG=b:170375809
TEST=android.media.cts.EncoderTest

Change-Id: I74d4ebe9a819f0564e10736ba5f35c5f8fc8aa1b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2503995
Reviewed-by: Jason Macnak <natsu@google.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Commit-Queue: David Stevens <stevensd@chromium.org>
Tested-by: David Stevens <stevensd@chromium.org>
diff --git a/virtio_gpu.c b/virtio_gpu.c
index e6392bc..b086c80 100644
--- a/virtio_gpu.c
+++ b/virtio_gpu.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <stdatomic.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
@@ -71,6 +72,7 @@
 	int caps_is_v2;
 	union virgl_caps caps;
 	int host_gbm_enabled;
+	atomic_int next_blob_id;
 };
 
 static uint32_t translate_format(uint32_t drm_fourcc)
@@ -680,8 +682,10 @@
 {
 	int ret;
 	uint32_t stride;
+	uint32_t cur_blob_id;
 	uint32_t cmd[VIRGL_PIPE_RES_CREATE_SIZE + 1] = { 0 };
 	struct drm_virtgpu_resource_create_blob drm_rc_blob = { 0 };
+	struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv;
 
 	uint32_t blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE;
 	if (bo->meta.use_flags & BO_USE_SW_MASK)
@@ -689,6 +693,7 @@
 	if (bo->meta.use_flags & BO_USE_NON_GPU_HW)
 		blob_flags |= VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE;
 
+	cur_blob_id = atomic_fetch_add(&priv->next_blob_id, 1);
 	stride = drv_stride_from_format(bo->meta.format, bo->meta.width, 0);
 	drv_bo_from_format(bo, stride, bo->meta.height, bo->meta.format);
 	bo->meta.total_size = ALIGN(bo->meta.total_size, PAGE_SIZE);
@@ -701,12 +706,14 @@
 	cmd[VIRGL_PIPE_RES_CREATE_FORMAT] = translate_format(bo->meta.format);
 	cmd[VIRGL_PIPE_RES_CREATE_BIND] = use_flags_to_bind(bo->meta.use_flags);
 	cmd[VIRGL_PIPE_RES_CREATE_DEPTH] = 1;
+	cmd[VIRGL_PIPE_RES_CREATE_BLOB_ID] = cur_blob_id;
 
 	drm_rc_blob.cmd = (uint64_t)&cmd;
 	drm_rc_blob.cmd_size = 4 * (VIRGL_PIPE_RES_CREATE_SIZE + 1);
 	drm_rc_blob.size = bo->meta.total_size;
 	drm_rc_blob.blob_mem = VIRTGPU_BLOB_MEM_HOST3D;
 	drm_rc_blob.blob_flags = blob_flags;
+	drm_rc_blob.blob_id = cur_blob_id;
 
 	ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB, &drm_rc_blob);
 	if (ret < 0) {