* [PATCH 0/2] virtio-gpu: fix blob scanout post-load
@ 2024-01-15 15:48 marcandre.lureau
2024-01-15 15:48 ` [PATCH 1/2] virtio-gpu: remove needless condition marcandre.lureau
2024-01-15 15:48 ` [PATCH 2/2] virtio-gpu: fix scanout migration post-load marcandre.lureau
0 siblings, 2 replies; 6+ messages in thread
From: marcandre.lureau @ 2024-01-15 15:48 UTC (permalink / raw)
To: qemu-devel
Cc: peterx, Gerd Hoffmann, Michael S. Tsirkin, Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Hi,
The current post-loading code for scanout has a FIXME: it doesn't take the
resource region/rect into account. But there is more, when adding blob migration
support in commit f66767f75c9, I didn't realize that blob resources could be
used for scanouts. This situationn leads to a crash during post-load, as they
don't have an associated res->image.
virtio_gpu_do_set_scanout() handle all cases, but requires the associated
virtio_gpu_framebuffer, which is currently not saved during migration.
Add a v2 of "virtio-gpu-one-scanout" with the framebuffer fields, so we can
restore blob scanouts, as well as fixing the existing FIXME.
Marc-André Lureau (2):
virtio-gpu: remove needless condition
virtio-gpu: fix scanout migration post-load
include/hw/virtio/virtio-gpu.h | 1 +
hw/display/virtio-gpu.c | 61 ++++++++++++++++++++++++----------
2 files changed, 45 insertions(+), 17 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] virtio-gpu: remove needless condition
2024-01-15 15:48 [PATCH 0/2] virtio-gpu: fix blob scanout post-load marcandre.lureau
@ 2024-01-15 15:48 ` marcandre.lureau
2024-01-15 15:48 ` [PATCH 2/2] virtio-gpu: fix scanout migration post-load marcandre.lureau
1 sibling, 0 replies; 6+ messages in thread
From: marcandre.lureau @ 2024-01-15 15:48 UTC (permalink / raw)
To: qemu-devel
Cc: peterx, Gerd Hoffmann, Michael S. Tsirkin, Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
qemu_create_displaysurface_pixman() never returns NULL.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/display/virtio-gpu.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index f8a675eb30..a62ffb1627 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -679,10 +679,6 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
/* realloc the surface ptr */
scanout->ds = qemu_create_displaysurface_pixman(rect);
- if (!scanout->ds) {
- *error = VIRTIO_GPU_RESP_ERR_UNSPEC;
- return;
- }
#ifdef WIN32
qemu_displaysurface_win32_set_handle(scanout->ds, res->handle, fb->offset);
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] virtio-gpu: fix scanout migration post-load
2024-01-15 15:48 [PATCH 0/2] virtio-gpu: fix blob scanout post-load marcandre.lureau
2024-01-15 15:48 ` [PATCH 1/2] virtio-gpu: remove needless condition marcandre.lureau
@ 2024-01-15 15:48 ` marcandre.lureau
2024-01-16 11:16 ` Sebastian Ott
1 sibling, 1 reply; 6+ messages in thread
From: marcandre.lureau @ 2024-01-15 15:48 UTC (permalink / raw)
To: qemu-devel
Cc: peterx, Gerd Hoffmann, Michael S. Tsirkin, Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
The current post-loading code for scanout has a FIXME: it doesn't take
the resource region/rect into account. But there is more, when adding
blob migration support in commit f66767f75c9, I didn't realize that blob
resources could be used for scanouts. This situationn leads to a crash
during post-load, as they don't have an associated res->image.
virtio_gpu_do_set_scanout() handle all cases, but requires the
associated virtio_gpu_framebuffer, which is currently not saved during
migration.
Add a v2 of "virtio-gpu-one-scanout" with the framebuffer fields, so we
can restore blob scanouts, as well as fixing the existing FIXME.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/hw/virtio/virtio-gpu.h | 1 +
hw/display/virtio-gpu.c | 57 ++++++++++++++++++++++++++--------
2 files changed, 45 insertions(+), 13 deletions(-)
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 584ba2ed73..9a13afb34e 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -81,6 +81,7 @@ struct virtio_gpu_scanout {
uint32_t resource_id;
struct virtio_gpu_update_cursor cursor;
QEMUCursor *current_cursor;
+ struct virtio_gpu_framebuffer fb;
};
struct virtio_gpu_requested_state {
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index a62ffb1627..05c30f30b6 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -595,6 +595,7 @@ static void virtio_unref_resource(pixman_image_t *image, void *data)
static void virtio_gpu_update_scanout(VirtIOGPU *g,
uint32_t scanout_id,
struct virtio_gpu_simple_resource *res,
+ struct virtio_gpu_framebuffer *fb,
struct virtio_gpu_rect *r)
{
struct virtio_gpu_simple_resource *ores;
@@ -612,9 +613,10 @@ static void virtio_gpu_update_scanout(VirtIOGPU *g,
scanout->y = r->y;
scanout->width = r->width;
scanout->height = r->height;
+ scanout->fb = *fb;
}
-static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
+static bool virtio_gpu_do_set_scanout(VirtIOGPU *g,
uint32_t scanout_id,
struct virtio_gpu_framebuffer *fb,
struct virtio_gpu_simple_resource *res,
@@ -640,7 +642,7 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
r->x, r->y, r->width, r->height,
fb->width, fb->height);
*error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
- return;
+ return false;
}
g->parent_obj.enable = 1;
@@ -648,11 +650,12 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
if (res->blob) {
if (console_has_gl(scanout->con)) {
if (!virtio_gpu_update_dmabuf(g, scanout_id, res, fb, r)) {
- virtio_gpu_update_scanout(g, scanout_id, res, r);
+ virtio_gpu_update_scanout(g, scanout_id, res, fb, r);
} else {
*error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
+ return false;
}
- return;
+ return true;
}
data = res->blob;
@@ -688,7 +691,8 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
scanout->ds);
}
- virtio_gpu_update_scanout(g, scanout_id, res, r);
+ virtio_gpu_update_scanout(g, scanout_id, res, fb, r);
+ return true;
}
static void virtio_gpu_set_scanout(VirtIOGPU *g,
@@ -1159,7 +1163,8 @@ static void virtio_gpu_cursor_bh(void *opaque)
static const VMStateDescription vmstate_virtio_gpu_scanout = {
.name = "virtio-gpu-one-scanout",
- .version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 1,
.fields = (const VMStateField[]) {
VMSTATE_UINT32(resource_id, struct virtio_gpu_scanout),
VMSTATE_UINT32(width, struct virtio_gpu_scanout),
@@ -1171,6 +1176,12 @@ static const VMStateDescription vmstate_virtio_gpu_scanout = {
VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout),
VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout),
VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout),
+ VMSTATE_UINT32_V(fb.format, struct virtio_gpu_scanout, 2),
+ VMSTATE_UINT32_V(fb.bytes_pp, struct virtio_gpu_scanout, 2),
+ VMSTATE_UINT32_V(fb.width, struct virtio_gpu_scanout, 2),
+ VMSTATE_UINT32_V(fb.height, struct virtio_gpu_scanout, 2),
+ VMSTATE_UINT32_V(fb.stride, struct virtio_gpu_scanout, 2),
+ VMSTATE_UINT32_V(fb.offset, struct virtio_gpu_scanout, 2),
VMSTATE_END_OF_LIST()
},
};
@@ -1342,6 +1353,7 @@ static int virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size,
if (!res->blob_size) {
continue;
}
+ assert(!res->image);
qemu_put_be32(f, res->resource_id);
qemu_put_be32(f, res->blob_size);
qemu_put_be32(f, res->iov_cnt);
@@ -1404,24 +1416,43 @@ static int virtio_gpu_post_load(void *opaque, int version_id)
int i;
for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
- /* FIXME: should take scanout.r.{x,y} into account */
scanout = &g->parent_obj.scanout[i];
if (!scanout->resource_id) {
continue;
}
+
res = virtio_gpu_find_resource(g, scanout->resource_id);
if (!res) {
return -EINVAL;
}
- scanout->ds = qemu_create_displaysurface_pixman(res->image);
- if (!scanout->ds) {
- return -EINVAL;
- }
+
+ if (scanout->fb.format != 0) {
+ uint32_t error = 0;
+ struct virtio_gpu_rect r = {
+ .x = scanout->x,
+ .y = scanout->y,
+ .width = scanout->width,
+ .height = scanout->height
+ };
+
+ if (!virtio_gpu_do_set_scanout(g, i, &scanout->fb, res, &r, &error)) {
+ return -EINVAL;
+ }
+ } else {
+ /* legacy v1 migration support */
+ if (!res->image) {
+ return -EINVAL;
+ }
+ scanout->ds = qemu_create_displaysurface_pixman(res->image);
+ if (!scanout->ds) {
+ return -EINVAL;
+ }
#ifdef WIN32
- qemu_displaysurface_win32_set_handle(scanout->ds, res->handle, 0);
+ qemu_displaysurface_win32_set_handle(scanout->ds, res->handle, 0);
#endif
+ dpy_gfx_replace_surface(scanout->con, scanout->ds);
+ }
- dpy_gfx_replace_surface(scanout->con, scanout->ds);
dpy_gfx_update_full(scanout->con);
if (scanout->cursor.resource_id) {
update_cursor(g, &scanout->cursor);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] virtio-gpu: fix scanout migration post-load
2024-01-15 15:48 ` [PATCH 2/2] virtio-gpu: fix scanout migration post-load marcandre.lureau
@ 2024-01-16 11:16 ` Sebastian Ott
2024-01-17 11:13 ` Marc-André Lureau
0 siblings, 1 reply; 6+ messages in thread
From: Sebastian Ott @ 2024-01-16 11:16 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, peterx, Gerd Hoffmann, Michael S. Tsirkin
On Mon, 15 Jan 2024, marcandre.lureau@redhat.com wrote:
> + scanout->ds = qemu_create_displaysurface_pixman(res->image);
> + if (!scanout->ds) {
> + return -EINVAL;
> + }
"qemu_create_displaysurface_pixman() never returns NULL." ;-)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] virtio-gpu: fix scanout migration post-load
2024-01-16 11:16 ` Sebastian Ott
@ 2024-01-17 11:13 ` Marc-André Lureau
2024-01-17 17:00 ` Sebastian Ott
0 siblings, 1 reply; 6+ messages in thread
From: Marc-André Lureau @ 2024-01-17 11:13 UTC (permalink / raw)
To: Sebastian Ott; +Cc: qemu-devel, peterx, Gerd Hoffmann, Michael S. Tsirkin
Hi
On Tue, Jan 16, 2024 at 3:17 PM Sebastian Ott <sebott@redhat.com> wrote:
>
> On Mon, 15 Jan 2024, marcandre.lureau@redhat.com wrote:
> > + scanout->ds = qemu_create_displaysurface_pixman(res->image);
> > + if (!scanout->ds) {
> > + return -EINVAL;
> > + }
>
> "qemu_create_displaysurface_pixman() never returns NULL." ;-)
Right, I'll update the first patch.
Other comments about this patch?
thanks
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] virtio-gpu: fix scanout migration post-load
2024-01-17 11:13 ` Marc-André Lureau
@ 2024-01-17 17:00 ` Sebastian Ott
0 siblings, 0 replies; 6+ messages in thread
From: Sebastian Ott @ 2024-01-17 17:00 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, peterx, Gerd Hoffmann, Michael S. Tsirkin
[-- Attachment #1: Type: text/plain, Size: 571 bytes --]
On Wed, 17 Jan 2024, Marc-André Lureau wrote:
> On Tue, Jan 16, 2024 at 3:17 PM Sebastian Ott <sebott@redhat.com> wrote:
>> On Mon, 15 Jan 2024, marcandre.lureau@redhat.com wrote:
>>> + scanout->ds = qemu_create_displaysurface_pixman(res->image);
>>> + if (!scanout->ds) {
>>> + return -EINVAL;
>>> + }
>>
>> "qemu_create_displaysurface_pixman() never returns NULL." ;-)
>
> Right, I'll update the first patch.
>
> Other comments about this patch?
Nope, looks good to me.
Reviewed-by: Sebastian Ott <sebott@redhat.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-01-17 17:02 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-15 15:48 [PATCH 0/2] virtio-gpu: fix blob scanout post-load marcandre.lureau
2024-01-15 15:48 ` [PATCH 1/2] virtio-gpu: remove needless condition marcandre.lureau
2024-01-15 15:48 ` [PATCH 2/2] virtio-gpu: fix scanout migration post-load marcandre.lureau
2024-01-16 11:16 ` Sebastian Ott
2024-01-17 11:13 ` Marc-André Lureau
2024-01-17 17:00 ` Sebastian Ott
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).