ui/console: ensure graphic updates don't race with TCG vCPUs
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 <mark.cave-ayland@ilande.co.uk> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20170315144825.3108-1-alex.bennee@linaro.org Cc: BALATON Zoltan <balaton@eik.bme.hu> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> [ kraxel: updated comment clarifying the display adapters are buggy and this is a temporary workaround ] Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
272d7dee59
commit
8bb93c6f99
21
ui/console.c
21
ui/console.c
@ -1575,13 +1575,32 @@ bool dpy_gfx_check_format(QemuConsole *con,
|
|||||||
return true;
|
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)
|
static void dpy_refresh(DisplayState *s)
|
||||||
{
|
{
|
||||||
DisplayChangeListener *dcl;
|
DisplayChangeListener *dcl;
|
||||||
|
|
||||||
QLIST_FOREACH(dcl, &s->listeners, next) {
|
QLIST_FOREACH(dcl, &s->listeners, next) {
|
||||||
if (dcl->ops->dpy_refresh) {
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user