lguest: documentation update

Went through the documentation doing typo and content fixes.  This
patch contains only comment and whitespace changes.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index c91c28a..f266839 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -360,8 +360,8 @@
 }
 
 /*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. */
+ * come wrapped up in the self-decompressing "bzImage" format.  With a little
+ * work, we can load those, too. */
 static unsigned long load_kernel(int fd)
 {
 	Elf32_Ehdr hdr;
@@ -464,6 +464,7 @@
 	 * to know where it is. */
 	return to_guest_phys(pgdir);
 }
+/*:*/
 
 /* Simple routine to roll all the commandline arguments together with spaces
  * between them. */
@@ -480,9 +481,9 @@
 	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
+/*L:185 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 and the entry point for the Guest. */
 static int tell_kernel(unsigned long pgdir, unsigned long start)
 {
@@ -512,13 +513,14 @@
 /*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.
+ * With console, block 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
+ * the LHREQ_BREAK command to the /dev/lguest file descriptor to tell the Host
+ * stop running the Guest.  This causes the Launcher 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.
  *
@@ -544,7 +546,9 @@
 			if (read(pipefd, &fd, sizeof(fd)) == 0)
 				exit(0);
 			/* Otherwise it's telling us to change what file
-			 * descriptors we're to listen to. */
+			 * descriptors we're to listen to.  Positive means
+			 * listen to a new one, negative means stop
+			 * listening. */
 			if (fd >= 0)
 				FD_SET(fd, &devices.infds);
 			else
@@ -559,7 +563,7 @@
 {
 	int pipefd[2], child;
 
-	/* We create a pipe to talk to the waker, and also so it knows when the
+	/* 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();
@@ -567,7 +571,8 @@
 		err(1, "forking");
 
 	if (child == 0) {
-		/* Close the "writing" end of our copy of the pipe */
+		/* We are the Waker: close the "writing" end of our copy of the
+		 * pipe and start waiting for input. */
 		close(pipefd[1]);
 		wake_parent(pipefd[0], lguest_fd);
 	}
@@ -578,12 +583,12 @@
 	return pipefd[1];
 }
 
-/*L:210
+/*
  * Device Handling.
  *
- * When the Guest sends DMA to us, it sends us an array of addresses and sizes.
+ * When the Guest gives us a buffer, it sends 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
+ * we have a convenient routine which checks it and exits with an error message
  * if something funny is going on:
  */
 static void *_check_pointer(unsigned long addr, unsigned int size,
@@ -600,7 +605,9 @@
 /* A macro which transparently hands the line number to the real function. */
 #define check_pointer(addr,size) _check_pointer(addr, size, __LINE__)
 
-/* This function returns the next descriptor in the chain, or vq->vring.num. */
+/* Each buffer in the virtqueues is actually a chain of descriptors.  This
+ * function returns the next descriptor in the chain, or vq->vring.num if we're
+ * at the end. */
 static unsigned next_desc(struct virtqueue *vq, unsigned int i)
 {
 	unsigned int next;
@@ -679,13 +686,14 @@
 	return head;
 }
 
-/* Once we've used one of their buffers, we tell them about it.  We'll then
+/* After we've used one of their buffers, we tell them about it.  We'll then
  * want to send them an interrupt, using trigger_irq(). */
 static void add_used(struct virtqueue *vq, unsigned int head, int len)
 {
 	struct vring_used_elem *used;
 
-	/* Get a pointer to the next entry in the used ring. */
+	/* The virtqueue contains a ring of used buffers.  Get a pointer to the
+	 * next entry in that used ring. */
 	used = &vq->vring.used->ring[vq->vring.used->idx % vq->vring.num];
 	used->id = head;
 	used->len = len;
@@ -699,6 +707,7 @@
 {
 	unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
 
+	/* If they don't want an interrupt, don't send one. */
 	if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
 		return;
 
@@ -715,8 +724,11 @@
 	trigger_irq(fd, vq);
 }
 
-/* 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. */
+/*
+ * The Console
+ *
+ * Here is the input terminal setting we save, and the routine to restore them
+ * on exit so the user gets their terminal back. */
 static struct termios orig_term;
 static void restore_term(void)
 {
@@ -817,7 +829,10 @@
 	}
 }
 
-/* Handling output for network is also simple: we get all the output buffers
+/*
+ * The Network
+ *
+ * Handling output for network is also simple: we get all the output buffers
  * and write them (ignoring the first element) to this device's file descriptor
  * (stdout). */
 static void handle_net_output(int fd, struct virtqueue *vq)
@@ -830,8 +845,9 @@
 	while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) {
 		if (in)
 			errx(1, "Input buffers in output queue?");
-		/* Check header, but otherwise ignore it (we said we supported
-		 * no features). */
+		/* Check header, but otherwise ignore it (we told the Guest we
+		 * supported no features, so it shouldn't have anything
+		 * interesting). */
 		(void)convert(&iov[0], struct virtio_net_hdr);
 		len = writev(vq->dev->fd, iov+1, out-1);
 		add_used_and_trigger(fd, vq, head, len);
@@ -882,7 +898,8 @@
 	return true;
 }
 
-/* This callback ensures we try again, in case we stopped console or net
+/*L:215 This is the callback attached to the network and console input
+ * virtqueues: it ensures we try again, in case we stopped console or net
  * delivery because Guest didn't have any buffers. */
 static void enable_fd(int fd, struct virtqueue *vq)
 {
@@ -918,7 +935,7 @@
 	      strnlen(from_guest_phys(addr), guest_limit - addr));
 }
 
-/* This is called when the waker wakes us up: check for incoming file
+/* This is called when the Waker wakes us up: check for incoming file
  * descriptors. */
 static void handle_input(int fd)
 {
@@ -985,8 +1002,7 @@
 }
 
 /* Each device descriptor is followed by some configuration information.
- * The first byte is a "status" byte for the Guest to report what's happening.
- * After that are fields: u8 type, u8 len, [... len bytes...].
+ * Each configuration field looks like: u8 type, u8 len, [... len bytes...].
  *
  * This routine adds a new field to an existing device's descriptor.  It only
  * works for the last device, but that's OK because that's how we use it. */
@@ -1043,14 +1059,17 @@
 	/* Link virtqueue back to device. */
 	vq->dev = dev;
 
-	/* Set up handler. */
+	/* Set the routine to call when the Guest does something to this
+	 * virtqueue. */
 	vq->handle_output = handle_output;
+
+	/* Set the "Don't Notify Me" flag if we don't have a handler */
 	if (!handle_output)
 		vq->vring.used->flags = VRING_USED_F_NO_NOTIFY;
 }
 
 /* This routine does all the creation and setup of a new device, including
- * caling new_dev_desc() to allocate the descriptor and device memory. */
+ * calling new_dev_desc() to allocate the descriptor and device memory. */
 static struct device *new_device(const char *name, u16 type, int fd,
 				 bool (*handle_input)(int, struct device *))
 {
@@ -1059,7 +1078,7 @@
 	/* 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. */
+	 * is eth0, the first block device /dev/vda, etc. */
 	*devices.lastdev = dev;
 	dev->next = NULL;
 	devices.lastdev = &dev->next;
@@ -1103,7 +1122,7 @@
 	/* The console needs two virtqueues: the input then the output.  When
 	 * they put something the input queue, we make sure we're listening to
 	 * stdin.  When they put something in the output queue, we write it to
-	 * stdout.  */
+	 * stdout. */
 	add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
 	add_virtqueue(dev, VIRTQUEUE_NUM, handle_console_output);
 
@@ -1251,21 +1270,17 @@
 		verbose("attached to bridge: %s\n", br_name);
 }
 
-
-/*
- * Block device.
+/* Our block (disk) device should be really simple: the Guest asks for a block
+ * number and we read or write that position in the file.  Unfortunately, that
+ * was amazingly slow: the Guest waits until the read is finished before
+ * running anything else, even if it could have been doing useful work.
  *
- * Serving a block device is really easy: the Guest asks for a block number and
- * we read or write that position in the file.
- *
- * Unfortunately, this is amazingly slow: the Guest waits until the read is
- * finished before running anything else, even if it could be doing useful
- * work.  We could use async I/O, except it's reputed to suck so hard that
- * characters actually go missing from your code when you try to use it.
+ * We could use async I/O, except it's reputed to suck so hard that characters
+ * actually go missing from your code when you try to use it.
  *
  * So we farm the I/O out to thread, and communicate with it via a pipe. */
 
-/* This hangs off device->priv, with the data. */
+/* This hangs off device->priv. */
 struct vblk_info
 {
 	/* The size of the file. */
@@ -1281,8 +1296,14 @@
 	 * Launcher triggers interrupt to Guest. */
 	int done_fd;
 };
+/*:*/
 
