/*P:100 This is the Launcher code, a simple program which lays out the
 * "physical" memory for the new Guest by mapping the kernel image and the
 * virtual devices, then reads repeatedly from /dev/lguest to run the Guest.
:*/
#define _LARGEFILE64_SOURCE
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
#include <stdint.h>
#include <stdlib.h>
#include <elf.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdbool.h>
#include <errno.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <time.h>
#include <netinet/in.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <linux/if_tun.h>
#include <sys/uio.h>
#include <termios.h>
#include <getopt.h>
#include <zlib.h>
/*L:110 We can ignore the 28 include files we need for this program, but I do
 * want to draw attention to the use of kernel-style types.
 *
 * As Linus said, "C is a Spartan language, and so should your naming be."  I
 * like these abbreviations and the header we need uses them, so we define them
 * here.
 */
typedef unsigned long long u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
#include "linux/lguest_launcher.h"
#include "asm-x86/e820.h"
/*:*/

#define PAGE_PRESENT 0x7 	/* Present, RW, Execute */
#define NET_PEERNUM 1
#define BRIDGE_PFX "bridge:"
#ifndef SIOCBRADDIF
#define SIOCBRADDIF	0x89a2		/* add interface to bridge      */
#endif
/* We can have up to 256 pages for devices. */
#define DEVICE_PAGES 256

/*L:120 verbose is both a global flag and a macro.  The C preprocessor allows
 * this, and although I wouldn't recommend it, it works quite nicely here. */
static bool verbose;
#define verbose(args...) \
	do { if (verbose) printf(args); } while(0)
/*:*/

/* The pipe to send commands to the waker process */
static int waker_fd;
/* The pointer to the start of guest memory. */
static void *guest_base;
/* The maximum guest physical address allowed, and maximum possible. */
static unsigned long guest_limit, guest_max;

/* This is our list of devices. */
struct device_list
{
	/* Summary information about the devices in our list: ready to pass to
	 * select() to ask which need servicing.*/
	fd_set infds;
	int max_infd;

	/* The descriptor page for the devices. */
	struct lguest_device_desc *descs;

	/* A single linked list of devices. */
	struct device *dev;
	/* ... And an end pointer so we can easily append new devices */
	struct device **lastdev;
};

/* The device structure describes a single device. */
struct device
{
	/* The linked-list pointer. */
	struct device *next;
	/* The descriptor for this device, as mapped into the Guest. */
	struct lguest_device_desc *desc;
	/* The memory page(s) of this device, if any.  Also mapped in Guest. */
	void *mem;

	/* If handle_input is set, it wants to be called when this file
	 * descriptor is ready. */
	int fd;
	bool (*handle_input)(int fd, struct device *me);

	/* If handle_output is set, it wants to be called when the Guest sends
	 * DMA to this key. */
	unsigned long watch_key;
	u32 (*handle_output)(int fd, const struct iovec *iov,
			     unsigned int num, struct device *me);

	/* Device-specific data. */
	void *priv;
};

/*L:100 The Launcher code itself takes us out into userspace, that scary place
 * where pointers run wild and free!  Unfortunately, like most userspace
 * programs, it's quite boring (which is why everyone likes to hack on the
 * kernel!).  Perhaps if you make up an Lguest Drinking Game at this point, it
 * will get you through this section.  Or, maybe not.
 *
 * The Launcher sets up a big chunk of memory to be the Guest's "physical"
 * memory and stores it in "guest_base".  In other words, Guest physical ==
 * Launcher virtual with an offset.
 *
 * This can be tough to get your head around, but usually it just means that we
 * use these trivial conversion functions when the Guest gives us it's
 * "physical" addresses: */
static void *from_guest_phys(unsigned long addr)
{
	return guest_base + addr;
}

static unsigned long to_guest_phys(const void *addr)
{
	return (addr - guest_base);
}

/*L:130
 * Loading the Kernel.
 *
 * We start with couple of simple helper routines.  open_or_die() avoids
 * error-checking code cluttering the callers: */
static int open_or_die(const char *name, int flags)
{
	int fd = open(name, flags);
	if (fd < 0)
		err(1, "Failed to open %s", name);
	return fd;
}

/* map_zeroed_pages() takes a number of pages. */
static void *map_zeroed_pages(unsigned int num)
{
	int fd = open_or_die("/dev/zero", O_RDONLY);
	void *addr;

	/* We use a private mapping (ie. if we write to the page, it will be
	 * copied). */
	addr = mmap(NULL, getpagesize() * num,
		    PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0);
	if (addr == MAP_FAILED)
		err(1, "Mmaping %u pages of /dev/zero", num);

	return addr;
}

/* Get some more pages for a device. */
static void *get_pages(unsigned int num)
{
	void *addr = from_guest_phys(guest_limit);

	guest_limit += num * getpagesize();
	if (guest_limit > guest_max)
		errx(1, "Not enough memory for devices");
	return addr;
}

/* To find out where to start we look for the magic Guest string, which marks
 * the code we see in lguest_asm.S.  This is a hack which we are currently
 * plotting to replace with the normal Linux entry point. */
static unsigned long entry_point(const void *start, const void *end,
				 unsigned long page_offset)
{
	const void *p;

	/* The scan gives us the physical starting address.  We want the
	 * virtual address in this case, and fortunately, we already figured
	 * out the physical-virtual difference and passed it here in
	 * "page_offset". */
	for (p = start; p < end; p++)
		if (memcmp(p, "GenuineLguest", strlen("GenuineLguest")) == 0)
			return to_guest_phys(p + strlen("GenuineLguest"))
				+ page_offset;

	errx(1, "Is this image a genuine lguest?");
}

/* This routine is used to load the kernel or initrd.  It tries mmap, but if
 * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries),
 * it falls back to reading the memory in. */
