From 8bb93c6f99a42c2e0943bc904b283cd622d302c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Wed, 15 Mar 2017 14:48:25 +0000 Subject: [PATCH 1/3] ui/console: ensure graphic updates don't race with TCG vCPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 8d04fb55.. tcg: drop global lock during TCG code execution ..broke the assumption that updates to the GUI couldn't happen at the same time as TCG vCPUs where running. As a result the TCG vCPU could still be updating a directly mapped frame-buffer while the display side was updating. This would cause artefacts to appear when the update code assumed that memory block hadn't changed. The simplest solution is to ensure the two things can't happen at the same time like the old BQL locking scheme. Here we use the solution introduced for MTTCG and schedule the update as async_safe_work when we know no vCPUs can be running. Reported-by: Mark Cave-Ayland Signed-off-by: Alex Bennée Message-id: 20170315144825.3108-1-alex.bennee@linaro.org Cc: BALATON Zoltan Cc: Gerd Hoffmann Cc: Paolo Bonzini Signed-off-by: Alex Bennée [ kraxel: updated comment clarifying the display adapters are buggy and this is a temporary workaround ] Signed-off-by: Gerd Hoffmann --- ui/console.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/ui/console.c b/ui/console.c index 4c70d8bfda..937c950840 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1575,13 +1575,32 @@ bool dpy_gfx_check_format(QemuConsole *con, return true; } +/* + * Safe DPY refresh for TCG guests. This runs when the TCG vCPUs are + * quiescent so we can avoid races between dirty page tracking for + * direct frame-buffer access by the guest. + * + * This is a temporary stopgap until we've fixed the dirty tracking + * races in display adapters. + */ +static void do_safe_dpy_refresh(CPUState *cpu, run_on_cpu_data opaque) +{ + DisplayChangeListener *dcl = opaque.host_ptr; + dcl->ops->dpy_refresh(dcl); +} + static void dpy_refresh(DisplayState *s) { DisplayChangeListener *dcl; QLIST_FOREACH(dcl, &s->listeners, next) { if (dcl->ops->dpy_refresh) { - dcl->ops->dpy_refresh(dcl); + if (tcg_enabled()) { + async_safe_run_on_cpu(first_cpu, do_safe_dpy_refresh, + RUN_ON_CPU_HOST_PTR(dcl)); + } else { + dcl->ops->dpy_refresh(dcl); + } } } } From f019722cbbb45aea153294fc8921fcc96a4d3fa2 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 17 Mar 2017 08:21:36 +0100 Subject: [PATCH 2/3] cirrus: fix off-by-one in cirrus_bitblt_rop_bkwd_transp_*_16 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The switch from pointers to addresses (commit 026aeffcb4752054830ba203020ed6eb05bcaba8 and ffaf857778286ca54e3804432a2369a279e73aa7) added a off-by-one bug to 16bit backward blits. Fix. Reported-by: 李强 Signed-off-by: Gerd Hoffmann Reviewed-by: Li Qiang Message-id: 1489735296-19047-1-git-send-email-kraxel@redhat.com --- hw/display/cirrus_vga_rop.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/display/cirrus_vga_rop.h b/hw/display/cirrus_vga_rop.h index c61a677353..0841b9efa9 100644 --- a/hw/display/cirrus_vga_rop.h +++ b/hw/display/cirrus_vga_rop.h @@ -219,7 +219,7 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s, srcpitch += bltwidth; for (y = 0; y < bltheight; y++) { for (x = 0; x < bltwidth; x+=2) { - ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp); + ROP_OP_TR_16(s, dstaddr - 1, cirrus_src16(s, srcaddr - 1), transp); dstaddr -= 2; srcaddr -= 2; } From 7bc4f0846f5e15dad5a54490290241243b5a4416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 17 Mar 2017 13:28:02 +0400 Subject: [PATCH 3/3] vnc: fix a qio-channel leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spotted by ASAN. Signed-off-by: Marc-André Lureau Reviewed-by: Daniel P. Berrange Reviewed-by: Philippe Mathieu-Daudé Message-id: 20170317092802.17973-1-marcandre.lureau@redhat.com Signed-off-by: Gerd Hoffmann --- ui/vnc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/vnc.c b/ui/vnc.c index 8bfb1e0685..6e93b883b5 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3677,6 +3677,7 @@ static int vnc_display_listen_addr(VncDisplay *vd, qio_channel_set_name(QIO_CHANNEL(sioc), name); if (qio_channel_socket_listen_sync( sioc, rawaddrs[i], listenerr == NULL ? &listenerr : NULL) < 0) { + object_unref(OBJECT(sioc)); continue; } listening = true;