aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-04-27 11:39:31 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-04-27 11:39:31 +0100
commit10f4718b51d77ff06878afd326c3d3dd140770ee (patch)
tree2ae5bb09217ce4801b1e413e02fc8a842d2db0b6
parentdcbd26f881557b83b99869b138b337feaf2d705d (diff)
parent8983e3e35033ecb9234725c2bba65f020824969b (diff)
downloadqemu-10f4718b51d77ff06878afd326c3d3dd140770ee.zip
qemu-10f4718b51d77ff06878afd326c3d3dd140770ee.tar.gz
qemu-10f4718b51d77ff06878afd326c3d3dd140770ee.tar.bz2
Merge remote-tracking branch 'remotes/kraxel/tags/ui-20180427-pull-request' into staging
vnc: fix use-after-free. sdl2: gles support. vfio-display: add reset support. # gpg: Signature made Fri 27 Apr 2018 10:54:17 BST # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/ui-20180427-pull-request: ui: introduce vfio_display_reset console: introduce dpy_gfx_update_full sdl: Allow OpenGL ES context creation sdl: Move DisplayOptions global to sdl2_console qapi: Parameter gl of DisplayType now accept an enum vnc: fix use-after-free Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/vfio/display.c11
-rw-r--r--hw/vfio/pci.c4
-rw-r--r--hw/vfio/pci.h1
-rw-r--r--include/ui/console.h1
-rw-r--r--include/ui/sdl2.h1
-rw-r--r--qapi/ui.json20
-rw-r--r--qemu-options.hx2
-rw-r--r--ui/console.c10
-rw-r--r--ui/sdl2-gl.c19
-rw-r--r--ui/sdl2.c10
-rw-r--r--ui/vnc.c5
-rw-r--r--vl.c14
12 files changed, 82 insertions, 16 deletions
diff --git a/hw/vfio/display.c b/hw/vfio/display.c
index 7d727ce..59c0e5d 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -198,6 +198,17 @@ static void vfio_display_dmabuf_exit(VFIODisplay *dpy)
}
/* ---------------------------------------------------------------------- */
+void vfio_display_reset(VFIOPCIDevice *vdev)
+{
+ if (!vdev || !vdev->dpy || !vdev->dpy->con ||
+ !vdev->dpy->dmabuf.primary) {
+ return;
+ }
+
+ dpy_gl_scanout_disable(vdev->dpy->con);
+ vfio_display_dmabuf_exit(vdev->dpy);
+ dpy_gfx_update_full(vdev->dpy->con);
+}
static void vfio_display_region_update(void *opaque)
{
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index b9bc6cd..4947fe3 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3103,6 +3103,10 @@ static void vfio_pci_reset(DeviceState *dev)
vfio_pci_pre_reset(vdev);
+ if (vdev->display != ON_OFF_AUTO_OFF) {
+ vfio_display_reset(vdev);
+ }
+
if (vdev->resetfn && !vdev->resetfn(vdev)) {
goto post_reset;
}
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 629c875..59ab775 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -176,6 +176,7 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
struct vfio_region_info *info,
Error **errp);
+void vfio_display_reset(VFIOPCIDevice *vdev);
int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
void vfio_display_finalize(VFIOPCIDevice *vdev);
diff --git a/include/ui/console.h b/include/ui/console.h
index 37a8d68..981b519 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -291,6 +291,7 @@ bool dpy_ui_info_supported(QemuConsole *con);
int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info);
void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h);
+void dpy_gfx_update_full(QemuConsole *con);
void dpy_gfx_replace_surface(QemuConsole *con,
DisplaySurface *surface);
void dpy_text_cursor(QemuConsole *con, int x, int y);
diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h
index 51084e6..f43eecd 100644
--- a/include/ui/sdl2.h
+++ b/include/ui/sdl2.h
@@ -14,6 +14,7 @@
struct sdl2_console {
DisplayChangeListener dcl;
DisplaySurface *surface;
+ DisplayOptions *opts;
SDL_Texture *texture;
SDL_Window *real_window;
SDL_Renderer *real_renderer;
diff --git a/qapi/ui.json b/qapi/ui.json
index 5d01ad4..3ad7835 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -1019,6 +1019,24 @@
{ 'struct' : 'DisplayGTK',
'data' : { '*grab-on-hover' : 'bool' } }
+ ##
+ # @DisplayGLMode:
+ #
+ # Display OpenGL mode.
+ #
+ # @off: Disable OpenGL (default).
+ # @on: Use OpenGL, pick context type automatically.
+ # Would better be named 'auto' but is called 'on' for backward
+ # compatibility with bool type.
+ # @core: Use OpenGL with Core (desktop) Context.
+ # @es: Use OpenGL with ES (embedded systems) Context.
+ #
+ # Since: 2.13
+ #
+ ##
+ { 'enum' : 'DisplayGLMode',
+ 'data' : [ 'off', 'on', 'core', 'es' ] }
+
##
# @DisplayType:
#
@@ -1048,7 +1066,7 @@
'base' : { 'type' : 'DisplayType',
'*full-screen' : 'bool',
'*window-close' : 'bool',
- '*gl' : 'bool' },
+ '*gl' : 'DisplayGLMode' },
'discriminator' : 'type',
'data' : { 'default' : 'DisplayNoOpts',
'none' : 'DisplayNoOpts',
diff --git a/qemu-options.hx b/qemu-options.hx
index 5fbf966..c611766 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1240,7 +1240,7 @@ ETEXI
DEF("display", HAS_ARG, QEMU_OPTION_display,
"-display sdl[,frame=on|off][,alt_grab=on|off][,ctrl_grab=on|off]\n"
- " [,window_close=on|off][,gl=on|off]\n"
+ " [,window_close=on|off][,gl=on|core|es|off]\n"
"-display gtk[,grab_on_hover=on|off][,gl=on|off]|\n"
"-display vnc=<display>[,<optargs>]\n"
"-display curses\n"
diff --git a/ui/console.c b/ui/console.c
index 3fb2f4e..b02510c 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1574,6 +1574,16 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
}
}
+void dpy_gfx_update_full(QemuConsole *con)
+{
+ if (!con->surface) {
+ return;
+ }
+ dpy_gfx_update(con, 0, 0,
+ surface_width(con->surface),
+ surface_height(con->surface));
+}
+
void dpy_gfx_replace_surface(QemuConsole *con,
DisplaySurface *surface)
{
diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
index c3683e6..83b7185 100644
--- a/ui/sdl2-gl.c
+++ b/ui/sdl2-gl.c
@@ -140,12 +140,27 @@ QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl,
SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
- SDL_GL_CONTEXT_PROFILE_CORE);
+ if (scon->opts->gl == DISPLAYGL_MODE_ON ||
+ scon->opts->gl == DISPLAYGL_MODE_CORE) {
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
+ SDL_GL_CONTEXT_PROFILE_CORE);
+ } else if (scon->opts->gl == DISPLAYGL_MODE_ES) {
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
+ SDL_GL_CONTEXT_PROFILE_ES);
+ }
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, params->major_ver);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, params->minor_ver);
ctx = SDL_GL_CreateContext(scon->real_window);
+
+ /* If SDL fail to create a GL context and we use the "on" flag,
+ * then try to fallback to GLES.
+ */
+ if (!ctx && scon->opts->gl == DISPLAYGL_MODE_ON) {
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
+ SDL_GL_CONTEXT_PROFILE_ES);
+ ctx = SDL_GL_CreateContext(scon->real_window);
+ }
return (QEMUGLContext)ctx;
}
diff --git a/ui/sdl2.c b/ui/sdl2.c
index 83b917f..da03724 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -32,7 +32,6 @@
static int sdl2_num_outputs;
static struct sdl2_console *sdl2_console;
-static DisplayOptions *opts;
static SDL_Surface *guest_sprite_surface;
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
@@ -566,7 +565,7 @@ static void handle_windowevent(SDL_Event *ev)
break;
case SDL_WINDOWEVENT_CLOSE:
if (qemu_console_is_graphic(scon->dcl.con)) {
- if (opts->has_window_close && !opts->window_close) {
+ if (scon->opts->has_window_close && !scon->opts->window_close) {
allow_close = false;
}
if (allow_close) {
@@ -613,7 +612,7 @@ void sdl2_poll_events(struct sdl2_console *scon)
handle_textinput(ev);
break;
case SDL_QUIT:
- if (opts->has_window_close && !opts->window_close) {
+ if (scon->opts->has_window_close && !scon->opts->window_close) {
allow_close = false;
}
if (allow_close) {
@@ -770,7 +769,6 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
SDL_SysWMinfo info;
assert(o->type == DISPLAY_TYPE_SDL);
- opts = o;
#ifdef __linux__
/* on Linux, SDL may use fbcon|directfb|svgalib when run without
@@ -806,6 +804,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
return;
}
sdl2_console = g_new0(struct sdl2_console, sdl2_num_outputs);
+ sdl2_console->opts = o;
for (i = 0; i < sdl2_num_outputs; i++) {
QemuConsole *con = qemu_console_lookup_by_index(i);
assert(con != NULL);
@@ -846,7 +845,8 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
g_free(filename);
}
- if (opts->has_full_screen && opts->full_screen) {
+ if (sdl2_console->opts->has_full_screen &&
+ sdl2_console->opts->full_screen) {
gui_fullscreen = 1;
sdl_grab_start(0);
}
diff --git a/ui/vnc.c b/ui/vnc.c
index e164eb7..5526e54 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1539,13 +1539,14 @@ gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
VncState *vs = opaque;
if (condition & G_IO_IN) {
if (vnc_client_read(vs) < 0) {
- goto end;
+ /* vs is free()ed here */
+ return TRUE;
}
}
if (condition & G_IO_OUT) {
vnc_client_write(vs);
}
-end:
+
if (vs->disconnecting) {
if (vs->ioc_tag != 0) {
g_source_remove(vs->ioc_tag);
diff --git a/vl.c b/vl.c
index d37e857..7487535 100644
--- a/vl.c
+++ b/vl.c
@@ -2143,9 +2143,13 @@ static void parse_display(const char *p)
opts = nextopt;
dpy.has_gl = true;
if (strstart(opts, "on", &nextopt)) {
- dpy.gl = true;
+ dpy.gl = DISPLAYGL_MODE_ON;
+ } else if (strstart(opts, "core", &nextopt)) {
+ dpy.gl = DISPLAYGL_MODE_CORE;
+ } else if (strstart(opts, "es", &nextopt)) {
+ dpy.gl = DISPLAYGL_MODE_ES;
} else if (strstart(opts, "off", &nextopt)) {
- dpy.gl = false;
+ dpy.gl = DISPLAYGL_MODE_OFF;
} else {
goto invalid_sdl_args;
}
@@ -2186,9 +2190,9 @@ static void parse_display(const char *p)
opts = nextopt;
dpy.has_gl = true;
if (strstart(opts, "on", &nextopt)) {
- dpy.gl = true;
+ dpy.gl = DISPLAYGL_MODE_ON;
} else if (strstart(opts, "off", &nextopt)) {
- dpy.gl = false;
+ dpy.gl = DISPLAYGL_MODE_OFF;
} else {
goto invalid_gtk_args;
}
@@ -4356,7 +4360,7 @@ int main(int argc, char **argv, char **envp)
qemu_display_early_init(&dpy);
qemu_console_early_init();
- if (dpy.has_gl && dpy.gl && display_opengl == 0) {
+ if (dpy.has_gl && dpy.gl != DISPLAYGL_MODE_OFF && display_opengl == 0) {
#if defined(CONFIG_OPENGL)
error_report("OpenGL is not supported by the display");
#else