static void map_at(int fd, void *addr, unsigned long offset, unsigned long len)
{
	ssize_t r;

	/* We map writable even though for some segments are marked read-only.
	 * The kernel really wants to be writable: it patches its own
	 * instructions.
	 *
	 * MAP_PRIVATE means that the page won't be copied until a write is
	 * done to it.  This allows us to share untouched memory between
	 * Guests. */
	if (mmap(addr, len, PROT_READ|PROT_WRITE|PROT_EXEC,
		 MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED)
		return;

	/* pread does a seek and a read in one shot: saves a few lines. */
	r = pread(fd, addr, len, offset);
	if (r != len)
		err(1, "Reading offset %lu len %lu gave %zi", offset, len, r);
}

/* This routine takes an open vmlinux image, which is in ELF, and maps it into
 * the Guest memory.  ELF = Embedded Linking Format, which is the format used
 * by all modern binaries on Linux including the kernel.
 *
 * The ELF headers give *two* addresses: a physical address, and a virtual
 * address.  The Guest kernel expects to be placed in memory at the physical
 * address, and the page tables set up so it will correspond to that virtual
 * address.  We return the difference between the virtual and physical
 * addresses in the "page_offset" pointer.
 *
 * We return the starting address. */
static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr,
			     unsigned long *page_offset)
{
	void *start = (void *)-1, *end = NULL;
	Elf32_Phdr phdr[ehdr->e_phnum];
	unsigned int i;

	/* Sanity checks on the main ELF header: an x86 executable with a
	 * reasonable number of correctly-sized program headers. */
	if (ehdr->e_type != ET_EXEC
	    || ehdr->e_machine != EM_386
	    || ehdr->e_phentsize != sizeof(Elf32_Phdr)
	    || ehdr->e_phnum < 1 || ehdr->e_phnum > 65536U/sizeof(Elf32_Phdr))
		errx(1, "Malformed elf header");

	/* An ELF executable contains an ELF header and a number of "program"
	 * headers which indicate which parts ("segments") of the program to
	 * load where. */

	/* We read in all the program headers at once: */
	if (lseek(elf_fd, ehdr->e_phoff, SEEK_SET) < 0)
		err(1, "Seeking to program headers");
	if (read(elf_fd, phdr, sizeof(phdr)) != sizeof(phdr))
		err(1, "Reading program headers");

	/* We don't know page_offset yet. */
	*page_offset = 0;

	/* Try all the headers: there are usually only three.  A read-only one,
	 * a read-write one, and a "note" section which isn't loadable. */
	for (i = 0; i < ehdr->e_phnum; i++) {
		/* If this isn't a loadable segment, we ignore it */
		if (phdr[i].p_type != PT_LOAD)
			continue;

		verbose("Section %i: size %i addr %p\n",
			i, phdr[i].p_memsz, (void *)phdr[i].p_paddr);

		/* We expect a simple linear address space: every segment must
		 * have the same difference between virtual (p_vaddr) and
		 * physical (p_paddr) address. */
		if (!*page_offset)
			*page_offset = phdr[i].p_vaddr - phdr[i].p_paddr;
		else if (*page_offset != phdr[i].p_vaddr - phdr[i].p_paddr)
			errx(1, "Page offset of section %i different", i);

		/* We track the first and last address we mapped, so we can
		 * tell entry_point() where to scan. */
		if (from_guest_phys(phdr[i].p_paddr) < start)
			start = from_guest_phys(phdr[i].p_paddr);
		if (from_guest_phys(phdr[i].p_paddr) + phdr[i].p_filesz > end)
			end=from_guest_phys(phdr[i].p_paddr)+phdr[i].p_filesz;

		/* We map this section of the file at its physical address. */
		map_at(elf_fd, from_guest_phys(phdr[i].p_paddr),
		       phdr[i].p_offset, phdr[i].p_filesz);
	}

	return entry_point(start, end, *page_offset);
}

/*L:170 Prepare to be SHOCKED and AMAZED.  And possibly a trifle nauseated.
 *
 * We know that CONFIG_PAGE_OFFSET sets what virtual address the kernel expects
 * to be.  We don't know what that option was, but we can figure it out
 * approximately by looking at the addresses in the code.  I chose the common
 * case of reading a memory location into the %eax register:
 *
 *  movl <some-address>, %eax
 *
 * This gets encoded as five bytes: "0xA1 <4-byte-address>".  For example,
 * "0xA1 0x18 0x60 0x47 0xC0" reads the address 0xC0476018 into %eax.
 *
 * In this example can guess that the kernel was compiled with
 * CONFIG_PAGE_OFFSET set to 0xC0000000 (it's always a round number).  If the
 * kernel were larger than 16MB, we might see 0xC1 addresses show up, but our
 * kernel isn't that bloated yet.
 *
 * Unfortunately, x86 has variable-length instructions, so finding this
 * particular instruction properly involves writing a disassembler.  Instead,
 * we rely on statistics.  We look for "0xA1" and tally the different bytes
 * which occur 4 bytes later (the "0xC0" in our example above).  When one of
 * those bytes appears three times, we can be reasonably confident that it
 * forms the start of CONFIG_PAGE_OFFSET.
 *
 * This is amazingly reliable. */
static unsigned long intuit_page_offset(unsigned char *img, unsigned long len)
{
	unsigned int i, possibilities[256] = { 0 };

	for (i = 0; i + 4 < len; i++) {
		/* mov 0xXXXXXXXX,%eax */
		if (img[i] == 0xA1 && ++possibilities[img[i+4]] > 3)
			return (unsigned long)img[i+4] << 24;
	}
	errx(1, "could not determine page offset");
}

/*L:160 Unfortunately the entire ELF image isn't compressed: the segments
 * which need loading are extracted and compressed raw.  This denies us the
 * information we need to make a fully-general loader. */
static unsigned long unpack_bzimage(int fd, unsigned long *page_offset)
{
	gzFile f;
	int ret, len = 0;
	/* A bzImage always gets loaded at physical address 1M.  This is
	 * actually configurable as CONFIG_PHYSICAL_START, but as the comment
	 * there says, "Don't change this unless you know what you are doing".
	 * Indeed. */
	void *img = from_guest_phys(0x100000);

	/* gzdopen takes our file descriptor (carefully placed at the start of
	 * the GZIP header we found) and returns a gzFile. */
	f = gzdopen(fd, "rb");
	/* We read it into memory in 64k chunks until we hit the end. */
	while ((ret = gzread(f, img + len, 65536)) > 0)
		len += ret;
	if (ret < 0)
		err(1, "reading image from bzImage");

	verbose("Unpacked size %i addr %p\n", len, img);

	/* Without the ELF header, we can't tell virtual-physical gap.  This is
	 * CONFIG_PAGE_OFFSET, and people do actually change it.  Fortunately,
	 * I have a clever way of figuring it out from the code itself.  */
	*page_offset = intuit_page_offset(img, len);

	return entry_point(img, img + len, *page_offset);
}

/*L:150 A bzImage, unlike an ELF file, is not meant to be loaded.  You're
 * supposed to jump into it and it will unpack itself.  We can't do that
 * because the Guest can't run the unpacking code, and adding features to
 * lguest kills puppies, so we don't want to.
 *
 * The bzImage is formed by putting the decompressing code in front of the
 * compressed kernel code.  So we can simple scan through it looking for the
 * first "gzip" header, and start decompressing from there. */
static unsigned long load_bzimage(int fd, unsigned long *page_offset)
{
	unsigned char c;
	int state = 0;

	/* GZIP header is 0x1F 0x8B <method> <flags>... <compressed-by>. */
	while (read(fd, &c, 1) == 1) {
		switch (state) {
		case 0:
			if (c == 0x1F)
				state++;
			break;
		case 1:
			if (c == 0x8B)
				state++;
			else
				state = 0;
			break;
		case 2 ... 8:
			state++;
			break;
		case 9:
			/* Seek back to the start of the gzip header. */
			lseek(fd, -10, SEEK_CUR);
			/* One final check: "compressed under UNIX". */
			if (c != 0x03)
				state = -1;
			else
				return unpack_bzimage(fd, page_offset);
		}
	}
	errx(1, "Could not find kernel in bzImage");
}

/*L:140 Loading the kernel is easy when it's a "vmlinux", but most kernels
 * come wrapped up in the self-decompressing "bzImage" format.  With some funky
 * coding, we can load those, too. */
