aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/virtual
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2011-07-22 01:09:49 -0400
committerRusty Russell <rusty@rustcorp.com.au>2011-07-22 01:09:49 -0400
commit3c3ed482dc077a67903a58c9e1aedba1bb18c18a (patch)
treead3987515d68fcfa7155574e53ab47aabd41e593 /Documentation/virtual
parent6d7a5d1ea34495ecb1d608f0e40afba7776ee408 (diff)
lguest: Simplify device initialization.
We used to notify the Host every time we updated a device's status. However, it only really needs to know when we're resetting the device, or failed to initialize it, or when we've finished our feature negotiation. In particular, we used to wait for VIRTIO_CONFIG_S_DRIVER_OK in the status byte before starting the device service threads. But this corresponds to the successful finish of device initialization, which might (like virtio_blk's partition scanning) use the device. So we had a hack, if they used the device before we expected we started the threads anyway. Now we hook into the finalize_features hook in the Guest: at that point we tell the Launcher that it can rely on the features we have acked. On the Launcher side, we look at the status at that point, and start servicing the device. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'Documentation/virtual')
-rw-r--r--Documentation/virtual/lguest/lguest.c25
1 files changed, 6 insertions, 19 deletions
diff --git a/Documentation/virtual/lguest/lguest.c b/Documentation/virtual/lguest/lguest.c
index e3b9bb7a644a..80261d34da3d 100644
--- a/Documentation/virtual/lguest/lguest.c
+++ b/Documentation/virtual/lguest/lguest.c
@@ -1095,9 +1095,10 @@ static void update_device_status(struct device *dev)
1095 warnx("Device %s configuration FAILED", dev->name); 1095 warnx("Device %s configuration FAILED", dev->name);
1096 if (dev->running) 1096 if (dev->running)
1097 reset_device(dev); 1097 reset_device(dev);
1098 } else if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) { 1098 } else {
1099 if (!dev->running) 1099 if (dev->running)
1100 start_device(dev); 1100 err(1, "Device %s features finalized twice", dev->name);
1101 start_device(dev);
1101 } 1102 }
1102} 1103}
1103 1104
@@ -1122,25 +1123,11 @@ static void handle_output(unsigned long addr)
1122 return; 1123 return;
1123 } 1124 }
1124 1125
1125 /* 1126 /* Devices should not be used before features are finalized. */
1126 * Devices *can* be used before status is set to DRIVER_OK.
1127 * The original plan was that they would never do this: they
1128 * would always finish setting up their status bits before
1129 * actually touching the virtqueues. In practice, we allowed
1130 * them to, and they do (eg. the disk probes for partition
1131 * tables as part of initialization).
1132 *
1133 * If we see this, we start the device: once it's running, we
1134 * expect the device to catch all the notifications.
1135 */
1136 for (vq = i->vq; vq; vq = vq->next) { 1127 for (vq = i->vq; vq; vq = vq->next) {
1137 if (addr != vq->config.pfn*getpagesize()) 1128 if (addr != vq->config.pfn*getpagesize())
1138 continue; 1129 continue;
1139 if (i->running) 1130 errx(1, "Notification on %s before setup!", i->name);
1140 errx(1, "Notification on running %s", i->name);
1141 /* This just calls create_thread() for each virtqueue */
1142 start_device(i);
1143 return;
1144 } 1131 }
1145 } 1132 }
1146 1133