All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 00/23] Vga 20210527 patches
@ 2021-05-27 14:23 Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 01/23] vhost-user-gpu: fix memory disclosure in virgl_cmd_get_capset_info (CVE-2021-3545) Gerd Hoffmann
                   ` (23 more replies)
  0 siblings, 24 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Cornelia Huck, Michael S. Tsirkin,
	Gerd Hoffmann, Paolo Bonzini

The following changes since commit 2ab2dad01f6dc3667c0d53d2b1ba46b511031207:

  Merge remote-tracking branch 'remotes/kraxel/tags/input-20210526-pull-request' into staging (2021-05-26 15:27:20 +0100)

are available in the Git repository at:

  git://git.kraxel.org/qemu tags/vga-20210527-pull-request

for you to fetch changes up to bdd53f739273e97b5e5617b699d1763c42a5ea7e:

  virtio-gpu: Update cursor data using blob (2021-05-27 12:07:37 +0200)

----------------------------------------------------------------
virtio-gpu: add blob resource support.
vhost-user-gpu: security fixes.

----------------------------------------------------------------

Li Qiang (8):
  vhost-user-gpu: fix memory disclosure in virgl_cmd_get_capset_info
    (CVE-2021-3545)
  vhost-user-gpu: fix resource leak in 'vg_resource_create_2d'
    (CVE-2021-3544)
  vhost-user-gpu: fix memory leak in vg_resource_attach_backing
    (CVE-2021-3544)
  vhost-user-gpu: fix memory leak while calling 'vg_resource_unref'
    (CVE-2021-3544)
  vhost-user-gpu: fix memory leak in 'virgl_cmd_resource_unref'
    (CVE-2021-3544)
  vhost-user-gpu: fix memory leak in 'virgl_resource_attach_backing'
    (CVE-2021-3544)
  vhost-user-gpu: fix OOB write in 'virgl_cmd_get_capset'
    (CVE-2021-3546)
  vhost-user-gpu: abstract vg_cleanup_mapping_iov

Vivek Kasireddy (14):
  ui: Get the fd associated with udmabuf driver
  headers: Add udmabuf.h
  virtio-gpu: Add udmabuf helpers
  stubs: Add stubs for udmabuf helpers
  virtio-gpu: Add virtio_gpu_find_check_resource
  virtio-gpu: Refactor virtio_gpu_set_scanout
  virtio-gpu: Refactor virtio_gpu_create_mapping_iov
  virtio-gpu: Add initial definitions for blob resources
  virtio-gpu: Add virtio_gpu_resource_create_blob
  ui/pixman: Add qemu_pixman_to_drm_format()
  virtio-gpu: Add helpers to create and destroy dmabuf objects
  virtio-gpu: Factor out update scanout
  virtio-gpu: Add virtio_gpu_set_scanout_blob
  virtio-gpu: Update cursor data using blob

maobibo (1):
  hw/display/qxl: Set pci rom address aligned with page size

 contrib/vhost-user-gpu/vugpu.h           |   2 +-
 include/hw/virtio/virtio-gpu-bswap.h     |  16 +
 include/hw/virtio/virtio-gpu.h           |  39 +-
 include/standard-headers/linux/udmabuf.h |  32 ++
 include/ui/console.h                     |   3 +
 include/ui/qemu-pixman.h                 |   1 +
 contrib/vhost-user-gpu/vhost-user-gpu.c  |  29 +-
 contrib/vhost-user-gpu/virgl.c           |  20 +-
 hw/display/qxl.c                         |   2 +-
 hw/display/virtio-gpu-base.c             |   3 +
 hw/display/virtio-gpu-udmabuf.c          | 223 ++++++++++++
 hw/display/virtio-gpu-virgl.c            |   3 +-
 hw/display/virtio-gpu.c                  | 441 +++++++++++++++++------
 stubs/virtio-gpu-udmabuf.c               |  27 ++
 ui/qemu-pixman.c                         |  35 +-
 ui/udmabuf.c                             |  40 ++
 hw/display/meson.build                   |   1 +
 hw/display/trace-events                  |   2 +
 meson.build                              |   2 +-
 scripts/update-linux-headers.sh          |   3 +
 stubs/meson.build                        |   1 +
 ui/meson.build                           |   1 +
 22 files changed, 804 insertions(+), 122 deletions(-)
 create mode 100644 include/standard-headers/linux/udmabuf.h
 create mode 100644 hw/display/virtio-gpu-udmabuf.c
 create mode 100644 stubs/virtio-gpu-udmabuf.c
 create mode 100644 ui/udmabuf.c

-- 
2.31.1




^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PULL 01/23] vhost-user-gpu: fix memory disclosure in virgl_cmd_get_capset_info (CVE-2021-3545)
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 02/23] vhost-user-gpu: fix resource leak in 'vg_resource_create_2d' (CVE-2021-3544) Gerd Hoffmann
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Li Qiang, Gerd Hoffmann,
	Paolo Bonzini, Marc-André Lureau

From: Li Qiang <liq3ea@163.com>

Otherwise some of the 'resp' will be leaked to guest.

Fixes: CVE-2021-3545
Reported-by: Li Qiang <liq3ea@163.com>
virtio-gpu fix: 42a8dadc74 ("virtio-gpu: fix information leak
in getting capset info dispatch")

Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-2-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 contrib/vhost-user-gpu/virgl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c
index 9e6660c7ab87..6a332d601f80 100644
--- a/contrib/vhost-user-gpu/virgl.c
+++ b/contrib/vhost-user-gpu/virgl.c
@@ -128,6 +128,7 @@ virgl_cmd_get_capset_info(VuGpu *g,
 
     VUGPU_FILL_CMD(info);
 
+    memset(&resp, 0, sizeof(resp));
     if (info.capset_index == 0) {
         resp.capset_id = VIRTIO_GPU_CAPSET_VIRGL;
         virgl_renderer_get_cap_set(resp.capset_id,
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 02/23] vhost-user-gpu: fix resource leak in 'vg_resource_create_2d' (CVE-2021-3544)
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 01/23] vhost-user-gpu: fix memory disclosure in virgl_cmd_get_capset_info (CVE-2021-3545) Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-06-03 15:54   ` Peter Maydell
  2021-05-27 14:23 ` [PULL 03/23] vhost-user-gpu: fix memory leak in vg_resource_attach_backing (CVE-2021-3544) Gerd Hoffmann
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Prasad J Pandit, Michael S. Tsirkin, Cornelia Huck, Li Qiang,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Li Qiang <liq3ea@163.com>

Call 'vugbm_buffer_destroy' in error path to avoid resource leak.

Fixes: CVE-2021-3544
Reported-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-3-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 contrib/vhost-user-gpu/vhost-user-gpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c
index f73f292c9f72..b5e153d0d648 100644
--- a/contrib/vhost-user-gpu/vhost-user-gpu.c
+++ b/contrib/vhost-user-gpu/vhost-user-gpu.c
@@ -349,6 +349,7 @@ vg_resource_create_2d(VuGpu *g,
         g_critical("%s: resource creation failed %d %d %d",
                    __func__, c2d.resource_id, c2d.width, c2d.height);
         g_free(res);
+        vugbm_buffer_destroy(&res->buffer);
         cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
         return;
     }
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 03/23] vhost-user-gpu: fix memory leak in vg_resource_attach_backing (CVE-2021-3544)
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 01/23] vhost-user-gpu: fix memory disclosure in virgl_cmd_get_capset_info (CVE-2021-3545) Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 02/23] vhost-user-gpu: fix resource leak in 'vg_resource_create_2d' (CVE-2021-3544) Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 04/23] vhost-user-gpu: fix memory leak while calling 'vg_resource_unref' (CVE-2021-3544) Gerd Hoffmann
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Li Qiang, Gerd Hoffmann,
	Paolo Bonzini, Marc-André Lureau

From: Li Qiang <liq3ea@163.com>

Check whether the 'res' has already been attach_backing to avoid
memory leak.

Fixes: CVE-2021-3544
Reported-by: Li Qiang <liq3ea@163.com>
virtio-gpu fix: 204f01b309 ("virtio-gpu: fix memory leak
in resource attach backing")

Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-4-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 contrib/vhost-user-gpu/vhost-user-gpu.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c
index b5e153d0d648..0437e52b6460 100644
--- a/contrib/vhost-user-gpu/vhost-user-gpu.c
+++ b/contrib/vhost-user-gpu/vhost-user-gpu.c
@@ -489,6 +489,11 @@ vg_resource_attach_backing(VuGpu *g,
         return;
     }
 
+    if (res->iov) {
+        cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+        return;
+    }
+
     ret = vg_create_mapping_iov(g, &ab, cmd, &res->iov);
     if (ret != 0) {
         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 04/23] vhost-user-gpu: fix memory leak while calling 'vg_resource_unref' (CVE-2021-3544)
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 03/23] vhost-user-gpu: fix memory leak in vg_resource_attach_backing (CVE-2021-3544) Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 05/23] vhost-user-gpu: fix memory leak in 'virgl_cmd_resource_unref' (CVE-2021-3544) Gerd Hoffmann
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Prasad J Pandit, Michael S. Tsirkin, Cornelia Huck, Li Qiang,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Li Qiang <liq3ea@163.com>

If the guest trigger following sequences, the attach_backing will be leaked:

	vg_resource_create_2d
	vg_resource_attach_backing
	vg_resource_unref

This patch fix this by freeing 'res->iov' in vg_resource_destroy.

Fixes: CVE-2021-3544
Reported-by: Li Qiang <liq3ea@163.com>
virtio-gpu fix: 5e8e3c4c75 ("virtio-gpu: fix resource leak
in virgl_cmd_resource_unref")

Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-5-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 contrib/vhost-user-gpu/vhost-user-gpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c
index 0437e52b6460..770dfad52989 100644
--- a/contrib/vhost-user-gpu/vhost-user-gpu.c
+++ b/contrib/vhost-user-gpu/vhost-user-gpu.c
@@ -400,6 +400,7 @@ vg_resource_destroy(VuGpu *g,
     }
 
     vugbm_buffer_destroy(&res->buffer);
+    g_free(res->iov);
     pixman_image_unref(res->image);
     QTAILQ_REMOVE(&g->reslist, res, next);
     g_free(res);
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 05/23] vhost-user-gpu: fix memory leak in 'virgl_cmd_resource_unref' (CVE-2021-3544)
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 04/23] vhost-user-gpu: fix memory leak while calling 'vg_resource_unref' (CVE-2021-3544) Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 06/23] vhost-user-gpu: fix memory leak in 'virgl_resource_attach_backing' (CVE-2021-3544) Gerd Hoffmann
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Li Qiang, Gerd Hoffmann,
	Paolo Bonzini, Marc-André Lureau

From: Li Qiang <liq3ea@163.com>

The 'res->iov' will be leaked if the guest trigger following sequences:

	virgl_cmd_create_resource_2d
	virgl_resource_attach_backing
	virgl_cmd_resource_unref

This patch fixes this.

Fixes: CVE-2021-3544
Reported-by: Li Qiang <liq3ea@163.com>
virtio-gpu fix: 5e8e3c4c75 ("virtio-gpu: fix resource leak
in virgl_cmd_resource_unref"

Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-6-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 contrib/vhost-user-gpu/virgl.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c
index 6a332d601f80..c669d73a1dbe 100644
--- a/contrib/vhost-user-gpu/virgl.c
+++ b/contrib/vhost-user-gpu/virgl.c
@@ -108,9 +108,16 @@ virgl_cmd_resource_unref(VuGpu *g,
                          struct virtio_gpu_ctrl_command *cmd)
 {
     struct virtio_gpu_resource_unref unref;
+    struct iovec *res_iovs = NULL;
+    int num_iovs = 0;
 
     VUGPU_FILL_CMD(unref);
 
+    virgl_renderer_resource_detach_iov(unref.resource_id,
+                                       &res_iovs,
+                                       &num_iovs);
+    g_free(res_iovs);
+
     virgl_renderer_resource_unref(unref.resource_id);
 }
 
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 06/23] vhost-user-gpu: fix memory leak in 'virgl_resource_attach_backing' (CVE-2021-3544)
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 05/23] vhost-user-gpu: fix memory leak in 'virgl_cmd_resource_unref' (CVE-2021-3544) Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 07/23] vhost-user-gpu: fix OOB write in 'virgl_cmd_get_capset' (CVE-2021-3546) Gerd Hoffmann
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Li Qiang, Gerd Hoffmann,
	Paolo Bonzini, Marc-André Lureau

From: Li Qiang <liq3ea@163.com>

If 'virgl_renderer_resource_attach_iov' failed, the 'res_iovs' will
be leaked.

Fixes: CVE-2021-3544
Reported-by: Li Qiang <liq3ea@163.com>
virtio-gpu fix: 33243031da ("virtio-gpu-3d: fix memory leak
in resource attach backing")

Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-7-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 contrib/vhost-user-gpu/virgl.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c
index c669d73a1dbe..a16a311d80df 100644
--- a/contrib/vhost-user-gpu/virgl.c
+++ b/contrib/vhost-user-gpu/virgl.c
@@ -287,8 +287,11 @@ virgl_resource_attach_backing(VuGpu *g,
         return;
     }
 
-    virgl_renderer_resource_attach_iov(att_rb.resource_id,
+    ret = virgl_renderer_resource_attach_iov(att_rb.resource_id,
                                        res_iovs, att_rb.nr_entries);
+    if (ret != 0) {
+        g_free(res_iovs);
+    }
 }
 
 static void
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 07/23] vhost-user-gpu: fix OOB write in 'virgl_cmd_get_capset' (CVE-2021-3546)
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 06/23] vhost-user-gpu: fix memory leak in 'virgl_resource_attach_backing' (CVE-2021-3544) Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 08/23] vhost-user-gpu: abstract vg_cleanup_mapping_iov Gerd Hoffmann
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Prasad J Pandit, Michael S. Tsirkin, Cornelia Huck, Li Qiang,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Li Qiang <liq3ea@163.com>

If 'virgl_cmd_get_capset' set 'max_size' to 0,
the 'virgl_renderer_fill_caps' will write the data after the 'resp'.
This patch avoid this by checking the returned 'max_size'.

virtio-gpu fix: abd7f08b23 ("display: virtio-gpu-3d: check
virgl capabilities max_size")

Fixes: CVE-2021-3546
Reported-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-8-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 contrib/vhost-user-gpu/virgl.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c
index a16a311d80df..7172104b19d7 100644
--- a/contrib/vhost-user-gpu/virgl.c
+++ b/contrib/vhost-user-gpu/virgl.c
@@ -177,6 +177,10 @@ virgl_cmd_get_capset(VuGpu *g,
 
     virgl_renderer_get_cap_set(gc.capset_id, &max_ver,
                                &max_size);
+    if (!max_size) {
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+        return;
+    }
     resp = g_malloc0(sizeof(*resp) + max_size);
 
     resp->hdr.type = VIRTIO_GPU_RESP_OK_CAPSET;
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 08/23] vhost-user-gpu: abstract vg_cleanup_mapping_iov
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 07/23] vhost-user-gpu: fix OOB write in 'virgl_cmd_get_capset' (CVE-2021-3546) Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 09/23] hw/display/qxl: Set pci rom address aligned with page size Gerd Hoffmann
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Li Qiang, Gerd Hoffmann,
	Paolo Bonzini, Marc-André Lureau

From: Li Qiang <liq3ea@163.com>

Currently in vhost-user-gpu, we free resource directly in
the cleanup case of resource. If we change the cleanup logic
we need to change several places, also abstruct a
'vg_create_mapping_iov' can be symmetry with the
'vg_create_mapping_iov'. This is like what virtio-gpu does,
no function changed.

Signed-off-by: Li Qiang <liq3ea@163.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20210516030403.107723-9-liq3ea@163.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 contrib/vhost-user-gpu/vugpu.h          |  2 +-
 contrib/vhost-user-gpu/vhost-user-gpu.c | 24 ++++++++++++++++++++----
 contrib/vhost-user-gpu/virgl.c          |  9 +++++----
 3 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h
index 04d56158123d..e2864bba68e0 100644
--- a/contrib/vhost-user-gpu/vugpu.h
+++ b/contrib/vhost-user-gpu/vugpu.h
@@ -169,7 +169,7 @@ int     vg_create_mapping_iov(VuGpu *g,
                               struct virtio_gpu_resource_attach_backing *ab,
                               struct virtio_gpu_ctrl_command *cmd,
                               struct iovec **iov);
-
+void    vg_cleanup_mapping_iov(VuGpu *g, struct iovec *iov, uint32_t count);
 void    vg_get_display_info(VuGpu *vg, struct virtio_gpu_ctrl_command *cmd);
 
 void    vg_wait_ok(VuGpu *g);
diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c
index 770dfad52989..6dc6a44f4e26 100644
--- a/contrib/vhost-user-gpu/vhost-user-gpu.c
+++ b/contrib/vhost-user-gpu/vhost-user-gpu.c
@@ -49,6 +49,8 @@ static char *opt_render_node;
 static gboolean opt_virgl;
 
 static void vg_handle_ctrl(VuDev *dev, int qidx);
+static void vg_cleanup_mapping(VuGpu *g,
+                               struct virtio_gpu_simple_resource *res);
 
 static const char *
 vg_cmd_to_string(int cmd)
@@ -400,7 +402,7 @@ vg_resource_destroy(VuGpu *g,
     }
 
     vugbm_buffer_destroy(&res->buffer);
-    g_free(res->iov);
+    vg_cleanup_mapping(g, res);
     pixman_image_unref(res->image);
     QTAILQ_REMOVE(&g->reslist, res, next);
     g_free(res);
@@ -504,6 +506,22 @@ vg_resource_attach_backing(VuGpu *g,
     res->iov_cnt = ab.nr_entries;
 }
 
+/* Though currently only free iov, maybe later will do more work. */
+void vg_cleanup_mapping_iov(VuGpu *g,
+                            struct iovec *iov, uint32_t count)
+{
+    g_free(iov);
+}
+
+static void
+vg_cleanup_mapping(VuGpu *g,
+                   struct virtio_gpu_simple_resource *res)
+{
+    vg_cleanup_mapping_iov(g, res->iov, res->iov_cnt);
+    res->iov = NULL;
+    res->iov_cnt = 0;
+}
+
 static void
 vg_resource_detach_backing(VuGpu *g,
                            struct virtio_gpu_ctrl_command *cmd)
@@ -522,9 +540,7 @@ vg_resource_detach_backing(VuGpu *g,
         return;
     }
 
-    g_free(res->iov);
-    res->iov = NULL;
-    res->iov_cnt = 0;
+    vg_cleanup_mapping(g, res);
 }
 
 static void
diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c
index 7172104b19d7..3e45e1bd3360 100644
--- a/contrib/vhost-user-gpu/virgl.c
+++ b/contrib/vhost-user-gpu/virgl.c
@@ -116,8 +116,9 @@ virgl_cmd_resource_unref(VuGpu *g,
     virgl_renderer_resource_detach_iov(unref.resource_id,
                                        &res_iovs,
                                        &num_iovs);
-    g_free(res_iovs);
-
+    if (res_iovs != NULL && num_iovs != 0) {
+        vg_cleanup_mapping_iov(g, res_iovs, num_iovs);
+    }
     virgl_renderer_resource_unref(unref.resource_id);
 }
 
@@ -294,7 +295,7 @@ virgl_resource_attach_backing(VuGpu *g,
     ret = virgl_renderer_resource_attach_iov(att_rb.resource_id,
                                        res_iovs, att_rb.nr_entries);
     if (ret != 0) {
-        g_free(res_iovs);
+        vg_cleanup_mapping_iov(g, res_iovs, att_rb.nr_entries);
     }
 }
 
@@ -314,7 +315,7 @@ virgl_resource_detach_backing(VuGpu *g,
     if (res_iovs == NULL || num_iovs == 0) {
         return;
     }
-    g_free(res_iovs);
+    vg_cleanup_mapping_iov(g, res_iovs, num_iovs);
 }
 
 static void
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 09/23] hw/display/qxl: Set pci rom address aligned with page size
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 08/23] vhost-user-gpu: abstract vg_cleanup_mapping_iov Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 10/23] ui: Get the fd associated with udmabuf driver Gerd Hoffmann
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, maobibo, Gerd Hoffmann,
	Paolo Bonzini, Marc-André Lureau

From: maobibo <maobibo@loongson.cn>

On some MIPS system, page size is 16K, and qxl vga device can
be used for VM in kvm mode. Qxl pci rom size is set 8K fixed,
smaller than 16K page size on host system, it fails to be
added into memslots in kvm mode where memory_size and GPA
are required to align with page size.

This patch fixes this issue.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Message-Id: <1621340448-31617-1-git-send-email-maobibo@loongson.cn>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/qxl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 2ba75637ec30..6e1f8ff1b2a7 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -321,7 +321,7 @@ static ram_addr_t qxl_rom_size(void)
 #define QXL_ROM_SZ 8192
 
     QEMU_BUILD_BUG_ON(QXL_REQUIRED_SZ > QXL_ROM_SZ);
-    return QXL_ROM_SZ;
+    return QEMU_ALIGN_UP(QXL_REQUIRED_SZ, qemu_real_host_page_size);
 }
 
 static void init_qxl_rom(PCIQXLDevice *d)
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 10/23] ui: Get the fd associated with udmabuf driver
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (8 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 09/23] hw/display/qxl: Set pci rom address aligned with page size Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 11/23] headers: Add udmabuf.h Gerd Hoffmann
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

Try to open the udmabuf dev node for the first time or return the
fd if the device was previously opened.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-2-vivek.kasireddy@intel.com>

[ kraxel: fixup fcntl.h include ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h |  3 +++
 ui/udmabuf.c         | 40 ++++++++++++++++++++++++++++++++++++++++
 ui/meson.build       |  1 +
 3 files changed, 44 insertions(+)
 create mode 100644 ui/udmabuf.c

diff --git a/include/ui/console.h b/include/ui/console.h
index ca3c7af6a6c8..b30b63976a5a 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -471,4 +471,7 @@ bool vnc_display_reload_certs(const char *id,  Error **errp);
 /* input.c */
 int index_from_key(const char *key, size_t key_length);
 
+/* udmabuf.c */
+int udmabuf_fd(void);
+
 #endif
diff --git a/ui/udmabuf.c b/ui/udmabuf.c
new file mode 100644
index 000000000000..23abe1e7eb91
--- /dev/null
+++ b/ui/udmabuf.c
@@ -0,0 +1,40 @@
+/*
+ * udmabuf helper functions.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "ui/console.h"
+
+#ifdef CONFIG_LINUX
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+int udmabuf_fd(void)
+{
+    static bool first = true;
+    static int udmabuf;
+
+    if (!first) {
+        return udmabuf;
+    }
+    first = false;
+
+    udmabuf = open("/dev/udmabuf", O_RDWR);
+    if (udmabuf < 0) {
+        warn_report("open /dev/udmabuf: %s", strerror(errno));
+    }
+    return udmabuf;
+}
+
+#else
+
+int udmabuf_fd(void)
+{
+    return -1;
+}
+
+#endif
diff --git a/ui/meson.build b/ui/meson.build
index b5aed14886cf..a3a187d633ab 100644
--- a/ui/meson.build
+++ b/ui/meson.build
@@ -12,6 +12,7 @@ softmmu_ss.add(files(
   'kbd-state.c',
   'keymaps.c',
   'qemu-pixman.c',
+  'udmabuf.c',
 ))
 softmmu_ss.add([spice_headers, files('spice-module.c')])
 softmmu_ss.add(when: spice_protocol, if_true: files('vdagent.c'))
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 11/23] headers: Add udmabuf.h
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (9 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 10/23] ui: Get the fd associated with udmabuf driver Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 12/23] virtio-gpu: Add udmabuf helpers Gerd Hoffmann
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

This adds udmabuf header to standard headers so that the
relevant udmabuf objects can be accessed in subsequent
patches.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-3-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/standard-headers/linux/udmabuf.h | 32 ++++++++++++++++++++++++
 scripts/update-linux-headers.sh          |  3 +++
 2 files changed, 35 insertions(+)
 create mode 100644 include/standard-headers/linux/udmabuf.h

diff --git a/include/standard-headers/linux/udmabuf.h b/include/standard-headers/linux/udmabuf.h
new file mode 100644
index 000000000000..e19eb5b5ce75
--- /dev/null
+++ b/include/standard-headers/linux/udmabuf.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_UDMABUF_H
+#define _LINUX_UDMABUF_H
+
+#include "standard-headers/linux/types.h"
+
+#define UDMABUF_FLAGS_CLOEXEC	0x01
+
+struct udmabuf_create {
+	uint32_t memfd;
+	uint32_t flags;
+	uint64_t offset;
+	uint64_t size;
+};
+
+struct udmabuf_create_item {
+	uint32_t memfd;
+	uint32_t __pad;
+	uint64_t offset;
+	uint64_t size;
+};
+
+struct udmabuf_create_list {
+	uint32_t flags;
+	uint32_t count;
+	struct udmabuf_create_item list[];
+};
+
+#define UDMABUF_CREATE       _IOW('u', 0x42, struct udmabuf_create)
+#define UDMABUF_CREATE_LIST  _IOW('u', 0x43, struct udmabuf_create_list)
+
+#endif /* _LINUX_UDMABUF_H */
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 1050e361694f..fea4d6eb655f 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -34,6 +34,7 @@ cp_portable() {
     if
         grep '#include' "$f" | grep -v -e 'linux/virtio' \
                                      -e 'linux/types' \
+                                     -e 'linux/ioctl' \
                                      -e 'stdint' \
                                      -e 'linux/if_ether' \
                                      -e 'input-event-codes' \
@@ -66,6 +67,7 @@ cp_portable() {
         -e 's/__BITS_PER_LONG/HOST_LONG_BITS/' \
         -e '/\"drm.h\"/d' \
         -e '/sys\/ioctl.h/d' \
+        -e '/linux\/ioctl.h/d' \
         -e 's/SW_MAX/SW_MAX_/' \
         -e 's/atomic_t/int/' \
         -e 's/__kernel_long_t/long/' \
@@ -190,6 +192,7 @@ for i in "$tmpdir"/include/linux/*virtio*.h \
          "$tmpdir/include/linux/fuse.h" \
          "$tmpdir/include/linux/input.h" \
          "$tmpdir/include/linux/input-event-codes.h" \
+         "$tmpdir/include/linux/udmabuf.h" \
          "$tmpdir/include/linux/pci_regs.h" \
          "$tmpdir/include/linux/ethtool.h" \
          "$tmpdir/include/linux/const.h" \
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 12/23] virtio-gpu: Add udmabuf helpers
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (10 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 11/23] headers: Add udmabuf.h Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 13/23] stubs: Add stubs for " Gerd Hoffmann
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

Add helper functions to create a dmabuf for a resource and mmap it.
Also, introduce the fields blob and blob_size so that these helpers
can start to use them but the full picture will emerge only after
adding create_blob API in patch 8 of this series.

To be able to create a dmabuf using the udmabuf driver, Qemu needs
to be lauched with the memfd memory backend like this:

qemu-system-x86_64 -m 8192m -object memory-backend-memfd,id=mem1,size=8192M
-machine memory-backend=mem1

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-4-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/hw/virtio/virtio-gpu.h  |  11 +++
 hw/display/virtio-gpu-udmabuf.c | 158 ++++++++++++++++++++++++++++++++
 hw/display/meson.build          |   1 +
 3 files changed, 170 insertions(+)
 create mode 100644 hw/display/virtio-gpu-udmabuf.c

diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 8ca2c55d9abb..265b1c516cd1 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -50,6 +50,12 @@ struct virtio_gpu_simple_resource {
     uint32_t scanout_bitmask;
     pixman_image_t *image;
     uint64_t hostmem;
+
+    uint64_t blob_size;
+    void *blob;
+    int dmabuf_fd;
+    uint8_t *remapped;
+
     QTAILQ_ENTRY(virtio_gpu_simple_resource) next;
 };
 
@@ -238,6 +244,11 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
                                    struct virtio_gpu_scanout *s,
                                    uint32_t resource_id);
 
+/* virtio-gpu-udmabuf.c */
+bool virtio_gpu_have_udmabuf(void);
+void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);
+void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res);
+
 /* virtio-gpu-3d.c */
 void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
                                   struct virtio_gpu_ctrl_command *cmd);
diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c
new file mode 100644
index 000000000000..71c4672e327a
--- /dev/null
+++ b/hw/display/virtio-gpu-udmabuf.c
@@ -0,0 +1,158 @@
+/*
+ * Virtio GPU Device
+ *
+ * Copyright Red Hat, Inc. 2013-2014
+ *
+ * Authors:
+ *     Dave Airlie <airlied@redhat.com>
+ *     Gerd Hoffmann <kraxel@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu-common.h"
+#include "qemu/iov.h"
+#include "ui/console.h"
+#include "hw/virtio/virtio-gpu.h"
+#include "hw/virtio/virtio-gpu-pixman.h"
+#include "trace.h"
+#include "exec/ramblock.h"
+#include "sysemu/hostmem.h"
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <linux/memfd.h>
+#include "qemu/memfd.h"
+#include "standard-headers/linux/udmabuf.h"
+
+static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    struct udmabuf_create_list *list;
+    RAMBlock *rb;
+    ram_addr_t offset;
+    int udmabuf, i;
+
+    udmabuf = udmabuf_fd();
+    if (udmabuf < 0) {
+        return;
+    }
+
+    list = g_malloc0(sizeof(struct udmabuf_create_list) +
+                     sizeof(struct udmabuf_create_item) * res->iov_cnt);
+
+    for (i = 0; i < res->iov_cnt; i++) {
+        rcu_read_lock();
+        rb = qemu_ram_block_from_host(res->iov[i].iov_base, false, &offset);
+        rcu_read_unlock();
+
+        if (!rb || rb->fd < 0) {
+            g_free(list);
+            return;
+        }
+
+        list->list[i].memfd  = rb->fd;
+        list->list[i].offset = offset;
+        list->list[i].size   = res->iov[i].iov_len;
+    }
+
+    list->count = res->iov_cnt;
+    list->flags = UDMABUF_FLAGS_CLOEXEC;
+
+    res->dmabuf_fd = ioctl(udmabuf, UDMABUF_CREATE_LIST, list);
+    if (res->dmabuf_fd < 0) {
+        warn_report("%s: UDMABUF_CREATE_LIST: %s", __func__,
+                    strerror(errno));
+    }
+    g_free(list);
+}
+
+static void virtio_gpu_remap_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    res->remapped = mmap(NULL, res->blob_size, PROT_READ,
+                         MAP_SHARED, res->dmabuf_fd, 0);
+    if (res->remapped == MAP_FAILED) {
+        warn_report("%s: dmabuf mmap failed: %s", __func__,
+                    strerror(errno));
+        res->remapped = NULL;
+    }
+}
+
+static void virtio_gpu_destroy_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    if (res->remapped) {
+        munmap(res->remapped, res->blob_size);
+        res->remapped = NULL;
+    }
+    if (res->dmabuf_fd >= 0) {
+        close(res->dmabuf_fd);
+        res->dmabuf_fd = -1;
+    }
+}
+
+static int find_memory_backend_type(Object *obj, void *opaque)
+{
+    bool *memfd_backend = opaque;
+    int ret;
+
+    if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
+        HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+        RAMBlock *rb = backend->mr.ram_block;
+
+        if (rb && rb->fd > 0) {
+            ret = fcntl(rb->fd, F_GET_SEALS);
+            if (ret > 0) {
+                *memfd_backend = true;
+            }
+        }
+    }
+
+    return 0;
+}
+
+bool virtio_gpu_have_udmabuf(void)
+{
+    Object *memdev_root;
+    int udmabuf;
+    bool memfd_backend = false;
+
+    udmabuf = udmabuf_fd();
+    if (udmabuf < 0) {
+        return false;
+    }
+
+    memdev_root = object_resolve_path("/objects", NULL);
+    object_child_foreach(memdev_root, find_memory_backend_type, &memfd_backend);
+
+    return memfd_backend;
+}
+
+void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    void *pdata = NULL;
+
+    res->dmabuf_fd = -1;
+    if (res->iov_cnt == 1) {
+        pdata = res->iov[0].iov_base;
+    } else {
+        virtio_gpu_create_udmabuf(res);
+        if (res->dmabuf_fd < 0) {
+            return;
+        }
+        virtio_gpu_remap_udmabuf(res);
+        if (!res->remapped) {
+            return;
+        }
+        pdata = res->remapped;
+    }
+
+    res->blob = pdata;
+}
+
+void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    if (res->remapped) {
+        virtio_gpu_destroy_udmabuf(res);
+    }
+}
diff --git a/hw/display/meson.build b/hw/display/meson.build
index aaf797c5e9ee..e1f473c1dff5 100644
--- a/hw/display/meson.build
+++ b/hw/display/meson.build
@@ -56,6 +56,7 @@ if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
   virtio_gpu_ss = ss.source_set()
   virtio_gpu_ss.add(when: 'CONFIG_VIRTIO_GPU',
                     if_true: [files('virtio-gpu-base.c', 'virtio-gpu.c'), pixman])
+  virtio_gpu_ss.add(when: 'CONFIG_LINUX', if_true: files('virtio-gpu-udmabuf.c'))
   virtio_gpu_ss.add(when: 'CONFIG_VHOST_USER_GPU', if_true: files('vhost-user-gpu.c'))
   hw_display_modules += {'virtio-gpu': virtio_gpu_ss}
 
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 13/23] stubs: Add stubs for udmabuf helpers
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (11 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 12/23] virtio-gpu: Add udmabuf helpers Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 14/23] virtio-gpu: Add virtio_gpu_find_check_resource Gerd Hoffmann
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

This is needed to ensure that virtio-gpu device works for
non-linux builds.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-5-vivek.kasireddy@intel.com>

[ kraxel: add virtio-gpu-udmabuf.c stubs only when building
          system emulation ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 stubs/virtio-gpu-udmabuf.c | 18 ++++++++++++++++++
 meson.build                |  2 +-
 stubs/meson.build          |  1 +
 3 files changed, 20 insertions(+), 1 deletion(-)
 create mode 100644 stubs/virtio-gpu-udmabuf.c

diff --git a/stubs/virtio-gpu-udmabuf.c b/stubs/virtio-gpu-udmabuf.c
new file mode 100644
index 000000000000..e962e00d86d3
--- /dev/null
+++ b/stubs/virtio-gpu-udmabuf.c
@@ -0,0 +1,18 @@
+#include "qemu/osdep.h"
+#include "hw/virtio/virtio-gpu.h"
+
+bool virtio_gpu_have_udmabuf(void)
+{
+    /* nothing (stub) */
+    return false;
+}
+
+void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    /* nothing (stub) */
+}
+
+void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    /* nothing (stub) */
+}
diff --git a/meson.build b/meson.build
index 632b380738d3..9b6d93b8bb44 100644
--- a/meson.build
+++ b/meson.build
@@ -1899,7 +1899,7 @@ util_ss.add_all(trace_ss)
 util_ss = util_ss.apply(config_all, strict: false)
 libqemuutil = static_library('qemuutil',
                              sources: util_ss.sources() + stub_ss.sources() + genh,
-                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
+                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc, pixman])
 qemuutil = declare_dependency(link_with: libqemuutil,
                               sources: genh + version_res)
 
diff --git a/stubs/meson.build b/stubs/meson.build
index 3faef16892be..c32d18258538 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -52,6 +52,7 @@ if have_system
   stub_ss.add(files('semihost.c'))
   stub_ss.add(files('usb-dev-stub.c'))
   stub_ss.add(files('xen-hw-stub.c'))
+  stub_ss.add(files('virtio-gpu-udmabuf.c'))
 else
   stub_ss.add(files('qdev.c'))
 endif
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 14/23] virtio-gpu: Add virtio_gpu_find_check_resource
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (12 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 13/23] stubs: Add stubs for " Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 15/23] virtio-gpu: Refactor virtio_gpu_set_scanout Gerd Hoffmann
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

Move finding the resource and validating its backing storage into one
function.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-6-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/virtio-gpu.c | 66 +++++++++++++++++++++++++++++------------
 1 file changed, 47 insertions(+), 19 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index db56f0454a8a..7b5296f0d088 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -35,6 +35,10 @@
 
 static struct virtio_gpu_simple_resource*
 virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
+static struct virtio_gpu_simple_resource *
+virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
+                               bool require_backing,
+                               const char *caller, uint32_t *error);
 
 static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
                                        struct virtio_gpu_simple_resource *res);
@@ -46,7 +50,8 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
     struct virtio_gpu_simple_resource *res;
     uint32_t pixels;
 
-    res = virtio_gpu_find_resource(g, resource_id);
+    res = virtio_gpu_find_check_resource(g, resource_id, false,
+                                         __func__, NULL);
     if (!res) {
         return;
     }
@@ -114,6 +119,37 @@ virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id)
     return NULL;
 }
 
+static struct virtio_gpu_simple_resource *
+virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
+                               bool require_backing,
+                               const char *caller, uint32_t *error)
+{
+    struct virtio_gpu_simple_resource *res;
+
+    res = virtio_gpu_find_resource(g, resource_id);
+    if (!res) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid resource specified %d\n",
+                      caller, resource_id);
+        if (error) {
+            *error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+        }
+        return NULL;
+    }
+
+    if (require_backing) {
+        if (!res->iov || !res->image) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: no backing storage %d\n",
+                          caller, resource_id);
+            if (error) {
+                *error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+            }
+            return NULL;
+        }
+    }
+
+    return res;
+}
+
 void virtio_gpu_ctrl_response(VirtIOGPU *g,
                               struct virtio_gpu_ctrl_command *cmd,
                               struct virtio_gpu_ctrl_hdr *resp,
@@ -352,11 +388,9 @@ static void virtio_gpu_transfer_to_host_2d(VirtIOGPU *g,
     virtio_gpu_t2d_bswap(&t2d);
     trace_virtio_gpu_cmd_res_xfer_toh_2d(t2d.resource_id);
 
-    res = virtio_gpu_find_resource(g, t2d.resource_id);
-    if (!res || !res->iov) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-                      __func__, t2d.resource_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+    res = virtio_gpu_find_check_resource(g, t2d.resource_id, true,
+                                         __func__, &cmd->error);
+    if (!res) {
         return;
     }
 
@@ -410,11 +444,9 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
     trace_virtio_gpu_cmd_res_flush(rf.resource_id,
                                    rf.r.width, rf.r.height, rf.r.x, rf.r.y);
 
-    res = virtio_gpu_find_resource(g, rf.resource_id);
+    res = virtio_gpu_find_check_resource(g, rf.resource_id, false,
+                                         __func__, &cmd->error);
     if (!res) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-                      __func__, rf.resource_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
         return;
     }
 
@@ -497,11 +529,9 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
     }
 
     /* create a surface for this scanout */
-    res = virtio_gpu_find_resource(g, ss.resource_id);
+    res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
+                                         __func__, &cmd->error);
     if (!res) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-                      __func__, ss.resource_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
         return;
     }
 
@@ -709,11 +739,9 @@ virtio_gpu_resource_detach_backing(VirtIOGPU *g,
     virtio_gpu_bswap_32(&detach, sizeof(detach));
     trace_virtio_gpu_cmd_res_back_detach(detach.resource_id);
 
-    res = virtio_gpu_find_resource(g, detach.resource_id);
-    if (!res || !res->iov) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-                      __func__, detach.resource_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+    res = virtio_gpu_find_check_resource(g, detach.resource_id, true,
+                                         __func__, &cmd->error);
+    if (!res) {
         return;
     }
     virtio_gpu_cleanup_mapping(g, res);
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 15/23] virtio-gpu: Refactor virtio_gpu_set_scanout
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (13 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 14/23] virtio-gpu: Add virtio_gpu_find_check_resource Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-06-02 14:08   ` Alexander Bulekov
  2021-05-27 14:23 ` [PULL 16/23] virtio-gpu: Refactor virtio_gpu_create_mapping_iov Gerd Hoffmann
                   ` (8 subsequent siblings)
  23 siblings, 1 reply; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