-/* This is the core of the I/O thread.  It returns true if it did something. */
+/*L:210
+ * The Disk
+ *
+ * Remember that the block device is handled by a separate I/O thread.  We head
+ * straight into the core of that thread here:
+ */
 static bool service_io(struct device *dev)
 {
 	struct vblk_info *vblk = dev->priv;
@@ -1293,10 +1314,14 @@
 	struct iovec iov[dev->vq->vring.num];
 	off64_t off;
 
+	/* See if there's a request waiting.  If not, nothing to do. */
 	head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
 	if (head == dev->vq->vring.num)
 		return false;
 
+	/* Every block request should contain at least one output buffer
+	 * (detailing the location on disk and the type of request) and one
+	 * input buffer (to hold the result). */
 	if (out_num == 0 || in_num == 0)
 		errx(1, "Bad virtblk cmd %u out=%u in=%u",
 		     head, out_num, in_num);
@@ -1305,10 +1330,15 @@
 	in = convert(&iov[out_num+in_num-1], struct virtio_blk_inhdr);
 	off = out->sector * 512;
 
-	/* This is how we implement barriers.  Pretty poor, no? */
+	/* The block device implements "barriers", where the Guest indicates
+	 * that it wants all previous writes to occur before this write.  We
+	 * don't have a way of asking our kernel to do a barrier, so we just
+	 * synchronize all the data in the file.  Pretty poor, no? */
 	if (out->type & VIRTIO_BLK_T_BARRIER)
 		fdatasync(vblk->fd);
 
+	/* In general the virtio block driver is allowed to try SCSI commands.
+	 * It'd be nice if we supported eject, for example, but we don't. */
 	if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
 		fprintf(stderr, "Scsi commands unsupported\n");
 		in->status = VIRTIO_BLK_S_UNSUPP;
@@ -1374,7 +1404,7 @@
 
 	/* When this read fails, it means Launcher died, so we follow. */
 	while (read(vblk->workpipe[0], &c, 1) == 1) {
-		/* We acknowledge each request immediately, to reduce latency,
+		/* We acknowledge each request immediately to reduce latency,
 		 * rather than waiting until we've done them all.  I haven't
 		 * measured to see if it makes any difference. */
 		while (service_io(dev))
@@ -1383,12 +1413,14 @@
 	return 0;
 }
 
-/* When the thread says some I/O is done, we interrupt the Guest. */
+/* Now we've seen the I/O thread, we return to the Launcher to see what happens
+ * when the thread tells us it's completed some I/O. */
 static bool handle_io_finish(int fd, struct device *dev)
 {
 	char c;
 
-	/* If child died, presumably it printed message. */
+	/* If the I/O thread died, presumably it printed the error, so we
+	 * simply exit. */
 	if (read(dev->fd, &c, 1) != 1)
 		exit(1);
 
@@ -1397,7 +1429,7 @@
 	return true;
 }
 
-/* When the Guest submits some I/O, we wake the I/O thread. */
+/* When the Guest submits some I/O, we just need to wake the I/O thread. */
 static void handle_virtblk_output(int fd, struct virtqueue *vq)
 {
 	struct vblk_info *vblk = vq->dev->priv;
@@ -1409,7 +1441,7 @@
 		exit(1);
 }
 
-/* This creates a virtual block device. */
+/*L:198 This actually sets up a virtual block device. */
 static void setup_block_file(const char *filename)
 {
 	int p[2];
@@ -1425,7 +1457,7 @@
 	/* The device responds to return from I/O thread. */
 	dev = new_device("block", VIRTIO_ID_BLOCK, p[0], handle_io_finish);
 
-	/* The device has a virtqueue. */
+	/* The device has one virtqueue, where the Guest places requests. */
 	add_virtqueue(dev, VIRTQUEUE_NUM, handle_virtblk_output);
 
 	/* Allocate the room for our own bookkeeping */
@@ -1447,7 +1479,8 @@
 	/* The I/O thread writes to this end of the pipe when done. */
 	vblk->done_fd = p[1];
 
-	/* This is how we tell the I/O thread about more work. */
+	/* This is the second pipe, which is how we tell the I/O thread about
+	 * more work. */
 	pipe(vblk->workpipe);
 
 	/* Create stack for thread and run it */
@@ -1486,24 +1519,25 @@
 			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.
+		/* 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. */
+		/* Service input, then unset the BREAK to release the Waker. */
 		handle_input(lguest_fd);
 		if (write(lguest_fd, args, sizeof(args)) < 0)
 			err(1, "Resetting break");
 	}
 }
 /*
- * This is the end of the Launcher.
+ * This is the end of the Launcher.  The good news: we are over halfway
+ * through!  The bad news: the most fiendish part of the code still lies ahead
+ * of us.
  *
- * 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... :*/
+ * Are you ready?  Take a deep breath and join me in the core of the Host, in
+ * "make Host".
+ :*/
 
 static struct option opts[] = {
 	{ "verbose", 0, NULL, 'v' },
@@ -1526,7 +1560,7 @@
 	/* Memory, top-level pagetable, code startpoint and size of the
 	 * (optional) initrd. */
 	unsigned long mem = 0, pgdir, start, initrd_size = 0;
-	/* A temporary and the /dev/lguest file descriptor. */
+	/* Two temporaries and the /dev/lguest file descriptor. */
 	int i, c, lguest_fd;
 	/* The boot information for the Guest. */
 	struct boot_params *boot;
@@ -1621,6 +1655,7 @@
 	/* The boot header contains a command line pointer: we put the command
 	 * line after the boot header. */
 	boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1);
+	/* We use a simple helper to copy the arguments separated by spaces. */
 	concat((char *)(boot + 1), argv+optind+2);
 
 	/* Boot protocol version: 2.07 supports the fields for lguest. */
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index a0179fc..a55b090 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -99,7 +99,7 @@
  * When lazy_mode is set, it means we're allowed to defer all hypercalls and do
  * them as a batch when lazy_mode is eventually turned off.  Because hypercalls
  * are reasonably expensive, batching them up makes sense.  For example, a
- * large mmap might update dozens of page table entries: that code calls
+ * large munmap might update dozens of page table entries: that code calls
  * paravirt_enter_lazy_mmu(), does the dozen updates, then calls
  * lguest_leave_lazy_mode().
  *
@@ -164,8 +164,8 @@
 /*:*/
 
 /*G:033
- * Here are our first native-instruction replacements: four functions for
- * interrupt control.
+ * After that diversion we return to our first native-instruction
+ * replacements: four functions for interrupt control.
  *
  * The simplest way of implementing these would be to have "turn interrupts
  * off" and "turn interrupts on" hypercalls.  Unfortunately, this is too slow:
@@ -184,7 +184,7 @@
 	return lguest_data.irq_enabled;
 }
 
-/* "restore_flags" just sets the flags back to the value given. */
+/* restore_flags() just sets the flags back to the value given. */
 static void restore_fl(unsigned long flags)
 {
 	lguest_data.irq_enabled = flags;
@@ -357,7 +357,7 @@
  * it.  The Host needs to know when the Guest wants to change them, so we have
  * a whole series of functions like read_cr0() and write_cr0().
  *
- * We start with CR0.  CR0 allows you to turn on and off all kinds of basic
+ * We start with cr0.  cr0 allows you to turn on and off all kinds of basic
  * features, but Linux only really cares about one: the horrifically-named Task
  * Switched (TS) bit at bit 3 (ie. 8)
  *
@@ -390,7 +390,7 @@
 	current_cr0 &= ~X86_CR0_TS;
 }
 
-/* CR2 is the virtual address of the last page fault, which the Guest only ever
+/* cr2 is the virtual address of the last page fault, which the Guest only ever
  * reads.  The Host kindly writes this into our "struct lguest_data", so we
  * just read it out of there. */
 static unsigned long lguest_read_cr2(void)
@@ -398,7 +398,7 @@
 	return lguest_data.cr2;
 }
 
-/* CR3 is the current toplevel pagetable page: the principle is the same as
+/* cr3 is the current toplevel pagetable page: the principle is the same as
  * cr0.  Keep a local copy, and tell the Host when it changes. */
 static void lguest_write_cr3(unsigned long cr3)
 {
@@ -411,7 +411,7 @@
 	return current_cr3;
 }
 
