|
|
9ae3a8 |
From 8d537fb77d744265a23b0eda33da269ed672e549 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Tarun Gupta <tgupta@redhat.com>
|
|
|
9ae3a8 |
Date: Wed, 20 Jun 2018 18:54:19 +0200
|
|
|
9ae3a8 |
Subject: [PATCH 11/17] console: minimal hotplug suport
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Tarun Gupta <tgupta@redhat.com>
|
|
|
9ae3a8 |
Message-id: <1529520865-18127-6-git-send-email-tgupta@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 80914
|
|
|
9ae3a8 |
O-Subject: [RHEL7.6 qemu-kvm PATCH v3 05/11] console: minimal hotplug suport
|
|
|
9ae3a8 |
Bugzilla: 1555246
|
|
|
9ae3a8 |
RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
This patch allows to unbind devices from QemuConsoles, using the new
|
|
|
9ae3a8 |
graphic_console_close() function. The QemuConsole will show a static
|
|
|
9ae3a8 |
display then, saying the device was unplugged. When re-plugging a
|
|
|
9ae3a8 |
display later on the QemuConsole will be reused.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Eventually we will allocate and release QemuConsoles dynamically at some
|
|
|
9ae3a8 |
point in the future, that'll need more infrastructure though to notify
|
|
|
9ae3a8 |
user interfaces (gtk, sdl, spice, ...) about QemuConsoles coming and
|
|
|
9ae3a8 |
going.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
(cherry picked from 9588d67e72f853349dbb318503368ad01b12feb6)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Conflicts:
|
|
|
9ae3a8 |
qemu-kvm does not have ui/trace-events, so adding traces in
|
|
|
9ae3a8 |
trace_events.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
qemu-kvm does not have graphic_console_set_hwops() function,
|
|
|
9ae3a8 |
so manually setting the ops.
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
include/ui/console.h | 3 ++-
|
|
|
9ae3a8 |
trace-events | 2 ++
|
|
|
9ae3a8 |
ui/console.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++----
|
|
|
9ae3a8 |
3 files changed, 74 insertions(+), 6 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/include/ui/console.h b/include/ui/console.h
|
|
|
9ae3a8 |
index 7f5fa66..e23f809 100644
|
|
|
9ae3a8 |
--- a/include/ui/console.h
|
|
|
9ae3a8 |
+++ b/include/ui/console.h
|
|
|
9ae3a8 |
@@ -275,13 +275,14 @@ typedef struct GraphicHwOps {
|
|
|
9ae3a8 |
QemuConsole *graphic_console_init(DeviceState *dev,
|
|
|
9ae3a8 |
const GraphicHwOps *ops,
|
|
|
9ae3a8 |
void *opaque);
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
+void graphic_console_close(QemuConsole *con);
|
|
|
9ae3a8 |
void graphic_hw_update(QemuConsole *con);
|
|
|
9ae3a8 |
void graphic_hw_invalidate(QemuConsole *con);
|
|
|
9ae3a8 |
void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
QemuConsole *qemu_console_lookup_by_index(unsigned int index);
|
|
|
9ae3a8 |
QemuConsole *qemu_console_lookup_by_device(DeviceState *dev);
|
|
|
9ae3a8 |
+QemuConsole *qemu_console_lookup_unused(void);
|
|
|
9ae3a8 |
bool qemu_console_is_visible(QemuConsole *con);
|
|
|
9ae3a8 |
bool qemu_console_is_graphic(QemuConsole *con);
|
|
|
9ae3a8 |
bool qemu_console_is_fixedsize(QemuConsole *con);
|
|
|
9ae3a8 |
diff --git a/trace-events b/trace-events
|
|
|
9ae3a8 |
index 8c3ce0c..7b7aad1 100644
|
|
|
9ae3a8 |
--- a/trace-events
|
|
|
9ae3a8 |
+++ b/trace-events
|
|
|
9ae3a8 |
@@ -994,6 +994,8 @@ dma_map_wait(void *dbs) "dbs=%p"
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
# ui/console.c
|
|
|
9ae3a8 |
console_gfx_new(void) ""
|
|
|
9ae3a8 |
+console_gfx_reuse(int index) "%d"
|
|
|
9ae3a8 |
+console_gfx_close(int index) "%d"
|
|
|
9ae3a8 |
console_txt_new(int w, int h) "%dx%d"
|
|
|
9ae3a8 |
console_select(int nr) "%d"
|
|
|
9ae3a8 |
console_refresh(int interval) "interval %d ms"
|
|
|
9ae3a8 |
diff --git a/ui/console.c b/ui/console.c
|
|
|
9ae3a8 |
index c14a0bc..cc319a9 100644
|
|
|
9ae3a8 |
--- a/ui/console.c
|
|
|
9ae3a8 |
+++ b/ui/console.c
|
|
|
9ae3a8 |
@@ -1246,11 +1246,16 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type)
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
s->ds = ds;
|
|
|
9ae3a8 |
s->console_type = console_type;
|
|
|
9ae3a8 |
- if (console_type != GRAPHIC_CONSOLE) {
|
|
|
9ae3a8 |
+ if (console_type != GRAPHIC_CONSOLE || qdev_hotplug) {
|
|
|
9ae3a8 |
s->index = nb_consoles;
|
|
|
9ae3a8 |
consoles[nb_consoles++] = s;
|
|
|
9ae3a8 |
} else {
|
|
|
9ae3a8 |
- /* HACK: Put graphical consoles before text consoles. */
|
|
|
9ae3a8 |
+ /*
|
|
|
9ae3a8 |
+ * HACK: Put graphical consoles before text consoles.
|
|
|
9ae3a8 |
+ *
|
|
|
9ae3a8 |
+ * Only do that for coldplugged devices. After initial device
|
|
|
9ae3a8 |
+ * initialization we will not renumber the consoles any more.
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
for (i = nb_consoles; i > 0; i--) {
|
|
|
9ae3a8 |
if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE)
|
|
|
9ae3a8 |
break;
|
|
|
9ae3a8 |
@@ -1610,21 +1615,59 @@ QemuConsole *graphic_console_init(DeviceState *dev,
|
|
|
9ae3a8 |
int height = 480;
|
|
|
9ae3a8 |
QemuConsole *s;
|
|
|
9ae3a8 |
DisplayState *ds;
|
|
|
9ae3a8 |
+ DisplaySurface *surface;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
ds = get_alloc_displaystate();
|
|
|
9ae3a8 |
- trace_console_gfx_new();
|
|
|
9ae3a8 |
- s = new_console(ds, GRAPHIC_CONSOLE);
|
|
|
9ae3a8 |
+ s = qemu_console_lookup_unused();
|
|
|
9ae3a8 |
+ if (s) {
|
|
|
9ae3a8 |
+ trace_console_gfx_reuse(s->index);
|
|
|
9ae3a8 |
+ if (s->surface) {
|
|
|
9ae3a8 |
+ width = surface_width(s->surface);
|
|
|
9ae3a8 |
+ height = surface_height(s->surface);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ } else {
|
|
|
9ae3a8 |
+ trace_console_gfx_new();
|
|
|
9ae3a8 |
+ s = new_console(ds, GRAPHIC_CONSOLE);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
s->hw_ops = hw_ops;
|
|
|
9ae3a8 |
s->hw = opaque;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
if (dev) {
|
|
|
9ae3a8 |
object_property_set_link(OBJECT(s), OBJECT(dev),
|
|
|
9ae3a8 |
"device", &local_err);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- s->surface = qemu_create_message_surface(width, height, noinit);
|
|
|
9ae3a8 |
+ surface = qemu_create_message_surface(width, height, noinit);
|
|
|
9ae3a8 |
+ dpy_gfx_replace_surface(s, surface);
|
|
|
9ae3a8 |
return s;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+static const GraphicHwOps unused_ops = {
|
|
|
9ae3a8 |
+ /* no callbacks */
|
|
|
9ae3a8 |
+};
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+void graphic_console_close(QemuConsole *con)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ DisplaySurface *surface;
|
|
|
9ae3a8 |
+ int width = 640;
|
|
|
9ae3a8 |
+ int height = 480;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (con->surface) {
|
|
|
9ae3a8 |
+ width = surface_width(con->surface);
|
|
|
9ae3a8 |
+ height = surface_height(con->surface);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ trace_console_gfx_close(con->index);
|
|
|
9ae3a8 |
+ object_property_set_link(OBJECT(con), NULL, "device", &error_abort);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ con->hw_ops = &unused_ops;
|
|
|
9ae3a8 |
+ con->hw = NULL;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ surface = qemu_create_displaysurface(width, height);
|
|
|
9ae3a8 |
+ dpy_gfx_replace_surface(con, surface);
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
QemuConsole *qemu_console_lookup_by_index(unsigned int index)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
if (index >= MAX_CONSOLES) {
|
|
|
9ae3a8 |
@@ -1652,6 +1695,28 @@ QemuConsole *qemu_console_lookup_by_device(DeviceState *dev)
|
|
|
9ae3a8 |
return NULL;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+QemuConsole *qemu_console_lookup_unused(void)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ Object *obj;
|
|
|
9ae3a8 |
+ int i;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ for (i = 0; i < nb_consoles; i++) {
|
|
|
9ae3a8 |
+ if (!consoles[i]) {
|
|
|
9ae3a8 |
+ continue;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ if (consoles[i]->hw_ops != &unused_ops) {
|
|
|
9ae3a8 |
+ continue;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ obj = object_property_get_link(OBJECT(consoles[i]),
|
|
|
9ae3a8 |
+ "device", &error_abort);
|
|
|
9ae3a8 |
+ if (obj != NULL) {
|
|
|
9ae3a8 |
+ continue;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ return consoles[i];
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ return NULL;
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
bool qemu_console_is_visible(QemuConsole *con)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
return (con == active_console) || (con->dcls > 0);
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.8.3.1
|
|
|
9ae3a8 |
|