Store the meta-data associated with a FB in a new object
(struct virtio_gpu_framebuffer) and pass the object to set_scanout.
Also move code in set_scanout into a do_set_scanout function.
This will be helpful when adding set_scanout_blob API.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-7-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/hw/virtio/virtio-gpu.h |   8 ++
 hw/display/virtio-gpu.c        | 153 +++++++++++++++++++--------------
 2 files changed, 96 insertions(+), 65 deletions(-)

diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 265b1c516cd1..b83a91a67f3a 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -59,6 +59,14 @@ struct virtio_gpu_simple_resource {
     QTAILQ_ENTRY(virtio_gpu_simple_resource) next;
 };
 
+struct virtio_gpu_framebuffer {
+    pixman_format_code_t format;
+    uint32_t bytes_pp;
+    uint32_t width, height;
+    uint32_t stride;
+    uint32_t offset;
+};
+
 struct virtio_gpu_scanout {
     QemuConsole *con;
     DisplaySurface *ds;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 7b5296f0d088..fdcedfc61e54 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -500,95 +500,118 @@ static void virtio_unref_resource(pixman_image_t *image, void *data)
     pixman_image_unref(data);
 }
 
-static void virtio_gpu_set_scanout(VirtIOGPU *g,
-                                   struct virtio_gpu_ctrl_command *cmd)
+static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
+                                      uint32_t scanout_id,
+                                      struct virtio_gpu_framebuffer *fb,
+                                      struct virtio_gpu_simple_resource *res,
+                                      struct virtio_gpu_rect *r,
+                                      uint32_t *error)
 {
-    struct virtio_gpu_simple_resource *res, *ores;
+    struct virtio_gpu_simple_resource *ores;
     struct virtio_gpu_scanout *scanout;
-    pixman_format_code_t format;
-    uint32_t offset;
-    int bpp;
-    struct virtio_gpu_set_scanout ss;
+    uint8_t *data;
 
-    VIRTIO_GPU_FILL_CMD(ss);
-    virtio_gpu_bswap_32(&ss, sizeof(ss));
-    trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
-                                     ss.r.width, ss.r.height, ss.r.x, ss.r.y);
-
-    if (ss.scanout_id >= g->parent_obj.conf.max_outputs) {
+    if (scanout_id >= g->parent_obj.conf.max_outputs) {
         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
-                      __func__, ss.scanout_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
+                      __func__, scanout_id);
+        *error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
+        return;
+    }
+    scanout = &g->parent_obj.scanout[scanout_id];
+
+    if (r->x > fb->width ||
+        r->y > fb->height ||
+        r->width < 16 ||
+        r->height < 16 ||
+        r->width > fb->width ||
+        r->height > fb->height ||
+        r->x + r->width > fb->width ||
+        r->y + r->height > fb->height) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"
+                      " resource %d, rect (%d,%d)+%d,%d, fb %d %d\n",
+                      __func__, scanout_id, res->resource_id,
+                      r->x, r->y, r->width, r->height,
+                      fb->width, fb->height);
+        *error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
         return;
     }
 
     g->parent_obj.enable = 1;
