diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-13 01:43:40 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-13 01:45:45 -0500 |
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) | |||
1037 | kill(0, SIGTERM); | 1037 | kill(0, SIGTERM); |
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | static void reset_vq_pci_config(struct virtqueue *vq) | ||
1041 | { | ||
1042 | vq->pci_config.queue_size = VIRTQUEUE_NUM; | ||
1043 | vq->pci_config.queue_enable = 0; | ||
1044 | } | ||
1045 | |||
1040 | static void reset_device(struct device *dev) | 1046 | static void reset_device(struct device *dev) |
1041 | { | 1047 | { |
1042 | struct virtqueue *vq; | 1048 | struct virtqueue *vq; |
@@ -1049,8 +1055,19 @@ static void reset_device(struct device *dev) | |||
1049 | /* We're going to be explicitly killing threads, so ignore them. */ | 1055 | /* We're going to be explicitly killing threads, so ignore them. */ |
1050 | signal(SIGCHLD, SIG_IGN); | 1056 | signal(SIGCHLD, SIG_IGN); |
1051 | 1057 | ||
1058 | /* | ||
1059 | * 4.1.4.3.1: | ||
1060 | * | ||
1061 | * The device MUST present a 0 in queue_enable on reset. | ||
1062 | * | ||
1063 | * This means we set it here, and reset the saved ones in every vq. | ||
1064 | */ | ||
1065 | dev->mmio->cfg.queue_enable = 0; | ||
1066 | |||
1052 | /* Get rid of the virtqueue threads */ | 1067 | /* Get rid of the virtqueue threads */ |
1053 | for (vq = dev->vq; vq; vq = vq->next) { | 1068 | for (vq = dev->vq; vq; vq = vq->next) { |
1069 | vq->last_avail_idx = 0; | ||
1070 | reset_vq_pci_config(vq); | ||
1054 | if (vq->thread != (pid_t)-1) { | 1071 | if (vq->thread != (pid_t)-1) { |
1055 | kill(vq->thread, SIGTERM); | 1072 | kill(vq->thread, SIGTERM); |
1056 | waitpid(vq->thread, NULL, 0); | 1073 | waitpid(vq->thread, NULL, 0); |
@@ -1952,8 +1969,7 @@ static void add_pci_virtqueue(struct device *dev, | |||
1952 | vq->thread = (pid_t)-1; | 1969 | vq->thread = (pid_t)-1; |
1953 | 1970 | ||
1954 | /* Initialize the configuration. */ | 1971 | /* Initialize the configuration. */ |
1955 | vq->pci_config.queue_size = VIRTQUEUE_NUM; | 1972 | reset_vq_pci_config(vq); |
1956 | vq->pci_config.queue_enable = 0; | ||
1957 | vq->pci_config.queue_notify_off = 0; | 1973 | vq->pci_config.queue_notify_off = 0; |
1958 | 1974 | ||
1959 | /* Add one to the number of queues */ | 1975 | /* Add one to the number of queues */ |