static unsigned long load_kernel(int fd, unsigned long *page_offset)
{
	Elf32_Ehdr hdr;

	/* Read in the first few bytes. */
	if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
		err(1, "Reading kernel");

	/* If it's an ELF file, it starts with "\177ELF" */
	if (memcmp(hdr.e_ident, ELFMAG, SELFMAG) == 0)
		return map_elf(fd, &hdr, page_offset);

	/* Otherwise we assume it's a bzImage, and try to unpack it */
	return load_bzimage(fd, page_offset);
}

/* This is a trivial little helper to align pages.  Andi Kleen hated it because
 * it calls getpagesize() twice: "it's dumb code."
 *
 * Kernel guys get really het up about optimization, even when it's not
 * necessary.  I leave this code as a reaction against that. */
static inline unsigned long page_align(unsigned long addr)
{
	/* Add upwards and truncate downwards. */
	return ((addr + getpagesize()-1) & ~(getpagesize()-1));
}

/*L:180 An "initial ram disk" is a disk image loaded into memory along with
 * the kernel which the kernel can use to boot from without needing any
 * drivers.  Most distributions now use this as standard: the initrd contains
 * the code to load the appropriate driver modules for the current machine.
 *
 * Importantly, James Morris works for RedHat, and Fedora uses initrds for its
 * kernels.  He sent me this (and tells me when I break it). */
static unsigned long load_initrd(const char *name, unsigned long mem)
{
	int ifd;
	struct stat st;
	unsigned long len;

	ifd = open_or_die(name, O_RDONLY);
	/* fstat() is needed to get the file size. */
	if (fstat(ifd, &st) < 0)
		err(1, "fstat() on initrd '%s'", name);

	/* We map the initrd at the top of memory, but mmap wants it to be
	 * page-aligned, so we round the size up for that. */
	len = page_align(st.st_size);
	map_at(ifd, from_guest_phys(mem - len), 0, st.st_size);
	/* Once a file is mapped, you can close the file descriptor.  It's a
	 * little odd, but quite useful. */
	close(ifd);
	verbose("mapped initrd %s size=%lu @ %p\n", name, len, (void*)mem-len);

	/* We return the initrd size. */
	return len;
}

/* Once we know the address the Guest kernel expects, we can construct simple
 * linear page tables for all of memory which will get the Guest far enough
 * into the boot to create its own.
 *
 * We lay them out of the way, just below the initrd (which is why we need to
 * know its size). */
static unsigned long setup_pagetables(unsigned long mem,
				      unsigned long initrd_size,
				      unsigned long page_offset)
{
	unsigned long *pgdir, *linear;
	unsigned int mapped_pages, i, linear_pages;
	unsigned int ptes_per_page = getpagesize()/sizeof(void *);

	/* Ideally we map all physical memory starting at page_offset.
	 * However, if page_offset is 0xC0000000 we can only map 1G of physical
	 * (0xC0000000 + 1G overflows). */
	if (mem <= -page_offset)
		mapped_pages = mem/getpagesize();
	else
		mapped_pages = -page_offset/getpagesize();

	/* Each PTE page can map ptes_per_page pages: how many do we need? */
	linear_pages = (mapped_pages + ptes_per_page-1)/ptes_per_page;

	/* We put the toplevel page directory page at the top of memory. */
	pgdir = from_guest_phys(mem) - initrd_size - getpagesize();

	/* Now we use the next linear_pages pages as pte pages */
	linear = (void *)pgdir - linear_pages*getpagesize();

	/* Linear mapping is easy: put every page's address into the mapping in
	 * order.  PAGE_PRESENT contains the flags Present, Writable and
	 * Executable. */
	for (i = 0; i < mapped_pages; i++)
		linear[i] = ((i * getpagesize()) | PAGE_PRESENT);

	/* The top level points to the linear page table pages above.  The
	 * entry representing page_offset points to the first one, and they
	 * continue from there. */
	for (i = 0; i < mapped_pages; i += ptes_per_page) {
		pgdir[(i + page_offset/getpagesize())/ptes_per_page]
			= ((to_guest_phys(linear) + i*sizeof(void *))
			   | PAGE_PRESENT);
	}

	verbose("Linear mapping of %u pages in %u pte pages at %#lx\n",
		mapped_pages, linear_pages, to_guest_phys(linear));

	/* We return the top level (guest-physical) address: the kernel needs
	 * to know where it is. */
	return to_guest_phys(pgdir);
}

/* Simple routine to roll all the commandline arguments together with spaces
 * between them. */
static void concat(char *dst, char *args[])
{
	unsigned int i, len = 0;

	for (i = 0; args[i]; i++) {
		strcpy(dst+len, args[i]);
		strcat(dst+len, " ");
		len += strlen(args[i]) + 1;
	}
	/* In case it's empty. */
	dst[len] = '\0';
}

/* This is where we actually tell the kernel to initialize the Guest.  We saw
 * the arguments it expects when we looked at initialize() in lguest_user.c:
 * the base of guest "physical" memory, the top physical page to allow, the
 * top level pagetable, the entry point and the page_offset constant for the
 * Guest. */
static int tell_kernel(unsigned long pgdir, unsigned long start,
		       unsigned long page_offset)
{
	unsigned long args[] = { LHREQ_INITIALIZE,
				 (unsigned long)guest_base,
				 guest_limit / getpagesize(),
				 pgdir, start, page_offset };
	int fd;

	verbose("Guest: %p - %p (%#lx)\n",
		guest_base, guest_base + guest_limit, guest_limit);
	fd = open_or_die("/dev/lguest", O_RDWR);
	if (write(fd, args, sizeof(args)) < 0)
		err(1, "Writing to /dev/lguest");

	/* We return the /dev/lguest file descriptor to control this Guest */
	return fd;
}
/*:*/

static void set_fd(int fd, struct device_list *devices)
{
	FD_SET(fd, &devices->infds);
	if (fd > devices->max_infd)
		devices->max_infd = fd;
}

/*L:200
 * The Waker.
 *
 * With a console and network devices, we can have lots of input which we need
 * to process.  We could try to tell the kernel what file descriptors to watch,
 * but handing a file descriptor mask through to the kernel is fairly icky.
 *
 * Instead, we fork off a process which watches the file descriptors and writes
 * the LHREQ_BREAK command to the /dev/lguest filedescriptor to tell the Host
 * loop to stop running the Guest.  This causes it to return from the
 * /dev/lguest read with -EAGAIN, where it will write to /dev/lguest to reset
 * the LHREQ_BREAK and wake us up again.
 *
 * This, of course, is merely a different *kind* of icky.
 */
static void wake_parent(int pipefd, int lguest_fd, struct device_list *devices)
{
	/* Add the pipe from the Launcher to the fdset in the device_list, so
	 * we watch it, too. */
	set_fd(pipefd, devices);

	for (;;) {
		fd_set rfds = devices->infds;
		unsigned long args[] = { LHREQ_BREAK, 1 };

		/* Wait until input is ready from one of the devices. */
		select(devices->max_infd+1, &rfds, NULL, NULL, NULL);
		/* Is it a message from the Launcher? */
		if (FD_ISSET(pipefd, &rfds)) {
			int ignorefd;
			/* If read() returns 0, it means the Launcher has
			 * exited.  We silently follow. */
			if (read(pipefd, &ignorefd, sizeof(ignorefd)) == 0)
				exit(0);
			/* Otherwise it's telling us there's a problem with one
			 * of the devices, and we should ignore that file
			 * descriptor from now on. */
			FD_CLR(ignorefd, &devices->infds);
		} else /* Send LHREQ_BREAK command. */
			write(lguest_fd, args, sizeof(args));
	}
}

