diff options
Diffstat (limited to 'Documentation/virtual/lguest')
-rw-r--r-- | Documentation/virtual/lguest/.gitignore | 1 | ||||
-rw-r--r-- | Documentation/virtual/lguest/lguest.c | 50 |
2 files changed, 19 insertions, 32 deletions
diff --git a/Documentation/virtual/lguest/.gitignore b/Documentation/virtual/lguest/.gitignore deleted file mode 100644 index 115587fd5f6..00000000000 --- a/Documentation/virtual/lguest/.gitignore +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | lguest | ||
diff --git a/Documentation/virtual/lguest/lguest.c b/Documentation/virtual/lguest/lguest.c index cd9d6af61d0..d928c134dee 100644 --- a/Documentation/virtual/lguest/lguest.c +++ b/Documentation/virtual/lguest/lguest.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include <asm/bootparam.h> | 51 | #include <asm/bootparam.h> |
52 | #include "../../../include/linux/lguest_launcher.h" | 52 | #include "../../../include/linux/lguest_launcher.h" |
53 | /*L:110 | 53 | /*L:110 |
54 | * We can ignore the 42 include files we need for this program, but I do want | 54 | * We can ignore the 43 include files we need for this program, but I do want |
55 | * to draw attention to the use of kernel-style types. | 55 | * to draw attention to the use of kernel-style types. |
56 | * | 56 | * |
57 | * As Linus said, "C is a Spartan language, and so should your naming be." I | 57 | * As Linus said, "C is a Spartan language, and so should your naming be." I |
@@ -65,7 +65,6 @@ typedef uint16_t u16; | |||
65 | typedef uint8_t u8; | 65 | typedef uint8_t u8; |
66 | /*:*/ | 66 | /*:*/ |
67 | 67 | ||
68 | #define PAGE_PRESENT 0x7 /* Present, RW, Execute */ | ||
69 | #define BRIDGE_PFX "bridge:" | 68 | #define BRIDGE_PFX "bridge:" |
70 | #ifndef SIOCBRADDIF | 69 | #ifndef SIOCBRADDIF |
71 | #define SIOCBRADDIF 0x89a2 /* add interface to bridge */ | 70 | #define SIOCBRADDIF 0x89a2 /* add interface to bridge */ |
@@ -861,8 +860,10 @@ static void console_output(struct virtqueue *vq) | |||
861 | /* writev can return a partial write, so we loop here. */ | 860 | /* writev can return a partial write, so we loop here. */ |
862 | while (!iov_empty(iov, out)) { | 861 | while (!iov_empty(iov, out)) { |
863 | int len = writev(STDOUT_FILENO, iov, out); | 862 | int len = writev(STDOUT_FILENO, iov, out); |
864 | if (len <= 0) | 863 | if (len <= 0) { |
865 | err(1, "Write to stdout gave %i", len); | 864 | warn("Write to stdout gave %i (%d)", len, errno); |
865 | break; | ||
866 | } | ||
866 | iov_consume(iov, out, len); | 867 | iov_consume(iov, out, len); |
867 | } | 868 | } |
868 | 869 | ||
@@ -898,7 +899,7 @@ static void net_output(struct virtqueue *vq) | |||
898 | * same format: what a coincidence! | 899 | * same format: what a coincidence! |
899 | */ | 900 | */ |
900 | if (writev(net_info->tunfd, iov, out) < 0) | 901 | if (writev(net_info->tunfd, iov, out) < 0) |
901 | errx(1, "Write to tun failed?"); | 902 | warnx("Write to tun failed (%d)?", errno); |
902 | 903 | ||
903 | /* | 904 | /* |
904 | * Done with that one; wait_for_vq_desc() will send the interrupt if | 905 | * Done with that one; wait_for_vq_desc() will send the interrupt if |
@@ -955,7 +956,7 @@ static void net_input(struct virtqueue *vq) | |||
955 | */ | 956 | */ |
956 | len = readv(net_info->tunfd, iov, in); | 957 | len = readv(net_info->tunfd, iov, in); |
957 | if (len <= 0) | 958 | if (len <= 0) |
958 | err(1, "Failed to read from tun."); | 959 | warn("Failed to read from tun (%d).", errno); |
959 | 960 | ||
960 | /* | 961 | /* |
961 | * Mark that packet buffer as used, but don't interrupt here. We want | 962 | * Mark that packet buffer as used, but don't interrupt here. We want |
@@ -1093,9 +1094,10 @@ static void update_device_status(struct device *dev) | |||
1093 | warnx("Device %s configuration FAILED", dev->name); | 1094 | warnx("Device %s configuration FAILED", dev->name); |
1094 | if (dev->running) | 1095 | if (dev->running) |
1095 | reset_device(dev); | 1096 | reset_device(dev); |
1096 | } else if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) { | 1097 | } else { |
1097 | if (!dev->running) | 1098 | if (dev->running) |
1098 | start_device(dev); | 1099 | err(1, "Device %s features finalized twice", dev->name); |
1100 | start_device(dev); | ||
1099 | } | 1101 | } |
1100 | } | 1102 | } |
1101 | 1103 | ||
@@ -1120,25 +1122,11 @@ static void handle_output(unsigned long addr) | |||
1120 | return; | 1122 | return; |
1121 | } | 1123 | } |
1122 | 1124 | ||
1123 | /* | 1125 | /* Devices should not be used before features are finalized. */ |
1124 | * Devices *can* be used before status is set to DRIVER_OK. | ||
1125 | * The original plan was that they would never do this: they | ||
1126 | * would always finish setting up their status bits before | ||
1127 | * actually touching the virtqueues. In practice, we allowed | ||
1128 | * them to, and they do (eg. the disk probes for partition | ||
1129 | * tables as part of initialization). | ||
1130 | * | ||
1131 | * If we see this, we start the device: once it's running, we | ||
1132 | * expect the device to catch all the notifications. | ||
1133 | */ | ||
1134 | for (vq = i->vq; vq; vq = vq->next) { | 1126 | for (vq = i->vq; vq; vq = vq->next) { |
1135 | if (addr != vq->config.pfn*getpagesize()) | 1127 | if (addr != vq->config.pfn*getpagesize()) |
1136 | continue; | 1128 | continue; |
1137 | if (i->running) | 1129 | errx(1, "Notification on %s before setup!", i->name); |
1138 | errx(1, "Notification on running %s", i->name); | ||
1139 | /* This just calls create_thread() for each virtqueue */ | ||
1140 | start_device(i); | ||
1141 | return; | ||
1142 | } | 1130 | } |
1143 | } | 1131 | } |
1144 | 1132 | ||
@@ -1370,7 +1358,7 @@ static void setup_console(void) | |||
1370 | * --sharenet=<name> option which opens or creates a named pipe. This can be | 1358 | * --sharenet=<name> option which opens or creates a named pipe. This can be |
1371 | * used to send packets to another guest in a 1:1 manner. | 1359 | * used to send packets to another guest in a 1:1 manner. |
1372 | * | 1360 | * |
1373 | * More sopisticated is to use one of the tools developed for project like UML | 1361 | * More sophisticated is to use one of the tools developed for project like UML |
1374 | * to do networking. | 1362 | * to do networking. |
1375 | * | 1363 | * |
1376 | * Faster is to do virtio bonding in kernel. Doing this 1:1 would be | 1364 | * Faster is to do virtio bonding in kernel. Doing this 1:1 would be |
@@ -1380,7 +1368,7 @@ static void setup_console(void) | |||
1380 | * multiple inter-guest channels behind one interface, although it would | 1368 | * multiple inter-guest channels behind one interface, although it would |
1381 | * require some manner of hotplugging new virtio channels. | 1369 | * require some manner of hotplugging new virtio channels. |
1382 | * | 1370 | * |
1383 | * Finally, we could implement a virtio network switch in the kernel. | 1371 | * Finally, we could use a virtio network switch in the kernel, ie. vhost. |
1384 | :*/ | 1372 | :*/ |
1385 | 1373 | ||
1386 | static u32 str2ip(const char *ipaddr) | 1374 | static u32 str2ip(const char *ipaddr) |
@@ -2008,6 +1996,9 @@ int main(int argc, char *argv[]) | |||
2008 | /* We use a simple helper to copy the arguments separated by spaces. */ | 1996 | /* We use a simple helper to copy the arguments separated by spaces. */ |
2009 | concat((char *)(boot + 1), argv+optind+2); | 1997 | concat((char *)(boot + 1), argv+optind+2); |
2010 | 1998 | ||
1999 | /* Set kernel alignment to 16M (CONFIG_PHYSICAL_ALIGN) */ | ||
2000 | boot->hdr.kernel_alignment = 0x1000000; | ||
2001 | |||
2011 | /* Boot protocol version: 2.07 supports the fields for lguest. */ | 2002 | /* Boot protocol version: 2.07 supports the fields for lguest. */ |
2012 | boot->hdr.version = 0x207; | 2003 | boot->hdr.version = 0x207; |
2013 | 2004 | ||
@@ -2017,10 +2008,7 @@ int main(int argc, char *argv[]) | |||
2017 | /* Tell the entry path not to try to reload segment registers. */ | 2008 | /* Tell the entry path not to try to reload segment registers. */ |
2018 | boot->hdr.loadflags |= KEEP_SEGMENTS; | 2009 | boot->hdr.loadflags |= KEEP_SEGMENTS; |
2019 | 2010 | ||
2020 | /* | 2011 | /* We tell the kernel to initialize the Guest. */ |
2021 | * We tell the kernel to initialize the Guest: this returns the open | ||
2022 | * /dev/lguest file descriptor. | ||
2023 | */ | ||
2024 | tell_kernel(start); | 2012 | tell_kernel(start); |
2025 | 2013 | ||
2026 | /* Ensure that we terminate if a device-servicing child dies. */ | 2014 | /* Ensure that we terminate if a device-servicing child dies. */ |