summary refs log tree commit diff stats
path: root/hw/display/virtio-vga.c
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2018-08-03 17:32:35 +0200
committerPeter Maydell <peter.maydell@linaro.org>2018-08-07 15:03:58 +0100
commit93f874fe9dbe0b997b5a9459840957efd13d7191 (patch)
tree44484b3c3f6d071bf7dce2548d3bfbc61802a805 /hw/display/virtio-vga.c
parent09b94ac0f29db3b022a77a5aa50dc9e37032689d (diff)
downloadfocaccia-qemu-93f874fe9dbe0b997b5a9459840957efd13d7191.tar.gz
focaccia-qemu-93f874fe9dbe0b997b5a9459840957efd13d7191.zip
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>
Diffstat (limited to 'hw/display/virtio-vga.c')
-rw-r--r--hw/display/virtio-vga.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c
index 8d3d9e14a7..701d980872 100644
--- a/hw/display/virtio-vga.c
+++ b/hw/display/virtio-vga.c
@@ -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++) {