/* This routine just sets up a pipe to the Waker process. */
static int setup_waker(int lguest_fd, struct device_list *device_list)
{
	int pipefd[2], child;

	/* We create a pipe to talk to the waker, and also so it knows when the
	 * Launcher dies (and closes pipe). */
	pipe(pipefd);
	child = fork();
	if (child == -1)
		err(1, "forking");

	if (child == 0) {
		/* Close the "writing" end of our copy of the pipe */
		close(pipefd[1]);
		wake_parent(pipefd[0], lguest_fd, device_list);
	}
	/* Close the reading end of our copy of the pipe. */
	close(pipefd[0]);

	/* Here is the fd used to talk to the waker. */
	return pipefd[1];
}

/*L:210
 * Device Handling.
 *
 * When the Guest sends DMA to us, it sends us an array of addresses and sizes.
 * We need to make sure it's not trying to reach into the Launcher itself, so
 * we have a convenient routine which check it and exits with an error message
 * if something funny is going on:
 */
static void *_check_pointer(unsigned long addr, unsigned int size,
			    unsigned int line)
{
	/* We have to separately check addr and addr+size, because size could
	 * be huge and addr + size might wrap around. */
	if (addr >= guest_limit || addr + size >= guest_limit)
		errx(1, "%s:%i: Invalid address %li", __FILE__, line, addr);
	/* We return a pointer for the caller's convenience, now we know it's
	 * safe to use. */
	return from_guest_phys(addr);
}
/* A macro which transparently hands the line number to the real function. */
#define check_pointer(addr,size) _check_pointer(addr, size, __LINE__)

/* The Guest has given us the address of a "struct lguest_dma".  We check it's
 * OK and convert it to an iovec (which is a simple array of ptr/size
 * pairs). */
static u32 *dma2iov(unsigned long dma, struct iovec iov[], unsigned *num)
{
	unsigned int i;
	struct lguest_dma *udma;

	/* First we make sure that the array memory itself is valid. */
	udma = check_pointer(dma, sizeof(*udma));
	/* Now we check each element */
	for (i = 0; i < LGUEST_MAX_DMA_SECTIONS; i++) {
		/* A zero length ends the array. */
		if (!udma->len[i])
			break;

		iov[i].iov_base = check_pointer(udma->addr[i], udma->len[i]);
		iov[i].iov_len = udma->len[i];
	}
	*num = i;

	/* We return the pointer to where the caller should write the amount of
	 * the buffer used. */
	return &udma->used_len;
}

/* This routine gets a DMA buffer from the Guest for a given key, and converts
 * it to an iovec array.  It returns the interrupt the Guest wants when we're
 * finished, and a pointer to the "used_len" field to fill in. */
static u32 *get_dma_buffer(int fd, void *key,
			   struct iovec iov[], unsigned int *num, u32 *irq)
{
	unsigned long buf[] = { LHREQ_GETDMA, to_guest_phys(key) };
	unsigned long udma;
	u32 *res;

	/* Ask the kernel for a DMA buffer corresponding to this key. */
	udma = write(fd, buf, sizeof(buf));
	/* They haven't registered any, or they're all used? */
	if (udma == (unsigned long)-1)
		return NULL;

	/* Convert it into our iovec array */
	res = dma2iov(udma, iov, num);
	/* The kernel stashes irq in ->used_len to get it out to us. */
	*irq = *res;
	/* Return a pointer to ((struct lguest_dma *)udma)->used_len. */
	return res;
}

/* This is a convenient routine to send the Guest an interrupt. */
static void trigger_irq(int fd, u32 irq)
{
	unsigned long buf[] = { LHREQ_IRQ, irq };
	if (write(fd, buf, sizeof(buf)) != 0)
		err(1, "Triggering irq %i", irq);
}

/* This simply sets up an iovec array where we can put data to be discarded.
 * This happens when the Guest doesn't want or can't handle the input: we have
 * to get rid of it somewhere, and if we bury it in the ceiling space it will
 * start to smell after a week. */
static void discard_iovec(struct iovec *iov, unsigned int *num)
{
	static char discard_buf[1024];
	*num = 1;
	iov->iov_base = discard_buf;
	iov->iov_len = sizeof(discard_buf);
}

/* Here is the input terminal setting we save, and the routine to restore them
 * on exit so the user can see what they type next. */
static struct termios orig_term;
static void restore_term(void)
{
	tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
}

/* We associate some data with the console for our exit hack. */
struct console_abort
{
	/* How many times have they hit ^C? */
	int count;
	/* When did they start? */
	struct timeval start;
};

/* This is the routine which handles console input (ie. stdin). */
static bool handle_console_input(int fd, struct device *dev)
{
	u32 irq = 0, *lenp;
	int len;
	unsigned int num;
	struct iovec iov[LGUEST_MAX_DMA_SECTIONS];
	struct console_abort *abort = dev->priv;

	/* First we get the console buffer from the Guest.  The key is dev->mem
	 * which was set to 0 in setup_console(). */
	lenp = get_dma_buffer(fd, dev->mem, iov, &num, &irq);
	if (!lenp) {
		/* If it's not ready for input, warn and set up to discard. */
		warn("console: no dma buffer!");
		discard_iovec(iov, &num);
	}

	/* This is why we convert to iovecs: the readv() call uses them, and so
	 * it reads straight into the Guest's buffer. */
	len = readv(dev->fd, iov, num);
	if (len <= 0) {
		/* This implies that the console is closed, is /dev/null, or
		 * something went terribly wrong.  We still go through the rest
		 * of the logic, though, especially the exit handling below. */
		warnx("Failed to get console input, ignoring console.");
		len = 0;
	}

	/* If we read the data into the Guest, fill in the length and send the
	 * interrupt. */
	if (lenp) {
		*lenp = len;
		trigger_irq(fd, irq);
	}

	/* Three ^C within one second?  Exit.
	 *
	 * This is such a hack, but works surprisingly well.  Each ^C has to be
	 * in a buffer by itself, so they can't be too fast.  But we check that
	 * we get three within about a second, so they can't be too slow. */
	if (len == 1 && ((char *)iov[0].iov_base)[0] == 3) {
		if (!abort->count++)
			gettimeofday(&abort->start, NULL);
		else if (abort->count == 3) {
			struct timeval now;
			gettimeofday(&now, NULL);
			if (now.tv_sec <= abort->start.tv_sec+1) {
				unsigned long args[] = { LHREQ_BREAK, 0 };
				/* Close the fd so Waker will know it has to
				 * exit. */
				close(waker_fd);
				/* Just in case waker is blocked in BREAK, send
				 * unbreak now. */
				write(fd, args, sizeof(args));
				exit(2);
			}
			abort->count = 0;
		}
	} else
		/* Any other key resets the abort counter. */
		abort->count = 0;

	/* Now, if we didn't read anything, put the input terminal back and
	 * return failure (meaning, don't call us again). */
	if (!len) {
		restore_term();
		return false;
	}
	/* Everything went OK! */
	return true;
}

