diff --git a/Makefile b/Makefile
index c4016e8..8d5c913 100644
--- a/Makefile
+++ b/Makefile
@@ -10,11 +10,20 @@ VERSION=pre-0.4.3-$(shell date +"%Y%m%d_%H%M%S")-$(shell hostname)
 # Output directory
 OUT=out/
 
+# Configure as a coreboot payload.
+COREBOOT=y
+
+ifdef COREBOOT
+CFGSRC=cbcfg.c
+else
+CFGSRC=pv.c
+endif
+
 # Source files
 SRCBOTH=output.c util.c block.c floppy.c ata.c misc.c mouse.c kbd.c pci.c \
         serial.c clock.c pic.c cdrom.c ps2port.c smp.c resume.c \
         pnpbios.c pirtable.c vgahooks.c pmm.c ramdisk.c \
-        usb.c usb-uhci.c usb-hid.c
+        usb.c usb-uhci.c usb-hid.c $(CFGSRC)
 SRC16=$(SRCBOTH) system.c disk.c apm.c pcibios.c font.c
 SRC32=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
       acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
diff --git a/src/boot.c b/src/boot.c
index 7b74007..71d6e27 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -12,6 +12,7 @@
 #include "bregs.h" // struct bregs
 #include "boot.h" // struct ipl_s
 #include "cmos.h" // inb_cmos
+#include "cfg.h"
 
 struct ipl_s IPL;
 
@@ -206,7 +207,7 @@ menu_show_cbfs(struct ipl_entry_s *ie, int menupos)
 static void
 interactive_bootmenu()
 {
-    if (! CONFIG_BOOTMENU)
+    if (! CONFIG_BOOTMENU || ! cfg_show_boot_menu())
         return;
 
     while (get_keystroke(0) >= 0)
diff --git a/src/cbcfg.c b/src/cbcfg.c
new file mode 100644
index 0000000..56b6076
--- /dev/null
+++ b/src/cbcfg.c
@@ -0,0 +1,13 @@
+#include "config.h"
+#include "util.h"
+#include "cfg.h"
+
+void cfg_get_uuid(u8 *uuid)
+{
+    memset(uuid, 0, 16);
+}
+
+int cfg_show_boot_menu(void)
+{
+    return 1;
+}
diff --git a/src/cfg.h b/src/cfg.h
new file mode 100644
index 0000000..1f6b488
--- /dev/null
+++ b/src/cfg.h
@@ -0,0 +1,6 @@
+#ifndef __CFG_H
+#define __CFG_H
+
+void cfg_get_uuid(u8 *uuid);
+int cfg_show_boot_menu(void);
+#endif
diff --git a/src/post.c b/src/post.c
index f72e134..e8ae3f0 100644
--- a/src/post.c
+++ b/src/post.c
@@ -20,6 +20,7 @@
 #include "mptable.h" // mptable_init
 #include "boot.h" // IPL
 #include "usb.h" // usb_setup
+#include "pv.h"
 
 void
 __set_irq(int vector, void *loc)
@@ -184,6 +185,8 @@ post()
     serial_setup();
     mouse_setup();
 
+    qemu_cfg_port_probe();
+
     init_bios_tables();
 
     boot_setup();
diff --git a/src/pv.c b/src/pv.c
new file mode 100644
index 0000000..fa57b5b
--- /dev/null
+++ b/src/pv.c
@@ -0,0 +1,67 @@
+#include "config.h"
+#include "ioport.h"
+#include "pv.h"
+
+int qemu_cfg_present;
+
+static void
+qemu_cfg_select(u16 f)
+{
+    outw(f, PORT_QEMU_CFG_CTL);
+}
+
+static void
+qemu_cfg_read(u8 *buf, int len)
+{
+    while (len--)
+        *(buf++) = inb(PORT_QEMU_CFG_DATA);
+}
+
+static void
+qemu_cfg_read_entry(void *buf, int e, int len)
+{
+    qemu_cfg_select(e);
+    qemu_cfg_read(buf, len);
+}
+
+void qemu_cfg_port_probe(void)
+{
+    char *sig = "QEMU";
+    int i;
+
+    if (CONFIG_COREBOOT)
+        return;
+
+    qemu_cfg_present = 1;
+
+    qemu_cfg_select(QEMU_CFG_SIGNATURE);
+
+    for (i = 0; i < 4; i++)
+        if (inb(PORT_QEMU_CFG_DATA) != sig[i]) {
+            qemu_cfg_present = 0;
+            break;
+        }
+    dprintf(4, "qemu_cfg_present=%d\n", qemu_cfg_present);
+}
+
+void cfg_get_uuid(u8 *uuid)
+{
+    memset(uuid, 0, 16);
+
+    if (!qemu_cfg_present || !CONFIG_UUID_BACKDOOR)
+        return;
+
+    qemu_cfg_read_entry(uuid, QEMU_CFG_UUID, 16);
+}
+
+int cfg_show_boot_menu(void)
+{
+    u16 v;
+    if (!qemu_cfg_present)
+        return 1;
+
+    qemu_cfg_read_entry(&v, QEMU_CFG_BOOT_MENU, sizeof(v));
+
+    return v;
+}
+
diff --git a/src/pv.h b/src/pv.h
new file mode 100644
index 0000000..632a29c
--- /dev/null
+++ b/src/pv.h
@@ -0,0 +1,42 @@
+#ifndef __PV_H
+#define __PV_H
+
+#include "util.h"
+
+/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx.  It
+ * should be used to determine that a VM is running under KVM.
+ */
+#define KVM_CPUID_SIGNATURE     0x40000000
+
+static inline int kvm_para_available(void)
+{
+    unsigned int eax, ebx, ecx, edx;
+    char signature[13];
+
+    cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx);
+    memcpy(signature + 0, &ebx, 4);
+    memcpy(signature + 4, &ecx, 4);
+    memcpy(signature + 8, &edx, 4);
+    signature[12] = 0;
+
+    if (strcmp(signature, "KVMKVMKVM") == 0)
+        return 1;
+
+    return 0;
+}
+
+#define QEMU_CFG_SIGNATURE		0x00
+#define QEMU_CFG_ID			0x01
+#define QEMU_CFG_UUID			0x02
+#define QEMU_CFG_NUMA			0x0d
+#define QEMU_CFG_BOOT_MENU		0x0e
+#define QEMU_CFG_MAX_CPUS		0x0f
+#define QEMU_CFG_ARCH_LOCAL		0x8000
+#define QEMU_CFG_ACPI_TABLES		(QEMU_CFG_ARCH_LOCAL + 0)
+#define QEMU_CFG_SMBIOS_ENTRIES		(QEMU_CFG_ARCH_LOCAL + 1)
+
+extern int qemu_cfg_present;
+
+void qemu_cfg_port_probe(void);
+
+#endif
diff --git a/src/smbios.c b/src/smbios.c
index 6fbddd9..4caab19 100644
--- a/src/smbios.c
+++ b/src/smbios.c
@@ -7,50 +7,7 @@
 
 #include "util.h" // dprintf
 #include "biosvar.h" // GET_EBDA
