aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/lguest/lguest.c102
1 files changed, 47 insertions, 55 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index e65d6cbf2419..1a2b906a3ae6 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -79,7 +79,6 @@ static bool verbose;
79/* File descriptors for the Waker. */ 79/* File descriptors for the Waker. */
80struct { 80struct {
81 int pipe[2]; 81 int pipe[2];
82 int lguest_fd;
83} waker_fds; 82} waker_fds;
84 83
85/* The pointer to the start of guest memory. */ 84/* The pointer to the start of guest memory. */
@@ -89,6 +88,8 @@ static unsigned long guest_limit, guest_max;
89/* The pipe for signal hander to write to. */ 88/* The pipe for signal hander to write to. */
90static int timeoutpipe[2]; 89static int timeoutpipe[2];
91static unsigned int timeout_usec = 500; 90static unsigned int timeout_usec = 500;
91/* The /dev/lguest file descriptor. */
92static int lguest_fd;
92 93
93/* a per-cpu variable indicating whose vcpu is currently running */ 94/* a per-cpu variable indicating whose vcpu is currently running */
94static unsigned int __thread cpu_id; 95static unsigned int __thread cpu_id;
@@ -139,7 +140,7 @@ struct device
139 /* If handle_input is set, it wants to be called when this file 140 /* If handle_input is set, it wants to be called when this file
140 * descriptor is ready. */ 141 * descriptor is ready. */
141 int fd; 142 int fd;
142 bool (*handle_input)(int fd, struct device *me); 143 bool (*handle_input)(struct device *me);
143 144
144 /* Any queues attached to this device */ 145 /* Any queues attached to this device */
145 struct virtqueue *vq; 146 struct virtqueue *vq;
@@ -169,7 +170,7 @@ struct virtqueue
169 u16 last_avail_idx; 170 u16 last_avail_idx;
170 171
171 /* The routine to call when the Guest pings us, or timeout. */ 172 /* The routine to call when the Guest pings us, or timeout. */
172 void (*handle_output)(int fd, struct virtqueue *me, bool timeout); 173 void (*handle_output)(struct virtqueue *me, bool timeout);
173 174
174 /* Outstanding buffers */ 175 /* Outstanding buffers */
175 unsigned int inflight; 176 unsigned int inflight;
@@ -509,21 +510,16 @@ static void concat(char *dst, char *args[])
509 * saw the arguments it expects when we looked at initialize() in lguest_user.c: 510 * saw the arguments it expects when we looked at initialize() in lguest_user.c:
510 * the base of Guest "physical" memory, the top physical page to allow and the 511 * the base of Guest "physical" memory, the top physical page to allow and the
511 * entry point for the Guest. */ 512 * entry point for the Guest. */
512static int tell_kernel(unsigned long start) 513static void tell_kernel(unsigned long start)
513{ 514{
514 unsigned long args[] = { LHREQ_INITIALIZE, 515 unsigned long args[] = { LHREQ_INITIALIZE,
515 (unsigned long)guest_base, 516 (unsigned long)guest_base,
516 guest_limit / getpagesize(), start }; 517 guest_limit / getpagesize(), start };
517 int fd;
518
519 verbose("Guest: %p - %p (%#lx)\n", 518 verbose("Guest: %p - %p (%#lx)\n",
520 guest_base, guest_base + guest_limit, guest_limit); 519 guest_base, guest_base + guest_limit, guest_limit);
521 fd = open_or_die("/dev/lguest", O_RDWR); 520 lguest_fd = open_or_die("/dev/lguest", O_RDWR);
522 if (write(fd, args, sizeof(args)) < 0) 521 if (write(lguest_fd, args, sizeof(args)) < 0)
523 err(1, "Writing to /dev/lguest"); 522 err(1, "Writing to /dev/lguest");
524
525 /* We return the /dev/lguest file descriptor to control this Guest */
526 return fd;
527} 523}
528/*:*/ 524/*:*/
529 525
@@ -583,21 +579,18 @@ static int waker(void *unused)
583 } 579 }
584 580
585 /* Send LHREQ_BREAK command to snap the Launcher out of it. */ 581 /* Send LHREQ_BREAK command to snap the Launcher out of it. */
586 pwrite(waker_fds.lguest_fd, args, sizeof(args), cpu_id); 582 pwrite(lguest_fd, args, sizeof(args), cpu_id);
587 } 583 }
588 return 0; 584 return 0;
589} 585}
590 586
591/* This routine just sets up a pipe to the Waker process. */ 587/* This routine just sets up a pipe to the Waker process. */
592static void setup_waker(int lguest_fd) 588static void setup_waker(void)
593{ 589{
594 /* This pipe is closed when Launcher dies, telling Waker. */ 590 /* This pipe is closed when Launcher dies, telling Waker. */
595 if (pipe(waker_fds.pipe) != 0) 591 if (pipe(waker_fds.pipe) != 0)
596 err(1, "Creating pipe for Waker"); 592 err(1, "Creating pipe for Waker");
597 593
598 /* Waker also needs to know the lguest fd */
599 waker_fds.lguest_fd = lguest_fd;
600
601 if (clone(waker, malloc(4096) + 4096, CLONE_VM | SIGCHLD, NULL) == -1) 594 if (clone(waker, malloc(4096) + 4096, CLONE_VM | SIGCHLD, NULL) == -1)
602 err(1, "Creating Waker"); 595 err(1, "Creating Waker");
603} 596}
@@ -727,7 +720,7 @@ static void add_used(struct virtqueue *vq, unsigned int head, int len)
727} 720}
728 721
729/* This actually sends the interrupt for this virtqueue */ 722/* This actually sends the interrupt for this virtqueue */
730static void trigger_irq(int fd, struct virtqueue *vq) 723static void trigger_irq(struct virtqueue *vq)
731{ 724{
732 unsigned long buf[] = { LHREQ_IRQ, vq->config.irq }; 725 unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
733 726
@@ -737,16 +730,15 @@ static void trigger_irq(int fd, struct virtqueue *vq)
737 return; 730 return;
738 731
739 /* Send the Guest an interrupt tell them we used something up. */ 732 /* Send the Guest an interrupt tell them we used something up. */
740 if (write(fd, buf, sizeof(buf)) != 0) 733 if (write(lguest_fd, buf, sizeof(buf)) != 0)
741 err(1, "Triggering irq %i", vq->config.irq); 734 err(1, "Triggering irq %i", vq->config.irq);
742} 735}
743 736
744/* And here's the combo meal deal. Supersize me! */ 737/* And here's the combo meal deal. Supersize me! */
745static void add_used_and_trigger(int fd, struct virtqueue *vq, 738static void add_used_and_trigger(struct virtqueue *vq, unsigned head, int len)
746 unsigned int head, int len)
747{ 739{
748 add_used(vq, head, len); 740 add_used(vq, head, len);
749 trigger_irq(fd, vq); 741 trigger_irq(vq);
750} 742}
751 743
752/* 744/*
@@ -770,7 +762,7 @@ struct console_abort
770}; 762};
771 763
772/* This is the routine which handles console input (ie. stdin). */ 764/* This is the routine which handles console input (ie. stdin). */
773static bool handle_console_input(int fd, struct device *dev) 765static bool handle_console_input(struct device *dev)
774{ 766{
775 int len; 767 int len;
776 unsigned int head, in_num, out_num; 768 unsigned int head, in_num, out_num;
@@ -804,7 +796,7 @@ static bool handle_console_input(int fd, struct device *dev)
804 } 796 }
805 797
806 /* Tell the Guest about the new input. */ 798 /* Tell the Guest about the new input. */
807 add_used_and_trigger(fd, dev->vq, head, len); 799 add_used_and_trigger(dev->vq, head, len);
808 800
809 /* Three ^C within one second? Exit. 801 /* Three ^C within one second? Exit.
810 * 802 *
@@ -824,7 +816,7 @@ static bool handle_console_input(int fd, struct device *dev)
824 close(waker_fds.pipe[1]); 816 close(waker_fds.pipe[1]);
825 /* Just in case Waker is blocked in BREAK, send 817 /* Just in case Waker is blocked in BREAK, send
826 * unbreak now. */ 818 * unbreak now. */
827 write(fd, args, sizeof(args)); 819 write(lguest_fd, args, sizeof(args));
828 exit(2); 820 exit(2);
829 } 821 }
830 abort->count = 0; 822 abort->count = 0;
@@ -839,7 +831,7 @@ static bool handle_console_input(int fd, struct device *dev)
839 831
840/* Handling output for console is simple: we just get all the output buffers 832/* Handling output for console is simple: we just get all the output buffers
841 * and write them to stdout. */ 833 * and write them to stdout. */
842static void handle_console_output(int fd, struct virtqueue *vq, bool timeout) 834static void handle_console_output(struct virtqueue *vq, bool timeout)
843{ 835{
844 unsigned int head, out, in; 836 unsigned int head, out, in;
845 int len; 837 int len;
@@ -850,7 +842,7 @@ static void handle_console_output(int fd, struct virtqueue *vq, bool timeout)
850 if (in) 842 if (in)
851 errx(1, "Input buffers in output queue?"); 843 errx(1, "Input buffers in output queue?");
852 len = writev(STDOUT_FILENO, iov, out); 844 len = writev(STDOUT_FILENO, iov, out);
853 add_used_and_trigger(fd, vq, head, len); 845 add_used_and_trigger(vq, head, len);
854 } 846 }
855} 847}
856 848
@@ -879,7 +871,7 @@ static void block_vq(struct virtqueue *vq)
879 * and write them (ignoring the first element) to this device's file descriptor 871 * and write them (ignoring the first element) to this device's file descriptor
880 * (/dev/net/tun). 872 * (/dev/net/tun).
881 */ 873 */
882static void handle_net_output(int fd, struct virtqueue *vq, bool timeout) 874static void handle_net_output(struct virtqueue *vq, bool timeout)
883{ 875{
884 unsigned int head, out, in, num = 0; 876 unsigned int head, out, in, num = 0;
885 int len; 877 int len;
@@ -893,7 +885,7 @@ static void handle_net_output(int fd, struct virtqueue *vq, bool timeout)
893 len = writev(vq->dev->fd, iov, out); 885 len = writev(vq->dev->fd, iov, out);
894 if (len < 0) 886 if (len < 0)
895 err(1, "Writing network packet to tun"); 887 err(1, "Writing network packet to tun");
896 add_used_and_trigger(fd, vq, head, len); 888 add_used_and_trigger(vq, head, len);
897 num++; 889 num++;
898 } 890 }
899 891
@@ -917,7 +909,7 @@ static void handle_net_output(int fd, struct virtqueue *vq, bool timeout)
917 909
918/* This is where we handle a packet coming in from the tun device to our 910/* This is where we handle a packet coming in from the tun device to our
919 * Guest. */ 911 * Guest. */
920static bool handle_tun_input(int fd, struct device *dev) 912static bool handle_tun_input(struct device *dev)
921{ 913{
922 unsigned int head, in_num, out_num; 914 unsigned int head, in_num, out_num;
923 int len; 915 int len;
@@ -946,7 +938,7 @@ static bool handle_tun_input(int fd, struct device *dev)
946 err(1, "reading network"); 938 err(1, "reading network");
947 939
948 /* Tell the Guest about the new packet. */ 940 /* Tell the Guest about the new packet. */
949 add_used_and_trigger(fd, dev->vq, head, len); 941 add_used_and_trigger(dev->vq, head, len);
950 942
951 verbose("tun input packet len %i [%02x %02x] (%s)\n", len, 943 verbose("tun input packet len %i [%02x %02x] (%s)\n", len,
952 ((u8 *)iov[1].iov_base)[0], ((u8 *)iov[1].iov_base)[1], 944 ((u8 *)iov[1].iov_base)[0], ((u8 *)iov[1].iov_base)[1],
@@ -959,18 +951,18 @@ static bool handle_tun_input(int fd, struct device *dev)
959/*L:215 This is the callback attached to the network and console input 951/*L:215 This is the callback attached to the network and console input
960 * virtqueues: it ensures we try again, in case we stopped console or net 952 * virtqueues: it ensures we try again, in case we stopped console or net
961 * delivery because Guest didn't have any buffers. */ 953 * delivery because Guest didn't have any buffers. */
962static void enable_fd(int fd, struct virtqueue *vq, bool timeout) 954static void enable_fd(struct virtqueue *vq, bool timeout)
963{ 955{
964 add_device_fd(vq->dev->fd); 956 add_device_fd(vq->dev->fd);
965 /* Snap the Waker out of its select loop. */ 957 /* Snap the Waker out of its select loop. */
966 write(waker_fds.pipe[1], "", 1); 958 write(waker_fds.pipe[1], "", 1);
967} 959}
968 960
969static void net_enable_fd(int fd, struct virtqueue *vq, bool timeout) 961static void net_enable_fd(struct virtqueue *vq, bool timeout)
970{ 962{
971 /* We don't need to know again when Guest refills receive buffer. */ 963 /* We don't need to know again when Guest refills receive buffer. */
972 vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY; 964 vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
973 enable_fd(fd, vq, timeout); 965 enable_fd(vq, timeout);
974} 966}
975 967
976/* When the Guest tells us they updated the status field, we handle it. */ 968/* When the Guest tells us they updated the status field, we handle it. */
@@ -1011,7 +1003,7 @@ static void update_device_status(struct device *dev)
1011} 1003}
1012 1004
1013/* This is the generic routine we call when the Guest uses LHCALL_NOTIFY. */ 1005/* This is the generic routine we call when the Guest uses LHCALL_NOTIFY. */
1014static void handle_output(int fd, unsigned long addr) 1006static void handle_output(unsigned long addr)
1015{ 1007{
1016 struct device *i; 1008 struct device *i;
1017 struct virtqueue *vq; 1009 struct virtqueue *vq;
@@ -1039,7 +1031,7 @@ static void handle_output(int fd, unsigned long addr)
1039 if (strcmp(vq->dev->name, "console") != 0) 1031 if (strcmp(vq->dev->name, "console") != 0)
1040 verbose("Output to %s\n", vq->dev->name); 1032 verbose("Output to %s\n", vq->dev->name);
1041 if (vq->handle_output) 1033 if (vq->handle_output)
1042 vq->handle_output(fd, vq, false); 1034 vq->handle_output(vq, false);
1043 return; 1035 return;
1044 } 1036 }
1045 } 1037 }
@@ -1053,7 +1045,7 @@ static void handle_output(int fd, unsigned long addr)
1053 strnlen(from_guest_phys(addr), guest_limit - addr)); 1045 strnlen(from_guest_phys(addr), guest_limit - addr));
1054} 1046}
1055 1047
1056static void handle_timeout(int fd) 1048static void handle_timeout(void)
1057{ 1049{
1058 char buf[32]; 1050 char buf[32];
1059 struct device *i; 1051 struct device *i;
@@ -1071,14 +1063,14 @@ static void handle_timeout(int fd)
1071 vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY; 1063 vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
1072 vq->blocked = false; 1064 vq->blocked = false;
1073 if (vq->handle_output) 1065 if (vq->handle_output)
1074 vq->handle_output(fd, vq, true); 1066 vq->handle_output(vq, true);
1075 } 1067 }
1076 } 1068 }
1077} 1069}
1078 1070
1079/* This is called when the Waker wakes us up: check for incoming file 1071/* This is called when the Waker wakes us up: check for incoming file
1080 * descriptors. */ 1072 * descriptors. */
1081static void handle_input(int fd) 1073static void handle_input(void)
1082{ 1074{
1083 /* select() wants a zeroed timeval to mean "don't wait". */ 1075 /* select() wants a zeroed timeval to mean "don't wait". */
1084 struct timeval poll = { .tv_sec = 0, .tv_usec = 0 }; 1076 struct timeval poll = { .tv_sec = 0, .tv_usec = 0 };
@@ -1100,7 +1092,7 @@ static void handle_input(int fd)
1100 * descriptors and a method of handling them. */ 1092 * descriptors and a method of handling them. */
1101 for (i = devices.dev; i; i = i->next) { 1093 for (i = devices.dev; i; i = i->next) {
1102 if (i->handle_input && FD_ISSET(i->fd, &fds)) { 1094 if (i->handle_input && FD_ISSET(i->fd, &fds)) {
1103 if (i->handle_input(fd, i)) 1095 if (i->handle_input(i))
1104 continue; 1096 continue;
1105 1097
1106 /* If handle_input() returns false, it means we 1098 /* If handle_input() returns false, it means we
@@ -1114,7 +1106,7 @@ static void handle_input(int fd)
1114 1106
1115 /* Is this the timeout fd? */ 1107 /* Is this the timeout fd? */
1116 if (FD_ISSET(timeoutpipe[0], &fds)) 1108 if (FD_ISSET(timeoutpipe[0], &fds))
1117 handle_timeout(fd); 1109 handle_timeout();
1118 } 1110 }
1119} 1111}
1120 1112
@@ -1163,7 +1155,7 @@ static struct lguest_device_desc *new_dev_desc(u16 type)
1163/* Each device descriptor is followed by the description of its virtqueues. We 1155/* Each device descriptor is followed by the description of its virtqueues. We
1164 * specify how many descriptors the virtqueue is to have. */ 1156 * specify how many descriptors the virtqueue is to have. */
1165static void add_virtqueue(struct device *dev, unsigned int num_descs, 1157static void add_virtqueue(struct device *dev, unsigned int num_descs,
1166 void (*handle_output)(int, struct virtqueue *, bool)) 1158 void (*handle_output)(struct virtqueue *, bool))
1167{ 1159{
1168 unsigned int pages; 1160 unsigned int pages;
1169 struct virtqueue **i, *vq = malloc(sizeof(*vq)); 1161 struct virtqueue **i, *vq = malloc(sizeof(*vq));
@@ -1249,7 +1241,7 @@ static void set_config(struct device *dev, unsigned len, const void *conf)
1249 * 1241 *
1250 * See what I mean about userspace being boring? */ 1242 * See what I mean about userspace being boring? */
1251static struct device *new_device(const char *name, u16 type, int fd, 1243static struct device *new_device(const char *name, u16 type, int fd,
1252 bool (*handle_input)(int, struct device *)) 1244 bool (*handle_input)(struct device *))
1253{ 1245{
1254 struct device *dev = malloc(sizeof(*dev)); 1246 struct device *dev = malloc(sizeof(*dev));
1255 1247
@@ -1678,7 +1670,7 @@ static int io_thread(void *_dev)
1678 1670
1679/* Now we've seen the I/O thread, we return to the Launcher to see what happens 1671/* Now we've seen the I/O thread, we return to the Launcher to see what happens
1680 * when that thread tells us it's completed some I/O. */ 1672 * when that thread tells us it's completed some I/O. */
1681static bool handle_io_finish(int fd, struct device *dev) 1673static bool handle_io_finish(struct device *dev)
1682{ 1674{
1683 char c; 1675 char c;
1684 1676
@@ -1688,12 +1680,12 @@ static bool handle_io_finish(int fd, struct device *dev)
1688 exit(1); 1680 exit(1);
1689 1681
1690 /* It did some work, so trigger the irq. */ 1682 /* It did some work, so trigger the irq. */
1691 trigger_irq(fd, dev->vq); 1683 trigger_irq(dev->vq);
1692 return true; 1684 return true;
1693} 1685}
1694 1686
1695/* When the Guest submits some I/O, we just need to wake the I/O thread. */ 1687/* When the Guest submits some I/O, we just need to wake the I/O thread. */
1696static void handle_virtblk_output(int fd, struct virtqueue *vq, bool timeout) 1688static void handle_virtblk_output(struct virtqueue *vq, bool timeout)
1697{ 1689{
1698 struct vblk_info *vblk = vq->dev->priv; 1690 struct vblk_info *vblk = vq->dev->priv;
1699 char c = 0; 1691 char c = 0;
@@ -1771,7 +1763,7 @@ static void setup_block_file(const char *filename)
1771 * console is the reverse. 1763 * console is the reverse.
1772 * 1764 *
1773 * The same logic applies, however. */ 1765 * The same logic applies, however. */
1774static bool handle_rng_input(int fd, struct device *dev) 1766static bool handle_rng_input(struct device *dev)
1775{ 1767{
1776 int len; 1768 int len;
1777 unsigned int head, in_num, out_num, totlen = 0; 1769 unsigned int head, in_num, out_num, totlen = 0;
@@ -1800,7 +1792,7 @@ static bool handle_rng_input(int fd, struct device *dev)
1800 } 1792 }
1801 1793
1802 /* Tell the Guest about the new input. */ 1794 /* Tell the Guest about the new input. */
1803 add_used_and_trigger(fd, dev->vq, head, totlen); 1795 add_used_and_trigger(dev->vq, head, totlen);
1804 1796
1805 /* Everything went OK! */ 1797 /* Everything went OK! */
1806 return true; 1798 return true;
@@ -1841,7 +1833,7 @@ static void __attribute__((noreturn)) restart_guest(void)
1841 1833
1842/*L:220 Finally we reach the core of the Launcher which runs the Guest, serves 1834/*L:220 Finally we reach the core of the Launcher which runs the Guest, serves
1843 * its input and output, and finally, lays it to rest. */ 1835 * its input and output, and finally, lays it to rest. */
1844static void __attribute__((noreturn)) run_guest(int lguest_fd) 1836static void __attribute__((noreturn)) run_guest(void)
1845{ 1837{
1846 for (;;) { 1838 for (;;) {
1847 unsigned long args[] = { LHREQ_BREAK, 0 }; 1839 unsigned long args[] = { LHREQ_BREAK, 0 };
@@ -1855,7 +1847,7 @@ static void __attribute__((noreturn)) run_guest(int lguest_fd)
1855 /* One unsigned long means the Guest did HCALL_NOTIFY */ 1847 /* One unsigned long means the Guest did HCALL_NOTIFY */
1856 if (readval == sizeof(notify_addr)) { 1848 if (readval == sizeof(notify_addr)) {
1857 verbose("Notify on address %#lx\n", notify_addr); 1849 verbose("Notify on address %#lx\n", notify_addr);
1858 handle_output(lguest_fd, notify_addr); 1850 handle_output(notify_addr);
1859 continue; 1851 continue;
1860 /* ENOENT means the Guest died. Reading tells us why. */ 1852 /* ENOENT means the Guest died. Reading tells us why. */
1861 } else if (errno == ENOENT) { 1853 } else if (errno == ENOENT) {
@@ -1875,7 +1867,7 @@ static void __attribute__((noreturn)) run_guest(int lguest_fd)
1875 continue; 1867 continue;
1876 1868
1877 /* Service input, then unset the BREAK to release the Waker. */ 1869 /* Service input, then unset the BREAK to release the Waker. */
1878 handle_input(lguest_fd); 1870 handle_input();
1879 if (pwrite(lguest_fd, args, sizeof(args), cpu_id) < 0) 1871 if (pwrite(lguest_fd, args, sizeof(args), cpu_id) < 0)
1880 err(1, "Resetting break"); 1872 err(1, "Resetting break");
1881 } 1873 }
@@ -1911,8 +1903,8 @@ int main(int argc, char *argv[])
1911 /* Memory, top-level pagetable, code startpoint and size of the 1903 /* Memory, top-level pagetable, code startpoint and size of the
1912 * (optional) initrd. */ 1904 * (optional) initrd. */
1913 unsigned long mem = 0, start, initrd_size = 0; 1905 unsigned long mem = 0, start, initrd_size = 0;
1914 /* Two temporaries and the /dev/lguest file descriptor. */ 1906 /* Two temporaries. */
1915 int i, c, lguest_fd; 1907 int i, c;
1916 /* The boot information for the Guest. */ 1908 /* The boot information for the Guest. */
1917 struct boot_params *boot; 1909 struct boot_params *boot;
1918 /* If they specify an initrd file to load. */ 1910 /* If they specify an initrd file to load. */
@@ -2030,15 +2022,15 @@ int main(int argc, char *argv[])
2030 2022
2031 /* We tell the kernel to initialize the Guest: this returns the open 2023 /* We tell the kernel to initialize the Guest: this returns the open
2032 * /dev/lguest file descriptor. */ 2024 * /dev/lguest file descriptor. */
2033 lguest_fd = tell_kernel(start); 2025 tell_kernel(start);
2034 2026
2035 /* We clone off a thread, which wakes the Launcher whenever one of the 2027 /* We clone off a thread, which wakes the Launcher whenever one of the
2036 * input file descriptors needs attention. We call this the Waker, and 2028 * input file descriptors needs attention. We call this the Waker, and
2037 * we'll cover it in a moment. */ 2029 * we'll cover it in a moment. */
2038 setup_waker(lguest_fd); 2030 setup_waker();
2039 2031
2040 /* Finally, run the Guest. This doesn't return. */ 2032 /* Finally, run the Guest. This doesn't return. */
2041 run_guest(lguest_fd); 2033 run_guest();
2042} 2034}
2043/*:*/ 2035/*:*/
2044 2036