From cc85c433700aa998cb7366888f2d4fc49afa47e7 Mon Sep 17 00:00:00 2001 From: Alon Levy Date: Nov 20 2012 16:05:19 +0000 Subject: Virtio-serial fixes 1. Post migration inject interrupt to a running vm to workaround a bug in kvm irqchip emulation (pending upstream acceptance) 2. Redo fedora only fix for #725965 (replay guest open after migration) based on the above fix. --- diff --git a/0411-virtio-serial-bus-replay-guest_open-on-migration.patch b/0411-virtio-serial-bus-replay-guest_open-on-migration.patch deleted file mode 100644 index 7cdc9bb..0000000 --- a/0411-virtio-serial-bus-replay-guest_open-on-migration.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a9bc20afc1f0604ee81c23b7c67d627e51d2e8d4 Mon Sep 17 00:00:00 2001 -From: Alon Levy -Date: Thu, 28 Jul 2011 15:08:48 +0300 -Subject: [PATCH] virtio-serial-bus: replay guest_open on migration - -When migrating a host with with a spice agent running the mouse becomes -non operational after the migration. This is rhbz #725965. - -The problem is that after migration spice doesn't know the guest agent is open. -Spice is just a char dev here. And a chardev cannot query it's device, the -device has to let the chardev know when it is open. Right now after migration -the chardev which is recreated is in it's default state, which assumes the -guest is disconnected. - -Char devices carry no information across migration, but the virtio-serial does -already carry the guest_connected state. This patch passes that bit to the -chardev. - -Signed-off-by: Alon Levy -Signed-off-by: Cole Robinson ---- - hw/virtio-serial-bus.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c -index 82073f5..18c2ed3 100644 ---- a/hw/virtio-serial-bus.c -+++ b/hw/virtio-serial-bus.c -@@ -682,6 +682,7 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) - for (i = 0; i < nr_active_ports; i++) { - uint32_t id; - bool host_connected; -+ VirtIOSerialPortClass *vsc; - - id = qemu_get_be32(f); - port = find_port_by_id(s, id); -@@ -690,6 +691,11 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) - } - - port->guest_connected = qemu_get_byte(f); -+ vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); -+ if (port->guest_connected && vsc->guest_open) { -+ /* replay guest open */ -+ vsc->guest_open(port); -+ } - host_connected = qemu_get_byte(f); - if (host_connected != port->host_connected) { - /* --- -1.7.12.1 - diff --git a/0413-hw-virtio-serial-bus-post_load-send_event-when-vm-is.patch b/0413-hw-virtio-serial-bus-post_load-send_event-when-vm-is.patch new file mode 100644 index 0000000..2ec9363 --- /dev/null +++ b/0413-hw-virtio-serial-bus-post_load-send_event-when-vm-is.patch @@ -0,0 +1,130 @@ +From 9903053345528aa8eebb16365b2ece77c58c0cf6 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Wed, 14 Nov 2012 15:06:35 +0200 +Subject: [PATCH 1/2] hw/virtio-serial-bus: post_load send_event when vm is + running + +Add a new timer based on vm_clock for 1 ns in the future from post_load +to do the event send in case host_connected differs between migration +source and target. + +RHBZ: 867366 + +Signed-off-by: Alon Levy +--- + hw/virtio-serial-bus.c | 54 ++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 44 insertions(+), 10 deletions(-) + +diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c +index d20bd8b..a028877 100644 +--- a/hw/virtio-serial-bus.c ++++ b/hw/virtio-serial-bus.c +@@ -53,6 +53,15 @@ struct VirtIOSerial { + uint32_t *ports_map; + + struct virtio_console_config config; ++ ++ struct VirtIOSerialPostLoad { ++ QEMUTimer *timer; ++ int nr_active_ports; ++ struct VirtIOSerialPostLoadPort { ++ VirtIOSerialPort *port; ++ uint8_t host_connected; ++ } *connected; ++ } post_load; + }; + + static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id) +@@ -626,6 +635,29 @@ static void virtio_serial_save(QEMUFile *f, void *opaque) + } + } + ++static void virtio_serial_post_load_timer_cb(void *opaque) ++{ ++ int i; ++ VirtIOSerial *s = opaque; ++ VirtIOSerialPort *port; ++ uint8_t host_connected; ++ ++ for (i = 0 ; i < s->post_load.nr_active_ports; ++i) { ++ port = s->post_load.connected[i].port; ++ host_connected = s->post_load.connected[i].host_connected; ++ if (host_connected != port->host_connected) { ++ /* ++ * We have to let the guest know of the host connection ++ * status change ++ */ ++ send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, ++ port->host_connected); ++ } ++ } ++ g_free(s->post_load.connected); ++ s->post_load.connected = NULL; ++} ++ + static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) + { + VirtIOSerial *s = opaque; +@@ -673,10 +705,13 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) + + qemu_get_be32s(f, &nr_active_ports); + ++ s->post_load.nr_active_ports = nr_active_ports; ++ s->post_load.connected = ++ g_malloc0(sizeof(*s->post_load.connected) * nr_active_ports); ++ + /* Items in struct VirtIOSerialPort */ + for (i = 0; i < nr_active_ports; i++) { + uint32_t id; +- bool host_connected; + + id = qemu_get_be32(f); + port = find_port_by_id(s, id); +@@ -685,15 +720,8 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) + } + + port->guest_connected = qemu_get_byte(f); +- host_connected = qemu_get_byte(f); +- if (host_connected != port->host_connected) { +- /* +- * We have to let the guest know of the host connection +- * status change +- */ +- send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, +- port->host_connected); +- } ++ s->post_load.connected[i].port = port; ++ s->post_load.connected[i].host_connected = qemu_get_byte(f); + + if (version_id > 2) { + uint32_t elem_popped; +@@ -718,6 +746,7 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) + } + } + } ++ qemu_mod_timer(s->post_load.timer, 1); + return 0; + } + +@@ -967,6 +996,9 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf) + register_savevm(dev, "virtio-console", -1, 3, virtio_serial_save, + virtio_serial_load, vser); + ++ vser->post_load.timer = qemu_new_timer_ns(vm_clock, ++ virtio_serial_post_load_timer_cb, vser); ++ + return vdev; + } + +@@ -979,6 +1011,8 @@ void virtio_serial_exit(VirtIODevice *vdev) + g_free(vser->ivqs); + g_free(vser->ovqs); + g_free(vser->ports_map); ++ g_free(vser->post_load.connected); ++ qemu_free_timer(vser->post_load.timer); + + virtio_cleanup(vdev); + } +-- +1.8.0 + diff --git a/0414-hw-virtio-serial-bus-replay-guest-open-on-destinatio.patch b/0414-hw-virtio-serial-bus-replay-guest-open-on-destinatio.patch new file mode 100644 index 0000000..07b10f6 --- /dev/null +++ b/0414-hw-virtio-serial-bus-replay-guest-open-on-destinatio.patch @@ -0,0 +1,54 @@ +From 5b6831175b21aa5a3405a21dd79e1ef0a81bbdb3 Mon Sep 17 00:00:00 2001 +From: Alon Levy +Date: Fri, 16 Nov 2012 16:24:47 +0200 +Subject: [PATCH 2/2] hw/virtio-serial-bus: replay guest open on destination + +This is rewrite of a patch carried in Fedora previously based +on new code upstream, here is the original message, it still applies: +(the original fedora patch was commit id +a9bc20afc1f0604ee81c23b7c67d627e51d2e8d4, this is useful for grepping in +logs, it isn't in upstream) + +When migrating a host with with a spice agent running the mouse becomes +non operational after the migration. This is rhbz #725965. + +The problem is that after migration spice doesn't know the guest agent +is open. Spice is just a char dev here. And a chardev cannot query it's +device, the device has to let the chardev know when it is open. Right +now after migration the chardev which is recreated is in it's default +state, which assumes the guest is disconnected. + +Char devices carry no information across migration, but the +virtio-serial does already carry the guest_connected state. This patch +passes that bit to the chardev. +--- + hw/virtio-serial-bus.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c +index a028877..a6ec2df 100644 +--- a/hw/virtio-serial-bus.c ++++ b/hw/virtio-serial-bus.c +@@ -641,6 +641,7 @@ static void virtio_serial_post_load_timer_cb(void *opaque) + VirtIOSerial *s = opaque; + VirtIOSerialPort *port; + uint8_t host_connected; ++ VirtIOSerialPortClass *vsc; + + for (i = 0 ; i < s->post_load.nr_active_ports; ++i) { + port = s->post_load.connected[i].port; +@@ -653,6 +654,11 @@ static void virtio_serial_post_load_timer_cb(void *opaque) + send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, + port->host_connected); + } ++ vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); ++ if (port->guest_connected && vsc->guest_open) { ++ /* replay guest open */ ++ vsc->guest_open(port); ++ } + } + g_free(s->post_load.connected); + s->post_load.connected = NULL; +-- +1.8.0 + diff --git a/qemu.spec b/qemu.spec index b120dd5..5552539 100644 --- a/qemu.spec +++ b/qemu.spec @@ -414,8 +414,11 @@ Patch0407: 0407-virtio-console-Enable-port-throttling-when-chardev-i.patch Patch0408: 0408-spice-qemu-char.c-add-throttling.patch Patch0409: 0409-spice-qemu-char.c-remove-intermediate-buffer.patch Patch0410: 0410-usb-redir-Add-flow-control-support.patch -Patch0411: 0411-virtio-serial-bus-replay-guest_open-on-migration.patch +# 411 superceded by 414 which does the same thing but on top of 413 that is +# going upstream. Patch0412: 0412-char-Disable-write-callback-if-throttled-chardev-is-.patch +Patch0413: 0413-hw-virtio-serial-bus-post_load-send_event-when-vm-is.patch +Patch0414: 0414-hw-virtio-serial-bus-replay-guest-open-on-destinatio.patch # Spice features from upstream master: seamless migration & dynamic monitors Patch0500: 0500-qxl-disallow-unknown-revisions.patch @@ -490,7 +493,6 @@ Patch804: 0804-wip-hw-qxl-inject-interrupts-in-any-state.patch # 38f419f (configure: Fix CONFIG_QEMU_HELPERDIR generation, 2012-10-17) Patch805: 0805-configure-Fix-CONFIG_QEMU_HELPERDIR-generation.patch - BuildRequires: SDL-devel BuildRequires: zlib-devel BuildRequires: which @@ -1169,8 +1171,10 @@ such as kvm_stat. %patch0408 -p1 %patch0409 -p1 %patch0410 -p1 -%patch0411 -p1 +# 411 superceded by 414 %patch0412 -p1 +%patch0413 -p1 +%patch0414 -p1 %patch0500 -p1 %patch0501 -p1 @@ -1235,7 +1239,6 @@ such as kvm_stat. %patch804 -p1 %patch805 -p1 - %build %if %{with kvmonly} buildarch="%{kvm_target}-softmmu" @@ -1852,6 +1855,10 @@ fi %endif %changelog +* Tue Nov 17 2012 Alon Levy - 2:1.2.0-24 +- Rewrite fix for bz #725965 based on fix for bz #867366 +- Resolve bz #867366 + * Fri Nov 16 2012 Paolo Bonzini - 2:1.2.0-23 - Backport --with separate_kvm support from EPEL branch