diff options
-rw-r--r-- | src/hypervisor_vendor.c | 67 |
1 files changed, 60 insertions, 7 deletions
diff --git a/src/hypervisor_vendor.c b/src/hypervisor_vendor.c index 03ce1663..bfa78c21 100644 --- a/src/hypervisor_vendor.c +++ b/src/hypervisor_vendor.c @@ -6,6 +6,11 @@ #include <stdio.h> #include <string.h> +#include <unistd.h> + +#define PROC_XEN "/proc/xen" +#define PROC_XENCAP PROC_XEN "/capabilities" +#define PROC_PCIDEVS "/proc/bus/pci/devices" /* * This CPUID leaf returns the information about the hypervisor. @@ -61,16 +66,64 @@ static const char *get_hypervisor(void) else if (!strncmp("VMwareVMware", hyper_vendor_id, 12)) return "VMware"; else - return "Unknown"; + return NULL; } -int main(int argc, char **argv) +static int +has_pci_device(int vendor, int device) { - const char *vm = get_hypervisor(); + FILE *f; + int num, fn, ven, dev; + int res = 1; - if (vm) { - printf("%s\n", vm); + f = fopen(PROC_PCIDEVS, "r"); + if (!f) return 0; - } else - return 1; + + /* for more details about bus/pci/devices format see + * drivers/pci/proc.c in linux kernel + */ + while(fscanf(f, "%02x%02x\t%04x%04x\t%*[^\n]", + &num, &fn, &ven, &dev) == 4) { + + if (ven == vendor && dev == device) + goto found; + } + + res = 0; +found: + fclose(f); + return res; +} + +int main(int argc, char **argv) +{ + const char *hvm = get_hypervisor(); + + if (hvm) + printf("%s\n", hvm); + + /* Grotty code to look for old Xen */ + else if (access(PROC_XEN, F_OK) == 0) { + FILE *fd = fopen(PROC_XENCAP, "r"); + int dom0 = 0; + + if (fd) { + char buf[256]; + + if (fscanf(fd, "%s", buf) == 1 && + !strcmp(buf, "control_d")) + dom0 = 1; + fclose(fd); + } + printf("Xen %s\n", dom0 ? "none" : "para"); + } + + else if (has_pci_device(0x5853, 0x0001)) { + /* Xen full-virt on non-x86_64 */ + printf("Xen full\n"); + } + + /* print nothing if in real mode */ + return 0; } |