From: Akihiko Odaki <[email protected]>
Propagate udmabuf errors so that the requested operation will be
canceled instead of producing an incomplete result and the user can
notice the failure.
Fixes: e0933d91b1cd ("virtio-gpu: Add virtio_gpu_resource_create_blob")
Fixes: f66767f75c9c ("virtio-gpu: add virtio-gpu/blob vmstate subsection")
Fixes: 4ae1c5c7d6f3 ("hw/display/virtio-gpu: Initialize blob mapping for
ATTACH_BACKING")
Signed-off-by: Akihiko Odaki <[email protected]>
Reviewed-by: Marc-André Lureau <[email protected]>
Message-ID: <[email protected]>
---
hw/display/virtio-gpu-udmabuf-stubs.c | 3 ++-
hw/display/virtio-gpu-udmabuf.c | 8 +++++---
hw/display/virtio-gpu.c | 18 ++++++++++++++----
include/hw/virtio/virtio-gpu.h | 2 +-
4 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/hw/display/virtio-gpu-udmabuf-stubs.c
b/hw/display/virtio-gpu-udmabuf-stubs.c
index 85d03935a332..0883bf05fac1 100644
--- a/hw/display/virtio-gpu-udmabuf-stubs.c
+++ b/hw/display/virtio-gpu-udmabuf-stubs.c
@@ -7,9 +7,10 @@ bool virtio_gpu_have_udmabuf(void)
return false;
}
-void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
+bool virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
{
/* nothing (stub) */
+ return false;
}
void virtio_gpu_fini_udmabuf(VirtIOGPU *g, struct virtio_gpu_simple_resource
*res)
diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c
index ba02ba9e8616..c230509852ff 100644
--- a/hw/display/virtio-gpu-udmabuf.c
+++ b/hw/display/virtio-gpu-udmabuf.c
@@ -131,7 +131,7 @@ bool virtio_gpu_have_udmabuf(void)
return memfd_backend;
}
-void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
+bool virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
{
void *pdata = NULL;
@@ -142,17 +142,19 @@ void virtio_gpu_init_udmabuf(struct
virtio_gpu_simple_resource *res)
} else if (res->blob_size) {
virtio_gpu_create_udmabuf(res);
if (res->dmabuf_fd < 0) {
- return;
+ return false;
}
virtio_gpu_remap_udmabuf(res);
if (!res->remapped) {
virtio_gpu_destroy_udmabuf(res);
- return;
+ return false;
}
pdata = res->remapped;
}
res->blob = pdata;
+
+ return true;
}
static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDMABuf *dmabuf)
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 50c4dcd408bb..7f3301a9ac57 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -383,7 +383,12 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
return;
}
- virtio_gpu_init_udmabuf(res);
+ if (!virtio_gpu_init_udmabuf(res)) {
+ cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+ virtio_gpu_cleanup_mapping(g, res);
+ g_free(res);
+ return;
+ }
}
QTAILQ_INSERT_HEAD(&g->reslist, res, next);
@@ -1045,8 +1050,9 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
return;
}
- if (!res->image) {
- virtio_gpu_init_udmabuf(res);
+ if (!res->image && !virtio_gpu_init_udmabuf(res)) {
+ cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+ virtio_gpu_cleanup_mapping(g, res);
}
}
@@ -1558,7 +1564,11 @@ static int virtio_gpu_blob_load(QEMUFile *f, void
*opaque, size_t size,
return -EINVAL;
}
- virtio_gpu_init_udmabuf(res);
+ if (!virtio_gpu_init_udmabuf(res)) {
+ virtio_gpu_cleanup_mapping(g, res);
+ g_free(res);
+ return -EINVAL;
+ }
}
QTAILQ_INSERT_HEAD(&g->reslist, res, next);
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 220231ec9d43..69b5ee2e382f 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -388,7 +388,7 @@ bool virtio_gpu_scanout_blob_to_fb(struct
virtio_gpu_framebuffer *fb,
/* virtio-gpu-udmabuf.c */
bool virtio_gpu_have_udmabuf(void);
-void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);
+bool virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);
void virtio_gpu_fini_udmabuf(VirtIOGPU *g,
struct virtio_gpu_simple_resource *res);
int virtio_gpu_update_dmabuf(VirtIOGPU *g,
--
2.55.0.543.g5ebe2ebe4ea8