The command virt-what can be used to detect if the program is running in a virtual machine, and prints out a list of "facts" about the virtual machine. such as hyperv, lxc, qemu, kvm, xen and so on.
Refer to the following for more details, <http://people.redhat.com/~rjones/virt-what/> This patch references the method that has already proposed and implemented in the code of virt-what. Signed-off-by: Wei,Jiangang <weijg.f...@cn.fujitsu.com> --- lib/tst_virt.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/lib/tst_virt.c b/lib/tst_virt.c index 87f73dc..eb3b487 100644 --- a/lib/tst_virt.c +++ b/lib/tst_virt.c @@ -23,9 +23,78 @@ */ #include <unistd.h> +#include <string.h> #include "test.h" #include "safe_macros.h" +#define SIG_MAX_LEN 13 // Limit the length of the CPU sign array + +#if defined(__i386__) || defined(__x86_64__) + +static unsigned int +cpuid (unsigned int eax, char *sigp) +{ + unsigned int *sig32 = (unsigned int *) sigp; + + asm volatile ( + "xor %%ebx, %%ebx; cpuid" + : "=a" (eax), "=b" (sig32[0]), "=c" (sig32[1]), "=d" (sig32[2]) + : "0" (eax)); + sigp[SIG_MAX_LEN - 1] = 0; + + return eax; +} + +/* + * confirm that we are running inside KVM or Xen HVM by CPU sign + * + * Inputs: + * char* sigp - the pointer of CPU sign array, sig[]. + * Possible Values of sig[]: + * String - Virtual Type + * KVMKVMKVM - KVM guest + * XenVMMXenVMM - Xen HVM guest + * + * Returns: + * 0 - success + * -1 - an error has occurred (unsupported architecture) + */ +static int +cpu_sign (char* sigp) +{ + unsigned int base = 0x40000000, leaf = base; + unsigned int max_entries; + + memset (sigp, 0, SIG_MAX_LEN); + max_entries = cpuid (leaf, sigp); + + /* 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 (sigp, 0, SIG_MAX_LEN); + cpuid (leaf, sigp); + } + } + + return 0; +} + +#else /* !i386, !x86_64 */ + +static int +cpu_sign (char* sigp) +{ + /* nothing for other architectures */ + return -1; +} + +#endif + static int is_kvm(void) { FILE *cpuinfo; -- 1.9.3 ------------------------------------------------------------------------------ Dive into the World of Parallel Programming The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list