X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=virt-what-cpuid-helper.c;h=fdceb62f8763ad768111fcc5907b1dce87a117b4;hb=60d903fbb7653bc9754228bdab4c6933fcda1e72;hp=0cd4a6f2b168dcdb6d3025828a8d98170f5b68d8;hpb=0a0d9fa7c85c5474870cae37832d28ccd899d4ee;p=virt-what.git diff --git a/virt-what-cpuid-helper.c b/virt-what-cpuid-helper.c index 0cd4a6f..fdceb62 100644 --- a/virt-what-cpuid-helper.c +++ b/virt-what-cpuid-helper.c @@ -28,15 +28,16 @@ #if defined(__i386__) || defined(__x86_64__) /* Known x86 hypervisor signatures. Note that if you add a new test - * to virt-what.in you may need to update this list. The signature is - * always 12 bytes except in the case of KVM. + * to virt-what.in you may need to update this list. Note the + * signature is always 12 bytes long, plus we add \0 to the end to + * make it 13 bytes. */ static int -known_signature (char *sig) +known_signature (const char *sig) { return strcmp (sig, "bhyve bhyve ") == 0 || - strcmp (sig, "KVMKVMKVM") == 0 || + memcmp (sig, "KVMKVMKVM\0\0\0", 12) == 0 || strcmp (sig, "LKVMLKVMLKVM") == 0 || strcmp (sig, "Microsoft Hv") == 0 || strcmp (sig, "OpenBSDVMM58") == 0 || @@ -46,17 +47,25 @@ known_signature (char *sig) 0; } +/* Copied from the Linux kernel definition in + * arch/x86/include/asm/processor.h + */ +static inline void +cpuid (uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) +{ + asm volatile ("cpuid" + : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) + : "0" (*eax), "2" (*ecx) + : "memory"); +} + static uint32_t -cpuid (uint32_t eax, char *sig) +cpuid_leaf (uint32_t eax, char *sig) { uint32_t *sig32 = (uint32_t *) sig; - asm volatile ( - "xchgl %%ebx,%1; xor %%ebx,%%ebx; cpuid; xchgl %%ebx,%1" - : "=a" (eax), "+r" (sig32[0]), "=c" (sig32[1]), "=d" (sig32[2]) - : "0" (eax)); - sig[12] = 0; - + cpuid (&eax, &sig32[0], &sig32[1], &sig32[2]); + sig[12] = 0; /* \0-terminate the string to make string comparison possible */ return eax; } @@ -86,7 +95,7 @@ cpu_sig (void) */ for (leaf = base + 0xff00; leaf >= base; leaf -= 0x100) { memset (sig, 0, sizeof sig); - cpuid (leaf, sig); + cpuid_leaf (leaf, sig); if (known_signature (sig)) { puts (sig); break;