All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony-rdkfGonbjUSkNkDKm+mE6A@public.gmane.org>
To: danken-atKUWr5tajBWk0Htik3J/w@public.gmane.org
Cc: kvm-devel
	<kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>,
	qemu-devel-qX2TKyscuCcdnm+yROfE0A@public.gmane.org
Subject: Re: expose host CPU features to guests
Date: Wed, 05 Sep 2007 14:26:11 -0500	[thread overview]
Message-ID: <1189020371.7206.3.camel@squirrel> (raw)
In-Reply-To: <20070905174530.GA3945-iWbx9bcAnq+Hk9JtIoIkgNBPR1lH4CV8@public.gmane.org>

On Wed, 2007-09-05 at 20:45 +0300, danken-atKUWr5tajBWk0Htik3J/w@public.gmane.org wrote:
> Hi,
> 
> It's a pity not to use a host CPU feature if it is available. This patch
> exposes host CPU features to guests. It allows fine-tuning the presented
> features from the command-line.
> 
> The code could use some serious clean ups, but I think it is interesting
> enough right now. I'd be happy to hear your opinion and suggestions. 
> The diff are done against qemu cvs. I tried it with kvm, but I thinkg it
> should be useful also for kqemu.

I like this idea but I have some suggestions about the general approach.
I think instead of defining another machine type, it would be better to
just have a command line option like -cpuid that took a comma separate
string of features with "all" meaning all features that the host has.

I also think it would be nicer to use cpuid() directly instead of
attempting to parse /proc/cpuinfo.

Regards,

Anthony Liguori

