diff options
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/lguest/lguest.c | 102 |
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. */ |
80 | struct { | 80 | struct { |
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. */ |
90 | static int timeoutpipe[2]; | 89 | static int timeoutpipe[2]; |
91 | static unsigned int timeout_usec = 500; | 90 | static unsigned int timeout_usec = 500; |
91 | /* The /dev/lguest file descriptor. */ | ||
92 | static 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 */ |
94 | static unsigned int __thread cpu_id; | 95 | static 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. */ |
512 | static int tell_kernel(unsigned long start) | 513 | static 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. */ |
592 | static void setup_waker(int lguest_fd) | 588 | static 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 */ |
730 | static void trigger_irq(int fd, struct virtqueue *vq) | 723 | static 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! */ |
745 | static void add_used_and_trigger(int fd, struct virtqueue *vq, | 738 | static 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). */ |
773 | static bool handle_console_input(int fd, struct device *dev) | 765 | static 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. */ |
842 | static void handle_console_output(int fd, struct virtqueue *vq, bool timeout) | 834 | static 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 | */ |
882 | static void handle_net_output(int fd, struct virtqueue *vq, bool timeout) | 874 | static 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. */ |
920 | static bool handle_tun_input(int fd, struct device *dev) | 912 | static 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. */ |
962 | static void enable_fd(int fd, struct virtqueue *vq, bool timeout) | 954 | static 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 | ||
969 | static void net_enable_fd(int fd, struct virtqueue *vq, bool timeout) | 961 | static 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. */ |
1014 | static void handle_output(int fd, unsigned long addr) | 1006 | static 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 | ||
1056 | static void handle_timeout(int fd) | 1048 | static 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. */ |
1081 | static void handle_input(int fd) | 1073 | static 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. */ |
1165 | static void add_virtqueue(struct device *dev, unsigned int num_descs, | 1157 | static 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? */ |
1251 | static struct device *new_device(const char *name, u16 type, int fd, | 1243 | static 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. */ |
1681 | static bool handle_io_finish(int fd, struct device *dev) | 1673 | static 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. */ |
1696 | static void handle_virtblk_output(int fd, struct virtqueue *vq, bool timeout) | 1688 | static 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. */ |
1774 | static bool handle_rng_input(int fd, struct device *dev) | 1766 | static 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. */ |
1844 | static void __attribute__((noreturn)) run_guest(int lguest_fd) | 1836 | static 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 | ||