Hi, Gao It seems that you have referred to the implement of virt-what. In fact, I sent a patch which has the same method as your patch. you can refer to the email in maillist. title: [LTP][PATCH 2/2] lib/tst_virt.c: distinguish between KVM and QEMU time:Tue, 24 Feb 2015 16:27:39 +0800
And Jiri Jaburek <jjabu...@redhat.com> put different opinion. as following, >the code used by virt-what >is not easy, reliable or (IMO) reasonable to copy/paste into LTP. >Specifically with kvm, the KVMKVMKVM detection used to fail (IIRC) >with some specific hosts and qemu versions. It can also be easily >bypassed with -cpu host,kvm=off (which doesn't disable kvm accel). I think it's very reasonable. That's why i want to rename is_kvm. so your patch doesn't looks good for me. Thanks. wei On Tue, 2015-03-03 at 16:02 +0800, Wanlong Gao wrote: > Signed-off-by: Wanlong Gao <gaowanl...@cn.fujitsu.com> > --- > include/test.h | 6 ++-- > lib/tst_virt.c | 99 > +++++++++++++++++++++++++++++++++++++--------------------- > 2 files changed, 67 insertions(+), 38 deletions(-) > > diff --git a/include/test.h b/include/test.h > index f45bb36..abee23c 100644 > --- a/include/test.h > +++ b/include/test.h > @@ -53,8 +53,10 @@ > #include "tst_timer.h" > > /* virt types for tst_is_virt() */ > -#define VIRT_XEN 1 /* xen dom0/domU */ > -#define VIRT_KVM 2 /* only default virtual CPU */ > +#define VIRT_XEN 1 > +#define VIRT_KVM 2 > +#define VIRT_VMWARE 4 > +#define VIRT_ALL 7 > > /* > * Ensure that NUMSIGS is defined. > diff --git a/lib/tst_virt.c b/lib/tst_virt.c > index 87f73dc..ae40a3b 100644 > --- a/lib/tst_virt.c > +++ b/lib/tst_virt.c > @@ -22,55 +22,82 @@ > * 02110-1301, USA. > */ > > -#include <unistd.h> > +/* This program was suggested by Gleb Natapov and written by Paolo > + * Bonzini, with a few modifications by Richard W.M. Jones. > + */ > + > +#include <stdlib.h> > +#include <string.h> > #include "test.h" > -#include "safe_macros.h" > > -static int is_kvm(void) > +#if defined(__i386__) || defined(__x86_64__) > + > +static unsigned int cpuid(unsigned int eax, char *sig) > { > - FILE *cpuinfo; > - char line[64]; > - int found; > - > - /* this doesn't work with custom -cpu values, since there's > - * no easy, reasonable or reliable way to work around those */ > - cpuinfo = SAFE_FOPEN(NULL, "/proc/cpuinfo", "r"); > - found = 0; > - while (fgets(line, sizeof(line), cpuinfo) != NULL) { > - if (strstr(line, "QEMU Virtual CPU")) { > - found = 1; > - break; > - } > - } > + unsigned int *sig32 = (unsigned int *)sig; > > - SAFE_FCLOSE(NULL, cpuinfo); > - return found; > + asm volatile ( > + "xor %%ebx, %%ebx; cpuid" > + : "=a" (eax), "=b" (sig32[0]), "=c" (sig32[1]), "=d" (sig32[2]) > + : "0" (eax)); > + sig[12] = 0; > + > + return eax; > } > > -static int is_xen(void) > +static char *cpu_sig(void) > { > - char hypervisor_type[3]; > + char *sig = malloc(13); > + unsigned int base = 0x40000000, leaf = base; > + unsigned int max_entries; > > - if (access("/proc/xen", F_OK) == 0) > - return 1; > + memset(sig, 0, 13); > + max_entries = cpuid(leaf, sig); > > - if (access("/sys/hypervisor/type", F_OK) == 0) { > - SAFE_FILE_SCANF(NULL, "/sys/hypervisor/type", "%3s", > - hypervisor_type); > - return strncmp("xen", hypervisor_type, > - sizeof(hypervisor_type)) == 0; > + /* 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, 13); > + cpuid(leaf, sig); > + } > } > > - return 0; > + return sig; > } > > +#else /* !i386, !x86_64 */ > + > +static char *cpu_sig (void) > +{ > + /* nothing for other architectures */ > + return NULL; > +} > + > +#endif > + > + > int tst_is_virt(int virt_type) > { > - switch (virt_type) { > - case VIRT_XEN: > - return is_xen(); > - case VIRT_KVM: > - return is_kvm(); > - } > - tst_brkm(TBROK, NULL, "invalid virt_type flag: %d", virt_type); > + char *string; > + int virt = 0; > + > + string = cpu_sig(); > + > + if (!string) return 0; > + > + if (strncmp(string, "XenVMMXenVMM", 12) == 0) > + virt |= VIRT_XEN; > + else if (strncmp(string, "VMwareVMware", 12) == 0) > + virt |= VIRT_VMWARE; > + else if (strncmp(string, "KVMKVMKVM", 12) == 0) > + virt |= VIRT_KVM; > + > + free(string); > + > + return virt_type & virt; > } ------------------------------------------------------------------------------ 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