From 300c5168ca007ed5fbd49189efbe66ae0dbd9ad1 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 24 Jan 2011 11:03:42 +0000 Subject: [PATCH] cpuid: Find other leaf entries (RHBZ#671510). --- virt-what-cpuid-helper.c | 60 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/virt-what-cpuid-helper.c b/virt-what-cpuid-helper.c index 3024c37..8b81be3 100644 --- a/virt-what-cpuid-helper.c +++ b/virt-what-cpuid-helper.c @@ -24,40 +24,60 @@ #include #if defined(__i386__) || defined(__x86_64__) -void -cpu_sig (char *sig) + +static unsigned int +cpuid (unsigned int eax, char *sig) { - unsigned int eax = 0x40000000; - unsigned int *sig32 = (unsigned int *)sig; + unsigned int *sig32 = (unsigned int *) sig; + asm volatile ( "xor %%ebx, %%ebx; cpuid" : "=a" (eax), "=b" (sig32[0]), "=c" (sig32[1]), "=d" (sig32[2]) : "0" (eax)); sig[12] = 0; + + return eax; } -#else -void -cpu_sig (char *sig) -{ - /* nothing for other architectures */ -} -#endif -int -main() +static void +cpu_sig (void) { char sig[13]; + unsigned int base = 0x40000000, leaf = base; + unsigned int max_entries; memset (sig, 0, sizeof sig); - - cpu_sig (sig); - + max_entries = cpuid (leaf, sig); puts (sig); - /* Possible values: - * KVMKVMKVM KVM guest - * XenVMMXenVMM Xen HVM guest - * VMwareVMware VMware guest + + /* Most hypervisors only have information in leaf 0x40000000, but + * upstream Xen contains further leaf entries (in particular when + * used with Viridian [HyperV] extensions). CPUID is supposed to + * return the maximum leaf offset in %eax, so that's what we use, + * but only if it looks sensible. */ + if (max_entries > 3 && max_entries < 0x10000) { + for (leaf = base + 0x100; leaf <= base + max_entries; leaf += 0x100) { + memset (sig, 0, sizeof sig); + cpuid (leaf, sig); + puts (sig); + } + } +} + +#else /* !i386, !x86_64 */ + +static void +cpu_sig (void) +{ + /* nothing for other architectures */ +} +#endif + +int +main() +{ + cpu_sig (); return 0; } -- 1.8.3.1