[qemu/f18] Add "qxl: call dpy_gfx_resize when entering vga mode" patch, fixing

Hans de Goede jwrdegoede at fedoraproject.org
Mon Jan 21 15:06:56 UTC 2013


commit 83889a9bd2ed4ef11924d2e8f0b55d003279b70f
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon Jan 21 16:09:24 2013 +0100

    Add "qxl: call dpy_gfx_resize when entering vga mode" patch, fixing
    
      an often reported use after free crash (rhbz#873845)
    - Replace "wip: hw/qxl: inject interrupts in any state" patch with the
      official upstream fix
    - Add 5 other spice/qxl crash/bug fixes cherry-picked from upstream

 ...ccomp-adding-new-syscalls-bugzilla-855162.patch |  241 --------------------
 ...exit-on-failure-to-register-qxl-interface.patch |   35 +++
 ...w-qxl-fix-condition-for-exiting-guest_bug.patch |   29 +++
 0517-hw-qxl-qxl_send_events-nop-if-stopped.patch   |   50 ++++
 ...all-dpy_gfx_resize-when-entering-vga-mode.patch |   37 +++
 0519-spice-fix-initialization-order.patch          |   67 ++++++
 ...ew-spice-server-callbacks-to-ui-spice-dis.patch |   69 ++++++
 ...ve-qemu_create_displaysurface_from-result.patch |   41 ++++
 ...wip-hw-qxl-inject-interrupts-in-any-state.patch |   24 --
 qemu.spec                                          |   26 ++-
 10 files changed, 350 insertions(+), 269 deletions(-)
---
diff --git a/0515-hw-qxl-exit-on-failure-to-register-qxl-interface.patch b/0515-hw-qxl-exit-on-failure-to-register-qxl-interface.patch
new file mode 100644
index 0000000..f8aee4f
--- /dev/null
+++ b/0515-hw-qxl-exit-on-failure-to-register-qxl-interface.patch
@@ -0,0 +1,35 @@
+From 58891f4a215336182677e97c94198ba8cced19cd Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy at redhat.com>
+Date: Wed, 3 Oct 2012 20:13:58 +0200
+Subject: [PATCH 515/522] hw/qxl: exit on failure to register qxl interface
+
+This prevents a segfault later on when the device reset handler
+tries to access a NULL ssd.worker since interface_attach_worker has
+not been called.
+
+Signed-off-by: Alon Levy <alevy at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ hw/qxl.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/hw/qxl.c b/hw/qxl.c
+index 8d33745..db6440e 100644
+--- a/hw/qxl.c
++++ b/hw/qxl.c
+@@ -2035,7 +2035,11 @@ static int qxl_init_common(PCIQXLDevice *qxl)
+ 
+     qxl->ssd.qxl.base.sif = &qxl_interface.base;
+     qxl->ssd.qxl.id = qxl->id;
+-    qemu_spice_add_interface(&qxl->ssd.qxl.base);
++    if (qemu_spice_add_interface(&qxl->ssd.qxl.base) != 0) {
++        error_report("qxl interface %d.%d not supported by spice-server\n",
++                     SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR);
++        return -1;
++    }
+     qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl);
+ 
+     init_pipe_signaling(qxl);
+-- 
+1.8.0.2
+
diff --git a/0516-hw-qxl-fix-condition-for-exiting-guest_bug.patch b/0516-hw-qxl-fix-condition-for-exiting-guest_bug.patch
new file mode 100644
index 0000000..216c177
--- /dev/null
+++ b/0516-hw-qxl-fix-condition-for-exiting-guest_bug.patch
@@ -0,0 +1,29 @@
+From 8ceaa64ed2f20a7af865eb9bac0bc6e54f5f7eea Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy at redhat.com>
+Date: Tue, 2 Oct 2012 11:39:14 +0200
+Subject: [PATCH 516/522] hw/qxl: fix condition for exiting guest_bug
+
+Reported and suggested by Paolo Bonzini, thanks.
+
+Signed-off-by: Alon Levy <alevy at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ hw/qxl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/qxl.c b/hw/qxl.c
+index db6440e..445705e 100644
+--- a/hw/qxl.c
++++ b/hw/qxl.c
+@@ -1461,7 +1461,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
+     qxl_async_io async = QXL_SYNC;
+     uint32_t orig_io_port = io_port;
+ 
+-    if (d->guest_bug && !io_port == QXL_IO_RESET) {
++    if (d->guest_bug && io_port != QXL_IO_RESET) {
+         return;
+     }
+ 
+-- 
+1.8.0.2
+
diff --git a/0517-hw-qxl-qxl_send_events-nop-if-stopped.patch b/0517-hw-qxl-qxl_send_events-nop-if-stopped.patch
new file mode 100644
index 0000000..324ce7d
--- /dev/null
+++ b/0517-hw-qxl-qxl_send_events-nop-if-stopped.patch
@@ -0,0 +1,50 @@
+From 79868eccfd65a7926d7beff42b1094a000b10c01 Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy at redhat.com>
+Date: Thu, 1 Nov 2012 14:56:00 +0200
+Subject: [PATCH 517/522] hw/qxl: qxl_send_events: nop if stopped
+
+Added a trace point for easy logging.
+
+RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=870972
+
+Signed-off-by: Alon Levy <alevy at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ hw/qxl.c     | 8 +++++++-
+ trace-events | 1 +
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/hw/qxl.c b/hw/qxl.c
+index 445705e..8111bb9 100644
+--- a/hw/qxl.c
++++ b/hw/qxl.c
+@@ -1714,7 +1714,13 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
+     uint32_t le_events = cpu_to_le32(events);
+ 
+     trace_qxl_send_events(d->id, events);
+-    assert(qemu_spice_display_is_running(&d->ssd));
++    if (!qemu_spice_display_is_running(&d->ssd)) {
++        /* spice-server tracks guest running state and should not do this */
++        fprintf(stderr, "%s: spice-server bug: guest stopped, ignoring\n",
++                __func__);
++        trace_qxl_send_events_vm_stopped(d->id, events);
++        return;
++    }
+     old_pending = __sync_fetch_and_or(&d->ram->int_pending, le_events);
+     if ((old_pending & le_events) == le_events) {
+         return;
+diff --git a/trace-events b/trace-events
+index f5b5097..9d39d8d 100644
+--- a/trace-events
++++ b/trace-events
+@@ -978,6 +978,7 @@ qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t righ
+ qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
+ qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
+ qxl_send_events(int qid, uint32_t events) "%d %d"
++qxl_send_events_vm_stopped(int qid, uint32_t events) "%d %d"
+ qxl_set_guest_bug(int qid) "%d"
+ qxl_interrupt_client_monitors_config(int qid, int num_heads, void *heads) "%d %d %p"
+ qxl_client_monitors_config_unsupported_by_guest(int qid, uint32_t int_mask, void *client_monitors_config) "%d %X %p"
+-- 
+1.8.0.2
+
diff --git a/0518-qxl-call-dpy_gfx_resize-when-entering-vga-mode.patch b/0518-qxl-call-dpy_gfx_resize-when-entering-vga-mode.patch
new file mode 100644
index 0000000..12f90d7
--- /dev/null
+++ b/0518-qxl-call-dpy_gfx_resize-when-entering-vga-mode.patch
@@ -0,0 +1,37 @@
+From acbfa56143a6c8a4e0ceb2546612ae4caea907d3 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel at redhat.com>
+Date: Tue, 30 Oct 2012 14:55:12 +0100
+Subject: [PATCH 518/564] qxl: call dpy_gfx_resize when entering vga mode
+
+When entering vga mode the display size likely changes,
+notify all displaychangelisteners about this.
+
+Probably went unnoticed for a while as one if the first
+things the guest does after leaving qxl native mode and
+entering qxl vga mode is to set the vga video mode.  But
+there is still a small window where qemu can operate on
+stale data, leading to crashes now and then.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=865767
+
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ hw/qxl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/qxl.c b/hw/qxl.c
+index 8111bb9..3583d98 100644
+--- a/hw/qxl.c
++++ b/hw/qxl.c
+@@ -1084,7 +1084,7 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
+     trace_qxl_enter_vga_mode(d->id);
+     qemu_spice_create_host_primary(&d->ssd);
+     d->mode = QXL_MODE_VGA;
+-    memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty));
++    dpy_resize(d->ssd.ds);
+     vga_dirty_log_start(&d->vga);
+ }
+ 
+-- 
+1.8.1
+
diff --git a/0519-spice-fix-initialization-order.patch b/0519-spice-fix-initialization-order.patch
new file mode 100644
index 0000000..41a73a0
--- /dev/null
+++ b/0519-spice-fix-initialization-order.patch
@@ -0,0 +1,67 @@
+From d106523eff9b2f7e0b201c04a825c1fbcef1e495 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel at redhat.com>
+Date: Fri, 2 Nov 2012 09:37:27 +0100
+Subject: [PATCH 519/564] spice: fix initialization order
+
+Register displaychangelistener last, after spice is fully initialized,
+otherwise we may hit NULL pointer dereferences when qemu starts calling
+our callbacks.
+
+Commit e250d949feb1334828f27f0d145c35f29c4b7639 triggers this bug.
+
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ hw/qxl.c           | 10 ++++++++--
+ ui/spice-display.c |  2 +-
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/hw/qxl.c b/hw/qxl.c
+index 3583d98..525763b 100644
+--- a/hw/qxl.c
++++ b/hw/qxl.c
+@@ -2061,6 +2061,7 @@ static int qxl_init_primary(PCIDevice *dev)
+     PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
+     VGACommonState *vga = &qxl->vga;
+     PortioList *qxl_vga_port_list = g_new(PortioList, 1);
++    int rc;
+ 
+     qxl->id = 0;
+     qxl_init_ramsize(qxl);
+@@ -2075,9 +2076,14 @@ static int qxl_init_primary(PCIDevice *dev)
+     qemu_spice_display_init_common(&qxl->ssd, vga->ds);
+ 
+     qxl0 = qxl;
+-    register_displaychangelistener(vga->ds, &display_listener);
+ 
+-    return qxl_init_common(qxl);
++    rc = qxl_init_common(qxl);
++    if (rc != 0) {
++        return rc;
++    }
++
++    register_displaychangelistener(vga->ds, &display_listener);
++    return rc;
+ }
+ 
+ static int qxl_init_secondary(PCIDevice *dev)
+diff --git a/ui/spice-display.c b/ui/spice-display.c
+index d062765..4c24c32 100644
+--- a/ui/spice-display.c
++++ b/ui/spice-display.c
+@@ -617,7 +617,6 @@ void qemu_spice_display_init(DisplayState *ds)
+ {
+     assert(sdpy.ds == NULL);
+     qemu_spice_display_init_common(&sdpy, ds);
+-    register_displaychangelistener(ds, &display_listener);
+ 
+     sdpy.qxl.base.sif = &dpy_interface.base;
+     qemu_spice_add_interface(&sdpy.qxl.base);
+@@ -626,4 +625,5 @@ void qemu_spice_display_init(DisplayState *ds)
+     qemu_add_vm_change_state_handler(qemu_spice_vm_change_state_handler, &sdpy);
+     qemu_spice_create_host_memslot(&sdpy);
+     qemu_spice_create_host_primary(&sdpy);
++    register_displaychangelistener(ds, &display_listener);
+ }
+-- 
+1.8.1
+
diff --git a/0520-spice-add-new-spice-server-callbacks-to-ui-spice-dis.patch b/0520-spice-add-new-spice-server-callbacks-to-ui-spice-dis.patch
new file mode 100644
index 0000000..dbc8120
--- /dev/null
+++ b/0520-spice-add-new-spice-server-callbacks-to-ui-spice-dis.patch
@@ -0,0 +1,69 @@
+From e4e6427ffc8a25e6eafdbf1a284319721891fb77 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel at redhat.com>
+Date: Wed, 21 Nov 2012 14:41:48 +0100
+Subject: [PATCH 520/564] spice: add new spice-server callbacks to
+ ui/spice-display.c
+
+Otherwise qemu crashes with non-qxl graphics cards.
+
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ ui/spice-display.c | 35 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+diff --git a/ui/spice-display.c b/ui/spice-display.c
+index 4c24c32..85c055e 100644
+--- a/ui/spice-display.c
++++ b/ui/spice-display.c
+@@ -569,6 +569,37 @@ static int interface_flush_resources(QXLInstance *sin)
+     return 0;
+ }
+ 
++static void interface_update_area_complete(QXLInstance *sin,
++        uint32_t surface_id,
++        QXLRect *dirty, uint32_t num_updated_rects)
++{
++    /* should never be called, used in qxl native mode only */
++    fprintf(stderr, "%s: abort()\n", __func__);
++    abort();
++}
++
++/* called from spice server thread context only */
++static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
++{
++    /* should never be called, used in qxl native mode only */
++    fprintf(stderr, "%s: abort()\n", __func__);
++    abort();
++}
++
++static void interface_set_client_capabilities(QXLInstance *sin,
++                                              uint8_t client_present,
++                                              uint8_t caps[58])
++{
++    dprint(3, "%s:\n", __func__);
++}
++
++static int interface_client_monitors_config(QXLInstance *sin,
++                                        VDAgentMonitorsConfig *monitors_config)
++{
++    dprint(3, "%s:\n", __func__);
++    return 0; /* == not supported by guest */
++}
++
+ static const QXLInterface dpy_interface = {
+     .base.type               = SPICE_INTERFACE_QXL,
+     .base.description        = "qemu simple display",
+@@ -588,6 +619,10 @@ static const QXLInterface dpy_interface = {
+     .req_cursor_notification = interface_req_cursor_notification,
+     .notify_update           = interface_notify_update,
+     .flush_resources         = interface_flush_resources,
++    .async_complete          = interface_async_complete,
++    .update_area_complete    = interface_update_area_complete,
++    .set_client_capabilities = interface_set_client_capabilities,
++    .client_monitors_config  = interface_client_monitors_config,
+ };
+ 
+ static SimpleSpiceDisplay sdpy;
+-- 
+1.8.1
+
diff --git a/0521-qxl-save-qemu_create_displaysurface_from-result.patch b/0521-qxl-save-qemu_create_displaysurface_from-result.patch
new file mode 100644
index 0000000..8697610
--- /dev/null
+++ b/0521-qxl-save-qemu_create_displaysurface_from-result.patch
@@ -0,0 +1,41 @@
+From 39a4efbef72744cb09151954091710400c31f18d Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel at redhat.com>
+Date: Mon, 10 Dec 2012 07:41:07 +0100
+Subject: [PATCH 521/564] qxl: save qemu_create_displaysurface_from result
+
+Spotted by Coverity.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=885644
+
+Cc: qemu-stable at nongnu.org
+Reported-by: Markus Armbruster <armbru at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ hw/qxl-render.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/hw/qxl-render.c b/hw/qxl-render.c
+index b66c168..e7d41ec 100644
+--- a/hw/qxl-render.c
++++ b/hw/qxl-render.c
+@@ -113,11 +113,12 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
+                qxl->guest_primary.bits_pp);
+         if (qxl->guest_primary.qxl_stride > 0) {
+             qemu_free_displaysurface(vga->ds);
+-            qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
+-                                            qxl->guest_primary.surface.height,
+-                                            qxl->guest_primary.bits_pp,
+-                                            qxl->guest_primary.abs_stride,
+-                                            qxl->guest_primary.data);
++            vga->ds->surface = qemu_create_displaysurface_from
++                (qxl->guest_primary.surface.width,
++                 qxl->guest_primary.surface.height,
++                 qxl->guest_primary.bits_pp,
++                 qxl->guest_primary.abs_stride,
++                 qxl->guest_primary.data);
+         } else {
+             qemu_resize_displaysurface(vga->ds,
+                     qxl->guest_primary.surface.width,
+-- 
+1.8.1
+
diff --git a/qemu.spec b/qemu.spec
index fd17d5c..2ff5965 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -109,7 +109,7 @@
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
 Version: 1.2.2
-Release: 3%{?dist}
+Release: 4%{?dist}
 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
 Epoch: 2
 License: GPLv2+ and LGPLv2+ and BSD
@@ -468,6 +468,13 @@ Patch0511: 0511-hw-qxl-support-client-monitor-configuration-via-devi.patch
 Patch0512: 0512-qxl-update_area_io-cleanup-invalid-parameters-handli.patch
 Patch0513: 0513-qxl-fix-range-check-for-rev3-io-commands.patch
 Patch0514: 0514-qxl-vnc-register-a-vm-state-handler-for-dummy-spice_.patch
+Patch0515: 0515-hw-qxl-exit-on-failure-to-register-qxl-interface.patch
+Patch0516: 0516-hw-qxl-fix-condition-for-exiting-guest_bug.patch
+Patch0517: 0517-hw-qxl-qxl_send_events-nop-if-stopped.patch
+Patch0518: 0518-qxl-call-dpy_gfx_resize-when-entering-vga-mode.patch
+Patch0519: 0519-spice-fix-initialization-order.patch
+Patch0520: 0520-spice-add-new-spice-server-callbacks-to-ui-spice-dis.patch
+Patch0521: 0521-qxl-save-qemu_create_displaysurface_from-result.patch
 
 # usb-redir live-migration and misc bits from upstream master
 Patch0601: 0601-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch
@@ -516,8 +523,6 @@ Patch0702: 0702-configure-Add-disable-kvm-options.patch
 Patch0703: 0703-arm_boot-Change-initrd-load-address-to-halfway-throu.patch
 # Don't use reserved word 'function' in systemtap files (bz 870972)
 Patch0704: 0704-dtrace-backend-add-function-to-reserved-words.patch
-# Drop assertion that was triggering when pausing guests w/ qxl (bz 870972)
-Patch0705: 0705-wip-hw-qxl-inject-interrupts-in-any-state.patch
 # libcacard build fixes
 Patch0706: 0706-libcacard-fix-missing-symbols-in-libcacard.so.patch
 Patch0707: 0707-configure-move-vscclient-binary-under-libcacard.patch
@@ -1280,6 +1285,13 @@ CAC emulation development files.
 %patch0512 -p1
 %patch0513 -p1
 %patch0514 -p1
+%patch0515 -p1
+%patch0516 -p1
+%patch0517 -p1
+%patch0518 -p1
+%patch0519 -p1
+%patch0520 -p1
+%patch0521 -p1
 
 # usb-redir live-migration and misc bits from upstream master
 %patch0601 -p1
@@ -1323,7 +1335,6 @@ CAC emulation development files.
 %patch0702 -p1
 %patch0703 -p1
 %patch0704 -p1
-%patch0705 -p1
 %patch0706 -p1
 %patch0707 -p1
 %patch0708 -p1
@@ -1937,6 +1948,13 @@ getent passwd qemu >/dev/null || \
 %{_libdir}/pkgconfig/libcacard.pc
 
 %changelog
+* Mon Jan 21 2013 Hans de Goede <hdegoede at redhat.com> - 2:1.2.2-4
+- Add "qxl: call dpy_gfx_resize when entering vga mode" patch, fixing
+  an often reported use after free crash (rhbz#873845)
+- Replace "wip: hw/qxl: inject interrupts in any state" patch with the
+  official upstream fix
+- Add 5 other spice/qxl crash/bug fixes cherry-picked from upstream
+
 * Fri Jan 18 2013 Hans de Goede <hdegoede at redhat.com> - 2:1.2.2-3
 - Fix a crash when using -vga qxl without -spice (bz #892075)
 


More information about the scm-commits mailing list