/* Handling console output is much simpler than input. */
static u32 handle_console_output(int fd, const struct iovec *iov,
				 unsigned num, struct device*dev)
{
	/* Whatever the Guest sends, write it to standard output.  Return the
	 * number of bytes written. */
	return writev(STDOUT_FILENO, iov, num);
}

/* Guest->Host network output is also pretty easy. */
static u32 handle_tun_output(int fd, const struct iovec *iov,
			     unsigned num, struct device *dev)
{
	/* We put a flag in the "priv" pointer of the network device, and set
	 * it as soon as we see output.  We'll see why in handle_tun_input() */
	*(bool *)dev->priv = true;
	/* Whatever packet the Guest sent us, write it out to the tun
	 * device. */
	return writev(dev->fd, iov, num);
}

/* This matches the peer_key() in lguest_net.c.  The key for any given slot
 * is the address of the network device's page plus 4 * the slot number. */
static unsigned long peer_offset(unsigned int peernum)
{
	return 4 * peernum;
}

/* This is where we handle a packet coming in from the tun device */
static bool handle_tun_input(int fd, struct device *dev)
{
	u32 irq = 0, *lenp;
	int len;
	unsigned num;
	struct iovec iov[LGUEST_MAX_DMA_SECTIONS];

	/* First we get a buffer the Guest has bound to its key. */
	lenp = get_dma_buffer(fd, dev->mem+peer_offset(NET_PEERNUM), iov, &num,
			      &irq);
	if (!lenp) {
		/* Now, it's expected that if we try to send a packet too
		 * early, the Guest won't be ready yet.  This is why we set a
		 * flag when the Guest sends its first packet.  If it's sent a
		 * packet we assume it should be ready to receive them.
		 *
		 * Actually, this is what the status bits in the descriptor are
		 * for: we should *use* them.  FIXME! */
		if (*(bool *)dev->priv)
			warn("network: no dma buffer!");
		discard_iovec(iov, &num);
	}

	/* Read the packet from the device directly into the Guest's buffer. */
	len = readv(dev->fd, iov, num);
	if (len <= 0)
		err(1, "reading network");

	/* Write the used_len, and trigger the interrupt for the Guest */
	if (lenp) {
		*lenp = len;
		trigger_irq(fd, irq);
	}
	verbose("tun input packet len %i [%02x %02x] (%s)\n", len,
		((u8 *)iov[0].iov_base)[0], ((u8 *)iov[0].iov_base)[1],
		lenp ? "sent" : "discarded");
	/* All good. */
	return true;
}

/* The last device handling routine is block output: the Guest has sent a DMA
 * to the block device.  It will have placed the command it wants in the
 * "struct lguest_block_page". */
static u32 handle_block_output(int fd, const struct iovec *iov,
			       unsigned num, struct device *dev)
{
	struct lguest_block_page *p = dev->mem;
	u32 irq, *lenp;
	unsigned int len, reply_num;
	struct iovec reply[LGUEST_MAX_DMA_SECTIONS];
	off64_t device_len, off = (off64_t)p->sector * 512;

	/* First we extract the device length from the dev->priv pointer. */
	device_len = *(off64_t *)dev->priv;

	/* We first check that the read or write is within the length of the
	 * block file. */
	if (off >= device_len)
		errx(1, "Bad offset %llu vs %llu", off, device_len);
	/* Move to the right location in the block file.  This shouldn't fail,
	 * but best to check. */
	if (lseek64(dev->fd, off, SEEK_SET) != off)
		err(1, "Bad seek to sector %i", p->sector);

	verbose("Block: %s at offset %llu\n", p->type ? "WRITE" : "READ", off);

	/* They were supposed to bind a reply buffer at key equal to the start
	 * of the block device memory.  We need this to tell them when the
	 * request is finished. */
	lenp = get_dma_buffer(fd, dev->mem, reply, &reply_num, &irq);
	if (!lenp)
		err(1, "Block request didn't give us a dma buffer");

	if (p->type) {
		/* A write request.  The DMA they sent contained the data, so
		 * write it out. */
		len = writev(dev->fd, iov, num);
		/* Grr... Now we know how long the "struct lguest_dma" they
		 * sent was, we make sure they didn't try to write over the end
		 * of the block file (possibly extending it). */
		if (off + len > device_len) {
			/* Trim it back to the correct length */
			ftruncate64(dev->fd, device_len);
			/* Die, bad Guest, die. */
			errx(1, "Write past end %llu+%u", off, len);
		}
		/* The reply length is 0: we just send back an empty DMA to
		 * interrupt them and tell them the write is finished. */
		*lenp = 0;
	} else {
		/* A read request.  They sent an empty DMA to start the
		 * request, and we put the read contents into the reply
		 * buffer. */
		len = readv(dev->fd, reply, reply_num);
		*lenp = len;
	}

	/* The result is 1 (done), 2 if there was an error (short read or
	 * write). */
	p->result = 1 + (p->bytes != len);
	/* Now tell them we've used their reply buffer. */
	trigger_irq(fd, irq);

	/* We're supposed to return the number of bytes of the output buffer we
	 * used.  But the block device uses the "result" field instead, so we
	 * don't bother. */
	return 0;
}

/* This is the generic routine we call when the Guest sends some DMA out. */
static void handle_output(int fd, unsigned long dma, unsigned long key,
			  struct device_list *devices)
{
	struct device *i;
	u32 *lenp;
	struct iovec iov[LGUEST_MAX_DMA_SECTIONS];
	unsigned num = 0;

	/* Convert the "struct lguest_dma" they're sending to a "struct
	 * iovec". */
	lenp = dma2iov(dma, iov, &num);

	/* Check each device: if they expect output to this key, tell them to
	 * handle it. */
	for (i = devices->dev; i; i = i->next) {
		if (i->handle_output && key == i->watch_key) {
			/* We write the result straight into the used_len field
			 * for them. */
			*lenp = i->handle_output(fd, iov, num, i);
			return;
		}
	}

	/* This can happen: the kernel sends any SEND_DMA which doesn't match
	 * another Guest to us.  It could be that another Guest just left a
	 * network, for example.  But it's unusual. */
	warnx("Pending dma %p, key %p", (void *)dma, (void *)key);
}

/* This is called when the waker wakes us up: check for incoming file
 * descriptors. */
static void handle_input(int fd, struct device_list *devices)
{
	/* select() wants a zeroed timeval to mean "don't wait". */
	struct timeval poll = { .tv_sec = 0, .tv_usec = 0 };

	for (;;) {
		struct device *i;
		fd_set fds = devices->infds;

		/* If nothing is ready, we're done. */
		if (select(devices->max_infd+1, &fds, NULL, NULL, &poll) == 0)
			break;

		/* Otherwise, call the device(s) which have readable
		 * file descriptors and a method of handling them.  */
		for (i = devices->dev; i; i = i->next) {
			if (i->handle_input && FD_ISSET(i->fd, &fds)) {
				/* If handle_input() returns false, it means we
				 * should no longer service it.
				 * handle_console_input() does this. */
				if (!i->handle_input(fd, i)) {
					/* Clear it from the set of input file
					 * descriptors kept at the head of the
					 * device list. */
					FD_CLR(i->fd, &devices->infds);
					/* Tell waker to ignore it too... */
					write(waker_fd, &i->fd, sizeof(i->fd));
				}
			}
		}
	}
}