-/* CR4 is used to enable and disable PGE, but we don't care. */
+/* cr4 is used to enable and disable PGE, but we don't care. */
 static unsigned long lguest_read_cr4(void)
 {
 	return 0;
@@ -432,7 +432,7 @@
  * maps virtual addresses to physical addresses using "page tables".  We could
  * use one huge index of 1 million entries: each address is 4 bytes, so that's
  * 1024 pages just to hold the page tables.   But since most virtual addresses
- * are unused, we use a two level index which saves space.  The CR3 register
+ * are unused, we use a two level index which saves space.  The cr3 register
  * contains the physical address of the top level "page directory" page, which
  * contains physical addresses of up to 1024 second-level pages.  Each of these
  * second level pages contains up to 1024 physical addresses of actual pages,
@@ -440,7 +440,7 @@
  *
  * Here's a diagram, where arrows indicate physical addresses:
  *
- * CR3 ---> +---------+
+ * cr3 ---> +---------+
  *	    |  	   --------->+---------+
  *	    |	      |	     | PADDR1  |
  *	  Top-level   |	     | PADDR2  |
@@ -498,8 +498,7 @@
  *
  * ... except in early boot when the kernel sets up the initial pagetables,
  * which makes booting astonishingly slow.  So we don't even tell the Host
- * anything changed until we've done the first page table switch.
- */
+ * anything changed until we've done the first page table switch. */
 static void lguest_set_pte(pte_t *ptep, pte_t pteval)
 {
 	*ptep = pteval;
@@ -720,10 +719,10 @@
 	/* Set up the timer interrupt (0) to go to our simple timer routine */
 	set_irq_handler(0, lguest_time_irq);
 
-	/* Our clock structure look like arch/i386/kernel/tsc.c if we can use
-	 * the TSC, otherwise it's a dumb nanosecond-resolution clock.  Either
-	 * way, the "rating" is initialized so high that it's always chosen
-	 * over any other clocksource. */
+	/* Our clock structure looks like arch/x86/kernel/tsc_32.c if we can
+	 * use the TSC, otherwise it's a dumb nanosecond-resolution clock.
+	 * Either way, the "rating" is set so high that it's always chosen over
+	 * any other clocksource. */
 	if (lguest_data.tsc_khz)
 		lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz,
 							 lguest_clock.shift);
@@ -749,7 +748,7 @@
  * to work.  They're pretty simple.
  */
 
-/* The Guest needs to tell the host what stack it expects traps to use.  For
+/* The Guest needs to tell the Host what stack it expects traps to use.  For
  * native hardware, this is part of the Task State Segment mentioned above in
  * lguest_load_tr_desc(), but to help hypervisors there's this special call.
  *
@@ -850,13 +849,16 @@
 	return "LGUEST";
 }
 
-/* Before virtqueues are set up, we use LHCALL_NOTIFY on normal memory to
- * produce console output. */
+/* We will eventually use the virtio console device to produce console output,
+ * but before that is set up we use LHCALL_NOTIFY on normal memory to produce
+ * console output. */
 static __init int early_put_chars(u32 vtermno, const char *buf, int count)
 {
 	char scratch[17];
 	unsigned int len = count;
 
+	/* We use a nul-terminated string, so we have to make a copy.  Icky,
+	 * huh? */
 	if (len > sizeof(scratch) - 1)
 		len = sizeof(scratch) - 1;
 	scratch[len] = '\0';
@@ -883,7 +885,7 @@
  * Our current solution is to allow the paravirt back end to optionally patch
  * over the indirect calls to replace them with something more efficient.  We
  * patch the four most commonly called functions: disable interrupts, enable
- * interrupts, restore interrupts and save interrupts.  We usually have 10
+ * interrupts, restore interrupts and save interrupts.  We usually have 6 or 10
  * bytes to patch into: the Guest versions of these operations are small enough
  * that we can fit comfortably.
  *
@@ -1015,7 +1017,7 @@
 	asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory");
 
 	/* The Host uses the top of the Guest's virtual address space for the
-	 * Host<->Guest Switcher, and it tells us how much it needs in
+	 * Host<->Guest Switcher, and it tells us how big that is in
 	 * lguest_data.reserve_mem, set up on the LGUEST_INIT hypercall. */
 	reserve_top_address(lguest_data.reserve_mem);
 
@@ -1065,6 +1067,6 @@
 /*
  * This marks the end of stage II of our journey, The Guest.
  *
- * It is now time for us to explore the nooks and crannies of the three Guest
- * devices and complete our understanding of the Guest in "make Drivers".
+ * It is now time for us to explore the layer of virtual drivers and complete
+ * our understanding of the Guest in "make Drivers".
  */
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S
index ebc6ac7..95b6fbc 100644
--- a/arch/x86/lguest/i386_head.S
+++ b/arch/x86/lguest/i386_head.S
@@ -6,7 +6,7 @@
 #include <asm/processor-flags.h>
 
 /*G:020 This is where we begin: head.S notes that the boot header's platform
- * type field is "1" (lguest), so calls us here.  The boot header is in %esi.
+ * type field is "1" (lguest), so calls us here.
  *
  * WARNING: be very careful here!  We're running at addresses equal to physical
  * addesses (around 0), not above PAGE_OFFSET as most code expectes
@@ -17,13 +17,15 @@
  * boot. */
 .section .init.text, "ax", @progbits
 ENTRY(lguest_entry)
-	/* Make initial hypercall now, so we can set up the pagetables. */
+	/* We make the "initialization" hypercall now to tell the Host about
+	 * us, and also find out where it put our page tables. */
 	movl $LHCALL_LGUEST_INIT, %eax
 	movl $lguest_data - __PAGE_OFFSET, %edx
 	int $LGUEST_TRAP_ENTRY
 
 	/* The Host put the toplevel pagetable in lguest_data.pgdir.  The movsl
-	 * instruction uses %esi implicitly. */
+	 * instruction uses %esi implicitly as the source for the copy we'
+	 * about to do. */
 	movl lguest_data - __PAGE_OFFSET + LGUEST_DATA_pgdir, %esi
 
 	/* Copy first 32 entries of page directory to __PAGE_OFFSET entries.
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 35d19ae..cb4c670 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -128,9 +128,12 @@
 		__free_pages(switcher_page[i], 0);
 }
 
-/*L:305
+/*H:032
  * Dealing With Guest Memory.
  *
+ * Before we go too much further into the Host, we need to grok the routines
+ * we use to deal with Guest memory.
+ *
  * When the Guest gives us (what it thinks is) a physical address, we can use
  * the normal copy_from_user() & copy_to_user() on the corresponding place in
  * the memory region allocated by the Launcher.
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index 9d5184c..b478aff 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -90,6 +90,7 @@
 		lg->pending_notify = args->arg1;
 		break;
 	default:
+		/* It should be an architecture-specific hypercall. */
 		if (lguest_arch_do_hcall(lg, args))
 			kill_guest(lg, "Bad hypercall %li\n", args->arg0);
 	}
@@ -157,7 +158,6 @@
  * Guest makes a hypercall, we end up here to set things up: */
 static void initialize(struct lguest *lg)
 {
-
 	/* You can't do anything until you're initialized.  The Guest knows the
 	 * rules, so we're unforgiving here. */
 	if (lg->hcall->arg0 != LHCALL_LGUEST_INIT) {
@@ -174,7 +174,8 @@
 	    || get_user(lg->noirq_end, &lg->lguest_data->noirq_end))
 		kill_guest(lg, "bad guest page %p", lg->lguest_data);
 
-	/* We write the current time into the Guest's data page once now. */
+	/* We write the current time into the Guest's data page once so it can
+	 * set its clock. */
 	write_timestamp(lg);
 
 	/* page_tables.c will also do some setup. */
@@ -182,8 +183,8 @@
 
 	/* This is the one case where the above accesses might have been the
 	 * first write to a Guest page.  This may have caused a copy-on-write
-	 * fault, but the Guest might be referring to the old (read-only)
-	 * page. */
+	 * fault, but the old page might be (read-only) in the Guest
+	 * pagetable. */
 	guest_pagetable_clear_all(lg);
 }
 
@@ -220,7 +221,7 @@
 		 * Normally it doesn't matter: the Guest will run again and
 		 * update the trap number before we come back here.
 		 *
-		 * However, if we are signalled or the Guest sends DMA to the
+		 * However, if we are signalled or the Guest sends I/O to the
 		 * Launcher, the run_guest() loop will exit without running the
 		 * Guest.  When it comes back it would try to re-run the
 		 * hypercall. */
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index 8296698..2b66f79 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -92,8 +92,8 @@
 
 	/* Remember that we never let the Guest actually disable interrupts, so
 	 * the "Interrupt Flag" bit is always set.  We copy that bit from the
-	 * Guest's "irq_enabled" field into the eflags word: the Guest copies
-	 * it back in "lguest_iret". */
+	 * Guest's "irq_enabled" field into the eflags word: we saw the Guest
+	 * copy it back in "lguest_iret". */
 	eflags = lg->regs->eflags;
 	if (get_user(irq_enable, &lg->lguest_data->irq_enabled) == 0
 	    && !(irq_enable & X86_EFLAGS_IF))
@@ -124,7 +124,7 @@
 			kill_guest(lg, "Disabling interrupts");
 }
 
-/*H:200
+/*H:205
  * Virtual Interrupts.
  *
  * maybe_do_interrupt() gets called before every entry to the Guest, to see if
@@ -256,19 +256,21 @@
 	 * bogus one in): if we fail here, the Guest will be killed. */
 	if (!idt_present(lg->arch.idt[num].a, lg->arch.idt[num].b))
 		return 0;
-	set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b, has_err(num));
+	set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b,
+			    has_err(num));
 	return 1;
 }
 
 /*H:250 Here's the hard part: returning to the Host every time a trap happens
  * and then calling deliver_trap() and re-entering the Guest is slow.
- * Particularly because Guest userspace system calls are traps (trap 128).
+ * Particularly because Guest userspace system calls are traps (usually trap
+ * 128).
  *
  * So we'd like to set up the IDT to tell the CPU to deliver traps directly
  * into the Guest.  This is possible, but the complexities cause the size of
  * this file to double!  However, 150 lines of code is worth writing for taking
  * system calls down from 1750ns to 270ns.  Plus, if lguest didn't do it, all
- * the other hypervisors would tease it.
+ * the other hypervisors would beat it up at lunchtime.
  *
  * This routine indicates if a particular trap number could be delivered
  * directly. */
