virtio-gpu: fix crashes upon warm reboot with vga mode
With vga=775 on the Linux command line a first boot of the VM running Linux works fine. After a warm reboot it crashes during Linux boot. Before that, valgrind points out bad memory write to console surface. The VGA code is not aware that virtio-gpu got a message surface scanout when the display is disabled. Let's reset VGA graphic mode when it is the case, so that a new display surface is created when doing further VGA operations. https://bugs.launchpad.net/qemu/+bug/1784900/ Reported-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> Tested-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Message-id: 20180803153235.4134-1-marcandre.lureau@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
09b94ac0f2
commit
93f874fe9d
@ -421,6 +421,11 @@ static void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id)
|
||||
scanout->height ?: 480,
|
||||
"Guest disabled display.");
|
||||
}
|
||||
|
||||
if (g->disable_scanout) {
|
||||
g->disable_scanout(g, scanout_id);
|
||||
}
|
||||
|
||||
dpy_gfx_replace_surface(scanout->con, ds);
|
||||
scanout->resource_id = 0;
|
||||
scanout->ds = NULL;
|
||||
|
@ -75,6 +75,16 @@ static void virtio_vga_gl_block(void *opaque, bool block)
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_vga_disable_scanout(VirtIOGPU *g, int scanout_id)
|
||||
{
|
||||
VirtIOVGA *vvga = container_of(g, VirtIOVGA, vdev);
|
||||
|
||||
if (scanout_id == 0) {
|
||||
/* reset surface if needed */
|
||||
vvga->vga.graphic_mode = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static const GraphicHwOps virtio_vga_ops = {
|
||||
.invalidate = virtio_vga_invalidate_display,
|
||||
.gfx_update = virtio_vga_update_display,
|
||||
@ -156,6 +166,7 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
||||
vvga->vga_mrs, true);
|
||||
|
||||
vga->con = g->scanout[0].con;
|
||||
g->disable_scanout = virtio_vga_disable_scanout;
|
||||
graphic_console_set_hwops(vga->con, &virtio_vga_ops, vvga);
|
||||
|
||||
for (i = 0; i < g->conf.max_outputs; i++) {
|
||||
|
@ -125,6 +125,7 @@ typedef struct VirtIOGPU {
|
||||
uint32_t bytes_3d;
|
||||
} stats;
|
||||
|
||||
void (*disable_scanout)(struct VirtIOGPU *g, int scanout_id);
|
||||
Error *migration_blocker;
|
||||
} VirtIOGPU;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user