Skip to content

Commit

Permalink
virtio: console: Add freeze and restore handlers to support S4
Browse files Browse the repository at this point in the history
Remove all vqs and associated buffers in the freeze callback which
prepares us to go into hibernation state.  On restore, re-create all the
vqs and populate the input vqs with buffers to get to the pre-hibernate
state.

Note: Any outstanding unconsumed buffers are discarded; which means
there's a possibility of data loss in case the host or the guest didn't
consume any data already present in the vqs.  This can be addressed in a
later patch series, perhaps in virtio common code.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
Amit Shah authored and Rusty Russell committed Jan 12, 2012
1 parent a0e2dbf commit 2b8f41d
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions drivers/char/virtio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -1844,6 +1844,60 @@ static unsigned int features[] = {
VIRTIO_CONSOLE_F_MULTIPORT,
};

#ifdef CONFIG_PM
static int virtcons_freeze(struct virtio_device *vdev)
{
struct ports_device *portdev;
struct port *port;

portdev = vdev->priv;

vdev->config->reset(vdev);

cancel_work_sync(&portdev->control_work);
remove_controlq_data(portdev);

list_for_each_entry(port, &portdev->ports, list) {
/*
* We'll ask the host later if the new invocation has
* the port opened or closed.
*/
port->host_connected = false;
remove_port_data(port);
}
remove_vqs(portdev);

return 0;
}

static int virtcons_restore(struct virtio_device *vdev)
{
struct ports_device *portdev;
struct port *port;
int ret;

portdev = vdev->priv;

ret = init_vqs(portdev);
if (ret)
return ret;

if (use_multiport(portdev))
fill_queue(portdev->c_ivq, &portdev->cvq_lock);

list_for_each_entry(port, &portdev->ports, list) {
port->in_vq = portdev->in_vqs[port->id];
port->out_vq = portdev->out_vqs[port->id];

fill_queue(port->in_vq, &port->inbuf_lock);

/* Get port open/close status on the host */
send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
}
return 0;
}
#endif

static struct virtio_driver virtio_console = {
.feature_table = features,
.feature_table_size = ARRAY_SIZE(features),
Expand All @@ -1853,6 +1907,10 @@ static struct virtio_driver virtio_console = {
.probe = virtcons_probe,
.remove = virtcons_remove,
.config_changed = config_intr,
#ifdef CONFIG_PM
.freeze = virtcons_freeze,
.restore = virtcons_restore,
#endif
};

static int __init init(void)
Expand Down

0 comments on commit 2b8f41d

Please sign in to comment.