Lguest support for Virtio

This makes lguest able to use the virtio devices.

We change the device descriptor page from a simple array to a variable
length "type, config_len, status, config data..." format, and
implement virtio_config_ops to read from that config data.

We use the virtio ring implementation for an efficient Guest <-> Host
virtqueue mechanism, and the new LHCALL_NOTIFY hypercall to kick the
host when it changes.

We also use LHCALL_NOTIFY on kernel addresses for very very early
console output.  We could have another hypercall, but this hack works
quite well.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 959aeeb..495e46a 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -55,6 +55,7 @@
 #include <linux/clockchips.h>
 #include <linux/lguest.h>
 #include <linux/lguest_launcher.h>
+#include <linux/virtio_console.h>
 #include <asm/paravirt.h>
 #include <asm/param.h>
 #include <asm/page.h>
@@ -849,6 +850,23 @@
 	return "LGUEST";
 }
 
+/* Before virtqueues are 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;
+
+	if (len > sizeof(scratch) - 1)
+		len = sizeof(scratch) - 1;
+	scratch[len] = '\0';
+	memcpy(scratch, buf, len);
+	hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0);
+
+	/* This routine returns the number of bytes actually written. */
+	return len;
+}
+
 /*G:050
  * Patching (Powerfully Placating Performance Pedants)
  *
@@ -1048,6 +1066,9 @@
 	 * adapted for lguest's use. */
 	add_preferred_console("hvc", 0, NULL);
 
+	/* Register our very early console. */
+	virtio_cons_early_init(early_put_chars);
+
 	/* Last of all, we set the power management poweroff hook to point to
 	 * the Guest routine to power off. */
 	pm_power_off = lguest_power_off;