-    if (ss.resource_id == 0) {
-        virtio_gpu_disable_scanout(g, ss.scanout_id);
-        return;
-    }
+    data = (uint8_t *)pixman_image_get_data(res->image);
 
     /* create a surface for this scanout */
-    res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
-                                         __func__, &cmd->error);
-    if (!res) {
-        return;
-    }
-
-    if (ss.r.x > res->width ||
-        ss.r.y > res->height ||
-        ss.r.width < 16 ||
-        ss.r.height < 16 ||
-        ss.r.width > res->width ||
-        ss.r.height > res->height ||
-        ss.r.x + ss.r.width > res->width ||
-        ss.r.y + ss.r.height > res->height) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"
-                      " resource %d, (%d,%d)+%d,%d vs %d %d\n",
-                      __func__, ss.scanout_id, ss.resource_id, ss.r.x, ss.r.y,
-                      ss.r.width, ss.r.height, res->width, res->height);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
-        return;
-    }
-
-    scanout = &g->parent_obj.scanout[ss.scanout_id];
-
-    format = pixman_image_get_format(res->image);
-    bpp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(format), 8);
-    offset = (ss.r.x * bpp) + ss.r.y * pixman_image_get_stride(res->image);
-    if (!scanout->ds || surface_data(scanout->ds)
-        != ((uint8_t *)pixman_image_get_data(res->image) + offset) ||
-        scanout->width != ss.r.width ||
-        scanout->height != ss.r.height) {
+    if (!scanout->ds ||
+        surface_data(scanout->ds) != data + fb->offset ||
+        scanout->width != r->width ||
+        scanout->height != r->height) {
         pixman_image_t *rect;
-        void *ptr = (uint8_t *)pixman_image_get_data(res->image) + offset;
-        rect = pixman_image_create_bits(format, ss.r.width, ss.r.height, ptr,
-                                        pixman_image_get_stride(res->image));
-        pixman_image_ref(res->image);
-        pixman_image_set_destroy_function(rect, virtio_unref_resource,
-                                          res->image);
+        void *ptr = data + fb->offset;
+        rect = pixman_image_create_bits(fb->format, r->width, r->height,
+                                        ptr, fb->stride);
+
+        if (res->image) {
+            pixman_image_ref(res->image);
+            pixman_image_set_destroy_function(rect, virtio_unref_resource,
+                                              res->image);
+        }
+
         /* realloc the surface ptr */
         scanout->ds = qemu_create_displaysurface_pixman(rect);
         if (!scanout->ds) {
-            cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+            *error = VIRTIO_GPU_RESP_ERR_UNSPEC;
             return;
         }
+
         pixman_image_unref(rect);
-        dpy_gfx_replace_surface(g->parent_obj.scanout[ss.scanout_id].con,
+        dpy_gfx_replace_surface(g->parent_obj.scanout[scanout_id].con,
                                 scanout->ds);
     }
 
     ores = virtio_gpu_find_resource(g, scanout->resource_id);
     if (ores) {
-        ores->scanout_bitmask &= ~(1 << ss.scanout_id);
+        ores->scanout_bitmask &= ~(1 << scanout_id);
     }
 
-    res->scanout_bitmask |= (1 << ss.scanout_id);
-    scanout->resource_id = ss.resource_id;
-    scanout->x = ss.r.x;
-    scanout->y = ss.r.y;
-    scanout->width = ss.r.width;
-    scanout->height = ss.r.height;
+    res->scanout_bitmask |= (1 << scanout_id);
+    scanout->resource_id = res->resource_id;
+    scanout->x = r->x;
+    scanout->y = r->y;
+    scanout->width = r->width;
+    scanout->height = r->height;
+}
+
+static void virtio_gpu_set_scanout(VirtIOGPU *g,
+                                   struct virtio_gpu_ctrl_command *cmd)
+{
+    struct virtio_gpu_simple_resource *res;
+    struct virtio_gpu_framebuffer fb = { 0 };
+    struct virtio_gpu_set_scanout ss;
+
+    VIRTIO_GPU_FILL_CMD(ss);
+    virtio_gpu_bswap_32(&ss, sizeof(ss));
+    trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
+                                     ss.r.width, ss.r.height, ss.r.x, ss.r.y);
+
+    if (ss.resource_id == 0) {
+        virtio_gpu_disable_scanout(g, ss.scanout_id);
+        return;
+    }
+
+    res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
+                                         __func__, &cmd->error);
+    if (!res) {
+        return;
+    }
+
+    fb.format = pixman_image_get_format(res->image);
+    fb.bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb.format), 8);
+    fb.width  = pixman_image_get_width(res->image);
+    fb.height = pixman_image_get_height(res->image);
+    fb.stride = pixman_image_get_stride(res->image);
+    fb.offset = ss.r.x * fb.bytes_pp + ss.r.y * fb.stride;
+
+    virtio_gpu_do_set_scanout(g, ss.scanout_id,
+                              &fb, res, &ss.r, &cmd->error);
 }
 
 int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 16/23] virtio-gpu: Refactor virtio_gpu_create_mapping_iov
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (14 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 15/23] virtio-gpu: Refactor virtio_gpu_set_scanout Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 17/23] virtio-gpu: Add initial definitions for blob resources Gerd Hoffmann
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

