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

Reply via email to