@@ -331,7 +333,7 @@
  * change stacks on each context switch. */
 void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages)
 {
-	/* You are not allowd have a stack segment with privilege level 0: bad
+	/* You are not allowed have a stack segment with privilege level 0: bad
 	 * Guest! */
 	if ((seg & 0x3) != GUEST_PL)
 		kill_guest(lg, "bad stack segment %i", seg);
@@ -350,7 +352,7 @@
  * part of the Host: page table handling. */
 
 /*H:235 This is the routine which actually checks the Guest's IDT entry and
- * transfers it into our entry in "struct lguest": */
+ * transfers it into the entry in "struct lguest": */
 static void set_trap(struct lguest *lg, struct desc_struct *trap,
 		     unsigned int num, u32 lo, u32 hi)
 {
@@ -456,6 +458,18 @@
 	}
 }
 
+/*H:200
+ * The Guest Clock.
+ *
+ * There are two sources of virtual interrupts.  We saw one in lguest_user.c:
+ * the Launcher sending interrupts for virtual devices.  The other is the Guest
+ * timer interrupt.
+ *
+ * The Guest uses the LHCALL_SET_CLOCKEVENT hypercall to tell us how long to
+ * the next timer interrupt (in nanoseconds).  We use the high-resolution timer
+ * infrastructure to set a callback at that time.
+ *
+ * 0 means "turn off the clock". */
 void guest_set_clockevent(struct lguest *lg, unsigned long delta)
 {
 	ktime_t expires;
@@ -466,20 +480,27 @@
 		return;
 	}
 
+	/* We use wallclock time here, so the Guest might not be running for
+	 * all the time between now and the timer interrupt it asked for.  This
+	 * is almost always the right thing to do. */
 	expires = ktime_add_ns(ktime_get_real(), delta);
 	hrtimer_start(&lg->hrt, expires, HRTIMER_MODE_ABS);
 }
 
+/* This is the function called when the Guest's timer expires. */
 static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
 {
 	struct lguest *lg = container_of(timer, struct lguest, hrt);
 
+	/* Remember the first interrupt is the timer interrupt. */
 	set_bit(0, lg->irqs_pending);
+	/* If the Guest is actually stopped, we need to wake it up. */
 	if (lg->halted)
 		wake_up_process(lg->tsk);
 	return HRTIMER_NORESTART;
 }
 
+/* This sets up the timer for this Guest. */
 void init_clockdev(struct lguest *lg)
 {
 	hrtimer_init(&lg->hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 0c74ac4..8692489 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -100,7 +100,7 @@
 void __lgread(struct lguest *, void *, unsigned long, unsigned);
 void __lgwrite(struct lguest *, unsigned long, const void *, unsigned);
 
-/*L:306 Using memory-copy operations like that is usually inconvient, so we
+/*H:035 Using memory-copy operations like that is usually inconvient, so we
  * have the following helper macros which read and write a specific type (often
  * an unsigned long).
  *
@@ -188,7 +188,7 @@
  * Let's step aside for the moment, to study one important routine that's used
  * widely in the Host code.
  *
- * There are many cases where the Guest does something invalid, like pass crap
+ * There are many cases where the Guest can do something invalid, like pass crap
  * to a hypercall.  Since only the Guest kernel can make hypercalls, it's quite
  * acceptable to simply terminate the Guest and give the Launcher a nicely
  * formatted reason.  It's also simpler for the Guest itself, which doesn't
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index 71c6483..8904f72 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -53,7 +53,8 @@
  * Device configurations
  *
  * The configuration information for a device consists of a series of fields.
- * The device will look for these fields during setup.
+ * We don't really care what they are: the Launcher set them up, and the driver
+ * will look at them during setup.
  *
  * For us these fields come immediately after that device's descriptor in the
  * lguest_devices page.
@@ -122,8 +123,8 @@
  * The other piece of infrastructure virtio needs is a "virtqueue": a way of
  * the Guest device registering buffers for the other side to read from or
  * write into (ie. send and receive buffers).  Each device can have multiple
- * virtqueues: for example the console has one queue for sending and one for
- * receiving.
+ * virtqueues: for example the console driver uses one queue for sending and
+ * another for receiving.
  *
  * Fortunately for us, a very fast shared-memory-plus-descriptors virtqueue
  * already exists in virtio_ring.c.  We just need to connect it up.
@@ -158,7 +159,7 @@
  *
  * This is kind of an ugly duckling.  It'd be nicer to have a standard
  * representation of a virtqueue in the configuration space, but it seems that
- * everyone wants to do it differently.  The KVM guys want the Guest to
+ * everyone wants to do it differently.  The KVM coders want the Guest to
  * allocate its own pages and tell the Host where they are, but for lguest it's
  * simpler for the Host to simply tell us where the pages are.
  *
@@ -284,6 +285,8 @@
 {
 	struct lguest_device *ldev;
 
+	/* Start with zeroed memory; Linux's device layer seems to count on
+	 * it. */
 	ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
 	if (!ldev) {
 		printk(KERN_EMERG "Cannot allocate lguest dev %u\n",
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index ee405b38..9d716fa 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -8,20 +8,22 @@
 #include <linux/fs.h>
 #include "lg.h"
 
-/*L:315 To force the Guest to stop running and return to the Launcher, the
- * Waker sets writes LHREQ_BREAK and the value "1" to /dev/lguest.  The
- * Launcher then writes LHREQ_BREAK and "0" to release the Waker. */
+/*L:055 When something happens, the Waker process needs a way to stop the
+ * kernel running the Guest and return to the Launcher.  So the Waker writes
+ * LHREQ_BREAK and the value "1" to /dev/lguest to do this.  Once the Launcher
+ * has done whatever needs attention, it writes LHREQ_BREAK and "0" to release
+ * the Waker. */
 static int break_guest_out(struct lguest *lg, const unsigned long __user *input)
 {
 	unsigned long on;
 
-	/* Fetch whether they're turning break on or off.. */
+	/* Fetch whether they're turning break on or off. */
 	if (get_user(on, input) != 0)
 		return -EFAULT;
 
 	if (on) {
 		lg->break_out = 1;
-		/* Pop it out (may be running on different CPU) */
+		/* Pop it out of the Guest (may be running on different CPU) */
 		wake_up_process(lg->tsk);
 		/* Wait for them to reset it */
 		return wait_event_interruptible(lg->break_wq, !lg->break_out);
@@ -58,7 +60,7 @@
 	if (!lg)
 		return -EINVAL;
 
-	/* If you're not the task which owns the guest, go away. */
+	/* If you're not the task which owns the Guest, go away. */
 	if (current != lg->tsk)
 		return -EPERM;
 
@@ -92,8 +94,8 @@
  * base: The start of the Guest-physical memory inside the Launcher memory.
  *
  * pfnlimit: The highest (Guest-physical) page number the Guest should be
- * allowed to access.  The Launcher has to live in Guest memory, so it sets
- * this to ensure the Guest can't reach it.
+ * allowed to access.  The Guest memory lives inside the Launcher, so it sets
+ * this to ensure the Guest can only reach its own memory.
  *
  * pgdir: The (Guest-physical) address of the top of the initial Guest
  * pagetables (which are set up by the Launcher).
@@ -189,7 +191,7 @@
 }
 
 /*L:010 The first operation the Launcher does must be a write.  All writes
- * start with a 32 bit number: for the first write this must be
+ * start with an unsigned long number: for the first write this must be
  * LHREQ_INITIALIZE to set up the Guest.  After that the Launcher can use
  * writes of other values to send interrupts. */
 static ssize_t write(struct file *file, const char __user *in,
@@ -275,8 +277,7 @@
  * The Launcher is the Host userspace program which sets up, runs and services
  * the Guest.  In fact, many comments in the Drivers which refer to "the Host"
  * doing things are inaccurate: the Launcher does all the device handling for
- * the Guest.  The Guest can't tell what's done by the the Launcher and what by
- * the Host.
+ * the Guest, but the Guest can't know that.
  *
  * Just to confuse you: to the Host kernel, the Launcher *is* the Guest and we
  * shall see more of that later.
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 2a45f06..fffabb3 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -26,7 +26,8 @@
  *
  * We use two-level page tables for the Guest.  If you're not entirely
  * comfortable with virtual addresses, physical addresses and page tables then
- * I recommend you review lguest.c's "Page Table Handling" (with diagrams!).
+ * I recommend you review arch/x86/lguest/boot.c's "Page Table Handling" (with
+ * diagrams!).
  *
  * The Guest keeps page tables, but we maintain the actual ones here: these are
  * called "shadow" page tables.  Which is a very Guest-centric name: these are
@@ -36,11 +37,11 @@
  *
  * Anyway, this is the most complicated part of the Host code.  There are seven
  * parts to this:
- *  (i) Setting up a page table entry for the Guest when it faults,
- *  (ii) Setting up the page table entry for the Guest stack,
- *  (iii) Setting up a page table entry when the Guest tells us it has changed,
+ *  (i) Looking up a page table entry when the Guest faults,
+ *  (ii) Making sure the Guest stack is mapped,
+ *  (iii) Setting up a page table entry when the Guest tells us one has changed,
  *  (iv) Switching page tables,
- *  (v) Flushing (thowing away) page tables,
+ *  (v) Flushing (throwing away) page tables,
  *  (vi) Mapping the Switcher when the Guest is about to run,
  *  (vii) Setting up the page tables initially.
  :*/
@@ -57,16 +58,15 @@
 static DEFINE_PER_CPU(pte_t *, switcher_pte_pages);
 #define switcher_pte_page(cpu) per_cpu(switcher_pte_pages, cpu)
 
-/*H:320 With our shadow and Guest types established, we need to deal with
- * them: the page table code is curly enough to need helper functions to keep
- * it clear and clean.
+/*H:320 The page table code is curly enough to need helper functions to keep it
+ * clear and clean.
  *
  * There are two functions which return pointers to the shadow (aka "real")
  * page tables.
  *
  * spgd_addr() takes the virtual address and returns a pointer to the top-level
- * page directory entry for that address.  Since we keep track of several page
- * tables, the "i" argument tells us which one we're interested in (it's
+ * page directory entry (PGD) for that address.  Since we keep track of several
+ * page tables, the "i" argument tells us which one we're interested in (it's
  * usually the current one). */
 static pgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned long vaddr)
 {
@@ -81,9 +81,9 @@
 	return &lg->pgdirs[i].pgdir[index];
 }
 
-/* This routine then takes the PGD entry given above, which contains the
- * address of the PTE page.  It then returns a pointer to the PTE entry for the
- * given address. */
+/* This routine then takes the page directory entry returned above, which
+ * contains the address of the page table entry (PTE) page.  It then returns a
+ * pointer to the PTE entry for the given address. */
 static pte_t *spte_addr(struct lguest *lg, pgd_t spgd, unsigned long vaddr)
 {
 	pte_t *page = __va(pgd_pfn(spgd) << PAGE_SHIFT);
@@ -191,7 +191,7 @@
 }
 
 /*H:330
- * (i) Setting up a page table entry for the Guest when it faults
+ * (i) Looking up a page table entry when the Guest faults.
  *
  * We saw this call in run_guest(): when we see a page fault in the Guest, we
  * come here.  That's because we only set up the shadow page tables lazily as
@@ -199,7 +199,7 @@
  * and return to the Guest without it knowing.
  *
  * If we fixed up the fault (ie. we mapped the address), this routine returns
- * true. */
+ * true.  Otherwise, it was a real fault and we need to tell the Guest. */
 int demand_page(struct lguest *lg, unsigned long vaddr, int errcode)
 {
 	pgd_t gpgd;
@@ -246,16 +246,16 @@
 	if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW))
 		return 0;
 
-	/* User access to a kernel page? (bit 3 == user access) */
+	/* User access to a kernel-only page? (bit 3 == user access) */
 	if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER))
 		return 0;
 
 	/* Check that the Guest PTE flags are OK, and the page number is below
 	 * the pfn_limit (ie. not mapping the Launcher binary). */
 	check_gpte(lg, gpte);
+
 	/* Add the _PAGE_ACCESSED and (for a write) _PAGE_DIRTY flag */
 	gpte = pte_mkyoung(gpte);
-
 	if (errcode & 2)
 		gpte = pte_mkdirty(gpte);
 
@@ -272,23 +272,28 @@
 	else
 		/* If this is a read, don't set the "writable" bit in the page
 		 * table entry, even if the Guest says it's writable.  That way
-		 * we come back here when a write does actually ocur, so we can
-		 * update the Guest's _PAGE_DIRTY flag. */
+		 * we will come back here when a write does actually occur, so
+		 * we can update the Guest's _PAGE_DIRTY flag. */
 		*spte = gpte_to_spte(lg, pte_wrprotect(gpte), 0);
 
 	/* Finally, we write the Guest PTE entry back: we've set the
 	 * _PAGE_ACCESSED and maybe the _PAGE_DIRTY flags. */
 	lgwrite(lg, gpte_ptr, pte_t, gpte);
 
-	/* We succeeded in mapping the page! */
+	/* The fault is fixed, the page table is populated, the mapping
+	 * manipulated, the result returned and the code complete.  A small
+	 * delay and a trace of alliteration are the only indications the Guest
+	 * has that a page fault occurred at all. */
 	return 1;
 }
 
