Introduce standard for performing and inspecting the run-time detection of para-virtualized environments.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/Kconfig | 14 +++++++++++--- src/misc.c | 2 ++ src/paravirt.c | 5 +++++ src/paravirt.h | 20 ++++++++++++++++++-- src/xen.c | 7 +++++-- 5 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig index bbcefe0..6fd45b4 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -14,9 +14,10 @@ choice Configure as a coreboot payload.
config QEMU - bool "Build for QEMU" + bool "Build for QEMU/XEN/KVM/Bochs" + select QEMU_HARDWARE help - Configure as QEMU bios. + Configure for an emulated machine (QEMU, XEN, KVM, or Bochs).
config CSM bool "Build as Compatibilty Support Module for EFI BIOS" @@ -26,9 +27,16 @@ choice
endchoice
+ config QEMU_HARDWARE + bool "Support hardware found on emulators (QEMU/XEN/KVM/Bochs)" if !QEMU + default n + help + Support virtual hardware when the code detects it is + running on an emulator. + config XEN depends on QEMU - bool "Build for Xen HVM" + bool "Support Xen HVM" default y help Configure to be used by xen hvmloader, for a HVM guest. diff --git a/src/misc.c b/src/misc.c index bcc450a..3b2ffc1 100644 --- a/src/misc.c +++ b/src/misc.c @@ -16,6 +16,8 @@ u32 RamSize VAR16VISIBLE; u64 RamSizeOver4G; // Space for bios tables built an run-time. char BiosTableSpace[CONFIG_MAX_BIOSTABLE] __aligned(MALLOC_MIN_ALIGN) VAR16VISIBLE; +// Type of emulator platform. +int PlatformRunningOn VAR16VISIBLE;
/**************************************************************** diff --git a/src/paravirt.c b/src/paravirt.c index 9022186..6e230ee 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -24,6 +24,11 @@ int qemu_cfg_present; void qemu_ramsize_preinit(void) { + if (!CONFIG_QEMU) + return; + + PlatformRunningOn = PF_QEMU; + // On emulators, get memory size from nvram. u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24)); diff --git a/src/paravirt.h b/src/paravirt.h index 4f2d5b8..d32ca13 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -1,8 +1,24 @@ #ifndef __PV_H #define __PV_H
-#include "config.h" // CONFIG_COREBOOT -#include "util.h" +#include "config.h" // CONFIG_* +#include "util.h" // memcpy +#include "biosvar.h" // GET_GLOBAL + +// Types of paravirtualized platforms. +#define PF_QEMU (1<<0) +#define PF_XEN (1<<1) + +// misc.c +extern int PlatformRunningOn; + +static inline int runningOnQEMU(void) { + return CONFIG_QEMU || ( + CONFIG_QEMU_HARDWARE && GET_GLOBAL(PlatformRunningOn) & PF_QEMU); +} +static inline int runningOnXen(void) { + return CONFIG_XEN && GET_GLOBAL(PlatformRunningOn) & PF_XEN; +}
/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It * should be used to determine that a VM is running under KVM. diff --git a/src/xen.c b/src/xen.c index c9759f0..e075af2 100644 --- a/src/xen.c +++ b/src/xen.c @@ -6,7 +6,7 @@
#include "config.h" #include "xen.h" - +#include "paravirt.h" // PlatformRunningOn #include "memmap.h" // add_e820 #include "types.h" // ASM32FLAT #include "util.h" // copy_acpi_rsdp @@ -76,8 +76,11 @@ void xen_preinit(void) break; } } - if (!xen_cpuid_base) + if (!xen_cpuid_base) { dprintf(1, "No Xen hypervisor found.\n"); + return; + } + PlatformRunningOn = PF_QEMU|PF_XEN; }
static int hypercall_xen_version( int cmd, void *arg)