summaryrefslogtreecommitdiffstats
path: root/ui/console.c
diff options
context:
space:
mode:
authorPeter Maydell2018-03-16 10:51:47 +0100
committerPeter Maydell2018-03-16 10:51:47 +0100
commita57946ff2acb9c0d95c9f127914540586b0b8c21 (patch)
treebc790f23ea3802e0a5241c4b6a0d4f6b441cec60 /ui/console.c
parentMerge remote-tracking branch 'remotes/berrange/tags/socket-next-pull-request'... (diff)
parentppc/spapr, vfio: Turn off MSIX emulation for VFIO devices (diff)
downloadqemu-a57946ff2acb9c0d95c9f127914540586b0b8c21.tar.gz
qemu-a57946ff2acb9c0d95c9f127914540586b0b8c21.tar.xz
qemu-a57946ff2acb9c0d95c9f127914540586b0b8c21.zip
Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20180313.0' into staging
VFIO updates 2018-03-13 - Display support for vGPUs (Gerd Hoffmann) - Enable new kernel support for mmaps overlapping MSI-X vector table, disable MSI-X emulation on POWER (Alexey Kardashevskiy) # gpg: Signature made Tue 13 Mar 2018 19:48:49 GMT # gpg: using RSA key 239B9B6E3BB08B22 # gpg: Good signature from "Alex Williamson <alex.williamson@redhat.com>" # gpg: aka "Alex Williamson <alex@shazbot.org>" # gpg: aka "Alex Williamson <alwillia@redhat.com>" # gpg: aka "Alex Williamson <alex.l.williamson@gmail.com>" # Primary key fingerprint: 42F6 C04E 540B D1A9 9E7B 8A90 239B 9B6E 3BB0 8B22 * remotes/awilliam/tags/vfio-update-20180313.0: ppc/spapr, vfio: Turn off MSIX emulation for VFIO devices vfio-pci: Allow mmap of MSIX BAR vfio/pci: Relax DMA map errors for MMIO regions vfio/display: adding dmabuf support vfio/display: adding region support vfio/display: core & wireup vfio/common: cleanup in vfio_region_finalize secondary-vga: properly close QemuConsole on unplug console: minimal hotplug suport ui/pixman: add qemu_drm_format_to_pixman() standard-headers: add drm/drm_fourcc.h Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'ui/console.c')
-rw-r--r--ui/console.c79
1 files changed, 73 insertions, 6 deletions
diff --git a/ui/console.c b/ui/console.c
index a8868fc04f..530a491987 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1282,11 +1282,16 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
s->console_type = console_type;
consoles = g_realloc(consoles, sizeof(*consoles) * (nb_consoles+1));
- if (console_type != GRAPHIC_CONSOLE) {
+ if (console_type != GRAPHIC_CONSOLE || qdev_hotplug) {
s->index = nb_consoles;
consoles[nb_consoles++] = s;
} else {
- /* HACK: Put graphical consoles before text consoles. */
+ /*
+ * HACK: Put graphical consoles before text consoles.
+ *
+ * Only do that for coldplugged devices. After initial device
+ * initialization we will not renumber the consoles any more.
+ */
for (i = nb_consoles; i > 0; i--) {
if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE)
break;
@@ -1874,21 +1879,61 @@ QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head,
int height = 480;
QemuConsole *s;
DisplayState *ds;
+ DisplaySurface *surface;
ds = get_alloc_displaystate();
- trace_console_gfx_new();
- s = new_console(ds, GRAPHIC_CONSOLE, head);
- s->ui_timer = timer_new_ms(QEMU_CLOCK_REALTIME, dpy_set_ui_info_timer, s);
+ s = qemu_console_lookup_unused();
+ if (s) {
+ trace_console_gfx_reuse(s->index);
+ if (s->surface) {
+ width = surface_width(s->surface);
+ height = surface_height(s->surface);
+ }
+ } else {
+ trace_console_gfx_new();
+ s = new_console(ds, GRAPHIC_CONSOLE, head);
+ s->ui_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
+ dpy_set_ui_info_timer, s);
+ }
graphic_console_set_hwops(s, hw_ops, opaque);
if (dev) {
object_property_set_link(OBJECT(s), OBJECT(dev), "device",
&error_abort);
}
- s->surface = qemu_create_message_surface(width, height, noinit);
+ surface = qemu_create_message_surface(width, height, noinit);
+ dpy_gfx_replace_surface(s, surface);
return s;
}
+static const GraphicHwOps unused_ops = {
+ /* no callbacks */
+};
+
+void graphic_console_close(QemuConsole *con)
+{
+ static const char unplugged[] =
+ "Guest display has been unplugged";
+ DisplaySurface *surface;
+ int width = 640;
+ int height = 480;
+
+ if (con->surface) {
+ width = surface_width(con->surface);
+ height = surface_height(con->surface);
+ }
+
+ trace_console_gfx_close(con->index);
+ object_property_set_link(OBJECT(con), NULL, "device", &error_abort);
+ graphic_console_set_hwops(con, &unused_ops, NULL);
+
+ if (con->gl) {
+ dpy_gl_scanout_disable(con);
+ }
+ surface = qemu_create_message_surface(width, height, unplugged);
+ dpy_gfx_replace_surface(con, surface);
+}
+
QemuConsole *qemu_console_lookup_by_index(unsigned int index)
{
if (index >= nb_consoles) {
@@ -1945,6 +1990,28 @@ QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
return con;
}
+QemuConsole *qemu_console_lookup_unused(void)
+{
+ Object *obj;
+ int i;
+
+ for (i = 0; i < nb_consoles; i++) {
+ if (!consoles[i]) {
+ continue;
+ }
+ if (consoles[i]->hw_ops != &unused_ops) {
+ continue;
+ }
+ obj = object_property_get_link(OBJECT(consoles[i]),
+ "device", &error_abort);
+ if (obj != NULL) {
+ continue;
+ }
+ return consoles[i];
+ }
+ return NULL;
+}
+
bool qemu_console_is_visible(QemuConsole *con)
{
return (con == active_console) || (con->dcls > 0);