-/*H:360 (ii) Setting up the page table entry for the Guest stack.
+/*H:360
+ * (ii) Making sure the Guest stack is mapped.
  *
- * Remember pin_stack_pages() which makes sure the stack is mapped?  It could
- * simply call demand_page(), but as we've seen that logic is quite long, and
- * usually the stack pages are already mapped anyway, so it's not required.
+ * Remember that direct traps into the Guest need a mapped Guest kernel stack.
+ * pin_stack_pages() calls us here: we could simply call demand_page(), but as
+ * we've seen that logic is quite long, and usually the stack pages are already
+ * mapped, so it's overkill.
  *
  * This is a quick version which answers the question: is this virtual address
  * mapped by the shadow page tables, and is it writable? */
@@ -297,7 +302,7 @@
 	pgd_t *spgd;
 	unsigned long flags;
 
-	/* Look at the top level entry: is it present? */
+	/* Look at the current top level entry: is it present? */
 	spgd = spgd_addr(lg, lg->pgdidx, vaddr);
 	if (!(pgd_flags(*spgd) & _PAGE_PRESENT))
 		return 0;
@@ -333,15 +338,14 @@
 			release_pte(ptepage[i]);
 		/* Now we can free the page of PTEs */
 		free_page((long)ptepage);
-		/* And zero out the PGD entry we we never release it twice. */
+		/* And zero out the PGD entry so we never release it twice. */
 		*spgd = __pgd(0);
 	}
 }
 
-/*H:440 (v) Flushing (thowing away) page tables,
- *
- * We saw flush_user_mappings() called when we re-used a top-level pgdir page.
- * It simply releases every PTE page from 0 up to the kernel address. */
+/*H:445 We saw flush_user_mappings() twice: once from the flush_user_mappings()
+ * hypercall and once in new_pgdir() when we re-used a top-level pgdir page.
+ * It simply releases every PTE page from 0 up to the Guest's kernel address. */
 static void flush_user_mappings(struct lguest *lg, int idx)
 {
 	unsigned int i;
@@ -350,8 +354,10 @@
 		release_pgd(lg, lg->pgdirs[idx].pgdir + i);
 }
 
-/* The Guest also has a hypercall to do this manually: it's used when a large
- * number of mappings have been changed. */
+/*H:440 (v) Flushing (throwing away) page tables,
+ *
+ * The Guest has a hypercall to throw away the page tables: it's used when a
+ * large number of mappings have been changed. */
 void guest_pagetable_flush_user(struct lguest *lg)
 {
 	/* Drop the userspace part of the current page table. */
@@ -423,8 +429,9 @@
 
 /*H:430 (iv) Switching page tables
  *
- * This is what happens when the Guest changes page tables (ie. changes the
- * top-level pgdir).  This happens on almost every context switch. */
+ * Now we've seen all the page table setting and manipulation, let's see what
+ * what happens when the Guest changes page tables (ie. changes the top-level
+ * pgdir).  This occurs on almost every context switch. */
 void guest_new_pagetable(struct lguest *lg, unsigned long pgtable)
 {
 	int newpgdir, repin = 0;
@@ -443,7 +450,8 @@
 }
 
 /*H:470 Finally, a routine which throws away everything: all PGD entries in all
- * the shadow page tables.  This is used when we destroy the Guest. */
+ * the shadow page tables, including the Guest's kernel mappings.  This is used
+ * when we destroy the Guest. */
 static void release_all_pagetables(struct lguest *lg)
 {
 	unsigned int i, j;
@@ -458,13 +466,22 @@
 
 /* We also throw away everything when a Guest tells us it's changed a kernel
  * mapping.  Since kernel mappings are in every page table, it's easiest to
- * throw them all away.  This is amazingly slow, but thankfully rare. */
+ * throw them all away.  This traps the Guest in amber for a while as
+ * everything faults back in, but it's rare. */
 void guest_pagetable_clear_all(struct lguest *lg)
 {
 	release_all_pagetables(lg);
 	/* We need the Guest kernel stack mapped again. */
 	pin_stack_pages(lg);
 }
+/*:*/
+/*M:009 Since we throw away all mappings when a kernel mapping changes, our
+ * performance sucks for guests using highmem.  In fact, a guest with
+ * PAGE_OFFSET 0xc0000000 (the default) and more than about 700MB of RAM is
+ * usually slower than a Guest with less memory.
+ *
+ * This, of course, cannot be fixed.  It would take some kind of... well, I
+ * don't know, but the term "puissant code-fu" comes to mind. :*/
 
 /*H:420 This is the routine which actually sets the page table entry for then
  * "idx"'th shadow page table.
@@ -483,7 +500,7 @@
 static void do_set_pte(struct lguest *lg, int idx,
 		       unsigned long vaddr, pte_t gpte)
 {
-	/* Look up the matching shadow page directot entry. */
+	/* Look up the matching shadow page directory entry. */
 	pgd_t *spgd = spgd_addr(lg, idx, vaddr);
 
 	/* If the top level isn't present, there's no entry to update. */
@@ -500,7 +517,8 @@
 			*spte = gpte_to_spte(lg, gpte,
 					     pte_flags(gpte) & _PAGE_DIRTY);
 		} else
-			/* Otherwise we can demand_page() it in later. */
+			/* Otherwise kill it and we can demand_page() it in
+			 * later. */
 			*spte = __pte(0);
 	}
 }
@@ -535,7 +553,7 @@
 }
 
 /*H:400
- * (iii) Setting up a page table entry when the Guest tells us it has changed.
+ * (iii) Setting up a page table entry when the Guest tells us one has changed.
  *
  * Just like we did in interrupts_and_traps.c, it makes sense for us to deal
  * with the other side of page tables while we're here: what happens when the
@@ -612,9 +630,10 @@
 
 /*H:480 (vi) Mapping the Switcher when the Guest is about to run.
  *
- * The Switcher and the two pages for this CPU need to be available to the
+ * The Switcher and the two pages for this CPU need to be visible in the
  * Guest (and not the pages for other CPUs).  We have the appropriate PTE pages
- * for each CPU already set up, we just need to hook them in. */
+ * for each CPU already set up, we just need to hook them in now we know which
+ * Guest is about to run on this CPU. */
 void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages)
 {
 	pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
@@ -677,6 +696,18 @@
 			   __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED));
 }
 
+/* We've made it through the page table code.  Perhaps our tired brains are
+ * still processing the details, or perhaps we're simply glad it's over.
+ *
+ * If nothing else, note that all this complexity in juggling shadow page
+ * tables in sync with the Guest's page tables is for one reason: for most
+ * Guests this page table dance determines how bad performance will be.  This
+ * is why Xen uses exotic direct Guest pagetable manipulation, and why both
+ * Intel and AMD have implemented shadow page table support directly into
+ * hardware.
+ *
+ * There is just one file remaining in the Host. */
+
 /*H:510 At boot or module load time, init_pagetables() allocates and populates
  * the Switcher PTE page for each CPU. */
 __init int init_pagetables(struct page **switcher_page, unsigned int pages)
diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
index c2434ec..9e189cb 100644
--- a/drivers/lguest/segments.c
+++ b/drivers/lguest/segments.c
@@ -12,8 +12,6 @@
 #include "lg.h"
 
 /*H:600
- * We've almost completed the Host; there's just one file to go!
- *
  * Segments & The Global Descriptor Table
  *
  * (That title sounds like a bad Nerdcore group.  Not to suggest that there are
@@ -55,7 +53,7 @@
 		|| num == GDT_ENTRY_DOUBLEFAULT_TSS);
 }
 
-/*H:610 Once the GDT has been changed, we fix the new entries up a little.  We
+/*H:630 Once the Guest gave us new GDT entries, we fix them up a little.  We
  * don't care if they're invalid: the worst that can happen is a General
  * Protection Fault in the Switcher when it restores a Guest segment register
  * which tries to use that entry.  Then we kill the Guest for causing such a
@@ -84,25 +82,33 @@
 	}
 }
 
-/* This routine is called at boot or modprobe time for each CPU to set up the
- * "constant" GDT entries for Guests running on that CPU. */
+/*H:610 Like the IDT, we never simply use the GDT the Guest gives us.  We keep
+ * a GDT for each CPU, and copy across the Guest's entries each time we want to
+ * run the Guest on that CPU.
+ *
+ * This routine is called at boot or modprobe time for each CPU to set up the
+ * constant GDT entries: the ones which are the same no matter what Guest we're
+ * running. */
 void setup_default_gdt_entries(struct lguest_ro_state *state)
 {
 	struct desc_struct *gdt = state->guest_gdt;
 	unsigned long tss = (unsigned long)&state->guest_tss;
 
-	/* The hypervisor segments are full 0-4G segments, privilege level 0 */
+	/* The Switcher segments are full 0-4G segments, privilege level 0 */
 	gdt[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
 	gdt[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
 
-	/* The TSS segment refers to the TSS entry for this CPU, so we cannot
-	 * copy it from the Guest.  Forgive the magic flags */
+	/* The TSS segment refers to the TSS entry for this particular CPU.
+	 * Forgive the magic flags: the 0x8900 means the entry is Present, it's
+	 * privilege level 0 Available 386 TSS system segment, and the 0x67
+	 * means Saturn is eclipsed by Mercury in the twelfth house. */
 	gdt[GDT_ENTRY_TSS].a = 0x00000067 | (tss << 16);
 	gdt[GDT_ENTRY_TSS].b = 0x00008900 | (tss & 0xFF000000)
 		| ((tss >> 16) & 0x000000FF);
 }
 
-/* This routine is called before the Guest is run for the first time. */
+/* This routine sets up the initial Guest GDT for booting.  All entries start
+ * as 0 (unusable). */
 void setup_guest_gdt(struct lguest *lg)
 {
 	/* Start with full 0-4G segments... */
@@ -114,13 +120,8 @@
 	lg->arch.gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13);
 }
 
-/* Like the IDT, we never simply use the GDT the Guest gives us.  We set up the
- * GDTs for each CPU, then we copy across the entries each time we want to run
- * a different Guest on that CPU. */
-
-/* A partial GDT load, for the three "thead-local storage" entries.  Otherwise
- * it's just like load_guest_gdt().  So much, in fact, it would probably be
- * neater to have a single hypercall to cover both. */
+/*H:650 An optimization of copy_gdt(), for just the three "thead-local storage"
+ * entries. */
 void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt)
 {
 	unsigned int i;
@@ -129,7 +130,9 @@
 		gdt[i] = lg->arch.gdt[i];
 }
 
-/* This is the full version */
+/*H:640 When the Guest is run on a different CPU, or the GDT entries have
+ * changed, copy_gdt() is called to copy the Guest's GDT entries across to this
+ * CPU's GDT. */
 void copy_gdt(const struct lguest *lg, struct desc_struct *gdt)
 {
 	unsigned int i;
@@ -141,7 +144,8 @@
 			gdt[i] = lg->arch.gdt[i];
 }
 