Instead of passing the attach_backing object to extract nr_entries
and offset, explicitly pass these as arguments to this function.
This will be helpful when adding create_blob API.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-8-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/hw/virtio/virtio-gpu.h |  2 +-
 hw/display/virtio-gpu-virgl.c  |  3 ++-
 hw/display/virtio-gpu.c        | 19 +++++++++----------
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index b83a91a67f3a..dad9a1d221f9 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -238,7 +238,7 @@ void virtio_gpu_get_display_info(VirtIOGPU *g,
 void virtio_gpu_get_edid(VirtIOGPU *g,
                          struct virtio_gpu_ctrl_command *cmd);
 int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
-                                  struct virtio_gpu_resource_attach_backing *ab,
+                                  uint32_t nr_entries, uint32_t offset,
                                   struct virtio_gpu_ctrl_command *cmd,
                                   uint64_t **addr, struct iovec **iov,
                                   uint32_t *niov);
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 72c14d91324b..092c6dc380d9 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -289,7 +289,8 @@ static void virgl_resource_attach_backing(VirtIOGPU *g,
     VIRTIO_GPU_FILL_CMD(att_rb);
     trace_virtio_gpu_cmd_res_back_attach(att_rb.resource_id);
 
-    ret = virtio_gpu_create_mapping_iov(g, &att_rb, cmd, NULL, &res_iovs, &res_niov);
+    ret = virtio_gpu_create_mapping_iov(g, att_rb.nr_entries, sizeof(att_rb),
+                                        cmd, NULL, &res_iovs, &res_niov);
     if (ret != 0) {
         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
         return;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index fdcedfc61e54..7a0db3a8602e 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -615,7 +615,7 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
 }
 
 int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
-                                  struct virtio_gpu_resource_attach_backing *ab,
+                                  uint32_t nr_entries, uint32_t offset,
                                   struct virtio_gpu_ctrl_command *cmd,
                                   uint64_t **addr, struct iovec **iov,
                                   uint32_t *niov)