/*L:190
 * Device Setup
 *
 * All devices need a descriptor so the Guest knows it exists, and a "struct
 * device" so the Launcher can keep track of it.  We have common helper
 * routines to allocate them.
 *
 * This routine allocates a new "struct lguest_device_desc" from descriptor
 * table in the devices array just above the Guest's normal memory. */
static struct lguest_device_desc *
new_dev_desc(struct lguest_device_desc *descs,
	     u16 type, u16 features, u16 num_pages)
{
	unsigned int i;

	for (i = 0; i < LGUEST_MAX_DEVICES; i++) {
		if (!descs[i].type) {
			descs[i].type = type;
			descs[i].features = features;
			descs[i].num_pages = num_pages;
			/* If they said the device needs memory, we allocate
			 * that now. */
			if (num_pages) {
				unsigned long pa;
				pa = to_guest_phys(get_pages(num_pages));
				descs[i].pfn = pa / getpagesize();
			}
			return &descs[i];
		}
	}
	errx(1, "too many devices");
}

/* This monster routine does all the creation and setup of a new device,
 * including caling new_dev_desc() to allocate the descriptor and device
 * memory. */
static struct device *new_device(struct device_list *devices,
				 u16 type, u16 num_pages, u16 features,
				 int fd,
				 bool (*handle_input)(int, struct device *),
				 unsigned long watch_off,
				 u32 (*handle_output)(int,
						      const struct iovec *,
						      unsigned,
						      struct device *))
{
	struct device *dev = malloc(sizeof(*dev));

	/* Append to device list.  Prepending to a single-linked list is
	 * easier, but the user expects the devices to be arranged on the bus
	 * in command-line order.  The first network device on the command line
	 * is eth0, the first block device /dev/lgba, etc. */
	*devices->lastdev = dev;
	dev->next = NULL;
	devices->lastdev = &dev->next;

	/* Now we populate the fields one at a time. */
	dev->fd = fd;
	/* If we have an input handler for this file descriptor, then we add it
	 * to the device_list's fdset and maxfd. */
	if (handle_input)
		set_fd(dev->fd, devices);
	dev->desc = new_dev_desc(devices->descs, type, features, num_pages);
	dev->mem = from_guest_phys(dev->desc->pfn * getpagesize());
	dev->handle_input = handle_input;
	dev->watch_key = to_guest_phys(dev->mem) + watch_off;
	dev->handle_output = handle_output;
	return dev;
}

/* Our first setup routine is the console.  It's a fairly simple device, but
 * UNIX tty handling makes it uglier than it could be. */
static void setup_console(struct device_list *devices)
{
	struct device *dev;

	/* If we can save the initial standard input settings... */
	if (tcgetattr(STDIN_FILENO, &orig_term) == 0) {
		struct termios term = orig_term;
		/* Then we turn off echo, line buffering and ^C etc.  We want a
		 * raw input stream to the Guest. */
		term.c_lflag &= ~(ISIG|ICANON|ECHO);
		tcsetattr(STDIN_FILENO, TCSANOW, &term);
		/* If we exit gracefully, the original settings will be
		 * restored so the user can see what they're typing. */
		atexit(restore_term);
	}

	/* We don't currently require any memory for the console, so we ask for
	 * 0 pages. */
	dev = new_device(devices, LGUEST_DEVICE_T_CONSOLE, 0, 0,
			 STDIN_FILENO, handle_console_input,
			 LGUEST_CONSOLE_DMA_KEY, handle_console_output);
	/* We store the console state in dev->priv, and initialize it. */
	dev->priv = malloc(sizeof(struct console_abort));
	((struct console_abort *)dev->priv)->count = 0;
	verbose("device %p: console\n",
		(void *)(dev->desc->pfn * getpagesize()));
}

/* Setting up a block file is also fairly straightforward. */
static void setup_block_file(const char *filename, struct device_list *devices)
{
	int fd;
	struct device *dev;
	off64_t *device_len;
	struct lguest_block_page *p;

	/* We open with O_LARGEFILE because otherwise we get stuck at 2G.  We
	 * open with O_DIRECT because otherwise our benchmarks go much too
	 * fast. */
	fd = open_or_die(filename, O_RDWR|O_LARGEFILE|O_DIRECT);

	/* We want one page, and have no input handler (the block file never
	 * has anything interesting to say to us).  Our timing will be quite
	 * random, so it should be a reasonable randomness source. */
	dev = new_device(devices, LGUEST_DEVICE_T_BLOCK, 1,
			 LGUEST_DEVICE_F_RANDOMNESS,
			 fd, NULL, 0, handle_block_output);

	/* We store the device size in the private area */
	device_len = dev->priv = malloc(sizeof(*device_len));
	/* This is the safe way of establishing the size of our device: it
	 * might be a normal file or an actual block device like /dev/hdb. */
	*device_len = lseek64(fd, 0, SEEK_END);

	/* The device memory is a "struct lguest_block_page".  It's zeroed
	 * already, we just need to put in the device size.  Block devices
	 * think in sectors (ie. 512 byte chunks), so we translate here. */
	p = dev->mem;
	p->num_sectors = *device_len/512;
	verbose("device %p: block %i sectors\n",
		(void *)(dev->desc->pfn * getpagesize()), p->num_sectors);
}

/*
 * Network Devices.
 *
 * Setting up network devices is quite a pain, because we have three types.
 * First, we have the inter-Guest network.  This is a file which is mapped into
 * the address space of the Guests who are on the network.  Because it is a
 * shared mapping, the same page underlies all the devices, and they can send
 * DMA to each other.
 *
 * Remember from our network driver, the Guest is told what slot in the page it
 * is to use.  We use exclusive fnctl locks to reserve a slot.  If another
 * Guest is using a slot, the lock will fail and we try another.  Because fnctl
 * locks are cleaned up automatically when we die, this cleverly means that our
 * reservation on the slot will vanish if we crash. */
static unsigned int find_slot(int netfd, const char *filename)
{
	struct flock fl;

	fl.l_type = F_WRLCK;
	fl.l_whence = SEEK_SET;
	fl.l_len = 1;
	/* Try a 1 byte lock in each possible position number */
	for (fl.l_start = 0;
	     fl.l_start < getpagesize()/sizeof(struct lguest_net);
	     fl.l_start++) {
		/* If we succeed, return the slot number. */
		if (fcntl(netfd, F_SETLK, &fl) == 0)
			return fl.l_start;
	}
	errx(1, "No free slots in network file %s", filename);
}

/* This function sets up the network file */
static void setup_net_file(const char *filename,
			   struct device_list *devices)
{
	int netfd;
	struct device *dev;

