virtio-serial: add enable_backend callback
We should guarantee that RAM will not be modified while VM has a stopped state, otherwise it can lead to negative consequences during post-copy migration. In RUN_STATE_FINISH_MIGRATE step, it's expected that RAM on source side will not be modified as this could lead to non-consistent vm state on the destination side. Also RAM access during postcopy-ram migration with enabled release-ram capability can lead to sad consequences. Let's add enable_backend() callback to avoid undesirable virtioqueue changes in the guest memory. Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> Message-Id: <20170919120733.22020-1-pbutsykin@virtuozzo.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
b62b7ed0fc
commit
55289fb036
|
@ -187,6 +187,26 @@ static int chr_be_change(void *opaque)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtconsole_enable_backend(VirtIOSerialPort *port, bool enable)
|
||||||
|
{
|
||||||
|
VirtConsole *vcon = VIRTIO_CONSOLE(port);
|
||||||
|
|
||||||
|
if (!qemu_chr_fe_backend_connected(&vcon->chr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
|
||||||
|
|
||||||
|
qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read,
|
||||||
|
k->is_console ? NULL : chr_event,
|
||||||
|
chr_be_change, vcon, NULL, false);
|
||||||
|
} else {
|
||||||
|
qemu_chr_fe_set_handlers(&vcon->chr, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void virtconsole_realize(DeviceState *dev, Error **errp)
|
static void virtconsole_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
|
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
|
||||||
|
@ -258,6 +278,7 @@ static void virtserialport_class_init(ObjectClass *klass, void *data)
|
||||||
k->unrealize = virtconsole_unrealize;
|
k->unrealize = virtconsole_unrealize;
|
||||||
k->have_data = flush_buf;
|
k->have_data = flush_buf;
|
||||||
k->set_guest_connected = set_guest_connected;
|
k->set_guest_connected = set_guest_connected;
|
||||||
|
k->enable_backend = virtconsole_enable_backend;
|
||||||
k->guest_writable = guest_writable;
|
k->guest_writable = guest_writable;
|
||||||
dc->props = virtserialport_properties;
|
dc->props = virtserialport_properties;
|
||||||
}
|
}
|
||||||
|
|
|
@ -637,6 +637,13 @@ static void set_status(VirtIODevice *vdev, uint8_t status)
|
||||||
if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
|
if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
|
||||||
guest_reset(vser);
|
guest_reset(vser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTAILQ_FOREACH(port, &vser->ports, next) {
|
||||||
|
VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
|
||||||
|
if (vsc->enable_backend) {
|
||||||
|
vsc->enable_backend(port, vdev->vm_running);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vser_reset(VirtIODevice *vdev)
|
static void vser_reset(VirtIODevice *vdev)
|
||||||
|
|
|
@ -58,6 +58,9 @@ typedef struct VirtIOSerialPortClass {
|
||||||
/* Guest opened/closed device. */
|
/* Guest opened/closed device. */
|
||||||
void (*set_guest_connected)(VirtIOSerialPort *port, int guest_connected);
|
void (*set_guest_connected)(VirtIOSerialPort *port, int guest_connected);
|
||||||
|
|
||||||
|
/* Enable/disable backend for virtio serial port */
|
||||||
|
void (*enable_backend)(VirtIOSerialPort *port, bool enable);
|
||||||
|
|
||||||
/* Guest is now ready to accept data (virtqueues set up). */
|
/* Guest is now ready to accept data (virtqueues set up). */
|
||||||
void (*guest_ready)(VirtIOSerialPort *port);
|
void (*guest_ready)(VirtIOSerialPort *port);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue