From: Akihiko Odaki <akihiko.odaki@daynix.com>
To: "Dmitry Osipenko" <dmitry.osipenko@collabora.com>,
"Huang Rui" <ray.huang@amd.com>,
"Marc-André Lureau" <marcandre.lureau@gmail.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Gerd Hoffmann" <kraxel@redhat.com>,
"Michael S . Tsirkin" <mst@redhat.com>,
"Stefano Stabellini" <sstabellini@kernel.org>,
"Anthony PERARD" <anthony.perard@citrix.com>,
"Antonio Caggiano" <quic_acaggian@quicinc.com>,
"Dr . David Alan Gilbert" <dgilbert@redhat.com>,
"Robert Beckett" <bob.beckett@collabora.com>,
"Gert Wollny" <gert.wollny@collabora.com>,
"Alex Bennée" <alex.bennee@linaro.org>
Cc: qemu-devel@nongnu.org,
"Gurchetan Singh" <gurchetansingh@chromium.org>,
ernunes@redhat.com, "Alyssa Ross" <hi@alyssa.is>,
"Roger Pau Monné" <roger.pau@citrix.com>,
"Alex Deucher" <alexander.deucher@amd.com>,
"Stefano Stabellini" <stefano.stabellini@amd.com>,
"Christian König" <christian.koenig@amd.com>,
"Xenia Ragiadakou" <xenia.ragiadakou@amd.com>,
"Pierre-Eric Pelloux-Prayer" <pierre-eric.pelloux-prayer@amd.com>,
"Honglei Huang" <honglei1.huang@amd.com>,
"Julia Zhang" <julia.zhang@amd.com>,
"Chen Jiqian" <Jiqian.Chen@amd.com>
Subject: Re: [PATCH v7 07/10] virtio-gpu: Handle resource blob commands
Date: Sat, 13 Apr 2024 20:57:10 +0900 [thread overview]
Message-ID: <29a55f63-593e-46d0-8dfe-f55e2b2de7ac@daynix.com> (raw)
In-Reply-To: <20240411102002.240536-8-dmitry.osipenko@collabora.com>
On 2024/04/11 19:19, Dmitry Osipenko wrote:
> From: Antonio Caggiano <antonio.caggiano@collabora.com>
>
> Support BLOB resources creation, mapping and unmapping by calling the
> new stable virglrenderer 0.10 interface. Only enabled when available and
> via the blob config. E.g. -device virtio-vga-gl,blob=true
>
> Signed-off-by: Antonio Caggiano <antonio.caggiano@collabora.com>
> Signed-off-by: Xenia Ragiadakou <xenia.ragiadakou@amd.com>
> Signed-off-by: Huang Rui <ray.huang@amd.com>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> ---
> hw/display/virtio-gpu-virgl.c | 196 +++++++++++++++++++++++++++++++++
> hw/display/virtio-gpu.c | 4 +-
> include/hw/virtio/virtio-gpu.h | 1 +
> 3 files changed, 200 insertions(+), 1 deletion(-)
>
> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
> index c2057b0c2147..ec63f5d698b7 100644
> --- a/hw/display/virtio-gpu-virgl.c
> +++ b/hw/display/virtio-gpu-virgl.c
> @@ -32,6 +32,55 @@ virgl_get_egl_display(G_GNUC_UNUSED void *cookie)
> }
> #endif
>
> +#ifdef HAVE_VIRGL_RESOURCE_BLOB
> +static int
> +virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
> + struct virtio_gpu_simple_resource *res,
> + uint64_t offset)
> +{
> + VirtIOGPUBase *b = VIRTIO_GPU_BASE(g);
> + uint64_t size;
> + void *data;
> + int ret;
> +
> + if (!virtio_gpu_hostmem_enabled(b->conf)) {
> + return -EOPNOTSUPP;
> + }
> +
> + ret = virgl_renderer_resource_map(res->resource_id, &data, &size);
> + if (ret) {
> + return -ret;
> + }
> +
> + res->mr = g_new0(MemoryRegion, 1);
> + memory_region_init_ram_ptr(res->mr, OBJECT(res->mr), "blob",
> + size, data);
> + memory_region_add_subregion(&b->hostmem, offset, res->mr);
> + memory_region_set_enabled(res->mr, true);
> +
> + return 0;
> +}
> +
> +static void
> +virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g,
> + struct virtio_gpu_simple_resource *res)
> +{
> + VirtIOGPUBase *b = VIRTIO_GPU_BASE(g);
> +
> + if (!res->mr) {
> + return;
> + }
> +
> + memory_region_set_enabled(res->mr, false);
> + memory_region_del_subregion(&b->hostmem, res->mr);
> +
> + /* memory region owns res->mr object and frees it when mr is released */
> + res->mr = NULL;
> +
> + virgl_renderer_resource_unmap(res->resource_id);
Hi,
First, thanks for keeping working on this.
This patch has some changes since the previous version, but it is still
vulnerable to the race condition pointed out. The memory region is
asynchronously unmapped from the guest address space, but the backing
memory on the host address space is unmapped synchronously before that.
This results in use-after-free. The whole unmapping operation needs to
be implemented in an asynchronous manner.
Regards,
Akihiko Odaki
> +}
> +#endif /* HAVE_VIRGL_RESOURCE_BLOB */
> +
> static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
> struct virtio_gpu_ctrl_command *cmd)
> {
> @@ -145,6 +194,10 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g,
> return;
> }
>
> +#ifdef HAVE_VIRGL_RESOURCE_BLOB
> + virtio_gpu_virgl_unmap_resource_blob(g, res);
> +#endif
> +
> virgl_renderer_resource_detach_iov(unref.resource_id,
> &res_iovs,
> &num_iovs);
> @@ -495,6 +548,140 @@ static void virgl_cmd_get_capset(VirtIOGPU *g,
> }
>
> #ifdef HAVE_VIRGL_RESOURCE_BLOB
> +static void virgl_cmd_resource_create_blob(VirtIOGPU *g,
> + struct virtio_gpu_ctrl_command *cmd)
> +{
> + struct virgl_renderer_resource_create_blob_args virgl_args = { 0 };
> + struct virtio_gpu_resource_create_blob cblob;
> + struct virtio_gpu_simple_resource *res;
> + int ret;
> +
> + if (!virtio_gpu_blob_enabled(g->parent_obj.conf)) {
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
> + return;
> + }
> +
> + 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;
> + res->dmabuf_fd = -1;
> +
> + if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_HOST3D) {
> + ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
> + cmd, &res->addrs,
> + &res->iov, &res->iov_cnt);
> + if (!ret) {
> + g_free(res);
> + cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
> + return;
> + }
> + }
> +
> + QTAILQ_INSERT_HEAD(&g->reslist, res, next);
> +
> + virgl_args.res_handle = cblob.resource_id;
> + virgl_args.ctx_id = cblob.hdr.ctx_id;
> + virgl_args.blob_mem = cblob.blob_mem;
> + virgl_args.blob_id = cblob.blob_id;
> + virgl_args.blob_flags = cblob.blob_flags;
> + virgl_args.size = cblob.size;
> + virgl_args.iovecs = res->iov;
> + virgl_args.num_iovs = res->iov_cnt;
> +
> + ret = virgl_renderer_resource_create_blob(&virgl_args);
> + if (ret) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: virgl blob create error: %s\n",
> + __func__, strerror(-ret));
> + cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
> + }
> +}
> +
> +static void virgl_cmd_resource_map_blob(VirtIOGPU *g,
> + struct virtio_gpu_ctrl_command *cmd)
> +{
> + struct virtio_gpu_resource_map_blob mblob;
> + struct virtio_gpu_simple_resource *res;
> + struct virtio_gpu_resp_map_info resp;
> + int ret;
> +
> + VIRTIO_GPU_FILL_CMD(mblob);
> + virtio_gpu_map_blob_bswap(&mblob);
> +
> + res = virtio_gpu_find_resource(g, mblob.resource_id);
> + if (!res) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: resource does not exist %d\n",
> + __func__, mblob.resource_id);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
> + return;
> + }
> +
> + if (res->mr) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already mapped %d\n",
> + __func__, mblob.resource_id);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
> + return;
> + }
> +
> + ret = virtio_gpu_virgl_map_resource_blob(g, res, mblob.offset);
> + if (ret) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: resource map error: %s\n",
> + __func__, strerror(ret));
> + cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
> + return;
> + }
> +
> + memset(&resp, 0, sizeof(resp));
> + resp.hdr.type = VIRTIO_GPU_RESP_OK_MAP_INFO;
> + virgl_renderer_resource_get_map_info(mblob.resource_id, &resp.map_info);
> + virtio_gpu_ctrl_response(g, cmd, &resp.hdr, sizeof(resp));
> +}
> +
> +static void virgl_cmd_resource_unmap_blob(VirtIOGPU *g,
> + struct virtio_gpu_ctrl_command *cmd)
> +{
> + struct virtio_gpu_resource_unmap_blob ublob;
> + struct virtio_gpu_simple_resource *res;
> +
> + VIRTIO_GPU_FILL_CMD(ublob);
> + virtio_gpu_unmap_blob_bswap(&ublob);
> +
> + res = virtio_gpu_find_resource(g, ublob.resource_id);
> + if (!res) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: resource does not exist %d\n",
> + __func__, ublob.resource_id);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
> + return;
> + }
> +
> + if (!res->mr) {
> + qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already unmapped %d\n",
> + __func__, ublob.resource_id);
> + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
> + return;
> + }
> +
> + virtio_gpu_virgl_unmap_resource_blob(g, res);
> +}
> +
> static void virgl_cmd_set_scanout_blob(VirtIOGPU *g,
> struct virtio_gpu_ctrl_command *cmd)
> {
> @@ -661,6 +848,15 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
> virtio_gpu_get_edid(g, cmd);
> break;
> #ifdef HAVE_VIRGL_RESOURCE_BLOB
> + case VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB:
> + virgl_cmd_resource_create_blob(g, cmd);
> + break;
> + case VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB:
> + virgl_cmd_resource_map_blob(g, cmd);
> + break;
> + case VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB:
> + virgl_cmd_resource_unmap_blob(g, cmd);
> + break;
> case VIRTIO_GPU_CMD_SET_SCANOUT_BLOB:
> virgl_cmd_set_scanout_blob(g, cmd);
> break;
> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> index 1e57a53d346c..e6e09f4bf8da 100644
> --- a/hw/display/virtio-gpu.c
> +++ b/hw/display/virtio-gpu.c
> @@ -1478,10 +1478,12 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
> return;
> }
>
> +#ifndef HAVE_VIRGL_RESOURCE_BLOB
> if (virtio_gpu_virgl_enabled(g->parent_obj.conf)) {
> - error_setg(errp, "blobs and virgl are not compatible (yet)");
> + error_setg(errp, "old virglrenderer, blob resources unsupported");
> return;
> }
> +#endif
> }
>
> if (!virtio_gpu_base_device_realize(qdev,
> diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
> index 44c676c3ca4a..f3681476eaf6 100644
> --- a/include/hw/virtio/virtio-gpu.h
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -60,6 +60,7 @@ struct virtio_gpu_simple_resource {
> void *blob;
> int dmabuf_fd;
> uint8_t *remapped;
> + MemoryRegion *mr;
>
> QTAILQ_ENTRY(virtio_gpu_simple_resource) next;
> };
next prev parent reply other threads:[~2024-04-13 11:58 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-11 10:19 [PATCH v7 00/10] Support blob memory and venus on qemu Dmitry Osipenko
2024-04-11 10:19 ` [PATCH v7 01/10] linux-headers: Update to Linux v6.9-rc3 Dmitry Osipenko
2024-04-11 10:19 ` [PATCH v7 02/10] virtio-gpu: Use pkgconfig version to decide which virgl features are available Dmitry Osipenko
2024-04-11 10:19 ` [PATCH v7 03/10] virtio-gpu: Support context-init feature with virglrenderer Dmitry Osipenko
2024-04-11 10:19 ` [PATCH v7 04/10] virtio-gpu: Don't require udmabuf when blobs and virgl are enabled Dmitry Osipenko
2024-04-11 10:19 ` [PATCH v7 05/10] virtio-gpu: Add virgl resource management Dmitry Osipenko
2024-04-11 10:19 ` [PATCH v7 06/10] virtio-gpu: Support blob scanout using dmabuf fd Dmitry Osipenko
2024-04-11 10:19 ` [PATCH v7 07/10] virtio-gpu: Handle resource blob commands Dmitry Osipenko
2024-04-13 11:57 ` Akihiko Odaki [this message]
2024-04-15 8:03 ` Dmitry Osipenko
2024-04-15 8:13 ` Akihiko Odaki
2024-04-15 8:49 ` Dmitry Osipenko
2024-04-15 10:05 ` Akihiko Odaki
2024-04-18 15:20 ` Dmitry Osipenko
2024-04-11 10:20 ` [PATCH v7 08/10] virtio-gpu: Resource UUID Dmitry Osipenko
2024-04-11 10:20 ` [PATCH v7 09/10] virtio-gpu: Support Venus capset Dmitry Osipenko
2024-04-11 12:52 ` Antonio Caggiano
2024-04-11 13:00 ` Dmitry Osipenko
2024-04-11 10:20 ` [PATCH v7 10/10] virtio-gpu: Initialize Venus Dmitry Osipenko
2024-04-12 3:58 ` [PATCH v7 00/10] Support blob memory and venus on qemu Huang Rui
2024-04-15 7:15 ` Dmitry Osipenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=29a55f63-593e-46d0-8dfe-f55e2b2de7ac@daynix.com \
--to=akihiko.odaki@daynix.com \
--cc=Jiqian.Chen@amd.com \
--cc=alex.bennee@linaro.org \
--cc=alexander.deucher@amd.com \
--cc=anthony.perard@citrix.com \
--cc=bob.beckett@collabora.com \
--cc=christian.koenig@amd.com \
--cc=dgilbert@redhat.com \
--cc=dmitry.osipenko@collabora.com \
--cc=ernunes@redhat.com \
--cc=gert.wollny@collabora.com \
--cc=gurchetansingh@chromium.org \
--cc=hi@alyssa.is \
--cc=honglei1.huang@amd.com \
--cc=julia.zhang@amd.com \
--cc=kraxel@redhat.com \
--cc=marcandre.lureau@gmail.com \
--cc=mst@redhat.com \
--cc=philmd@linaro.org \
--cc=pierre-eric.pelloux-prayer@amd.com \
--cc=qemu-devel@nongnu.org \
--cc=quic_acaggian@quicinc.com \
--cc=ray.huang@amd.com \
--cc=roger.pau@citrix.com \
--cc=sstabellini@kernel.org \
--cc=stefano.stabellini@amd.com \
--cc=xenia.ragiadakou@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).