@@ -624,17 +624,17 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
     size_t esize, s;
     int e, v;
 
-    if (ab->nr_entries > 16384) {
+    if (nr_entries > 16384) {
         qemu_log_mask(LOG_GUEST_ERROR,
                       "%s: nr_entries is too big (%d > 16384)\n",
-                      __func__, ab->nr_entries);
+                      __func__, nr_entries);
         return -1;
     }
 
-    esize = sizeof(*ents) * ab->nr_entries;
+    esize = sizeof(*ents) * nr_entries;
     ents = g_malloc(esize);
     s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
-                   sizeof(*ab), ents, esize);
+                   offset, ents, esize);
     if (s != esize) {
         qemu_log_mask(LOG_GUEST_ERROR,
                       "%s: command data size incorrect %zu vs %zu\n",
@@ -647,7 +647,7 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
     if (addr) {
         *addr = NULL;
     }
-    for (e = 0, v = 0; e < ab->nr_entries; e++) {
+    for (e = 0, v = 0; e < nr_entries; e++) {
         uint64_t a = le64_to_cpu(ents[e].addr);
         uint32_t l = le32_to_cpu(ents[e].length);
         hwaddr len;
@@ -659,8 +659,7 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
                                  a, &len, DMA_DIRECTION_TO_DEVICE);
             if (!map) {
                 qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for"
-                              " resource %d element %d\n",
-                              __func__, ab->resource_id, e);
+                              " element %d\n", __func__, e);
                 virtio_gpu_cleanup_mapping_iov(g, *iov, v);
                 g_free(ents);
                 *iov = NULL;
@@ -743,8 +742,8 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
         return;
     }
 
-    ret = virtio_gpu_create_mapping_iov(g, &ab, cmd, &res->addrs,
-                                        &res->iov, &res->iov_cnt);
+    ret = virtio_gpu_create_mapping_iov(g, ab.nr_entries, sizeof(ab), cmd,
+                                        &res->addrs, &res->iov, &res->iov_cnt);
     if (ret != 0) {
         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
         return;
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 17/23] virtio-gpu: Add initial definitions for blob resources
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (15 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 16/23] virtio-gpu: Refactor virtio_gpu_create_mapping_iov Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 18/23] virtio-gpu: Add virtio_gpu_resource_create_blob Gerd Hoffmann
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

Add the property bit, configuration flag and other relevant
macros and definitions associated with this feature.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-9-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/hw/virtio/virtio-gpu.h |  3 +++
 hw/display/virtio-gpu-base.c   |  3 +++
 hw/display/virtio-gpu.c        | 14 ++++++++++++++
 3 files changed, 20 insertions(+)

diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index dad9a1d221f9..66e7aaad0e98 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -89,6 +89,7 @@ enum virtio_gpu_base_conf_flags {
     VIRTIO_GPU_FLAG_STATS_ENABLED,
     VIRTIO_GPU_FLAG_EDID_ENABLED,
     VIRTIO_GPU_FLAG_DMABUF_ENABLED,
+    VIRTIO_GPU_FLAG_BLOB_ENABLED,
 };
 
 #define virtio_gpu_virgl_enabled(_cfg) \
@@ -99,6 +100,8 @@ enum virtio_gpu_base_conf_flags {
     (_cfg.flags & (1 << VIRTIO_GPU_FLAG_EDID_ENABLED))
 #define virtio_gpu_dmabuf_enabled(_cfg) \
     (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED))