-/* This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT). */
+/*H:620 This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT).
+ * We copy it from the Guest and tweak the entries. */
 void load_guest_gdt(struct lguest *lg, unsigned long table, u32 num)
 {
 	/* We assume the Guest has the same number of GDT entries as the
@@ -157,16 +161,22 @@
 	lg->changed |= CHANGED_GDT;
 }
 
+/* This is the fast-track version for just changing the three TLS entries.
+ * Remember that this happens on every context switch, so it's worth
+ * optimizing.  But wouldn't it be neater to have a single hypercall to cover
+ * both cases? */
 void guest_load_tls(struct lguest *lg, unsigned long gtls)
 {
 	struct desc_struct *tls = &lg->arch.gdt[GDT_ENTRY_TLS_MIN];
 
 	__lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
 	fixup_gdt_table(lg, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1);
+	/* Note that just the TLS entries have changed. */
 	lg->changed |= CHANGED_GDT_TLS;
 }
+/*:*/
 
-/*
+/*H:660
  * With this, we have finished the Host.
  *
  * Five of the seven parts of our task are complete.  You have made it through
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 09d9207..482aec2 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -63,7 +63,7 @@
 static DEFINE_PER_CPU(struct lguest *, last_guest);
 
 /*S:010
- * We are getting close to the Switcher.
+ * We approach the Switcher.
  *
  * Remember that each CPU has two pages which are visible to the Guest when it
  * runs on that CPU.  This has to contain the state for that Guest: we copy the
@@ -134,7 +134,7 @@
 	 *
 	 * The lcall also pushes the old code segment (KERNEL_CS) onto the
 	 * stack, then the address of this call.  This stack layout happens to
-	 * exactly match the stack of an interrupt... */
+	 * exactly match the stack layout created by an interrupt... */
 	asm volatile("pushf; lcall *lguest_entry"
 		     /* This is how we tell GCC that %eax ("a") and %ebx ("b")
 		      * are changed by this routine.  The "=" means output. */
@@ -151,40 +151,46 @@
 }
 /*:*/
 
+/*M:002 There are hooks in the scheduler which we can register to tell when we
+ * get kicked off the CPU (preempt_notifier_register()).  This would allow us
+ * to lazily disable SYSENTER which would regain some performance, and should
+ * also simplify copy_in_guest_info().  Note that we'd still need to restore
+ * things when we exit to Launcher userspace, but that's fairly easy.
+ *
+ * The hooks were designed for KVM, but we can also put them to good use. :*/
+
 /*H:040 This is the i386-specific code to setup and run the Guest.  Interrupts
  * are disabled: we own the CPU. */
 void lguest_arch_run_guest(struct lguest *lg)
 {
-	/* Remember the awfully-named TS bit?  If the Guest has asked
-	 * to set it we set it now, so we can trap and pass that trap
-	 * to the Guest if it uses the FPU. */
+	/* Remember the awfully-named TS bit?  If the Guest has asked to set it
+	 * we set it now, so we can trap and pass that trap to the Guest if it
+	 * uses the FPU. */
 	if (lg->ts)
 		lguest_set_ts();
 
-	/* SYSENTER is an optimized way of doing system calls.  We
-	 * can't allow it because it always jumps to privilege level 0.
-	 * A normal Guest won't try it because we don't advertise it in
-	 * CPUID, but a malicious Guest (or malicious Guest userspace
-	 * program) could, so we tell the CPU to disable it before
-	 * running the Guest. */
+	/* SYSENTER is an optimized way of doing system calls.  We can't allow
+	 * it because it always jumps to privilege level 0.  A normal Guest
+	 * won't try it because we don't advertise it in CPUID, but a malicious
+	 * Guest (or malicious Guest userspace program) could, so we tell the
+	 * CPU to disable it before running the Guest. */
 	if (boot_cpu_has(X86_FEATURE_SEP))
 		wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);
 
-	/* Now we actually run the Guest.  It will pop back out when
-	 * something interesting happens, and we can examine its
-	 * registers to see what it was doing. */
+	/* Now we actually run the Guest.  It will return when something
+	 * interesting happens, and we can examine its registers to see what it
+	 * was doing. */
 	run_guest_once(lg, lguest_pages(raw_smp_processor_id()));
 
-	/* The "regs" pointer contains two extra entries which are not
-	 * really registers: a trap number which says what interrupt or
-	 * trap made the switcher code come back, and an error code
-	 * which some traps set.  */
+	/* Note that the "regs" pointer contains two extra entries which are
+	 * not really registers: a trap number which says what interrupt or
+	 * trap made the switcher code come back, and an error code which some
+	 * traps set.  */
 
-	/* If the Guest page faulted, then the cr2 register will tell
-	 * us the bad virtual address.  We have to grab this now,
-	 * because once we re-enable interrupts an interrupt could
-	 * fault and thus overwrite cr2, or we could even move off to a
-	 * different CPU. */
+	/* If the Guest page faulted, then the cr2 register will tell us the
+	 * bad virtual address.  We have to grab this now, because once we
+	 * re-enable interrupts an interrupt could fault and thus overwrite
+	 * cr2, or we could even move off to a different CPU. */
 	if (lg->regs->trapnum == 14)
 		lg->arch.last_pagefault = read_cr2();
 	/* Similarly, if we took a trap because the Guest used the FPU,
@@ -197,14 +203,15 @@
 		wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
 }
 
-/*H:130 Our Guest is usually so well behaved; it never tries to do things it
- * isn't allowed to.  Unfortunately, Linux's paravirtual infrastructure isn't
- * quite complete, because it doesn't contain replacements for the Intel I/O
- * instructions.  As a result, the Guest sometimes fumbles across one during
- * the boot process as it probes for various things which are usually attached
- * to a PC.
+/*H:130 Now we've examined the hypercall code; our Guest can make requests.
+ * Our Guest is usually so well behaved; it never tries to do things it isn't
+ * allowed to, and uses hypercalls instead.  Unfortunately, Linux's paravirtual
+ * infrastructure isn't quite complete, because it doesn't contain replacements
+ * for the Intel I/O instructions.  As a result, the Guest sometimes fumbles
+ * across one during the boot process as it probes for various things which are
+ * usually attached to a PC.
  *
- * When the Guest uses one of these instructions, we get trap #13 (General
+ * When the Guest uses one of these instructions, we get a trap (General
  * Protection Fault) and come here.  We see if it's one of those troublesome
  * instructions and skip over it.  We return true if we did. */
 static int emulate_insn(struct lguest *lg)
@@ -275,43 +282,43 @@
 void lguest_arch_handle_trap(struct lguest *lg)
 {
 	switch (lg->regs->trapnum) {
-	case 13: /* We've intercepted a GPF. */
-		 /* Check if this was one of those annoying IN or OUT
-		  * instructions which we need to emulate.  If so, we
-		  * just go back into the Guest after we've done it. */
+	case 13: /* We've intercepted a General Protection Fault. */
+		/* Check if this was one of those annoying IN or OUT
+		 * instructions which we need to emulate.  If so, we just go
+		 * back into the Guest after we've done it. */
 		if (lg->regs->errcode == 0) {
 			if (emulate_insn(lg))
 				return;
 		}
 		break;
-	case 14: /* We've intercepted a page fault. */
-		 /* The Guest accessed a virtual address that wasn't
-		  * mapped.  This happens a lot: we don't actually set
-		  * up most of the page tables for the Guest at all when
-		  * we start: as it runs it asks for more and more, and
-		  * we set them up as required. In this case, we don't
-		  * even tell the Guest that the fault happened.
-		  *
-		  * The errcode tells whether this was a read or a
-		  * write, and whether kernel or userspace code. */
+	case 14: /* We've intercepted a Page Fault. */
+		/* The Guest accessed a virtual address that wasn't mapped.
+		 * This happens a lot: we don't actually set up most of the
+		 * page tables for the Guest at all when we start: as it runs
+		 * it asks for more and more, and we set them up as
+		 * required. In this case, we don't even tell the Guest that
+		 * the fault happened.
+		 *
+		 * The errcode tells whether this was a read or a write, and
+		 * whether kernel or userspace code. */
 		if (demand_page(lg, lg->arch.last_pagefault, lg->regs->errcode))
 			return;
 
-		 /* OK, it's really not there (or not OK): the Guest
-		  * needs to know.  We write out the cr2 value so it
-		  * knows where the fault occurred.
-		  *
-		  * Note that if the Guest were really messed up, this
-		  * could happen before it's done the INITIALIZE
-		  * hypercall, so lg->lguest_data will be NULL */
+		/* OK, it's really not there (or not OK): the Guest needs to
+		 * know.  We write out the cr2 value so it knows where the
+		 * fault occurred.
+		 *
+		 * Note that if the Guest were really messed up, this could
+		 * happen before it's done the LHCALL_LGUEST_INIT hypercall, so
+		 * lg->lguest_data could be NULL */
 		if (lg->lguest_data &&
 		    put_user(lg->arch.last_pagefault, &lg->lguest_data->cr2))
 			kill_guest(lg, "Writing cr2");
 		break;
 	case 7: /* We've intercepted a Device Not Available fault. */
-		/* If the Guest doesn't want to know, we already
-		 * restored the Floating Point Unit, so we just
-		 * continue without telling it. */
+		/* If the Guest doesn't want to know, we already restored the
+		 * Floating Point Unit, so we just continue without telling
+		 * it. */
 		if (!lg->ts)
 			return;
 		break;
@@ -536,9 +543,6 @@
 
 	return 0;
 }
-/* Now we've examined the hypercall code; our Guest can make requests.  There
- * is one other way we can do things for the Guest, as we see in
- * emulate_insn(). :*/
 
 /*L:030 lguest_arch_setup_regs()
  *
@@ -570,8 +574,8 @@
 
 	/* %esi points to our boot information, at physical address 0, so don't
 	 * touch it. */
+
 	/* There are a couple of GDT entries the Guest expects when first
 	 * booting. */
-
 	setup_guest_gdt(lg);
 }
diff --git a/drivers/lguest/x86/switcher_32.S b/drivers/lguest/x86/switcher_32.S
index 1010b90..0af8baa 100644
--- a/drivers/lguest/x86/switcher_32.S
+++ b/drivers/lguest/x86/switcher_32.S
@@ -6,6 +6,37 @@
  * are feeling invigorated and refreshed then the next, more challenging stage
  * can be found in "make Guest". :*/
 
+/*M:012 Lguest is meant to be simple: my rule of thumb is that 1% more LOC must
+ * gain at least 1% more performance.  Since neither LOC nor performance can be
+ * measured beforehand, it generally means implementing a feature then deciding
+ * if it's worth it.  And once it's implemented, who can say no?
+ *
+ * This is why I haven't implemented this idea myself.  I want to, but I
+ * haven't.  You could, though.
+ *
+ * The main place where lguest performance sucks is Guest page faulting.  When
+ * a Guest userspace process hits an unmapped page we switch back to the Host,
+ * walk the page tables, find it's not mapped, switch back to the Guest page
+ * fault handler, which calls a hypercall to set the page table entry, then
+ * finally returns to userspace.  That's two round-trips.
+ *
+ * If we had a small walker in the Switcher, we could quickly check the Guest
+ * page table and if the page isn't mapped, immediately reflect the fault back
+ * into the Guest.  This means the Switcher would have to know the top of the
+ * Guest page table and the page fault handler address.
+ *
+ * For simplicity, the Guest should only handle the case where the privilege
+ * level of the fault is 3 and probably only not present or write faults.  It
+ * should also detect recursive faults, and hand the original fault to the
+ * Host (which is actually really easy).
+ *
+ * Two questions remain.  Would the performance gain outweigh the complexity?
+ * And who would write the verse documenting it? :*/
+
+/*M:011 Lguest64 handles NMI.  This gave me NMI envy (until I looked at their
+ * code).  It's worth doing though, since it would let us use oprofile in the
+ * Host when a Guest is running. :*/
+
 /*S:100
  * Welcome to the Switcher itself!
  *
@@ -88,7 +119,7 @@
 
 	// All saved and there's now five steps before us:
 	// Stack, GDT, IDT, TSS
-	// And last of all the page tables are flipped.
+	// Then last of all the page tables are flipped.
 
 	// Yet beware that our stack pointer must be
 	// Always valid lest an NMI hits
@@ -103,25 +134,25 @@
 	lgdt	LGUEST_PAGES_guest_gdt_desc(%eax)
 
 	// The Guest's IDT we did partially
-	// Move to the "struct lguest_pages" as well.
+	// Copy to "struct lguest_pages" as well.
 	lidt	LGUEST_PAGES_guest_idt_desc(%eax)
 
 	// The TSS entry which controls traps
 	// Must be loaded up with "ltr" now:
+	// The GDT entry that TSS uses 
+	// Changes type when we load it: damn Intel!
 	// For after we switch over our page tables
-	// It (as the rest) will be writable no more.
-	// (The GDT entry TSS needs
-	// Changes type when we load it: damn Intel!)
+	// That entry will be read-only: we'd crash.
 	movl	$(GDT_ENTRY_TSS*8), %edx
 	ltr	%dx
 
 	// Look back now, before we take this last step!
 	// The Host's TSS entry was also marked used;
-	// Let's clear it again, ere we return.
+	// Let's clear it again for our return.
 	// The GDT descriptor of the Host
 	// Points to the table after two "size" bytes
 	movl	(LGUEST_PAGES_host_gdt_desc+2)(%eax), %edx
-	// Clear the type field of "used" (byte 5, bit 2)
+	// Clear "used" from type field (byte 5, bit 2)
 	andb	$0xFD, (GDT_ENTRY_TSS*8 + 5)(%edx)
 
 	// Once our page table's switched, the Guest is live!
@@ -131,7 +162,7 @@
 
 	// The page table change did one tricky thing:
 	// The Guest's register page has been mapped
-	// Writable onto our %esp (stack) --
+	// Writable under our %esp (stack) --
 	// We can simply pop off all Guest regs.
 	popl	%eax
 	popl	%ebx
@@ -152,16 +183,15 @@
 	addl	$8, %esp
 
 	// The last five stack slots hold return address
-	// And everything needed to change privilege
-	// Into the Guest privilege level of 1,
+	// And everything needed to switch privilege
+	// From Switcher's level 0 to Guest's 1,
 	// And the stack where the Guest had last left it.
 	// Interrupts are turned back on: we are Guest.
 	iret
 
-// There are two paths where we switch to the Host
+// We treat two paths to switch back to the Host
+// Yet both must save Guest state and restore Host
 // So we put the routine in a macro.
-// We are on our way home, back to the Host
-// Interrupted out of the Guest, we come here.
 #define SWITCH_TO_HOST							\
 	/* We save the Guest state: all registers first			\
 	 * Laid out just as "struct lguest_regs" defines */		\
@@ -194,7 +224,7 @@
 	movl	%esp, %eax;						\
 	andl	$(~(1 << PAGE_SHIFT - 1)), %eax;			\
 	/* Save our trap number: the switch will obscure it		\
-	 * (The Guest regs are not mapped here in the Host)		\
+	 * (In the Host the Guest regs are not mapped here)		\
 	 * %ebx holds it safe for deliver_to_host */			\
 	movl	LGUEST_PAGES_regs_trapnum(%eax), %ebx;			\
 	/* The Host GDT, IDT and stack!					\
@@ -210,9 +240,9 @@
 	/* Switch to Host's GDT, IDT. */				\
 	lgdt	LGUEST_PAGES_host_gdt_desc(%eax);			\
 	lidt	LGUEST_PAGES_host_idt_desc(%eax);			\
-	/* Restore the Host's stack where it's saved regs lie */	\
+	/* Restore the Host's stack where its saved regs lie */		\
 	movl	LGUEST_PAGES_host_sp(%eax), %esp;			\
-	/* Last the TSS: our Host is complete */			\
+	/* Last the TSS: our Host is returned */			\
 	movl	$(GDT_ENTRY_TSS*8), %edx;				\
 	ltr	%dx;							\
 	/* Restore now the regs saved right at the first. */		\
@@ -222,14 +252,15 @@
 	popl	%ds;							\
 	popl	%es
 
-// Here's where we come when the Guest has just trapped:
-// (Which trap we'll see has been pushed on the stack).
+// The first path is trod when the Guest has trapped:
+// (Which trap it was has been pushed on the stack).
 // We need only switch back, and the Host will decode
 // Why we came home, and what needs to be done.
 return_to_host:
 	SWITCH_TO_HOST
 	iret
 
+// We are lead to the second path like so:
 // An interrupt, with some cause external
 // Has ajerked us rudely from the Guest's code
 // Again we must return home to the Host
@@ -238,7 +269,7 @@
 	// But now we must go home via that place
 	// Where that interrupt was supposed to go
 	// Had we not been ensconced, running the Guest.
-	// Here we see the cleverness of our stack:
+	// Here we see the trickness of run_guest_once():
 	// The Host stack is formed like an interrupt
 	// With EIP, CS and EFLAGS layered.
 	// Interrupt handlers end with "iret"
@@ -263,7 +294,7 @@
 	xorw	%ax, %ax
 	orl	%eax, %edx
 	// Now the address of the handler's in %edx
-	// We call it now: its "iret" takes us home.
+	// We call it now: its "iret" drops us home.
 	jmp	*%edx
 
 // Every interrupt can come to us here
diff --git a/include/asm-x86/lguest_hcall.h b/include/asm-x86/lguest_hcall.h
index f948491..9c5092b 100644
--- a/include/asm-x86/lguest_hcall.h
+++ b/include/asm-x86/lguest_hcall.h
@@ -18,12 +18,17 @@
 #define LHCALL_LOAD_TLS		16
 #define LHCALL_NOTIFY		17
 
+#define LGUEST_TRAP_ENTRY 0x1F
+
+#ifndef __ASSEMBLY__
+#include <asm/hw_irq.h>
+
 /*G:031 First, how does our Guest contact the Host to ask for privileged
  * operations?  There are two ways: the direct way is to make a "hypercall",
  * to make requests of the Host Itself.
  *
  * Our hypercall mechanism uses the highest unused trap code (traps 32 and
- * above are used by real hardware interrupts).  Seventeen hypercalls are
+ * above are used by real hardware interrupts).  Fifteen hypercalls are
  * available: the hypercall number is put in the %eax register, and the
  * arguments (when required) are placed in %edx, %ebx and %ecx.  If a return
  * value makes sense, it's returned in %eax.
@@ -31,20 +36,15 @@
  * Grossly invalid calls result in Sudden Death at the hands of the vengeful
  * Host, rather than returning failure.  This reflects Winston Churchill's
  * definition of a gentleman: "someone who is only rude intentionally". */
-#define LGUEST_TRAP_ENTRY 0x1F
-
-#ifndef __ASSEMBLY__
-#include <asm/hw_irq.h>
-
 static inline unsigned long
 hcall(unsigned long call,
       unsigned long arg1, unsigned long arg2, unsigned long arg3)
 {
 	/* "int" is the Intel instruction to trigger a trap. */
 	asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
-		       /* The call is in %eax (aka "a"), and can be replaced */
+		       /* The call in %eax (aka "a") might be overwritten */
 		     : "=a"(call)
-		       /* The other arguments are in %eax, %edx, %ebx & %ecx */
+		       /* The arguments are in %eax, %edx, %ebx & %ecx */
 		     : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3)
 		       /* "memory" means this might write somewhere in memory.
 			* This isn't true for all calls, but it's safe to tell
diff --git a/include/linux/lguest.h b/include/linux/lguest.h
index 8beb291..175e63f 100644
--- a/include/linux/lguest.h
+++ b/include/linux/lguest.h
@@ -12,8 +12,8 @@
 #define LG_CLOCK_MAX_DELTA	ULONG_MAX
 
 /*G:032 The second method of communicating with the Host is to via "struct
- * lguest_data".  The Guest's very first hypercall is to tell the Host where
- * this is, and then the Guest and Host both publish information in it. :*/
+ * lguest_data".  Once the Guest's initialization hypercall tells the Host where
+ * this is, the Guest and Host both publish information in it. :*/
 struct lguest_data
 {
 	/* 512 == enabled (same as eflags in normal hardware).  The Guest
diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h
index c41fd48..697104d 100644
--- a/include/linux/lguest_launcher.h
+++ b/include/linux/lguest_launcher.h
@@ -10,7 +10,11 @@
  * real devices (think of the damage it could do!) we provide virtual devices.
  * We could emulate a PCI bus with various devices on it, but that is a fairly
  * complex burden for the Host and suboptimal for the Guest, so we have our own
- * "lguest" bus and simple drivers.
+ * simple lguest bus and we use "virtio" drivers.  These drivers need a set of
+ * routines from us which will actually do the virtual I/O, but they handle all
+ * the net/block/console stuff themselves.  This means that if we want to add
+ * a new device, we simply need to write a new virtio driver and create support
+ * for it in the Launcher: this code won't need to change.
  *
  * Devices are described by a simplified ID, a status byte, and some "config"
  * bytes which describe this device's configuration.  This is placed by the