-
-
-/****************************************************************
- * UUID probe
- ****************************************************************/
-
-#define QEMU_CFG_SIGNATURE  0x00
-#define QEMU_CFG_ID         0x01
-#define QEMU_CFG_UUID       0x02
-
-static void
-qemu_cfg_read(u8 *buf, u16 f, int len)
-{
-    outw(f, PORT_QEMU_CFG_CTL);
-    while (len--)
-        *(buf++) = inb(PORT_QEMU_CFG_DATA);
-}
-
-static int
-qemu_cfg_port_probe()
-{
-    u8 sig[4] = "QEMU";
-    u8 buf[4];
-    qemu_cfg_read(buf, QEMU_CFG_SIGNATURE, 4);
-    return *(u32*)buf == *(u32*)sig;
-}
-
-static void
-uuid_probe(u8 *bios_uuid)
-{
-    // Default to UUID not set
-    memset(bios_uuid, 0, 16);
-
-    if (! CONFIG_UUID_BACKDOOR)
-        return;
-    if (CONFIG_COREBOOT)
-        return;
-    if (! qemu_cfg_port_probe())
-        // Feature not available
-        return;
-
-    qemu_cfg_read(bios_uuid, QEMU_CFG_UUID, 16);
-}
-
+#include "cfg.h"
 
 /****************************************************************
  * smbios tables
@@ -304,7 +261,7 @@ smbios_type_1_init(void *start)
     p->version_str = 0;
     p->serial_number_str = 0;
 
-    uuid_probe(p->uuid);
+    cfg_get_uuid(p->uuid);
 
     p->wake_up_type = 0x06; /* power switch */
     p->sku_number_str = 0;