+#define virtio_gpu_blob_enabled(_cfg) \
+    (_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED))
 
 struct virtio_gpu_base_conf {
     uint32_t max_outputs;
diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index afb3ee7d9afc..dd294276cb38 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -208,6 +208,9 @@ virtio_gpu_base_get_features(VirtIODevice *vdev, uint64_t features,
     if (virtio_gpu_edid_enabled(g->conf)) {
         features |= (1 << VIRTIO_GPU_F_EDID);
     }
+    if (virtio_gpu_blob_enabled(g->conf)) {
+        features |= (1 << VIRTIO_GPU_F_RESOURCE_BLOB);
+    }
 
     return features;
 }
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 7a0db3a8602e..f77a7fc7dd21 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1108,6 +1108,18 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
     VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
     VirtIOGPU *g = VIRTIO_GPU(qdev);
 
+    if (virtio_gpu_blob_enabled(g->parent_obj.conf)) {
+        if (!virtio_gpu_have_udmabuf()) {
+            error_setg(errp, "cannot enable blob resources without udmabuf");
+            return;
+        }
+
+        if (virtio_gpu_virgl_enabled(g->parent_obj.conf)) {
+            error_setg(errp, "blobs and virgl are not compatible (yet)");
+            return;
+        }
+    }
+
     if (!virtio_gpu_base_device_realize(qdev,
                                         virtio_gpu_handle_ctrl_cb,
                                         virtio_gpu_handle_cursor_cb,
@@ -1201,6 +1213,8 @@ static Property virtio_gpu_properties[] = {
     VIRTIO_GPU_BASE_PROPERTIES(VirtIOGPU, parent_obj.conf),
     DEFINE_PROP_SIZE("max_hostmem", VirtIOGPU, conf_max_hostmem,
                      256 * MiB),
+    DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
+                    VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 18/23] virtio-gpu: Add virtio_gpu_resource_create_blob
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (16 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 17/23] virtio-gpu: Add initial definitions for blob resources Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 19/23] ui/pixman: Add qemu_pixman_to_drm_format() Gerd Hoffmann
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

This API allows Qemu to register the blob allocated by the Guest
as a new resource and map its backing storage.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-10-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/hw/virtio/virtio-gpu-bswap.h |  9 ++++
 hw/display/virtio-gpu.c              | 73 ++++++++++++++++++++++++++--
 hw/display/trace-events              |  1 +
 3 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/include/hw/virtio/virtio-gpu-bswap.h b/include/hw/virtio/virtio-gpu-bswap.h
index 203f9e17189e..d23ac5cc4a06 100644
--- a/include/hw/virtio/virtio-gpu-bswap.h
+++ b/include/hw/virtio/virtio-gpu-bswap.h
@@ -59,4 +59,13 @@ virtio_gpu_t2d_bswap(struct virtio_gpu_transfer_to_host_2d *t2d)
     le32_to_cpus(&t2d->padding);
 }
 
+static inline void
+virtio_gpu_create_blob_bswap(struct virtio_gpu_resource_create_blob *cblob)
+{
+    virtio_gpu_ctrl_hdr_bswap(&cblob->hdr);
+    le32_to_cpus(&cblob->resource_id);
+    le32_to_cpus(&cblob->blob_flags);
+    le64_to_cpus(&cblob->size);
+}
+
 #endif
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index f77a7fc7dd21..788b4540d5ea 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -137,7 +137,7 @@ virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
     }
 
     if (require_backing) {
-        if (!res->iov || !res->image) {
+        if (!res->iov || (!res->image && !res->blob)) {
             qemu_log_mask(LOG_GUEST_ERROR, "%s: no backing storage %d\n",
                           caller, resource_id);
             if (error) {
@@ -313,6 +313,62 @@ static void virtio_gpu_resource_create_2d(VirtIOGPU *g,
     g->hostmem += res->hostmem;
 }
 
+static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
+                                            struct virtio_gpu_ctrl_command *cmd)
+{
+    struct virtio_gpu_simple_resource *res;
+    struct virtio_gpu_resource_create_blob cblob;
+    int ret;
+
+    VIRTIO_GPU_FILL_CMD(cblob);
+    virtio_gpu_create_blob_bswap(&cblob);
+    trace_virtio_gpu_cmd_res_create_blob(cblob.resource_id, cblob.size);
+
+    if (cblob.resource_id == 0) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
+                      __func__);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+        return;
+    }
+
+    res = virtio_gpu_find_resource(g, cblob.resource_id);
+    if (res) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
+                      __func__, cblob.resource_id);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+        return;
+    }
+
+    res = g_new0(struct virtio_gpu_simple_resource, 1);
+    res->resource_id = cblob.resource_id;
+    res->blob_size = cblob.size;
+
+    if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_GUEST &&
+        cblob.blob_flags != VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid memory type\n",
+                      __func__);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+        g_free(res);
+        return;
+    }
+
+    if (res->iov) {
+        cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+        return;
+    }
+
+    ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
+                                        cmd, &res->addrs, &res->iov,
+                                        &res->iov_cnt);
+    if (ret != 0) {
+        cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+        return;
+    }
+
+    virtio_gpu_init_udmabuf(res);
+    QTAILQ_INSERT_HEAD(&g->reslist, res, next);
+}
+
 static void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id)
 {
     struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id];
@@ -390,7 +446,7 @@ static void virtio_gpu_transfer_to_host_2d(VirtIOGPU *g,
 
     res = virtio_gpu_find_check_resource(g, t2d.resource_id, true,
                                          __func__, &cmd->error);
-    if (!res) {
+    if (!res || res->blob) {
         return;
     }
 
@@ -446,7 +502,7 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 
     res = virtio_gpu_find_check_resource(g, rf.resource_id, false,
                                          __func__, &cmd->error);
-    if (!res) {
+    if (!res || res->blob) {
         return;
     }
 
@@ -715,6 +771,10 @@ static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
     res->iov_cnt = 0;
     g_free(res->addrs);
     res->addrs = NULL;
+
+    if (res->blob) {
+        virtio_gpu_fini_udmabuf(res);
+    }
 }
 
 static void
@@ -785,6 +845,13 @@ void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
     case VIRTIO_GPU_CMD_RESOURCE_CREATE_2D:
         virtio_gpu_resource_create_2d(g, cmd);
         break;
+    case VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB:
+        if (!virtio_gpu_blob_enabled(g->parent_obj.conf)) {
+            cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+            break;
+        }
+        virtio_gpu_resource_create_blob(g, cmd);
+        break;
     case VIRTIO_GPU_CMD_RESOURCE_UNREF:
         virtio_gpu_resource_unref(g, cmd);
         break;
diff --git a/hw/display/trace-events b/hw/display/trace-events
index 9fccca18a1d7..f3f77b6984b7 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -32,6 +32,7 @@ virtio_gpu_cmd_get_edid(uint32_t scanout) "scanout %d"
 virtio_gpu_cmd_set_scanout(uint32_t id, uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
 virtio_gpu_cmd_res_create_2d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h) "res 0x%x, fmt 0x%x, w %d, h %d"
 virtio_gpu_cmd_res_create_3d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h, uint32_t d) "res 0x%x, fmt 0x%x, w %d, h %d, d %d"
+virtio_gpu_cmd_res_create_blob(uint32_t res, uint64_t size) "res 0x%x, size %" PRId64
 virtio_gpu_cmd_res_unref(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_back_attach(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_back_detach(uint32_t res) "res 0x%x"
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 19/23] ui/pixman: Add qemu_pixman_to_drm_format()
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (17 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 18/23] virtio-gpu: Add virtio_gpu_resource_create_blob Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 20/23] virtio-gpu: Add helpers to create and destroy dmabuf objects Gerd Hoffmann
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

This new function to get the drm_format associated with a pixman
format will be useful while creating a dmabuf.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-11-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/qemu-pixman.h |  1 +
 ui/qemu-pixman.c         | 35 ++++++++++++++++++++++++-----------
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index 87737a6f1629..806ddcd7cdab 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -62,6 +62,7 @@ typedef struct PixelFormat {
 PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format);
 pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian);
 pixman_format_code_t qemu_drm_format_to_pixman(uint32_t drm_format);
+uint32_t qemu_pixman_to_drm_format(pixman_format_code_t pixman);
 int qemu_pixman_get_type(int rshift, int gshift, int bshift);
 pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf);
 bool qemu_pixman_check_format(DisplayChangeListener *dcl,
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index 85f2945e886f..3ab7e2e958a5 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -89,21 +89,34 @@ pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian)
 }
 
 /* Note: drm is little endian, pixman is native endian */
+static const struct {
+    uint32_t drm_format;
+    pixman_format_code_t pixman_format;
+} drm_format_pixman_map[] = {
+    { DRM_FORMAT_RGB888,   PIXMAN_LE_r8g8b8   },
+    { DRM_FORMAT_ARGB8888, PIXMAN_LE_a8r8g8b8 },
+    { DRM_FORMAT_XRGB8888, PIXMAN_LE_x8r8g8b8 }
+};
+
 pixman_format_code_t qemu_drm_format_to_pixman(uint32_t drm_format)
 {
-    static const struct {
-        uint32_t drm_format;
-        pixman_format_code_t pixman;
-    } map[] = {
-        { DRM_FORMAT_RGB888,   PIXMAN_LE_r8g8b8   },
-        { DRM_FORMAT_ARGB8888, PIXMAN_LE_a8r8g8b8 },
-        { DRM_FORMAT_XRGB8888, PIXMAN_LE_x8r8g8b8 }
-    };
     int i;
 
-    for (i = 0; i < ARRAY_SIZE(map); i++) {
-        if (drm_format == map[i].drm_format) {
-            return map[i].pixman;
+    for (i = 0; i < ARRAY_SIZE(drm_format_pixman_map); i++) {
+        if (drm_format == drm_format_pixman_map[i].drm_format) {
+            return drm_format_pixman_map[i].pixman_format;
+        }
+    }
+    return 0;
+}
+
+uint32_t qemu_pixman_to_drm_format(pixman_format_code_t pixman_format)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(drm_format_pixman_map); i++) {
+        if (pixman_format == drm_format_pixman_map[i].pixman_format) {
+            return drm_format_pixman_map[i].drm_format;
         }
     }
     return 0;
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 20/23] virtio-gpu: Add helpers to create and destroy dmabuf objects
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (18 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 19/23] ui/pixman: Add qemu_pixman_to_drm_format() Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 21/23] virtio-gpu: Factor out update scanout Gerd Hoffmann
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

These helpers can be useful for creating dmabuf objects from blobs
and submitting them to the UI.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-12-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/hw/virtio/virtio-gpu.h  | 15 ++++++++
 hw/display/virtio-gpu-udmabuf.c | 65 +++++++++++++++++++++++++++++++++
 stubs/virtio-gpu-udmabuf.c      |  9 +++++
 3 files changed, 89 insertions(+)

diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 66e7aaad0e98..bcf54d970f24 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -150,6 +150,12 @@ struct VirtIOGPUBaseClass {
     DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1024), \
     DEFINE_PROP_UINT32("yres", _state, _conf.yres, 768)
 
+typedef struct VGPUDMABuf {
+    QemuDmaBuf buf;
+    uint32_t scanout_id;
+    QTAILQ_ENTRY(VGPUDMABuf) next;
+} VGPUDMABuf;
+
 struct VirtIOGPU {
     VirtIOGPUBase parent_obj;
 
@@ -178,6 +184,11 @@ struct VirtIOGPU {
         uint32_t req_3d;
         uint32_t bytes_3d;
     } stats;
+
+    struct {
+        QTAILQ_HEAD(, VGPUDMABuf) bufs;
+        VGPUDMABuf *primary;
+    } dmabuf;
 };
 
 struct VirtIOGPUClass {
@@ -259,6 +270,10 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
 bool virtio_gpu_have_udmabuf(void);
 void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);
 void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res);
+int virtio_gpu_update_dmabuf(VirtIOGPU *g,
+                             uint32_t scanout_id,
+                             struct virtio_gpu_simple_resource *res,
+                             struct virtio_gpu_framebuffer *fb);
 
 /* virtio-gpu-3d.c */
 void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c
index 71c4672e327a..3c01a415e71b 100644
--- a/hw/display/virtio-gpu-udmabuf.c
+++ b/hw/display/virtio-gpu-udmabuf.c
@@ -156,3 +156,68 @@ void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
         virtio_gpu_destroy_udmabuf(res);
     }
 }