	/* We don't use open_or_die() here: for friendliness we create the file
	 * if it doesn't already exist. */
	netfd = open(filename, O_RDWR, 0);
	if (netfd < 0) {
		if (errno == ENOENT) {
			netfd = open(filename, O_RDWR|O_CREAT, 0600);
			if (netfd >= 0) {
				/* If we succeeded, initialize the file with a
				 * blank page. */
				char page[getpagesize()];
				memset(page, 0, sizeof(page));
				write(netfd, page, sizeof(page));
			}
		}
		if (netfd < 0)
			err(1, "cannot open net file '%s'", filename);
	}

	/* We need 1 page, and the features indicate the slot to use and that
	 * no checksum is needed.  We never touch this device again; it's
	 * between the Guests on the network, so we don't register input or
	 * output handlers. */
	dev = new_device(devices, LGUEST_DEVICE_T_NET, 1,
			 find_slot(netfd, filename)|LGUEST_NET_F_NOCSUM,
			 -1, NULL, 0, NULL);

	/* Map the shared file. */
	if (mmap(dev->mem, getpagesize(), PROT_READ|PROT_WRITE,
			 MAP_FIXED|MAP_SHARED, netfd, 0) != dev->mem)
			err(1, "could not mmap '%s'", filename);
	verbose("device %p: shared net %s, peer %i\n",
		(void *)(dev->desc->pfn * getpagesize()), filename,
		dev->desc->features & ~LGUEST_NET_F_NOCSUM);
}
/*:*/

static u32 str2ip(const char *ipaddr)
{
	unsigned int byte[4];

	sscanf(ipaddr, "%u.%u.%u.%u", &byte[0], &byte[1], &byte[2], &byte[3]);
	return (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | byte[3];
}

/* This code is "adapted" from libbridge: it attaches the Host end of the
 * network device to the bridge device specified by the command line.
 *
 * This is yet another James Morris contribution (I'm an IP-level guy, so I
 * dislike bridging), and I just try not to break it. */
static void add_to_bridge(int fd, const char *if_name, const char *br_name)
{
	int ifidx;
	struct ifreq ifr;

	if (!*br_name)
		errx(1, "must specify bridge name");

	ifidx = if_nametoindex(if_name);
	if (!ifidx)
		errx(1, "interface %s does not exist!", if_name);

	strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
	ifr.ifr_ifindex = ifidx;
	if (ioctl(fd, SIOCBRADDIF, &ifr) < 0)
		err(1, "can't add %s to bridge %s", if_name, br_name);
}

/* This sets up the Host end of the network device with an IP address, brings
 * it up so packets will flow, the copies the MAC address into the hwaddr
 * pointer (in practice, the Host's slot in the network device's memory). */
static void configure_device(int fd, const char *devname, u32 ipaddr,
			     unsigned char hwaddr[6])
{
	struct ifreq ifr;
	struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;

	/* Don't read these incantations.  Just cut & paste them like I did! */
	memset(&ifr, 0, sizeof(ifr));
	strcpy(ifr.ifr_name, devname);
	sin->sin_family = AF_INET;
	sin->sin_addr.s_addr = htonl(ipaddr);
	if (ioctl(fd, SIOCSIFADDR, &ifr) != 0)
		err(1, "Setting %s interface address", devname);
	ifr.ifr_flags = IFF_UP;
	if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0)
		err(1, "Bringing interface %s up", devname);

	/* SIOC stands for Socket I/O Control.  G means Get (vs S for Set
	 * above).  IF means Interface, and HWADDR is hardware address.
	 * Simple! */
	if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0)
		err(1, "getting hw address for %s", devname);
	memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6);
}

/*L:195 The other kind of network is a Host<->Guest network.  This can either
 * use briding or routing, but the principle is the same: it uses the "tun"
 * device to inject packets into the Host as if they came in from a normal
 * network card.  We just shunt packets between the Guest and the tun
 * device. */
static void setup_tun_net(const char *arg, struct device_list *devices)
{
	struct device *dev;
	struct ifreq ifr;
	int netfd, ipfd;
	u32 ip;
	const char *br_name = NULL;

	/* We open the /dev/net/tun device and tell it we want a tap device.  A
	 * tap device is like a tun device, only somehow different.  To tell
	 * the truth, I completely blundered my way through this code, but it
	 * works now! */
	netfd = open_or_die("/dev/net/tun", O_RDWR);
	memset(&ifr, 0, sizeof(ifr));
	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
	strcpy(ifr.ifr_name, "tap%d");
	if (ioctl(netfd, TUNSETIFF, &ifr) != 0)
		err(1, "configuring /dev/net/tun");
	/* We don't need checksums calculated for packets coming in this
	 * device: trust us! */
	ioctl(netfd, TUNSETNOCSUM, 1);

	/* We create the net device with 1 page, using the features field of
	 * the descriptor to tell the Guest it is in slot 1 (NET_PEERNUM), and
	 * that the device has fairly random timing.  We do *not* specify
	 * LGUEST_NET_F_NOCSUM: these packets can reach the real world.
	 *
	 * We will put our MAC address is slot 0 for the Guest to see, so
	 * it will send packets to us using the key "peer_offset(0)": */
	dev = new_device(devices, LGUEST_DEVICE_T_NET, 1,
			 NET_PEERNUM|LGUEST_DEVICE_F_RANDOMNESS, netfd,
			 handle_tun_input, peer_offset(0), handle_tun_output);

	/* We keep a flag which says whether we've seen packets come out from
	 * this network device. */
	dev->priv = malloc(sizeof(bool));
	*(bool *)dev->priv = false;

	/* We need a socket to perform the magic network ioctls to bring up the
	 * tap interface, connect to the bridge etc.  Any socket will do! */
	ipfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
	if (ipfd < 0)
		err(1, "opening IP socket");

	/* If the command line was --tunnet=bridge:<name> do bridging. */
	if (!strncmp(BRIDGE_PFX, arg, strlen(BRIDGE_PFX))) {
		ip = INADDR_ANY;
		br_name = arg + strlen(BRIDGE_PFX);
		add_to_bridge(ipfd, ifr.ifr_name, br_name);
	} else /* It is an IP address to set up the device with */
		ip = str2ip(arg);

	/* We are peer 0, ie. first slot, so we hand dev->mem to this routine
	 * to write the MAC address at the start of the device memory.  */
	configure_device(ipfd, ifr.ifr_name, ip, dev->mem);

	/* Set "promisc" bit: we want every single packet if we're going to
	 * bridge to other machines (and otherwise it doesn't matter). */
	*((u8 *)dev->mem) |= 0x1;

	close(ipfd);

	verbose("device %p: tun net %u.%u.%u.%u\n",
		(void *)(dev->desc->pfn * getpagesize()),
		(u8)(ip>>24), (u8)(ip>>16), (u8)(ip>>8), (u8)ip);
	if (br_name)
		verbose("attached to bridge: %s\n", br_name);
}
/* That's the end of device setup. */

/*L:220 Finally we reach the core of the Launcher, which runs the Guest, serves
 * its input and output, and finally, lays it to rest. */
