diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-13 17:13:40 +1030 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-13 17:15:45 +1030 |
commit | d2dbdac336e8ea1296fd08c4eb8a28daacec1817 (patch) | |
tree | cafaba8f442a59c4fde6bd25a551c711a8cbe785 /tools/lguest | |
parent | a2e199915725e666772dd077dbffbef154e58096 (diff) |
tools/lguest: handle device reset correctly in example launcher.
The example launcher doesn't reset the queue_enable like the spec says
we have to. Plus, we should reset the size in case they negotiated
a different (smaller) one.
This is easy to test by unloading and reloading a virtio module.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'tools/lguest')
-rw-r--r-- | tools/lguest/lguest.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c index 5d104321f70f..60cabafdf615 100644 --- a/tools/lguest/lguest.c +++ b/tools/lguest/lguest.c @@ -1037,6 +1037,12 @@ static void kill_launcher(int signal) kill(0, SIGTERM); } +static void reset_vq_pci_config(struct virtqueue *vq) +{ + vq->pci_config.queue_size = VIRTQUEUE_NUM; + vq->pci_config.queue_enable = 0; +} + static void reset_device(struct device *dev) { struct virtqueue *vq; @@ -1049,8 +1055,19 @@ static void reset_device(struct device *dev) /* We're going to be explicitly killing threads, so ignore them. */ signal(SIGCHLD, SIG_IGN); + /* + * 4.1.4.3.1: + * + * The device MUST present a 0 in queue_enable on reset. + * + * This means we set it here, and reset the saved ones in every vq. + */ + dev->mmio->cfg.queue_enable = 0; + /* Get rid of the virtqueue threads */ for (vq = dev->vq; vq; vq = vq->next) { + vq->last_avail_idx = 0; + reset_vq_pci_config(vq); if (vq->thread != (pid_t)-1) { kill(vq->thread, SIGTERM); waitpid(vq->thread, NULL, 0); @@ -1952,8 +1969,7 @@ static void add_pci_virtqueue(struct device *dev, vq->thread = (pid_t)-1; /* Initialize the configuration. */ - vq->pci_config.queue_size = VIRTQUEUE_NUM; - vq->pci_config.queue_enable = 0; + reset_vq_pci_config(vq); vq->pci_config.queue_notify_off = 0; /* Add one to the number of queues */ |