+
+static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDMABuf *dmabuf)
+{
+    struct virtio_gpu_scanout *scanout;
+
+    scanout = &g->parent_obj.scanout[dmabuf->scanout_id];
+    dpy_gl_release_dmabuf(scanout->con, &dmabuf->buf);
+    QTAILQ_REMOVE(&g->dmabuf.bufs, dmabuf, next);
+    g_free(dmabuf);
+}
+
+static VGPUDMABuf
+*virtio_gpu_create_dmabuf(VirtIOGPU *g,
+                          uint32_t scanout_id,
+                          struct virtio_gpu_simple_resource *res,
+                          struct virtio_gpu_framebuffer *fb)
+{
+    VGPUDMABuf *dmabuf;
+
+    if (res->dmabuf_fd < 0) {
+        return NULL;
+    }
+
+    dmabuf = g_new0(VGPUDMABuf, 1);
+    dmabuf->buf.width = fb->width;
+    dmabuf->buf.height = fb->height;
+    dmabuf->buf.stride = fb->stride;
+    dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format);
+    dmabuf->buf.fd = res->dmabuf_fd;
+
+    dmabuf->scanout_id = scanout_id;
+    QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next);
+
+    return dmabuf;
+}
+
+int virtio_gpu_update_dmabuf(VirtIOGPU *g,
+                             uint32_t scanout_id,
+                             struct virtio_gpu_simple_resource *res,
+                             struct virtio_gpu_framebuffer *fb)
+{
+    struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id];
+    VGPUDMABuf *new_primary, *old_primary = NULL;
+
+    new_primary = virtio_gpu_create_dmabuf(g, scanout_id, res, fb);
+    if (!new_primary) {
+        return -EINVAL;
+    }
+
+    if (g->dmabuf.primary) {
+        old_primary = g->dmabuf.primary;
+    }
+
+    g->dmabuf.primary = new_primary;
+    qemu_console_resize(scanout->con,
+                        new_primary->buf.width,
+                        new_primary->buf.height);
+    dpy_gl_scanout_dmabuf(scanout->con, &new_primary->buf);
+
+    if (old_primary) {
+        virtio_gpu_free_dmabuf(g, old_primary);
+    }
+
+    return 0;
+}
diff --git a/stubs/virtio-gpu-udmabuf.c b/stubs/virtio-gpu-udmabuf.c
index e962e00d86d3..81f661441ab9 100644
--- a/stubs/virtio-gpu-udmabuf.c
+++ b/stubs/virtio-gpu-udmabuf.c
@@ -16,3 +16,12 @@ void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
 {
     /* nothing (stub) */
 }
+
+int virtio_gpu_update_dmabuf(VirtIOGPU *g,
+                             uint32_t scanout_id,
+                             struct virtio_gpu_simple_resource *res,
+                             struct virtio_gpu_framebuffer *fb)
+{
+    /* nothing (stub) */
+    return 0;
+}
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 21/23] virtio-gpu: Factor out update scanout
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (19 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 20/23] virtio-gpu: Add helpers to create and destroy dmabuf objects Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 22/23] virtio-gpu: Add virtio_gpu_set_scanout_blob Gerd Hoffmann
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

Creating a small helper function for updating the scanout
will be useful in the next patch where this needs to be
done early in do_set_scanout before returning.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-13-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/virtio-gpu.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 788b4540d5ea..0af08edde85b 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -556,6 +556,28 @@ static void virtio_unref_resource(pixman_image_t *image, void *data)
     pixman_image_unref(data);
 }
 
+static void virtio_gpu_update_scanout(VirtIOGPU *g,
+                                      uint32_t scanout_id,
+                                      struct virtio_gpu_simple_resource *res,
+                                      struct virtio_gpu_rect *r)
+{
+    struct virtio_gpu_simple_resource *ores;
+    struct virtio_gpu_scanout *scanout;
+
+    scanout = &g->parent_obj.scanout[scanout_id];
+    ores = virtio_gpu_find_resource(g, scanout->resource_id);
+    if (ores) {
+        ores->scanout_bitmask &= ~(1 << scanout_id);
+    }
+
+    res->scanout_bitmask |= (1 << scanout_id);
+    scanout->resource_id = res->resource_id;
+    scanout->x = r->x;
+    scanout->y = r->y;
+    scanout->width = r->width;
+    scanout->height = r->height;
+}
+
 static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
                                       uint32_t scanout_id,
                                       struct virtio_gpu_framebuffer *fb,
@@ -563,7 +585,6 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
                                       struct virtio_gpu_rect *r,
                                       uint32_t *error)
 {
-    struct virtio_gpu_simple_resource *ores;
     struct virtio_gpu_scanout *scanout;
     uint8_t *data;
 
@@ -623,17 +644,7 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
                                 scanout->ds);
     }
 
-    ores = virtio_gpu_find_resource(g, scanout->resource_id);
-    if (ores) {
-        ores->scanout_bitmask &= ~(1 << scanout_id);
-    }
-
-    res->scanout_bitmask |= (1 << scanout_id);
-    scanout->resource_id = res->resource_id;
-    scanout->x = r->x;
-    scanout->y = r->y;
-    scanout->width = r->width;
-    scanout->height = r->height;
+    virtio_gpu_update_scanout(g, scanout_id, res, r);
 }
 
 static void virtio_gpu_set_scanout(VirtIOGPU *g,
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 22/23] virtio-gpu: Add virtio_gpu_set_scanout_blob
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (20 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 21/23] virtio-gpu: Factor out update scanout Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-27 14:23 ` [PULL 23/23] virtio-gpu: Update cursor data using blob Gerd Hoffmann
  2021-05-30 18:55 ` [PULL 00/23] Vga 20210527 patches Peter Maydell
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

This API allows Qemu to set the blob allocated by the Guest as
the scanout buffer. If Opengl support is available, then the
scanout buffer would be submitted as a dmabuf to the UI; if not,
a pixman image is created from the scanout buffer and is
submitted to the UI via the display surface.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-14-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/hw/virtio/virtio-gpu-bswap.h |   7 ++
 hw/display/virtio-gpu.c              | 102 +++++++++++++++++++++++++--
 hw/display/trace-events              |   1 +
 3 files changed, 103 insertions(+), 7 deletions(-)

diff --git a/include/hw/virtio/virtio-gpu-bswap.h b/include/hw/virtio/virtio-gpu-bswap.h
index d23ac5cc4a06..e2bee8f59557 100644
--- a/include/hw/virtio/virtio-gpu-bswap.h
+++ b/include/hw/virtio/virtio-gpu-bswap.h
@@ -68,4 +68,11 @@ virtio_gpu_create_blob_bswap(struct virtio_gpu_resource_create_blob *cblob)
     le64_to_cpus(&cblob->size);
 }
 
+static inline void
+virtio_gpu_scanout_blob_bswap(struct virtio_gpu_set_scanout_blob *ssb)
+{
+    virtio_gpu_bswap_32(ssb, sizeof(*ssb) - sizeof(ssb->offsets[3]));
+    le32_to_cpus(&ssb->offsets[3]);
+}
+
 #endif
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 0af08edde85b..8cee6cb3e57d 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -403,7 +403,7 @@ static void virtio_gpu_resource_destroy(VirtIOGPU *g,
         }
     }
 
-    pixman_image_unref(res->image);
+    qemu_pixman_image_unref(res->image);
     virtio_gpu_cleanup_mapping(g, res);
     QTAILQ_REMOVE(&g->reslist, res, next);
     g->hostmem -= res->hostmem;
@@ -492,6 +492,7 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 {
     struct virtio_gpu_simple_resource *res;
     struct virtio_gpu_resource_flush rf;
+    struct virtio_gpu_scanout *scanout;
     pixman_region16_t flush_region;
     int i;
 
@@ -502,16 +503,29 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 
     res = virtio_gpu_find_check_resource(g, rf.resource_id, false,
                                          __func__, &cmd->error);
-    if (!res || res->blob) {
+    if (!res) {
         return;
     }
 
-    if (rf.r.x > res->width ||
+    if (res->blob) {
+        for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
+            scanout = &g->parent_obj.scanout[i];
+            if (scanout->resource_id == res->resource_id &&
+                console_has_gl(scanout->con)) {
+                dpy_gl_update(scanout->con, 0, 0, scanout->width,
+                              scanout->height);
+                return;
+            }
+        }
+    }
+
+    if (!res->blob &&
+        (rf.r.x > res->width ||
         rf.r.y > res->height ||
         rf.r.width > res->width ||
         rf.r.height > res->height ||
         rf.r.x + rf.r.width > res->width ||
-        rf.r.y + rf.r.height > res->height) {
+        rf.r.y + rf.r.height > res->height)) {
         qemu_log_mask(LOG_GUEST_ERROR, "%s: flush bounds outside resource"
                       " bounds for resource %d: %d %d %d %d vs %d %d\n",
                       __func__, rf.resource_id, rf.r.x, rf.r.y,
@@ -523,7 +537,6 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
     pixman_region_init_rect(&flush_region,
                             rf.r.x, rf.r.y, rf.r.width, rf.r.height);
     for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
-        struct virtio_gpu_scanout *scanout;
         pixman_region16_t region, finalregion;
         pixman_box16_t *extents;
 
@@ -614,10 +627,23 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
     }
 
     g->parent_obj.enable = 1;
-    data = (uint8_t *)pixman_image_get_data(res->image);
+
+    if (res->blob) {
+        if (console_has_gl(scanout->con)) {
+            if (!virtio_gpu_update_dmabuf(g, scanout_id, res, fb)) {
+                virtio_gpu_update_scanout(g, scanout_id, res, r);
+                return;
+            }
+        }
+
+        data = res->blob;
+    } else {
+        data = (uint8_t *)pixman_image_get_data(res->image);
+    }
 
     /* create a surface for this scanout */
-    if (!scanout->ds ||
+    if ((res->blob && !console_has_gl(scanout->con)) ||
+        !scanout->ds ||
         surface_data(scanout->ds) != data + fb->offset ||
         scanout->width != r->width ||
         scanout->height != r->height) {
@@ -681,6 +707,61 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
                               &fb, res, &ss.r, &cmd->error);
 }
 
+static void virtio_gpu_set_scanout_blob(VirtIOGPU *g,
+                                        struct virtio_gpu_ctrl_command *cmd)
+{
+    struct virtio_gpu_simple_resource *res;
+    struct virtio_gpu_framebuffer fb = { 0 };
+    struct virtio_gpu_set_scanout_blob ss;
+    uint64_t fbend;
+
+    VIRTIO_GPU_FILL_CMD(ss);
+    virtio_gpu_scanout_blob_bswap(&ss);
+    trace_virtio_gpu_cmd_set_scanout_blob(ss.scanout_id, ss.resource_id,
+                                          ss.r.width, ss.r.height, ss.r.x,
+                                          ss.r.y);
+
+    if (ss.resource_id == 0) {
+        virtio_gpu_disable_scanout(g, ss.scanout_id);
+        return;
+    }
+
+    res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
+                                         __func__, &cmd->error);
+    if (!res) {
+        return;
+    }
+
+    fb.format = virtio_gpu_get_pixman_format(ss.format);
+    if (!fb.format) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: host couldn't handle guest format %d\n",
+                      __func__, ss.format);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+        return;
+    }
+
+    fb.bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb.format), 8);
+    fb.width = ss.width;
+    fb.height = ss.height;
+    fb.stride = ss.strides[0];
+    fb.offset = ss.offsets[0] + ss.r.x * fb.bytes_pp + ss.r.y * fb.stride;
+
+    fbend = fb.offset;
+    fbend += fb.stride * (ss.r.height - 1);
+    fbend += fb.bytes_pp * ss.r.width;
+    if (fbend > res->blob_size) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: fb end out of range\n",
+                      __func__);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+        return;
+    }
+
+    virtio_gpu_do_set_scanout(g, ss.scanout_id,
+                              &fb, res, &ss.r, &cmd->error);
+}
+
 int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
                                   uint32_t nr_entries, uint32_t offset,
                                   struct virtio_gpu_ctrl_command *cmd,
@@ -875,6 +956,13 @@ void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
     case VIRTIO_GPU_CMD_SET_SCANOUT:
         virtio_gpu_set_scanout(g, cmd);
         break;
+    case VIRTIO_GPU_CMD_SET_SCANOUT_BLOB:
+        if (!virtio_gpu_blob_enabled(g->parent_obj.conf)) {
+            cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+            break;
+        }
+        virtio_gpu_set_scanout_blob(g, cmd);
+        break;
     case VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING:
         virtio_gpu_resource_attach_backing(g, cmd);
         break;