static void __attribute__((noreturn))
run_guest(int lguest_fd, struct device_list *device_list)
{
	for (;;) {
		unsigned long args[] = { LHREQ_BREAK, 0 };
		unsigned long arr[2];
		int readval;

		/* We read from the /dev/lguest device to run the Guest. */
		readval = read(lguest_fd, arr, sizeof(arr));

		/* The read can only really return sizeof(arr) (the Guest did a
		 * SEND_DMA to us), or an error. */

		/* For a successful read, arr[0] is the address of the "struct
		 * lguest_dma", and arr[1] is the key the Guest sent to. */
		if (readval == sizeof(arr)) {
			handle_output(lguest_fd, arr[0], arr[1], device_list);
			continue;
		/* ENOENT means the Guest died.  Reading tells us why. */
		} else if (errno == ENOENT) {
			char reason[1024] = { 0 };
			read(lguest_fd, reason, sizeof(reason)-1);
			errx(1, "%s", reason);
		/* EAGAIN means the waker wanted us to look at some input.
		 * Anything else means a bug or incompatible change. */
		} else if (errno != EAGAIN)
			err(1, "Running guest failed");

		/* Service input, then unset the BREAK which releases
		 * the Waker. */
		handle_input(lguest_fd, device_list);
		if (write(lguest_fd, args, sizeof(args)) < 0)
			err(1, "Resetting break");
	}
}
/*
 * This is the end of the Launcher.
 *
 * But wait!  We've seen I/O from the Launcher, and we've seen I/O from the
 * Drivers.  If we were to see the Host kernel I/O code, our understanding
 * would be complete... :*/

static struct option opts[] = {
	{ "verbose", 0, NULL, 'v' },
	{ "sharenet", 1, NULL, 's' },
	{ "tunnet", 1, NULL, 't' },
	{ "block", 1, NULL, 'b' },
	{ "initrd", 1, NULL, 'i' },
	{ NULL },
};
static void usage(void)
{
	errx(1, "Usage: lguest [--verbose] "
	     "[--sharenet=<filename>|--tunnet=(<ipaddr>|bridge:<bridgename>)\n"
	     "|--block=<filename>|--initrd=<filename>]...\n"
	     "<mem-in-mb> vmlinux [args...]");
}

/*L:105 The main routine is where the real work begins: */
int main(int argc, char *argv[])
{
	/* Memory, top-level pagetable, code startpoint, PAGE_OFFSET and size
	 * of the (optional) initrd. */
	unsigned long mem = 0, pgdir, start, page_offset, initrd_size = 0;
	/* A temporary and the /dev/lguest file descriptor. */
	int i, c, lguest_fd;
	/* The list of Guest devices, based on command line arguments. */
	struct device_list device_list;
	/* The boot information for the Guest. */
	void *boot;
	/* If they specify an initrd file to load. */
	const char *initrd_name = NULL;

	/* First we initialize the device list.  Since console and network
	 * device receive input from a file descriptor, we keep an fdset
	 * (infds) and the maximum fd number (max_infd) with the head of the
	 * list.  We also keep a pointer to the last device, for easy appending
	 * to the list. */
	device_list.max_infd = -1;
	device_list.dev = NULL;
	device_list.lastdev = &device_list.dev;
	FD_ZERO(&device_list.infds);

	/* We need to know how much memory so we can set up the device
	 * descriptor and memory pages for the devices as we parse the command
	 * line.  So we quickly look through the arguments to find the amount
	 * of memory now. */
	for (i = 1; i < argc; i++) {
		if (argv[i][0] != '-') {
			mem = atoi(argv[i]) * 1024 * 1024;
			/* We start by mapping anonymous pages over all of
			 * guest-physical memory range.  This fills it with 0,
			 * and ensures that the Guest won't be killed when it
			 * tries to access it. */
			guest_base = map_zeroed_pages(mem / getpagesize()
						      + DEVICE_PAGES);
			guest_limit = mem;
			guest_max = mem + DEVICE_PAGES*getpagesize();
			device_list.descs = get_pages(1);
			break;
		}
	}

	/* The options are fairly straight-forward */
	while ((c = getopt_long(argc, argv, "v", opts, NULL)) != EOF) {
		switch (c) {
		case 'v':
			verbose = true;
			break;
		case 's':
			setup_net_file(optarg, &device_list);
			break;
		case 't':
			setup_tun_net(optarg, &device_list);
			break;
		case 'b':
			setup_block_file(optarg, &device_list);
			break;
		case 'i':
			initrd_name = optarg;
			break;
		default:
			warnx("Unknown argument %s", argv[optind]);
			usage();
		}
	}
	/* After the other arguments we expect memory and kernel image name,
	 * followed by command line arguments for the kernel. */
	if (optind + 2 > argc)
		usage();

	verbose("Guest base is at %p\n", guest_base);

	/* We always have a console device */
	setup_console(&device_list);

	/* Now we load the kernel */
	start = load_kernel(open_or_die(argv[optind+1], O_RDONLY),
			    &page_offset);

	/* Boot information is stashed at physical address 0 */
	boot = from_guest_phys(0);

	/* Map the initrd image if requested (at top of physical memory) */
	if (initrd_name) {
		initrd_size = load_initrd(initrd_name, mem);
		/* These are the location in the Linux boot header where the
		 * start and size of the initrd are expected to be found. */
		*(unsigned long *)(boot+0x218) = mem - initrd_size;
		*(unsigned long *)(boot+0x21c) = initrd_size;
		/* The bootloader type 0xFF means "unknown"; that's OK. */
		*(unsigned char *)(boot+0x210) = 0xFF;
	}

	/* Set up the initial linear pagetables, starting below the initrd. */
	pgdir = setup_pagetables(mem, initrd_size, page_offset);

	/* The Linux boot header contains an "E820" memory map: ours is a
	 * simple, single region. */
	*(char*)(boot+E820NR) = 1;
	*((struct e820entry *)(boot+E820MAP))
		= ((struct e820entry) { 0, mem, E820_RAM });
	/* The boot header contains a command line pointer: we put the command
	 * line after the boot header (at address 4096) */
	*(u32 *)(boot + 0x228) = 4096;
	concat(boot + 4096, argv+optind+2);

	/* The guest type value of "1" tells the Guest it's under lguest. */
	*(int *)(boot + 0x23c) = 1;

	/* We tell the kernel to initialize the Guest: this returns the open
	 * /dev/lguest file descriptor. */
	lguest_fd = tell_kernel(pgdir, start, page_offset);

	/* We fork off a child process, which wakes the Launcher whenever one
	 * of the input file descriptors needs attention.  Otherwise we would
	 * run the Guest until it tries to output something. */
	waker_fd = setup_waker(lguest_fd, &device_list);

	/* Finally, run the Guest.  This doesn't return. */
	run_guest(lguest_fd, &device_list);
}
/*:*/

/*M:999
 * Mastery is done: you now know everything I do.
 *
 * But surely you have seen code, features and bugs in your wanderings which
 * you now yearn to attack?  That is the real game, and I look forward to you
 * patching and forking lguest into the Your-Name-Here-visor.
 *
 * Farewell, and good coding!
 * Rusty Russell.
 */
