aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/lguest/lguest.c107
1 files changed, 57 insertions, 50 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 7418f852e40c..cbf4becd2667 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -598,15 +598,17 @@ static void wake_parent(int pipefd, int lguest_fd)
598 select(devices.max_infd+1, &rfds, NULL, NULL, NULL); 598 select(devices.max_infd+1, &rfds, NULL, NULL, NULL);
599 /* Is it a message from the Launcher? */ 599 /* Is it a message from the Launcher? */
600 if (FD_ISSET(pipefd, &rfds)) { 600 if (FD_ISSET(pipefd, &rfds)) {
601 int ignorefd; 601 int fd;
602 /* If read() returns 0, it means the Launcher has 602 /* If read() returns 0, it means the Launcher has
603 * exited. We silently follow. */ 603 * exited. We silently follow. */
604 if (read(pipefd, &ignorefd, sizeof(ignorefd)) == 0) 604 if (read(pipefd, &fd, sizeof(fd)) == 0)
605 exit(0); 605 exit(0);
606 /* Otherwise it's telling us there's a problem with one 606 /* Otherwise it's telling us to change what file
607 * of the devices, and we should ignore that file 607 * descriptors we're to listen to. */
608 * descriptor from now on. */ 608 if (fd >= 0)
609 FD_CLR(ignorefd, &devices.infds); 609 FD_SET(fd, &devices.infds);
610 else
611 FD_CLR(-fd - 1, &devices.infds);
610 } else /* Send LHREQ_BREAK command. */ 612 } else /* Send LHREQ_BREAK command. */
611 write(lguest_fd, args, sizeof(args)); 613 write(lguest_fd, args, sizeof(args));
612 } 614 }
@@ -658,18 +660,6 @@ static void *_check_pointer(unsigned long addr, unsigned int size,
658/* A macro which transparently hands the line number to the real function. */ 660/* A macro which transparently hands the line number to the real function. */
659#define check_pointer(addr,size) _check_pointer(addr, size, __LINE__) 661#define check_pointer(addr,size) _check_pointer(addr, size, __LINE__)
660 662
661/* This simply sets up an iovec array where we can put data to be discarded.
662 * This happens when the Guest doesn't want or can't handle the input: we have
663 * to get rid of it somewhere, and if we bury it in the ceiling space it will
664 * start to smell after a week. */
665static void discard_iovec(struct iovec *iov, unsigned int *num)
666{
667 static char discard_buf[1024];
668 *num = 1;
669 iov->iov_base = discard_buf;
670 iov->iov_len = sizeof(discard_buf);
671}
672
673/* This function returns the next descriptor in the chain, or vq->vring.num. */ 663/* This function returns the next descriptor in the chain, or vq->vring.num. */
674static unsigned next_desc(struct virtqueue *vq, unsigned int i) 664static unsigned next_desc(struct virtqueue *vq, unsigned int i)
675{ 665{
@@ -812,12 +802,13 @@ static bool handle_console_input(int fd, struct device *dev)
812 802
813 /* First we need a console buffer from the Guests's input virtqueue. */ 803 /* First we need a console buffer from the Guests's input virtqueue. */
814 head = get_vq_desc(dev->vq, iov, &out_num, &in_num); 804 head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
815 if (head == dev->vq->vring.num) { 805
816 /* If they're not ready for input, we warn and set up to 806 /* If they're not ready for input, stop listening to this file
817 * discard. */ 807 * descriptor. We'll start again once they add an input buffer. */
818 warnx("console: no dma buffer!"); 808 if (head == dev->vq->vring.num)
819 discard_iovec(iov, &in_num); 809 return false;
820 } else if (out_num) 810
811 if (out_num)
821 errx(1, "Output buffers in console in queue?"); 812 errx(1, "Output buffers in console in queue?");
822 813
823 /* This is why we convert to iovecs: the readv() call uses them, and so 814 /* This is why we convert to iovecs: the readv() call uses them, and so
@@ -827,15 +818,16 @@ static bool handle_console_input(int fd, struct device *dev)
827 /* This implies that the console is closed, is /dev/null, or 818 /* This implies that the console is closed, is /dev/null, or
828 * something went terribly wrong. */ 819 * something went terribly wrong. */
829 warnx("Failed to get console input, ignoring console."); 820 warnx("Failed to get console input, ignoring console.");
830 /* Put the input terminal back and return failure (meaning, 821 /* Put the input terminal back. */
831 * don't call us again). */
832 restore_term(); 822 restore_term();
823 /* Remove callback from input vq, so it doesn't restart us. */
824 dev->vq->handle_output = NULL;
825 /* Stop listening to this fd: don't call us again. */
833 return false; 826 return false;
834 } 827 }
835 828
836 /* If we actually read the data into the Guest, tell them about it. */ 829 /* Tell the Guest about the new input. */
837 if (head != dev->vq->vring.num) 830 add_used_and_trigger(fd, dev->vq, head, len);
838 add_used_and_trigger(fd, dev->vq, head, len);
839 831
840 /* Three ^C within one second? Exit. 832 /* Three ^C within one second? Exit.
841 * 833 *
@@ -924,7 +916,8 @@ static bool handle_tun_input(int fd, struct device *dev)
924 /* FIXME: Actually want DRIVER_ACTIVE here. */ 916 /* FIXME: Actually want DRIVER_ACTIVE here. */
925 if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) 917 if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK)
926 warn("network: no dma buffer!"); 918 warn("network: no dma buffer!");
927 discard_iovec(iov, &in_num); 919 /* We'll turn this back on if input buffers are registered. */
920 return false;
928 } else if (out_num) 921 } else if (out_num)
929 errx(1, "Output buffers in network recv queue?"); 922 errx(1, "Output buffers in network recv queue?");
930 923
@@ -938,9 +931,8 @@ static bool handle_tun_input(int fd, struct device *dev)
938 if (len <= 0) 931 if (len <= 0)
939 err(1, "reading network"); 932 err(1, "reading network");
940 933
941 /* If we actually read the data into the Guest, tell them about it. */ 934 /* Tell the Guest about the new packet. */
942 if (head != dev->vq->vring.num) 935 add_used_and_trigger(fd, dev->vq, head, sizeof(*hdr) + len);
943 add_used_and_trigger(fd, dev->vq, head, sizeof(*hdr) + len);
944 936
945 verbose("tun input packet len %i [%02x %02x] (%s)\n", len, 937 verbose("tun input packet len %i [%02x %02x] (%s)\n", len,
946 ((u8 *)iov[1].iov_base)[0], ((u8 *)iov[1].iov_base)[1], 938 ((u8 *)iov[1].iov_base)[0], ((u8 *)iov[1].iov_base)[1],
@@ -950,6 +942,15 @@ static bool handle_tun_input(int fd, struct device *dev)
950 return true; 942 return true;
951} 943}
952 944
945/* This callback ensures we try again, in case we stopped console or net
946 * delivery because Guest didn't have any buffers. */
947static void enable_fd(int fd, struct virtqueue *vq)
948{
949 add_device_fd(vq->dev->fd);
950 /* Tell waker to listen to it again */
951 write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd));
952}
953
953/* This is the generic routine we call when the Guest uses LHCALL_NOTIFY. */ 954/* This is the generic routine we call when the Guest uses LHCALL_NOTIFY. */
954static void handle_output(int fd, unsigned long addr) 955static void handle_output(int fd, unsigned long addr)
955{ 956{
@@ -996,17 +997,22 @@ static void handle_input(int fd)
996 * file descriptors and a method of handling them. */ 997 * file descriptors and a method of handling them. */
997 for (i = devices.dev; i; i = i->next) { 998 for (i = devices.dev; i; i = i->next) {
998 if (i->handle_input && FD_ISSET(i->fd, &fds)) { 999 if (i->handle_input && FD_ISSET(i->fd, &fds)) {
1000 int dev_fd;
1001 if (i->handle_input(fd, i))
1002 continue;
1003
999 /* If handle_input() returns false, it means we 1004 /* If handle_input() returns false, it means we
1000 * should no longer service it. 1005 * should no longer service it. Networking and
1001 * handle_console_input() does this. */ 1006 * console do this when there's no input
1002 if (!i->handle_input(fd, i)) { 1007 * buffers to deliver into. Console also uses
1003 /* Clear it from the set of input file 1008 * it when it discovers that stdin is
1004 * descriptors kept at the head of the 1009 * closed. */
1005 * device list. */ 1010 FD_CLR(i->fd, &devices.infds);
1006 FD_CLR(i->fd, &devices.infds); 1011 /* Tell waker to ignore it too, by sending a
1007 /* Tell waker to ignore it too... */ 1012 * negative fd number (-1, since 0 is a valid
1008 write(waker_fd, &i->fd, sizeof(i->fd)); 1013 * FD number). */
1009 } 1014 dev_fd = -i->fd - 1;
1015 write(waker_fd, &dev_fd, sizeof(dev_fd));
1010 } 1016 }
1011 } 1017 }
1012 } 1018 }
@@ -1154,11 +1160,11 @@ static void setup_console(void)
1154 dev->priv = malloc(sizeof(struct console_abort)); 1160 dev->priv = malloc(sizeof(struct console_abort));
1155 ((struct console_abort *)dev->priv)->count = 0; 1161 ((struct console_abort *)dev->priv)->count = 0;
1156 1162
1157 /* The console needs two virtqueues: the input then the output. We 1163 /* The console needs two virtqueues: the input then the output. When
1158 * don't care when they refill the input queue, since we don't hold 1164 * they put something the input queue, we make sure we're listening to
1159 * data waiting for them. That's why the input queue's callback is 1165 * stdin. When they put something in the output queue, we write it to
1160 * NULL. */ 1166 * stdout. */
1161 add_virtqueue(dev, VIRTQUEUE_NUM, NULL); 1167 add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
1162 add_virtqueue(dev, VIRTQUEUE_NUM, handle_console_output); 1168 add_virtqueue(dev, VIRTQUEUE_NUM, handle_console_output);
1163 1169
1164 verbose("device %u: console\n", devices.device_num++); 1170 verbose("device %u: console\n", devices.device_num++);
@@ -1270,8 +1276,9 @@ static void setup_tun_net(const char *arg)
1270 /* First we create a new network device. */ 1276 /* First we create a new network device. */
1271 dev = new_device("net", VIRTIO_ID_NET, netfd, handle_tun_input); 1277 dev = new_device("net", VIRTIO_ID_NET, netfd, handle_tun_input);
1272 1278
1273 /* Network devices need a receive and a send queue. */ 1279 /* Network devices need a receive and a send queue, just like
1274 add_virtqueue(dev, VIRTQUEUE_NUM, NULL); 1280 * console. */
1281 add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
1275 add_virtqueue(dev, VIRTQUEUE_NUM, handle_net_output); 1282 add_virtqueue(dev, VIRTQUEUE_NUM, handle_net_output);
1276 1283
1277 /* We need a socket to perform the magic network ioctls to bring up the 1284 /* We need a socket to perform the magic network ioctls to bring up the