diff --git a/hw/display/trace-events b/hw/display/trace-events
index f3f77b6984b7..e47264af5da1 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -30,6 +30,7 @@ virtio_gpu_features(bool virgl) "virgl %d"
 virtio_gpu_cmd_get_display_info(void) ""
 virtio_gpu_cmd_get_edid(uint32_t scanout) "scanout %d"
 virtio_gpu_cmd_set_scanout(uint32_t id, uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
+virtio_gpu_cmd_set_scanout_blob(uint32_t id, uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
 virtio_gpu_cmd_res_create_2d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h) "res 0x%x, fmt 0x%x, w %d, h %d"
 virtio_gpu_cmd_res_create_3d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h, uint32_t d) "res 0x%x, fmt 0x%x, w %d, h %d, d %d"
 virtio_gpu_cmd_res_create_blob(uint32_t res, uint64_t size) "res 0x%x, size %" PRId64
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PULL 23/23] virtio-gpu: Update cursor data using blob
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (21 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 22/23] virtio-gpu: Add virtio_gpu_set_scanout_blob Gerd Hoffmann
@ 2021-05-27 14:23 ` Gerd Hoffmann
  2021-05-30 18:55 ` [PULL 00/23] Vga 20210527 patches Peter Maydell
  23 siblings, 0 replies; 27+ messages in thread
From: Gerd Hoffmann @ 2021-05-27 14:23 UTC (permalink / raw)
  To: qemu-devel
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy,
	Gerd Hoffmann, Paolo Bonzini, Marc-André Lureau

From: Vivek Kasireddy <vivek.kasireddy@intel.com>

If a blob is available for the cursor, copy the data from the blob.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Message-Id: <20210526231429.1045476-15-vivek.kasireddy@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/virtio-gpu.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 8cee6cb3e57d..4d549377cbc1 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -49,6 +49,7 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
 {
     struct virtio_gpu_simple_resource *res;
     uint32_t pixels;
+    void *data;
 
     res = virtio_gpu_find_check_resource(g, resource_id, false,
                                          __func__, NULL);
@@ -56,14 +57,22 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
         return;
     }
 
-    if (pixman_image_get_width(res->image)  != s->current_cursor->width ||
-        pixman_image_get_height(res->image) != s->current_cursor->height) {
-        return;
+    if (res->blob_size) {
+        if (res->blob_size < (s->current_cursor->width *
+                              s->current_cursor->height * 4)) {
+            return;
+        }
+        data = res->blob;
+    } else {
+        if (pixman_image_get_width(res->image)  != s->current_cursor->width ||
+            pixman_image_get_height(res->image) != s->current_cursor->height) {
+            return;
+        }
+        data = pixman_image_get_data(res->image);
     }
 
     pixels = s->current_cursor->width * s->current_cursor->height;
-    memcpy(s->current_cursor->data,
-           pixman_image_get_data(res->image),
+    memcpy(s->current_cursor->data, data,
            pixels * sizeof(uint32_t));
 }
 
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PULL 00/23] Vga 20210527 patches
  2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
                   ` (22 preceding siblings ...)
  2021-05-27 14:23 ` [PULL 23/23] virtio-gpu: Update cursor data using blob Gerd Hoffmann
@ 2021-05-30 18:55 ` Peter Maydell
  23 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2021-05-30 18:55 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Marc-André Lureau, Cornelia Huck, QEMU Developers,
	Paolo Bonzini, Michael S. Tsirkin

On Thu, 27 May 2021 at 15:25, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> The following changes since commit 2ab2dad01f6dc3667c0d53d2b1ba46b511031207:
>
>   Merge remote-tracking branch 'remotes/kraxel/tags/input-20210526-pull-request' into staging (2021-05-26 15:27:20 +0100)
>
> are available in the Git repository at:
>
>   git://git.kraxel.org/qemu tags/vga-20210527-pull-request
>
> for you to fetch changes up to bdd53f739273e97b5e5617b699d1763c42a5ea7e:
>
>   virtio-gpu: Update cursor data using blob (2021-05-27 12:07:37 +0200)
>
> ----------------------------------------------------------------
> virtio-gpu: add blob resource support.
> vhost-user-gpu: security fixes.
>
> ----------------------------------------------------------------
>


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/6.1
for any user-visible changes.

-- PMM


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PULL 15/23] virtio-gpu: Refactor virtio_gpu_set_scanout
  2021-05-27 14:23 ` [PULL 15/23] virtio-gpu: Refactor virtio_gpu_set_scanout Gerd Hoffmann
@ 2021-06-02 14:08   ` Alexander Bulekov
  0 siblings, 0 replies; 27+ messages in thread
From: Alexander Bulekov @ 2021-06-02 14:08 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Michael S. Tsirkin, Cornelia Huck, Vivek Kasireddy, qemu-devel,
	Marc-André Lureau, Paolo Bonzini

On 210527 1623, Gerd Hoffmann wrote:
> From: Vivek Kasireddy <vivek.kasireddy@intel.com>
> 
> Store the meta-data associated with a FB in a new object
> (struct virtio_gpu_framebuffer) and pass the object to set_scanout.
> Also move code in set_scanout into a do_set_scanout function.
> This will be helpful when adding set_scanout_blob API.
> 
> Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
> Message-Id: <20210526231429.1045476-7-vivek.kasireddy@intel.com>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---

Hi,
Recently OSS-Fuzz found a heap-overflow in virtio_gpu_disable_scanout. I
bisected it to this patch:
https://gitlab.com/qemu-project/qemu/-/issues/383
-Alex


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PULL 02/23] vhost-user-gpu: fix resource leak in 'vg_resource_create_2d' (CVE-2021-3544)
  2021-05-27 14:23 ` [PULL 02/23] vhost-user-gpu: fix resource leak in 'vg_resource_create_2d' (CVE-2021-3544) Gerd Hoffmann
@ 2021-06-03 15:54   ` Peter Maydell
  0 siblings, 0 replies; 27+ messages in thread
From: Peter Maydell @ 2021-06-03 15:54 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Prasad J Pandit, Michael S. Tsirkin, Cornelia Huck, Li Qiang,
	QEMU Developers, Marc-André Lureau, Paolo Bonzini

On Thu, 27 May 2021 at 15:28, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> From: Li Qiang <liq3ea@163.com>
>
> Call 'vugbm_buffer_destroy' in error path to avoid resource leak.
>
> Fixes: CVE-2021-3544
> Reported-by: Li Qiang <liq3ea@163.com>
> Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
> Signed-off-by: Li Qiang <liq3ea@163.com>
> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Message-Id: <20210516030403.107723-3-liq3ea@163.com>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  contrib/vhost-user-gpu/vhost-user-gpu.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c b/contrib/vhost-user-gpu/vhost-user-gpu.c
> index f73f292c9f72..b5e153d0d648 100644
> --- a/contrib/vhost-user-gpu/vhost-user-gpu.c
> +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c
> @@ -349,6 +349,7 @@ vg_resource_create_2d(VuGpu *g,
>          g_critical("%s: resource creation failed %d %d %d",
>                     __func__, c2d.resource_id, c2d.width, c2d.height);
>          g_free(res);
> +        vugbm_buffer_destroy(&res->buffer);
>          cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
>          return;
>      }

Hi; Coverity reports this as a use-after-free: we free 'res'
and then on the next line we pass a pointer into this freed
memory to vugbm_buffer_destroy(), which dereferences it.
Probably the two lines should be in the other order ?

(CID 1453812)

thanks
-- PMM


^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2021-06-03 15:56 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-27 14:23 [PULL 00/23] Vga 20210527 patches Gerd Hoffmann
2021-05-27 14:23 ` [PULL 01/23] vhost-user-gpu: fix memory disclosure in virgl_cmd_get_capset_info (CVE-2021-3545) Gerd Hoffmann
2021-05-27 14:23 ` [PULL 02/23] vhost-user-gpu: fix resource leak in 'vg_resource_create_2d' (CVE-2021-3544) Gerd Hoffmann
2021-06-03 15:54   ` Peter Maydell
2021-05-27 14:23 ` [PULL 03/23] vhost-user-gpu: fix memory leak in vg_resource_attach_backing (CVE-2021-3544) Gerd Hoffmann
2021-05-27 14:23 ` [PULL 04/23] vhost-user-gpu: fix memory leak while calling 'vg_resource_unref' (CVE-2021-3544) Gerd Hoffmann
2021-05-27 14:23 ` [PULL 05/23] vhost-user-gpu: fix memory leak in 'virgl_cmd_resource_unref' (CVE-2021-3544) Gerd Hoffmann
2021-05-27 14:23 ` [PULL 06/23] vhost-user-gpu: fix memory leak in 'virgl_resource_attach_backing' (CVE-2021-3544) Gerd Hoffmann
2021-05-27 14:23 ` [PULL 07/23] vhost-user-gpu: fix OOB write in 'virgl_cmd_get_capset' (CVE-2021-3546) Gerd Hoffmann
2021-05-27 14:23 ` [PULL 08/23] vhost-user-gpu: abstract vg_cleanup_mapping_iov Gerd Hoffmann
2021-05-27 14:23 ` [PULL 09/23] hw/display/qxl: Set pci rom address aligned with page size Gerd Hoffmann
2021-05-27 14:23 ` [PULL 10/23] ui: Get the fd associated with udmabuf driver Gerd Hoffmann
2021-05-27 14:23 ` [PULL 11/23] headers: Add udmabuf.h Gerd Hoffmann
2021-05-27 14:23 ` [PULL 12/23] virtio-gpu: Add udmabuf helpers Gerd Hoffmann
2021-05-27 14:23 ` [PULL 13/23] stubs: Add stubs for " Gerd Hoffmann
2021-05-27 14:23 ` [PULL 14/23] virtio-gpu: Add virtio_gpu_find_check_resource Gerd Hoffmann
2021-05-27 14:23 ` [PULL 15/23] virtio-gpu: Refactor virtio_gpu_set_scanout Gerd Hoffmann
2021-06-02 14:08   ` Alexander Bulekov
2021-05-27 14:23 ` [PULL 16/23] virtio-gpu: Refactor virtio_gpu_create_mapping_iov Gerd Hoffmann
2021-05-27 14:23 ` [PULL 17/23] virtio-gpu: Add initial definitions for blob resources Gerd Hoffmann
2021-05-27 14:23 ` [PULL 18/23] virtio-gpu: Add virtio_gpu_resource_create_blob Gerd Hoffmann
2021-05-27 14:23 ` [PULL 19/23] ui/pixman: Add qemu_pixman_to_drm_format() Gerd Hoffmann
2021-05-27 14:23 ` [PULL 20/23] virtio-gpu: Add helpers to create and destroy dmabuf objects Gerd Hoffmann
2021-05-27 14:23 ` [PULL 21/23] virtio-gpu: Factor out update scanout Gerd Hoffmann
2021-05-27 14:23 ` [PULL 22/23] virtio-gpu: Add virtio_gpu_set_scanout_blob Gerd Hoffmann
2021-05-27 14:23 ` [PULL 23/23] virtio-gpu: Update cursor data using blob Gerd Hoffmann
2021-05-30 18:55 ` [PULL 00/23] Vga 20210527 patches Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.