diff options
author | Lennart Poettering <lennart@poettering.net> | 2011-02-22 01:39:19 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-02-22 01:39:19 +0100 |
commit | 721bca5763a9e2befebc84b37c6d537990d4ce6e (patch) | |
tree | 4c23ffde10c918175f00724e49e570e49942d247 /src/util.c | |
parent | 4e08da90d4df797308d4646af345cfc0486b06d1 (diff) |
virtualization: check cpuid first, since it is cheaper than DMI
Diffstat (limited to 'src/util.c')
-rw-r--r-- | src/util.c | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/src/util.c b/src/util.c index aa49390b87..e2859fafc1 100644 --- a/src/util.c +++ b/src/util.c @@ -3713,7 +3713,7 @@ int detect_vm(const char **id) { /* Both CPUID and DMI are x86 specific interfaces... */ - const char *const dmi_vendors[] = { + static const char *const dmi_vendors[] = { "/sys/class/dmi/id/sys_vendor", "/sys/class/dmi/id/board_vendor", "/sys/class/dmi/id/bios_vendor" @@ -3727,6 +3727,7 @@ int detect_vm(const char **id) { "Microsoft Corporation\0" "microsoft\0" "innotek GmbH\0" "oracle\0" "Xen\0" "xen\0" + "Bochs\0" "bochs\0" "\0"; static const char cpuid_vendor_table[] = @@ -3743,34 +3744,9 @@ int detect_vm(const char **id) { uint32_t sig32[3]; char text[13]; } sig; - unsigned i; const char *j, *k; - - for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) { - char *s; - int r; - const char *found = NULL; - - if ((r = read_one_line_file(dmi_vendors[i], &s)) < 0) { - if (r != -ENOENT) - return r; - - continue; - } - - NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table) - if (startswith(s, j)) - found = k; - free(s); - - if (found) { - if (id) - *id = found; - - return 1; - } - } + bool hypervisor; /* http://lwn.net/Articles/301888/ */ zero(sig); @@ -3795,7 +3771,9 @@ int detect_vm(const char **id) { : "0" (eax) ); - if (ecx & 0x80000000U) { + hypervisor = !!(ecx & ecx & 0x80000000U); + + if (hypervisor) { /* There is a hypervisor, see what it is */ eax = 0x40000000U; @@ -3818,14 +3796,41 @@ int detect_vm(const char **id) { return 1; } + } + for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) { + char *s; + int r; + const char *found = NULL; + + if ((r = read_one_line_file(dmi_vendors[i], &s)) < 0) { + if (r != -ENOENT) + return r; + + continue; + } + + NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table) + if (startswith(s, j)) + found = k; + free(s); + + if (found) { + if (id) + *id = found; + + return 1; + } + } + + if (hypervisor) { if (id) *id = "other"; return 1; } -#endif +#endif return 0; } |