> Regards,
> 
> Dan.
> 
> Index: vl.c
> ===================================================================
> RCS file: /sources/qemu/qemu/vl.c,v
> retrieving revision 1.336
> diff -u -p -r1.336 vl.c
> --- vl.c	28 Aug 2007 22:21:40 -0000	1.336
> +++ vl.c	5 Sep 2007 15:48:10 -0000
> @@ -6575,12 +6575,24 @@ int qemu_register_machine(QEMUMachine *m
>      return 0;
>  }
>  
> +const char *machine_flavor = 0;
> +
>  QEMUMachine *find_machine(const char *name)
>  {
>      QEMUMachine *m;
>  
> +    int n;
> +    machine_flavor = strchr(name, ',');
> +    if (machine_flavor) {
> +	n = machine_flavor - name;
> +	machine_flavor++;
> +    } else {
> +        n = strlen(name);
> +        machine_flavor = "";
> +    }
> +
>      for(m = first_machine; m != NULL; m = m->next) {
> -        if (!strcmp(m->name, name))
> +        if (!strncmp(m->name, name, n))
>              return m;
>      }
>      return NULL;
> @@ -7343,6 +7355,7 @@ static void read_passwords(void)
>  void register_machines(void)
>  {
>  #if defined(TARGET_I386)
> +    qemu_register_machine(&host_pc_machine);
>      qemu_register_machine(&pc_machine);
>      qemu_register_machine(&isapc_machine);
>  #elif defined(TARGET_PPC)
> Index: vl.h
> ===================================================================
> RCS file: /sources/qemu/qemu/vl.h,v
> retrieving revision 1.264
> diff -u -p -r1.264 vl.h
> --- vl.h	26 Aug 2007 17:46:00 -0000	1.264
> +++ vl.h	5 Sep 2007 15:48:10 -0000
> @@ -1156,6 +1156,7 @@ void piix4_smbus_register_device(SMBusDe
>  void acpi_bios_init(void);
>  
>  /* pc.c */
> +extern QEMUMachine host_pc_machine;
>  extern QEMUMachine pc_machine;
>  extern QEMUMachine isapc_machine;
>  extern int fd_bootchk;
> Index: hw/pc.c
> ===================================================================
> RCS file: /sources/qemu/qemu/hw/pc.c,v
> retrieving revision 1.83
> diff -u -p -r1.83 pc.c
> --- hw/pc.c	26 Aug 2007 17:51:39 -0000	1.83
> +++ hw/pc.c	5 Sep 2007 15:48:10 -0000
> @@ -965,6 +965,28 @@ static void pc_init_isa(int ram_size, in
>               initrd_filename, 0);
>  }
>  
> +int use_hostlike_cpu = 0;
> +
> +static void pc_init_hostlike(ram_addr_t ram_size, int vga_ram_size, int boot_device,
> +                        DisplayState *ds, const char **fd_filename, 
> +                        int snapshot, 
> +                        const char *kernel_filename, 
> +                        const char *kernel_cmdline,
> +                        const char *initrd_filename)
> +{
> +    use_hostlike_cpu = 1;
> +    pc_init1(ram_size, vga_ram_size, boot_device,
> +             ds, fd_filename, snapshot,
> +             kernel_filename, kernel_cmdline,
> +             initrd_filename, 1);
> +}
> +
> +QEMUMachine host_pc_machine = {
> +    "host",
> +    "Standard PC with host-like CPU",
> +    pc_init_hostlike,
> +};
> +
>  QEMUMachine pc_machine = {
>      "pc",
>      "Standard PC",
> Index: target-i386/cpu.h
> ===================================================================
> RCS file: /sources/qemu/qemu/target-i386/cpu.h,v
> retrieving revision 1.45
> diff -u -p -r1.45 cpu.h
> --- target-i386/cpu.h	11 Jul 2007 22:48:58 -0000	1.45
> +++ target-i386/cpu.h	5 Sep 2007 15:48:10 -0000
> @@ -267,21 +267,44 @@
>  #define CPUID_CMOV (1 << 15)
>  #define CPUID_PAT  (1 << 16)
>  #define CPUID_PSE36   (1 << 17)
> +#define CPUID_PN   (1 << 18)
>  #define CPUID_CLFLUSH (1 << 19)
> -/* ... */
> +#define CPUID_DTS (1 << 21)
> +#define CPUID_ACPI (1 << 22)
>  #define CPUID_MMX  (1 << 23)
>  #define CPUID_FXSR (1 << 24)
>  #define CPUID_SSE  (1 << 25)
>  #define CPUID_SSE2 (1 << 26)
> +#define CPUID_SS (1 << 27)
> +#define CPUID_HT (1 << 28)
> +#define CPUID_TM (1 << 29)
> +#define CPUID_IA64 (1 << 30)
> +#define CPUID_PBE (1 << 31)
>  
>  #define CPUID_EXT_SSE3     (1 << 0)
>  #define CPUID_EXT_MONITOR  (1 << 3)
> +#define CPUID_EXT_DSCPL    (1 << 4)
> +#define CPUID_EXT_VMX      (1 << 5)
> +#define CPUID_EXT_SMX      (1 << 6)
> +#define CPUID_EXT_EST      (1 << 7)
> +#define CPUID_EXT_TM2      (1 << 8)
> +#define CPUID_EXT_SSSE3    (1 << 9)
> +#define CPUID_EXT_CID      (1 << 10)
>  #define CPUID_EXT_CX16     (1 << 13)
> +#define CPUID_EXT_XTPR     (1 << 14)
> +#define CPUID_EXT_DCA      (1 << 17)
> +#define CPUID_EXT_POPCNT   (1 << 22)
>  
>  #define CPUID_EXT2_SYSCALL (1 << 11)
> +#define CPUID_EXT2_MP      (1 << 19)
>  #define CPUID_EXT2_NX      (1 << 20)
> +#define CPUID_EXT2_MMXEXT  (1 << 22)
>  #define CPUID_EXT2_FFXSR   (1 << 25)
> +#define CPUID_EXT2_PDPE1GB (1 << 26)
> +#define CPUID_EXT2_RDTSCP  (1 << 27)
>  #define CPUID_EXT2_LM      (1 << 29)
> +#define CPUID_EXT2_3DNOWEXT (1 << 30)
> +#define CPUID_EXT2_3DNOW   (1 << 31)
>  
>  #define EXCP00_DIVZ	0
>  #define EXCP01_SSTP	1
> Index: target-i386/helper2.c
> ===================================================================
> RCS file: /sources/qemu/qemu/target-i386/helper2.c,v
> retrieving revision 1.48
> diff -u -p -r1.48 helper2.c
> --- target-i386/helper2.c	31 Jul 2007 23:09:18 -0000	1.48
> +++ target-i386/helper2.c	5 Sep 2007 15:48:10 -0000
> @@ -45,6 +45,272 @@ int modify_ldt(int func, void *ptr, unsi
>  #endif
>  #endif /* USE_CODE_COPY */
>  
> +/* x86_cap_flags taken from Linux's arch/i386/kernel/cpu/proc.c */
> +static const char * const x86_cap_flags[] = {
> +	/* Intel-defined */
> +        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
> +        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
> +        "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
> +        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
> +
> +	/* AMD-defined */
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
> +	NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext", "3dnow",
> +
> +	/* Transmeta-defined */
> +	"recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +
> +	/* Other (Linux-defined) */
> +	"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
> +	NULL, NULL, NULL, NULL,
> +	"constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +
> +	/* Intel-defined (#2) */
> +	"pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est",
> +	"tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
> +	NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +
> +	/* VIA/Cyrix/Centaur-defined */
> +	NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
> +	"ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +
> +	/* AMD-defined (#2) */
> +	"lahf_lm", "cmp_legacy", "svm", "extapic", "cr8legacy", "abm",
> +	"sse4a", "misalignsse",
> +	"3dnowprefetch", "osvw", "ibs", NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +};
> +
> +void add_flagname_to_bitmaps(char *flagname, int *features, int *ext_features, int *ext2_features)
> +{
> +    int i;
> +    for ( i = 0 ; i < 32 ; i++ ) 
> +        if (x86_cap_flags[i] && !strcmp (flagname, x86_cap_flags[i])) {
> +            *features |= 1 << i;
> +            return;
> +        }
> +    for ( i = 0 ; i < 32 ; i++ ) 
> +        if (x86_cap_flags[32*4+i] && !strcmp (flagname, x86_cap_flags[32*4+i])) {
> +            *ext_features |= 1 << i;
> +            return;
> +        }
> +    for ( i = 0 ; i < 32 ; i++ ) 
> +        if (x86_cap_flags[32*1+i] && !strcmp (flagname, x86_cap_flags[32*1+i])) {
> +            *ext2_features |= 1 << i;
> +            return;
> +        }
> +    /* Silently ignore Linux-defined features */
> +    for ( i = 0 ; i < 32 ; i++ ) 
> +        if (x86_cap_flags[32*3+i] && !strcmp (flagname, x86_cap_flags[32*3+i])) {
> +            return;
> +        }
> +    fprintf(stderr, "CPU feature %s not found\n", flagname);
> +}
> +
> +static void apply_machine_flavor(CPUX86State *env)
> +{
> +    int plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0;
> +    int minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0;
> +    int family = -1, model = -1, stepping = -1;
> +
> +    extern char *machine_flavor;
> +    char *s = strdup(machine_flavor);
> +    char *featurestr = strtok(s, ",");
> +
> +    while (featurestr) {
> +      char *val;
> +      if (featurestr[0] == '+') {
> +         add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features);
> +      }
> +      else if (featurestr[0] == '-') {
> +         add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features);
> +      } 
> +      else if ((val = strchr(featurestr, '='))) {
> +         *val = 0; val++;
> +         if (!strcmp(featurestr, "family")) {
> +            family = atoi(val);
> +            if (family <= 0) {
> +               fprintf(stderr, "bad numerical value %s\n", val);
> +               exit(1);
> +            }
> +            env->cpuid_version &= 0xFF;
> +            env->cpuid_version |= (family << 8);
> +         } else if (!strcmp(featurestr, "model")) {
> +            model = atoi(val);
> +            if (model <= 0) {
> +               fprintf(stderr, "bad numerical value %s\n", val);
> +               exit(1);
> +            }
> +            env->cpuid_version &= 0xFFFFFF0F;
> +            env->cpuid_version |= (model << 4);
> +         } else if (!strcmp(featurestr, "stepping")) {
> +            stepping = atoi(val);
> +            if (stepping <= 0) {
> +               fprintf(stderr, "bad numerical value %s\n", val);
> +               exit(1);
> +            }
> +            env->cpuid_version &= 0xFFFFFFF0;
> +            env->cpuid_version |= stepping;
> +         } else {
> +            fprintf(stderr, "unknown feature %s\n", featurestr);
> +            exit(1);
> +         }
> +      } else {
> +         fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
> +         exit(1);
> +      }
> +      featurestr = strtok(NULL, ",");
> +    }
> +    free(s);
> +    env->cpuid_features |= plus_features;
> +    env->cpuid_ext_features |= plus_ext_features;
> +    env->cpuid_ext2_features |= plus_ext2_features;
> +    env->cpuid_features &= ~minus_features;
> +    env->cpuid_ext_features &= ~minus_ext_features;
> +    env->cpuid_ext2_features &= ~minus_ext2_features;
> +}
> +
> +static int read_one_cpu_info(CPUX86State *env, FILE *f)
> +{
> +    char line[300], *val;
> +    char vendor_id[13];
> +    int family = -1, model = -1, stepping = -1;
> +    int features = 0, ext_features = 0, ext2_features = 0;
> +
> +    while (fgets(line, sizeof(line), f)) {
> +        if (!strtok(line, "\t") || line[0]=='\n') {
> +            break;
> +        }
> +        val = strtok(NULL, "\t:");
> +        if (!val)
> +            val = "";
> +        if (*val==' ')
> +            val++;
> +
> +        if (!strcmp(line,"vendor_id")) {
> +            strncpy(vendor_id, val, sizeof(vendor_id) - 1);
> +            vendor_id[sizeof(vendor_id)-1] = 0;
> +        }
> +        if (!strcmp(line,"cpu family")) {
> +            family = atoi(val);
> +        }
> +        if (!strcmp(line,"model")) {
> +            model = atoi(val);
> +        }
> +        if (!strcmp(line,"stepping")) {
> +            stepping = atoi(val);
> +        }
> +        if (!strcmp(line,"flags")) {
> +            char *flagname;
> +            struct flagstorage {
> +                char *name;
> +                int  bit;
> +                int  *container;
> +            };
> +
> +            flagname = strtok(val, " ");
> +            while (flagname) {
> +                add_flagname_to_bitmaps(flagname, &features, &ext_features, &ext2_features);
> +                flagname = strtok(NULL, " \n");
> +            }
> +            features &= ~CPUID_ACPI; /* acpi causes guest kernel panic on boot time, in cpu_identify */
> +            ext_features &= ~CPUID_EXT_VMX; /* KVM is not recursive */
> +        }
> +    }
> +    if (family==-1 || model==-1 || stepping==-1)
> +        return -1;
> +    env->cpuid_level = 2;
> +    env->cpuid_vendor1 = *(uint32_t *)&vendor_id[0];
> +    env->cpuid_vendor2 = *(uint32_t *)&vendor_id[4];
> +    env->cpuid_vendor3 = *(uint32_t *)&vendor_id[8];
> +    env->cpuid_version = (family << 8) | (model << 4) | stepping;
> +    env->cpuid_features = features;
> +    env->cpuid_ext_features = ext_features;
> +    env->cpuid_ext2_features = ext2_features;
> +    env->pat = 0x0007040600070406ULL;
> +    /* TODO expose real cpuid extended level */
> +#ifdef TARGET_X86_64
> +    env->cpuid_xlevel = 0x80000008;
> +#else
> +    env->cpuid_xlevel = 0;
> +#endif
> +    return 0;
> +}
> +
> +static int set_guest_cpu_hostlike(CPUX86State *env) {
> +    FILE *f;
> +    f = fopen("/proc/cpuinfo", "r");
> +    if (!f) {
> +      fprintf(stderr, "falling back to standard guest cpu\n");
> +      return -1;
> +    }
> +    read_one_cpu_info(env, f);
> +    fclose(f);
> +    return 0;
> +}
> +
> +static int set_guest_cpu_standard(CPUX86State *env)
> +{
> +    int family, model, stepping;
> +#ifdef TARGET_X86_64
> +    env->cpuid_vendor1 = 0x68747541; /* "Auth" */
> +    env->cpuid_vendor2 = 0x69746e65; /* "enti" */
> +    env->cpuid_vendor3 = 0x444d4163; /* "cAMD" */
> +    family = 6;
> +    model = 2;
> +    stepping = 3;
> +#else
> +    env->cpuid_vendor1 = 0x756e6547; /* "Genu" */
> +    env->cpuid_vendor2 = 0x49656e69; /* "ineI" */
> +    env->cpuid_vendor3 = 0x6c65746e; /* "ntel" */
> +#if 0
> +    /* pentium 75-200 */
> +    family = 5;
> +    model = 2;
> +    stepping = 11;
> +#else
> +    /* pentium pro */
> +    family = 6;
> +    model = 3;
> +    stepping = 3;
> +#endif
> +#endif
> +    env->cpuid_level = 2;
> +    env->cpuid_version = (family << 8) | (model << 4) | stepping;
> +    env->cpuid_features = (CPUID_FP87 | CPUID_DE | CPUID_PSE |
> +            CPUID_TSC | CPUID_MSR | CPUID_MCE |
> +            CPUID_CX8 | CPUID_PGE | CPUID_CMOV |
> +            CPUID_PAT);
> +    env->pat = 0x0007040600070406ULL;
> +    env->cpuid_ext_features = CPUID_EXT_SSE3;
> +    env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_PAE | CPUID_SEP;
> +    env->cpuid_features |= CPUID_APIC;
> +    env->cpuid_xlevel = 0;
> +#ifdef TARGET_X86_64
> +    /* currently not enabled for std i386 because not fully tested */
> +    env->cpuid_ext2_features = (env->cpuid_features & 0x0183F3FF);
> +    env->cpuid_ext2_features |= CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
> +    env->cpuid_xlevel = 0x80000008;
> +
> +    /* these features are needed for Win64 and aren't fully implemented */
> +    env->cpuid_features |= CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA;
> +    /* this feature is needed for Solaris and isn't fully implemented */
> +    env->cpuid_features |= CPUID_PSE36;
> +#endif
> +    return 0;
> +}
> +
>  CPUX86State *cpu_x86_init(void)
>  {
>      CPUX86State *env;
> @@ -80,64 +346,23 @@ CPUX86State *cpu_x86_init(void)
>      }
>  #endif
>      {
> -        int family, model, stepping;
> -#ifdef TARGET_X86_64
> -        env->cpuid_vendor1 = 0x68747541; /* "Auth" */
> -        env->cpuid_vendor2 = 0x69746e65; /* "enti" */
> -        env->cpuid_vendor3 = 0x444d4163; /* "cAMD" */
> -        family = 6;
> -        model = 2;
> -        stepping = 3;
> -#else
> -        env->cpuid_vendor1 = 0x756e6547; /* "Genu" */
> -        env->cpuid_vendor2 = 0x49656e69; /* "ineI" */
> -        env->cpuid_vendor3 = 0x6c65746e; /* "ntel" */
> -#if 0
> -        /* pentium 75-200 */
> -        family = 5;
> -        model = 2;
> -        stepping = 11;
> -#else
> -        /* pentium pro */
> -        family = 6;
> -        model = 3;
> -        stepping = 3;
> -#endif
> -#endif
> -        env->cpuid_level = 2;
> -        env->cpuid_version = (family << 8) | (model << 4) | stepping;
> -        env->cpuid_features = (CPUID_FP87 | CPUID_DE | CPUID_PSE |
> -                               CPUID_TSC | CPUID_MSR | CPUID_MCE |
> -                               CPUID_CX8 | CPUID_PGE | CPUID_CMOV |
> -                               CPUID_PAT);
> -        env->pat = 0x0007040600070406ULL;
> -        env->cpuid_ext_features = CPUID_EXT_SSE3;
> -        env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_PAE | CPUID_SEP;
> -        env->cpuid_features |= CPUID_APIC;
> -        env->cpuid_xlevel = 0;
> -        {
> -            const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION;
> -            int c, len, i;
> -            len = strlen(model_id);
> -            for(i = 0; i < 48; i++) {
> -                if (i >= len)
> -                    c = '\0';
> -                else
> -                    c = model_id[i];
> -                env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
> -            }
> +        extern int use_hostlike_cpu;
> +        if (!use_hostlike_cpu || set_guest_cpu_hostlike(env))
> +            set_guest_cpu_standard(env);
> +        apply_machine_flavor(env);
> +    }
> +    {
> +        const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION;
> +        int c, len, i;
> +
> +        len = strlen(model_id);
> +        for(i = 0; i < 48; i++) {
> +            if (i >= len)
> +                c = '\0';
> +            else
> +                c = model_id[i];
> +            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
>          }
> -#ifdef TARGET_X86_64
> -        /* currently not enabled for std i386 because not fully tested */
> -        env->cpuid_ext2_features = (env->cpuid_features & 0x0183F3FF);
> -        env->cpuid_ext2_features |= CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
> -        env->cpuid_xlevel = 0x80000008;
> -
> -        /* these features are needed for Win64 and aren't fully implemented */
> -        env->cpuid_features |= CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA;
> -        /* this feature is needed for Solaris and isn't fully implemented */
> -        env->cpuid_features |= CPUID_PSE36;
> -#endif
>      }
>      cpu_reset(env);
>  #ifdef USE_KQEMU
> 
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc.
> Still grepping through log files to find problems?  Stop.
> Now Search log events and configuration files using AJAX and a browser.
> Download your FREE copy of Splunk now >>  http://get.splunk.com/
> _______________________________________________
> kvm-devel mailing list
> kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> https://lists.sourceforge.net/lists/listinfo/kvm-devel


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

WARNING: multiple messages have this Message-ID (diff)
From: Anthony Liguori <anthony@codemonkey.ws>
To: danken@qumranet.com
Cc: kvm-devel <kvm-devel@lists.sourceforge.net>, qemu-devel@nongnu.org
Subject: [Qemu-devel] Re: [kvm-devel] expose host CPU features to guests
Date: Wed, 05 Sep 2007 14:26:11 -0500	[thread overview]
Message-ID: <1189020371.7206.3.camel@squirrel> (raw)
In-Reply-To: <20070905174530.GA3945@karma.qumranet.com>

On Wed, 2007-09-05 at 20:45 +0300, danken@qumranet.com wrote:
> Hi,
> 
> It's a pity not to use a host CPU feature if it is available. This patch
> exposes host CPU features to guests. It allows fine-tuning the presented
> features from the command-line.
> 
> The code could use some serious clean ups, but I think it is interesting
> enough right now. I'd be happy to hear your opinion and suggestions. 
> The diff are done against qemu cvs. I tried it with kvm, but I thinkg it
> should be useful also for kqemu.

I like this idea but I have some suggestions about the general approach.
I think instead of defining another machine type, it would be better to
just have a command line option like -cpuid that took a comma separate
string of features with "all" meaning all features that the host has.

I also think it would be nicer to use cpuid() directly instead of
attempting to parse /proc/cpuinfo.

Regards,

Anthony Liguori

> Regards,
> 
> Dan.
> 
> Index: vl.c
> ===================================================================
> RCS file: /sources/qemu/qemu/vl.c,v
> retrieving revision 1.336
> diff -u -p -r1.336 vl.c
> --- vl.c	28 Aug 2007 22:21:40 -0000	1.336
> +++ vl.c	5 Sep 2007 15:48:10 -0000
> @@ -6575,12 +6575,24 @@ int qemu_register_machine(QEMUMachine *m
>      return 0;
>  }
>  
> +const char *machine_flavor = 0;
> +
>  QEMUMachine *find_machine(const char *name)
>  {
>      QEMUMachine *m;
>  
> +    int n;
> +    machine_flavor = strchr(name, ',');
> +    if (machine_flavor) {
> +	n = machine_flavor - name;
> +	machine_flavor++;
> +    } else {
> +        n = strlen(name);
> +        machine_flavor = "";
> +    }
> +
>      for(m = first_machine; m != NULL; m = m->next) {
> -        if (!strcmp(m->name, name))
> +        if (!strncmp(m->name, name, n))
>              return m;
>      }
>      return NULL;
> @@ -7343,6 +7355,7 @@ static void read_passwords(void)
>  void register_machines(void)
>  {
>  #if defined(TARGET_I386)
> +    qemu_register_machine(&host_pc_machine);
>      qemu_register_machine(&pc_machine);
>      qemu_register_machine(&isapc_machine);
>  #elif defined(TARGET_PPC)
> Index: vl.h
> ===================================================================
> RCS file: /sources/qemu/qemu/vl.h,v
> retrieving revision 1.264
> diff -u -p -r1.264 vl.h
> --- vl.h	26 Aug 2007 17:46:00 -0000	1.264
> +++ vl.h	5 Sep 2007 15:48:10 -0000
> @@ -1156,6 +1156,7 @@ void piix4_smbus_register_device(SMBusDe
>  void acpi_bios_init(void);
>  
>  /* pc.c */
> +extern QEMUMachine host_pc_machine;
>  extern QEMUMachine pc_machine;
>  extern QEMUMachine isapc_machine;
>  extern int fd_bootchk;
> Index: hw/pc.c
> ===================================================================
> RCS file: /sources/qemu/qemu/hw/pc.c,v
> retrieving revision 1.83
> diff -u -p -r1.83 pc.c
> --- hw/pc.c	26 Aug 2007 17:51:39 -0000	1.83
> +++ hw/pc.c	5 Sep 2007 15:48:10 -0000
> @@ -965,6 +965,28 @@ static void pc_init_isa(int ram_size, in
>               initrd_filename, 0);
>  }
>  
> +int use_hostlike_cpu = 0;
> +
> +static void pc_init_hostlike(ram_addr_t ram_size, int vga_ram_size, int boot_device,
> +                        DisplayState *ds, const char **fd_filename, 
> +                        int snapshot, 
> +                        const char *kernel_filename, 
> +                        const char *kernel_cmdline,
> +                        const char *initrd_filename)
> +{
> +    use_hostlike_cpu = 1;
> +    pc_init1(ram_size, vga_ram_size, boot_device,
> +             ds, fd_filename, snapshot,
> +             kernel_filename, kernel_cmdline,
> +             initrd_filename, 1);
> +}
> +
> +QEMUMachine host_pc_machine = {
> +    "host",
> +    "Standard PC with host-like CPU",
> +    pc_init_hostlike,
> +};
> +
>  QEMUMachine pc_machine = {
>      "pc",
>      "Standard PC",
> Index: target-i386/cpu.h
> ===================================================================
> RCS file: /sources/qemu/qemu/target-i386/cpu.h,v
> retrieving revision 1.45
> diff -u -p -r1.45 cpu.h
> --- target-i386/cpu.h	11 Jul 2007 22:48:58 -0000	1.45
> +++ target-i386/cpu.h	5 Sep 2007 15:48:10 -0000
> @@ -267,21 +267,44 @@
>  #define CPUID_CMOV (1 << 15)
>  #define CPUID_PAT  (1 << 16)
>  #define CPUID_PSE36   (1 << 17)
> +#define CPUID_PN   (1 << 18)
>  #define CPUID_CLFLUSH (1 << 19)
> -/* ... */
> +#define CPUID_DTS (1 << 21)
> +#define CPUID_ACPI (1 << 22)
>  #define CPUID_MMX  (1 << 23)
>  #define CPUID_FXSR (1 << 24)
>  #define CPUID_SSE  (1 << 25)
>  #define CPUID_SSE2 (1 << 26)
> +#define CPUID_SS (1 << 27)
> +#define CPUID_HT (1 << 28)
> +#define CPUID_TM (1 << 29)
> +#define CPUID_IA64 (1 << 30)
> +#define CPUID_PBE (1 << 31)
>  
>  #define CPUID_EXT_SSE3     (1 << 0)
>  #define CPUID_EXT_MONITOR  (1 << 3)
> +#define CPUID_EXT_DSCPL    (1 << 4)
> +#define CPUID_EXT_VMX      (1 << 5)
> +#define CPUID_EXT_SMX      (1 << 6)
> +#define CPUID_EXT_EST      (1 << 7)
> +#define CPUID_EXT_TM2      (1 << 8)
> +#define CPUID_EXT_SSSE3    (1 << 9)
> +#define CPUID_EXT_CID      (1 << 10)
>  #define CPUID_EXT_CX16     (1 << 13)
> +#define CPUID_EXT_XTPR     (1 << 14)
> +#define CPUID_EXT_DCA      (1 << 17)
> +#define CPUID_EXT_POPCNT   (1 << 22)
>  
>  #define CPUID_EXT2_SYSCALL (1 << 11)
> +#define CPUID_EXT2_MP      (1 << 19)
>  #define CPUID_EXT2_NX      (1 << 20)
> +#define CPUID_EXT2_MMXEXT  (1 << 22)
>  #define CPUID_EXT2_FFXSR   (1 << 25)
> +#define CPUID_EXT2_PDPE1GB (1 << 26)
> +#define CPUID_EXT2_RDTSCP  (1 << 27)
>  #define CPUID_EXT2_LM      (1 << 29)
> +#define CPUID_EXT2_3DNOWEXT (1 << 30)
> +#define CPUID_EXT2_3DNOW   (1 << 31)
>  
>  #define EXCP00_DIVZ	0
>  #define EXCP01_SSTP	1
> Index: target-i386/helper2.c
> ===================================================================
> RCS file: /sources/qemu/qemu/target-i386/helper2.c,v
> retrieving revision 1.48
> diff -u -p -r1.48 helper2.c
> --- target-i386/helper2.c	31 Jul 2007 23:09:18 -0000	1.48
> +++ target-i386/helper2.c	5 Sep 2007 15:48:10 -0000
> @@ -45,6 +45,272 @@ int modify_ldt(int func, void *ptr, unsi
>  #endif
>  #endif /* USE_CODE_COPY */
>  
> +/* x86_cap_flags taken from Linux's arch/i386/kernel/cpu/proc.c */
> +static const char * const x86_cap_flags[] = {
> +	/* Intel-defined */
> +        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
> +        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
> +        "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
> +        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
> +
> +	/* AMD-defined */
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
> +	NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext", "3dnow",
> +
> +	/* Transmeta-defined */
> +	"recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +
> +	/* Other (Linux-defined) */
> +	"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
> +	NULL, NULL, NULL, NULL,
> +	"constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +
> +	/* Intel-defined (#2) */
> +	"pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est",
> +	"tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
> +	NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +
> +	/* VIA/Cyrix/Centaur-defined */
> +	NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
> +	"ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +
> +	/* AMD-defined (#2) */
> +	"lahf_lm", "cmp_legacy", "svm", "extapic", "cr8legacy", "abm",
> +	"sse4a", "misalignsse",
> +	"3dnowprefetch", "osvw", "ibs", NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +};
> +
> +void add_flagname_to_bitmaps(char *flagname, int *features, int *ext_features, int *ext2_features)
> +{
> +    int i;
> +    for ( i = 0 ; i < 32 ; i++ ) 
> +        if (x86_cap_flags[i] && !strcmp (flagname, x86_cap_flags[i])) {
> +            *features |= 1 << i;
> +            return;
> +        }
> +    for ( i = 0 ; i < 32 ; i++ ) 
> +        if (x86_cap_flags[32*4+i] && !strcmp (flagname, x86_cap_flags[32*4+i])) {
> +            *ext_features |= 1 << i;
> +            return;
> +        }
> +    for ( i = 0 ; i < 32 ; i++ ) 
> +        if (x86_cap_flags[32*1+i] && !strcmp (flagname, x86_cap_flags[32*1+i])) {
> +            *ext2_features |= 1 << i;
> +            return;
> +        }
> +    /* Silently ignore Linux-defined features */
> +    for ( i = 0 ; i < 32 ; i++ ) 
> +        if (x86_cap_flags[32*3+i] && !strcmp (flagname, x86_cap_flags[32*3+i])) {
> +            return;
> +        }
> +    fprintf(stderr, "CPU feature %s not found\n", flagname);
> +}
> +
> +static void apply_machine_flavor(CPUX86State *env)
> +{
> +    int plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0;
> +    int minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0;
> +    int family = -1, model = -1, stepping = -1;
> +
> +    extern char *machine_flavor;
> +    char *s = strdup(machine_flavor);
> +    char *featurestr = strtok(s, ",");
> +
> +    while (featurestr) {
> +      char *val;
> +      if (featurestr[0] == '+') {
> +         add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features);
> +      }
> +      else if (featurestr[0] == '-') {
> +         add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features);
> +      } 
> +      else if ((val = strchr(featurestr, '='))) {
> +         *val = 0; val++;
> +         if (!strcmp(featurestr, "family")) {
> +            family = atoi(val);
> +            if (family <= 0) {
> +               fprintf(stderr, "bad numerical value %s\n", val);
> +               exit(1);
> +            }
> +            env->cpuid_version &= 0xFF;
> +            env->cpuid_version |= (family << 8);
> +         } else if (!strcmp(featurestr, "model")) {
> +            model = atoi(val);
> +            if (model <= 0) {
> +               fprintf(stderr, "bad numerical value %s\n", val);
> +               exit(1);
> +            }
> +            env->cpuid_version &= 0xFFFFFF0F;
> +            env->cpuid_version |= (model << 4);
> +         } else if (!strcmp(featurestr, "stepping")) {
> +            stepping = atoi(val);
> +            if (stepping <= 0) {
> +               fprintf(stderr, "bad numerical value %s\n", val);
> +               exit(1);
> +            }
> +            env->cpuid_version &= 0xFFFFFFF0;
> +            env->cpuid_version |= stepping;
> +         } else {
> +            fprintf(stderr, "unknown feature %s\n", featurestr);
> +            exit(1);
> +         }
> +      } else {
> +         fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
> +         exit(1);
> +      }
> +      featurestr = strtok(NULL, ",");
> +    }
> +    free(s);
> +    env->cpuid_features |= plus_features;
> +    env->cpuid_ext_features |= plus_ext_features;
> +    env->cpuid_ext2_features |= plus_ext2_features;
> +    env->cpuid_features &= ~minus_features;
> +    env->cpuid_ext_features &= ~minus_ext_features;
> +    env->cpuid_ext2_features &= ~minus_ext2_features;
> +}
> +
> +static int read_one_cpu_info(CPUX86State *env, FILE *f)
> +{
> +    char line[300], *val;
> +    char vendor_id[13];
> +    int family = -1, model = -1, stepping = -1;
> +    int features = 0, ext_features = 0, ext2_features = 0;
> +
> +    while (fgets(line, sizeof(line), f)) {
> +        if (!strtok(line, "\t") || line[0]=='\n') {
> +            break;
> +        }
> +        val = strtok(NULL, "\t:");
> +        if (!val)
> +            val = "";
> +        if (*val==' ')
> +            val++;
> +
> +        if (!strcmp(line,"vendor_id")) {
> +            strncpy(vendor_id, val, sizeof(vendor_id) - 1);
> +            vendor_id[sizeof(vendor_id)-1] = 0;
> +        }
> +        if (!strcmp(line,"cpu family")) {
> +            family = atoi(val);
> +        }
> +        if (!strcmp(line,"model")) {
> +            model = atoi(val);
> +        }
> +        if (!strcmp(line,"stepping")) {
> +            stepping = atoi(val);
> +        }
> +        if (!strcmp(line,"flags")) {
> +            char *flagname;
> +            struct flagstorage {
> +                char *name;
> +                int  bit;
> +                int  *container;
> +            };
> +
> +            flagname = strtok(val, " ");
> +            while (flagname) {
> +                add_flagname_to_bitmaps(flagname, &features, &ext_features, &ext2_features);
> +                flagname = strtok(NULL, " \n");
> +            }
> +            features &= ~CPUID_ACPI; /* acpi causes guest kernel panic on boot time, in cpu_identify */
> +            ext_features &= ~CPUID_EXT_VMX; /* KVM is not recursive */
> +        }
> +    }
> +    if (family==-1 || model==-1 || stepping==-1)
> +        return -1;
> +    env->cpuid_level = 2;
> +    env->cpuid_vendor1 = *(uint32_t *)&vendor_id[0];
> +    env->cpuid_vendor2 = *(uint32_t *)&vendor_id[4];
> +    env->cpuid_vendor3 = *(uint32_t *)&vendor_id[8];
> +    env->cpuid_version = (family << 8) | (model << 4) | stepping;
> +    env->cpuid_features = features;
> +    env->cpuid_ext_features = ext_features;
> +    env->cpuid_ext2_features = ext2_features;
> +    env->pat = 0x0007040600070406ULL;
> +    /* TODO expose real cpuid extended level */
> +#ifdef TARGET_X86_64
> +    env->cpuid_xlevel = 0x80000008;
> +#else
> +    env->cpuid_xlevel = 0;
> +#endif
> +    return 0;
> +}
> +
> +static int set_guest_cpu_hostlike(CPUX86State *env) {
> +    FILE *f;
> +    f = fopen("/proc/cpuinfo", "r");
> +    if (!f) {
> +      fprintf(stderr, "falling back to standard guest cpu\n");
> +      return -1;
> +    }
> +    read_one_cpu_info(env, f);
> +    fclose(f);
> +    return 0;
> +}
> +
> +static int set_guest_cpu_standard(CPUX86State *env)
> +{
> +    int family, model, stepping;
> +#ifdef TARGET_X86_64
> +    env->cpuid_vendor1 = 0x68747541; /* "Auth" */
> +    env->cpuid_vendor2 = 0x69746e65; /* "enti" */
> +    env->cpuid_vendor3 = 0x444d4163; /* "cAMD" */
> +    family = 6;
> +    model = 2;
> +    stepping = 3;
> +#else
> +    env->cpuid_vendor1 = 0x756e6547; /* "Genu" */
> +    env->cpuid_vendor2 = 0x49656e69; /* "ineI" */
> +    env->cpuid_vendor3 = 0x6c65746e; /* "ntel" */
> +#if 0
> +    /* pentium 75-200 */
> +    family = 5;
> +    model = 2;
> +    stepping = 11;
> +#else
> +    /* pentium pro */
> +    family = 6;
> +    model = 3;
> +    stepping = 3;
> +#endif
> +#endif
> +    env->cpuid_level = 2;
> +    env->cpuid_version = (family << 8) | (model << 4) | stepping;
> +    env->cpuid_features = (CPUID_FP87 | CPUID_DE | CPUID_PSE |
> +            CPUID_TSC | CPUID_MSR | CPUID_MCE |
> +            CPUID_CX8 | CPUID_PGE | CPUID_CMOV |
> +            CPUID_PAT);
> +    env->pat = 0x0007040600070406ULL;
> +    env->cpuid_ext_features = CPUID_EXT_SSE3;
> +    env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_PAE | CPUID_SEP;
> +    env->cpuid_features |= CPUID_APIC;
> +    env->cpuid_xlevel = 0;
> +#ifdef TARGET_X86_64
> +    /* currently not enabled for std i386 because not fully tested */
> +    env->cpuid_ext2_features = (env->cpuid_features & 0x0183F3FF);
> +    env->cpuid_ext2_features |= CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
> +    env->cpuid_xlevel = 0x80000008;
> +
> +    /* these features are needed for Win64 and aren't fully implemented */
> +    env->cpuid_features |= CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA;
> +    /* this feature is needed for Solaris and isn't fully implemented */
> +    env->cpuid_features |= CPUID_PSE36;
> +#endif
> +    return 0;
> +}
> +
>  CPUX86State *cpu_x86_init(void)
>  {
>      CPUX86State *env;
> @@ -80,64 +346,23 @@ CPUX86State *cpu_x86_init(void)
>      }
>  #endif
>      {
> -        int family, model, stepping;
> -#ifdef TARGET_X86_64
> -        env->cpuid_vendor1 = 0x68747541; /* "Auth" */
> -        env->cpuid_vendor2 = 0x69746e65; /* "enti" */
> -        env->cpuid_vendor3 = 0x444d4163; /* "cAMD" */
> -        family = 6;
> -        model = 2;
> -        stepping = 3;
> -#else
> -        env->cpuid_vendor1 = 0x756e6547; /* "Genu" */
> -        env->cpuid_vendor2 = 0x49656e69; /* "ineI" */
> -        env->cpuid_vendor3 = 0x6c65746e; /* "ntel" */
> -#if 0
> -        /* pentium 75-200 */
> -        family = 5;
> -        model = 2;
> -        stepping = 11;
> -#else
> -        /* pentium pro */
> -        family = 6;
> -        model = 3;
> -        stepping = 3;
> -#endif
> -#endif
> -        env->cpuid_level = 2;
> -        env->cpuid_version = (family << 8) | (model << 4) | stepping;
> -        env->cpuid_features = (CPUID_FP87 | CPUID_DE | CPUID_PSE |
> -                               CPUID_TSC | CPUID_MSR | CPUID_MCE |
> -                               CPUID_CX8 | CPUID_PGE | CPUID_CMOV |
> -                               CPUID_PAT);
> -        env->pat = 0x0007040600070406ULL;
> -        env->cpuid_ext_features = CPUID_EXT_SSE3;
> -        env->cpuid_features |= CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_PAE | CPUID_SEP;
> -        env->cpuid_features |= CPUID_APIC;
> -        env->cpuid_xlevel = 0;
> -        {
> -            const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION;
> -            int c, len, i;
> -            len = strlen(model_id);
> -            for(i = 0; i < 48; i++) {
> -                if (i >= len)
> -                    c = '\0';
> -                else
> -                    c = model_id[i];
> -                env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
> -            }
> +        extern int use_hostlike_cpu;
> +        if (!use_hostlike_cpu || set_guest_cpu_hostlike(env))
> +            set_guest_cpu_standard(env);
> +        apply_machine_flavor(env);
> +    }
> +    {
> +        const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION;
> +        int c, len, i;
> +
> +        len = strlen(model_id);
> +        for(i = 0; i < 48; i++) {
> +            if (i >= len)
> +                c = '\0';
> +            else
> +                c = model_id[i];
> +            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
>          }
> -#ifdef TARGET_X86_64
> -        /* currently not enabled for std i386 because not fully tested */
> -        env->cpuid_ext2_features = (env->cpuid_features & 0x0183F3FF);
> -        env->cpuid_ext2_features |= CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
> -        env->cpuid_xlevel = 0x80000008;
> -
> -        /* these features are needed for Win64 and aren't fully implemented */
> -        env->cpuid_features |= CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA;
> -        /* this feature is needed for Solaris and isn't fully implemented */
> -        env->cpuid_features |= CPUID_PSE36;
> -#endif
>      }
>      cpu_reset(env);
>  #ifdef USE_KQEMU
> 
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc.
> Still grepping through log files to find problems?  Stop.
> Now Search log events and configuration files using AJAX and a browser.
> Download your FREE copy of Splunk now >>  http://get.splunk.com/
> _______________________________________________
> kvm-devel mailing list
> kvm-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/kvm-devel

  parent reply	other threads:[~2007-09-05 19:26 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-05 17:45 expose host CPU features to guests danken-atKUWr5tajBWk0Htik3J/w
2007-09-05 17:45 ` [Qemu-devel] " danken
     [not found] ` <20070905174530.GA3945-iWbx9bcAnq+Hk9JtIoIkgNBPR1lH4CV8@public.gmane.org>
2007-09-05 19:26   ` Anthony Liguori [this message]
2007-09-05 19:26     ` [Qemu-devel] Re: [kvm-devel] " Anthony Liguori
2007-09-05 19:34     ` Avi Kivity
2007-09-05 19:34       ` [Qemu-devel] Re: [kvm-devel] " Avi Kivity
     [not found]       ` <46DF04D5.5000807-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-09-05 19:44         ` Daniel P. Berrange
2007-09-05 19:44           ` [Qemu-devel] Re: [kvm-devel] " Daniel P. Berrange
     [not found]           ` <20070905194448.GN5503-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2007-09-06  0:30             ` [Qemu-devel] " Paul Brook
2007-09-06  0:30               ` [Qemu-devel] Re: [kvm-devel] " Paul Brook
2007-09-06  8:46               ` Avi Kivity
2007-09-06  8:46                 ` [Qemu-devel] " Avi Kivity
2007-09-07 10:47     ` [Qemu-devel] " Jamie Lokier
2007-09-07 10:47       ` [Qemu-devel] Re: [kvm-devel] " Jamie Lokier
     [not found]       ` <20070907104738.GA14723-tp2ajI7sM85Y6zH9YvfY1x2eb7JE58TQ@public.gmane.org>
2007-09-09  7:51         ` [Qemu-devel] " Avi Kivity
2007-09-09  7:51           ` [kvm-devel] " Avi Kivity
     [not found]           ` <46E3A618.7030505-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-09-09 12:47             ` Jamie Lokier
2007-09-09 12:47               ` [kvm-devel] " Jamie Lokier
     [not found]               ` <20070909124718.GE24240-tp2ajI7sM85Y6zH9YvfY1x2eb7JE58TQ@public.gmane.org>
2007-09-09 12:55                 ` Avi Kivity
2007-09-09 12:55                   ` [kvm-devel] " Avi Kivity
     [not found]                   ` <46E3ED2B.6080606-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-09-09 13:07                     ` Jamie Lokier
2007-09-09 13:07                       ` [kvm-devel] " Jamie Lokier
2007-09-09 13:14                       ` [kvm-devel] " Avi Kivity
2007-09-09 13:14                         ` [kvm-devel] [Qemu-devel] " Avi Kivity
     [not found]                       ` <20070909130725.GF24240-tp2ajI7sM85Y6zH9YvfY1x2eb7JE58TQ@public.gmane.org>
2007-09-09 15:25                         ` Paul Brook
2007-09-09 15:25                           ` [kvm-devel] " Paul Brook
2007-09-09 15:29                           ` [kvm-devel] " Avi Kivity
2007-09-09 15:29                             ` [kvm-devel] [Qemu-devel] " Avi Kivity
2007-09-09 15:47                             ` [kvm-devel] " Jamie Lokier
2007-09-09 15:47                               ` [kvm-devel] [Qemu-devel] " Jamie Lokier
2007-09-09 16:12                             ` [kvm-devel] " Paul Brook
2007-09-09 16:12                               ` [kvm-devel] [Qemu-devel] " Paul Brook
     [not found]                               ` <200709091712.15743.paul-qD8j1LwMmJjtCj0u4l0SBw@public.gmane.org>
2007-09-09 16:38                                 ` Avi Kivity
2007-09-09 16:38                                   ` [kvm-devel] " Avi Kivity
2007-09-10 16:53                                 ` Jamie Lokier
2007-09-10 16:53                                   ` [kvm-devel] " Jamie Lokier
2007-09-10  7:40 ` expose host CPU features to guests: Take 2 Dan Kenigsberg
2007-09-10  7:40   ` [Qemu-devel] " Dan Kenigsberg
2007-09-10 11:47   ` Natalia Portillo
2007-09-10 12:01     ` Dan Kenigsberg
2007-09-07 16:18       ` Natalia Portillo
2007-09-11 19:48         ` Luke -Jr
2007-09-10 17:16       ` Jamie Lokier
     [not found]   ` <20070910074005.GA26869-iWbx9bcAnq+Hk9JtIoIkgNBPR1lH4CV8@public.gmane.org>
2007-09-24 17:41     ` expose host CPU features to guests: Take 3 Dan Kenigsberg
2007-09-24 17:41       ` [Qemu-devel] " Dan Kenigsberg
     [not found]       ` <20070924174129.GA4507-iWbx9bcAnq+Hk9JtIoIkgNBPR1lH4CV8@public.gmane.org>
2007-09-25  1:28         ` andrzej zaborowski
2007-09-25  1:28           ` andrzej zaborowski
     [not found]           ` <fb249edb0709241828pb6b9fd4v1d1d8d4a3495f040-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2007-09-25  8:48             ` Dan Kenigsberg
2007-09-25  8:48               ` [kvm-devel] " Dan Kenigsberg
     [not found]               ` <20070925084842.GA14221-iWbx9bcAnq+Hk9JtIoIkgNBPR1lH4CV8@public.gmane.org>
2007-09-25  9:01                 ` Avi Kivity
2007-09-25  9:01                   ` [kvm-devel] " Avi Kivity
     [not found]                   ` <46F8CE52.3080502-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-09-25  9:19                     ` J. Mayer
2007-09-25  9:19                       ` [kvm-devel] " J. Mayer
2007-09-25  9:31                       ` Avi Kivity
2007-09-25  9:31                         ` [kvm-devel] " Avi Kivity
     [not found]                         ` <46F8D577.3020306-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-09-25 10:40                           ` Avi Kivity
2007-09-25 10:40                             ` [kvm-devel] " Avi Kivity
     [not found]                             ` <46F8E5A2.30906-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-09-25 11:09                               ` J. Mayer
2007-09-25 11:09                                 ` [kvm-devel] " J. Mayer
2007-09-25 11:36                                 ` Avi Kivity
2007-09-25 11:36                                   ` [kvm-devel] " Avi Kivity
     [not found]                                   ` <46F8F2B8.1080203-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-09-25 12:05                                     ` Fabrice Bellard
2007-09-25 12:05                                       ` [kvm-devel] " Fabrice Bellard
2007-09-25 13:07                                     ` Jocelyn Mayer
2007-09-25 13:07                                       ` [kvm-devel] " Jocelyn Mayer
     [not found]                                       ` <1190725664.13490.14.camel-JEa2SU7BmVsPEyPTZiGI+UEOCMrvLtNR@public.gmane.org>
2007-09-25 13:12                                         ` Avi Kivity
2007-09-25 13:12                                           ` [kvm-devel] " Avi Kivity
2007-09-25 13:27                                         ` Dan Kenigsberg
2007-09-25 13:27                                           ` [kvm-devel] " Dan Kenigsberg
2007-09-25 15:54                                       ` Jamie Lokier
2007-09-25 16:15                                         ` Avi Kivity
2007-09-25 12:51                           ` Paul Brook
2007-09-25 12:51                             ` [kvm-devel] " Paul Brook
     [not found]                             ` <200709251351.55481.paul-qD8j1LwMmJjtCj0u4l0SBw@public.gmane.org>
2007-09-25 13:13                               ` Avi Kivity
2007-09-25 13:13                                 ` [kvm-devel] " Avi Kivity
2007-09-25  9:29           ` Fabrice Bellard
2007-10-07 12:38         ` x86 -cpu option: Take 4 Dan Kenigsberg
2007-10-07 12:38           ` [Qemu-devel] " Dan Kenigsberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1189020371.7206.3.camel@squirrel \
    --to=anthony-rdkfgonbjusknkdkm+me6a@public.gmane.org \
    --cc=danken-atKUWr5tajBWk0Htik3J/w@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=qemu-devel-qX2TKyscuCcdnm+yROfE0A@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.