Patchwork [01/13] cpuid: move CPUID functions into separate file

login
register
mail settings
Submitter Andre Przywara
Date Feb. 2, 2010, 10:08 a.m.
Message ID <1265105301-3455-2-git-send-email-andre.przywara@amd.com>
Download mbox | patch
Permalink /patch/44277/
State New
Headers show

Comments

Andre Przywara - Feb. 2, 2010, 10:08 a.m.
about 40% of target-i386/helper.c consist of CPUID related functions.
Only one of them is a real TCG helper function. So move the whole
CPUID stuff out of this into a separate file to get better
maintainable parts.
This is only code reordering and should not affect QEMU's
functionality.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
 Makefile.target      |    3 +
 target-i386/cpu.h    |    3 +
 target-i386/cpuid.c  |  821 ++++++++++++++++++++++++++++++++++++++++++++++++++
 target-i386/helper.c |  779 -----------------------------------------------
 4 files changed, 827 insertions(+), 779 deletions(-)
 create mode 100644 target-i386/cpuid.c
Aurelien Jarno - March 6, 2010, 6:25 p.m.
On Tue, Feb 02, 2010 at 11:08:09AM +0100, Andre Przywara wrote:
> about 40% of target-i386/helper.c consist of CPUID related functions.
> Only one of them is a real TCG helper function. So move the whole
> CPUID stuff out of this into a separate file to get better
> maintainable parts.
> This is only code reordering and should not affect QEMU's
> functionality.
> 
> Signed-off-by: Andre Przywara <andre.przywara@amd.com>

This looks like a good idea, however, it doesn't apply anymore. Care to
resend it after rebasing it?

> ---
>  Makefile.target      |    3 +
>  target-i386/cpu.h    |    3 +
>  target-i386/cpuid.c  |  821 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  target-i386/helper.c |  779 -----------------------------------------------
>  4 files changed, 827 insertions(+), 779 deletions(-)
>  create mode 100644 target-i386/cpuid.c
> 
> diff --git a/Makefile.target b/Makefile.target
> index 5c0ef1f..37875b8 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -49,6 +49,9 @@ libobj-y += tcg/tcg.o
>  libobj-$(CONFIG_SOFTFLOAT) += fpu/softfloat.o
>  libobj-$(CONFIG_NOSOFTFLOAT) += fpu/softfloat-native.o
>  libobj-y += op_helper.o helper.o
> +ifeq ($(TARGET_BASE_ARCH), i386)
> +libobj-y += cpuid.o
> +endif
>  libobj-$(CONFIG_NEED_MMU) += mmu.o
>  libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
>  libobj-$(TARGET_ALPHA) += alpha_palcode.o
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index 216b00e..f826d3d 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -825,9 +825,12 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
>                               int is_write, int mmu_idx, int is_softmmu);
>  #define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault
>  void cpu_x86_set_a20(CPUX86State *env, int a20_state);
> +
> +/* cpuid.c */
>  void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
>                     uint32_t *eax, uint32_t *ebx,
>                     uint32_t *ecx, uint32_t *edx);
> +int cpu_x86_register (CPUX86State *env, const char *cpu_model);
>  
>  static inline int hw_breakpoint_enabled(unsigned long dr7, int index)
>  {
> diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
> new file mode 100644
> index 0000000..aaa14ba
> --- /dev/null
> +++ b/target-i386/cpuid.c
> @@ -0,0 +1,821 @@
> +/*
> + *  i386 CPUID helper functions
> + *
> + *  Copyright (c) 2003 Fabrice Bellard
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> + */
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <inttypes.h>
> +
> +#include "cpu.h"
> +#include "kvm.h"
> +
> +/* feature flags taken from "Intel Processor Identification and the CPUID
> + * Instruction" and AMD's "CPUID Specification". In cases of disagreement
> + * about feature names, the Linux name is used. */
> +static const char *feature_name[] = {
> +    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
> +    "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
> +    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
> +        NULL, "ds" /* Intel dts */, "acpi", "mmx",
> +    "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
> +};
> +static const char *ext_feature_name[] = {
> +    "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor",
> +        "ds_cpl", "vmx", NULL /* Linux 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, "hypervisor",
> +};
> +static const char *ext2_feature_name[] = {
> +    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
> +    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall",
> +        "mtrr", "pge", "mca", "cmov",
> +    "pat", "pse36", NULL, NULL /* Linux mp */,
> +        "nx" /* Intel xd */, NULL, "mmxext", "mmx",
> +    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp",
> +        NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
> +};
> +static const char *ext3_feature_name[] = {
> +    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy",
> +        "svm", "extapic" /* AMD ExtApicSpace */,
> +        "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
> +    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
> +    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> +};
> +
> +static const char *kvm_feature_name[] = {
> +    "kvmclock", "kvm_nopiodelay", "kvm_mmu", 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, NULL,
> +};
> +
> +static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
> +                                    uint32_t *ext_features,
> +                                    uint32_t *ext2_features,
> +                                    uint32_t *ext3_features,
> +                                    uint32_t *kvm_features)
> +{
> +    int i;
> +    int found = 0;
> +
> +    for ( i = 0 ; i < 32 ; i++ )
> +        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
> +            *features |= 1 << i;
> +            found = 1;
> +        }
> +    for ( i = 0 ; i < 32 ; i++ )
> +        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
> +            *ext_features |= 1 << i;
> +            found = 1;
> +        }
> +    for ( i = 0 ; i < 32 ; i++ )
> +        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
> +            *ext2_features |= 1 << i;
> +            found = 1;
> +        }
> +    for ( i = 0 ; i < 32 ; i++ )
> +        if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
> +            *ext3_features |= 1 << i;
> +            found = 1;
> +        }
> +    for ( i = 0 ; i < 32 ; i++ )
> +        if (kvm_feature_name[i] && !strcmp (flagname, kvm_feature_name[i])) {
> +            *kvm_features |= 1 << i;
> +            found = 1;
> +        }
> +
> +    if (!found) {
> +        fprintf(stderr, "CPU feature %s not found\n", flagname);
> +    }
> +}
> +
> +typedef struct x86_def_t {
> +    const char *name;
> +    uint32_t level;
> +    uint32_t vendor1, vendor2, vendor3;
> +    int family;
> +    int model;
> +    int stepping;
> +    uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
> +    uint32_t xlevel;
> +    char model_id[48];
> +    int vendor_override;
> +} x86_def_t;
> +
> +#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
> +#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
> +          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
> +#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
> +          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
> +          CPUID_PSE36 | CPUID_FXSR)
> +#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
> +#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
> +          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
> +          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
> +          CPUID_PAE | CPUID_SEP | CPUID_APIC)
> +static x86_def_t x86_defs[] = {
> +#ifdef TARGET_X86_64
> +    {
> +        .name = "qemu64",
> +        .level = 4,
> +        .vendor1 = CPUID_VENDOR_AMD_1,
> +        .vendor2 = CPUID_VENDOR_AMD_2,
> +        .vendor3 = CPUID_VENDOR_AMD_3,
> +        .family = 6,
> +        .model = 2,
> +        .stepping = 3,
> +        .features = PPRO_FEATURES | 
> +        /* these features are needed for Win64 and aren't fully implemented */
> +            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> +        /* this feature is needed for Solaris and isn't fully implemented */
> +            CPUID_PSE36,
> +        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
> +        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
> +            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> +        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
> +            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
> +        .xlevel = 0x8000000A,
> +        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
> +    },
> +    {
> +        .name = "phenom",
> +        .level = 5,
> +        .vendor1 = CPUID_VENDOR_AMD_1,
> +        .vendor2 = CPUID_VENDOR_AMD_2,
> +        .vendor3 = CPUID_VENDOR_AMD_3,
> +        .family = 16,
> +        .model = 2,
> +        .stepping = 3,
> +        /* Missing: CPUID_VME, CPUID_HT */
> +        .features = PPRO_FEATURES | 
> +            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> +            CPUID_PSE36,
> +        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
> +            CPUID_EXT_POPCNT,
> +        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
> +        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
> +            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
> +            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
> +            CPUID_EXT2_FFXSR,
> +        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
> +                    CPUID_EXT3_CR8LEG,
> +                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
> +                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
> +        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
> +            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
> +        .xlevel = 0x8000001A,
> +        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
> +    },
> +    {
> +        .name = "core2duo",
> +        .level = 10,
> +        .family = 6,
> +        .model = 15,
> +        .stepping = 11,
> +	/* The original CPU also implements these features:
> +               CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
> +               CPUID_TM, CPUID_PBE */
> +        .features = PPRO_FEATURES |
> +            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> +            CPUID_PSE36,
> +	/* The original CPU also implements these ext features:
> +               CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
> +               CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
> +        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
> +        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> +        .ext3_features = CPUID_EXT3_LAHF_LM,
> +        .xlevel = 0x80000008,
> +        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
> +    },
> +    {
> +        .name = "kvm64",
> +        .level = 5,
> +        .vendor1 = CPUID_VENDOR_INTEL_1,
> +        .vendor2 = CPUID_VENDOR_INTEL_2,
> +        .vendor3 = CPUID_VENDOR_INTEL_3,
> +        .family = 15,
> +        .model = 6,
> +        .stepping = 1,
> +        /* Missing: CPUID_VME, CPUID_HT */
> +        .features = PPRO_FEATURES |
> +            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> +            CPUID_PSE36,
> +        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
> +        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
> +        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
> +        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
> +            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> +        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
> +                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
> +                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
> +                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
> +        .ext3_features = 0,
> +        .xlevel = 0x80000008,
> +        .model_id = "Common KVM processor"
> +    },
> +#endif
> +    {
> +        .name = "qemu32",
> +        .level = 4,
> +        .family = 6,
> +        .model = 3,
> +        .stepping = 3,
> +        .features = PPRO_FEATURES,
> +        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
> +        .xlevel = 0,
> +        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
> +    },
> +    {
> +        .name = "coreduo",
> +        .level = 10,
> +        .family = 6,
> +        .model = 14,
> +        .stepping = 8,
> +        /* The original CPU also implements these features:
> +               CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
> +               CPUID_TM, CPUID_PBE */
> +        .features = PPRO_FEATURES | CPUID_VME |
> +            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
> +        /* The original CPU also implements these ext features:
> +               CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
> +               CPUID_EXT_PDCM */
> +        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
> +        .ext2_features = CPUID_EXT2_NX,
> +        .xlevel = 0x80000008,
> +        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
> +    },
> +    {
> +        .name = "486",
> +        .level = 0,
> +        .family = 4,
> +        .model = 0,
> +        .stepping = 0,
> +        .features = I486_FEATURES,
> +        .xlevel = 0,
> +    },
> +    {
> +        .name = "pentium",
> +        .level = 1,
> +        .family = 5,
> +        .model = 4,
> +        .stepping = 3,
> +        .features = PENTIUM_FEATURES,
> +        .xlevel = 0,
> +    },
> +    {
> +        .name = "pentium2",
> +        .level = 2,
> +        .family = 6,
> +        .model = 5,
> +        .stepping = 2,
> +        .features = PENTIUM2_FEATURES,
> +        .xlevel = 0,
> +    },
> +    {
> +        .name = "pentium3",
> +        .level = 2,
> +        .family = 6,
> +        .model = 7,
> +        .stepping = 3,
> +        .features = PENTIUM3_FEATURES,
> +        .xlevel = 0,
> +    },
> +    {
> +        .name = "athlon",
> +        .level = 2,
> +        .vendor1 = CPUID_VENDOR_AMD_1,
> +        .vendor2 = CPUID_VENDOR_AMD_2,
> +        .vendor3 = CPUID_VENDOR_AMD_3,
> +        .family = 6,
> +        .model = 2,
> +        .stepping = 3,
> +        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME |
> +                    CPUID_MTRR | CPUID_MCA,
> +        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT |
> +                          CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
> +        .xlevel = 0x80000008,
> +        /* XXX: put another string ? */
> +        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
> +    },
> +    {
> +        .name = "n270",
> +        /* original is on level 10 */
> +        .level = 5,
> +        .family = 6,
> +        .model = 28,
> +        .stepping = 2,
> +        .features = PPRO_FEATURES |
> +            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
> +            /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
> +             * CPUID_HT | CPUID_TM | CPUID_PBE */
> +            /* Some CPUs got no CPUID_SEP */
> +        .ext_features = CPUID_EXT_MONITOR |
> +            CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
> +            /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
> +             * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
> +        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
> +        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
> +        .xlevel = 0x8000000A,
> +        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
> +    },
> +};
> +
> +static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
> +                               uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
> +
> +static int cpu_x86_fill_model_id(char *str)
> +{
> +    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
> +    int i;
> +
> +    for (i = 0; i < 3; i++) {
> +        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
> +        memcpy(str + i * 16 +  0, &eax, 4);
> +        memcpy(str + i * 16 +  4, &ebx, 4);
> +        memcpy(str + i * 16 +  8, &ecx, 4);
> +        memcpy(str + i * 16 + 12, &edx, 4);
> +    }
> +    return 0;
> +}
> +
> +static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
> +{
> +    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
> +
> +    x86_cpu_def->name = "host";
> +    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
> +    x86_cpu_def->level = eax;
> +    x86_cpu_def->vendor1 = ebx;
> +    x86_cpu_def->vendor2 = edx;
> +    x86_cpu_def->vendor3 = ecx;
> +
> +    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
> +    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
> +    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
> +    x86_cpu_def->stepping = eax & 0x0F;
> +    x86_cpu_def->ext_features = ecx;
> +    x86_cpu_def->features = edx;
> +
> +    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
> +    x86_cpu_def->xlevel = eax;
> +
> +    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
> +    x86_cpu_def->ext2_features = edx;
> +    x86_cpu_def->ext3_features = ecx;
> +    cpu_x86_fill_model_id(x86_cpu_def->model_id);
> +    x86_cpu_def->vendor_override = 0;
> +
> +    return 0;
> +}
> +
> +static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> +{
> +    unsigned int i;
> +    x86_def_t *def;
> +
> +    char *s = strdup(cpu_model);
> +    char *featurestr, *name = strtok(s, ",");
> +    uint32_t plus_features = 0, plus_ext_features = 0,
> +        plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
> +    uint32_t minus_features = 0, minus_ext_features = 0,
> +        minus_ext2_features = 0, minus_ext3_features = 0,
> +        minus_kvm_features = 0;
> +    uint32_t numvalue;
> +
> +    def = NULL;
> +    for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
> +        if (strcmp(name, x86_defs[i].name) == 0) {
> +            def = &x86_defs[i];
> +            break;
> +        }
> +    }
> +    if (kvm_enabled() && strcmp(name, "host") == 0) {
> +        cpu_x86_fill_host(x86_cpu_def);
> +    } else if (!def) {
> +        goto error;
> +    } else {
> +        memcpy(x86_cpu_def, def, sizeof(*def));
> +    }
> +
> +    plus_kvm_features = ~0; /* not supported bits will be filtered out later */
> +
> +    add_flagname_to_bitmaps("hypervisor", &plus_features,
> +        &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
> +        &plus_kvm_features);
> +
> +    featurestr = strtok(NULL, ",");
> +
> +    while (featurestr) {
> +        char *val;
> +        if (featurestr[0] == '+') {
> +            add_flagname_to_bitmaps(featurestr + 1, &plus_features,
> +                                    &plus_ext_features, &plus_ext2_features,
> +                                    &plus_ext3_features, &plus_kvm_features);
> +        } else if (featurestr[0] == '-') {
> +            add_flagname_to_bitmaps(featurestr + 1, &minus_features,
> +                                    &minus_ext_features, &minus_ext2_features,
> +                                    &minus_ext3_features, &minus_kvm_features);
> +        } else if ((val = strchr(featurestr, '='))) {
> +            *val = 0; val++;
> +            if (!strcmp(featurestr, "family")) {
> +                char *err;
> +                numvalue = strtoul(val, &err, 0);
> +                if (!*val || *err) {
> +                    fprintf(stderr, "bad numerical value %s\n", val);
> +                    goto error;
> +                }
> +                x86_cpu_def->family = numvalue;
> +            } else if (!strcmp(featurestr, "model")) {
> +                char *err;
> +                numvalue = strtoul(val, &err, 0);
> +                if (!*val || *err || numvalue > 0xff) {
> +                    fprintf(stderr, "bad numerical value %s\n", val);
> +                    goto error;
> +                }
> +                x86_cpu_def->model = numvalue;
> +            } else if (!strcmp(featurestr, "stepping")) {
> +                char *err;
> +                numvalue = strtoul(val, &err, 0);
> +                if (!*val || *err || numvalue > 0xf) {
> +                    fprintf(stderr, "bad numerical value %s\n", val);
> +                    goto error;
> +                }
> +                x86_cpu_def->stepping = numvalue ;
> +            } else if (!strcmp(featurestr, "level")) {
> +                char *err;
> +                numvalue = strtoul(val, &err, 0);
> +                if (!*val || *err) {
> +                    fprintf(stderr, "bad numerical value %s\n", val);
> +                    goto error;
> +                }
> +                x86_cpu_def->level = numvalue;
> +            } else if (!strcmp(featurestr, "xlevel")) {
> +                char *err;
> +                numvalue = strtoul(val, &err, 0);
> +                if (!*val || *err) {
> +                    fprintf(stderr, "bad numerical value %s\n", val);
> +                    goto error;
> +                }
> +                if (numvalue < 0x80000000) {
> +                	numvalue += 0x80000000;
> +                }
> +                x86_cpu_def->xlevel = numvalue;
> +            } else if (!strcmp(featurestr, "vendor")) {
> +                if (strlen(val) != 12) {
> +                    fprintf(stderr, "vendor string must be 12 chars long\n");
> +                    goto error;
> +                }
> +                x86_cpu_def->vendor1 = 0;
> +                x86_cpu_def->vendor2 = 0;
> +                x86_cpu_def->vendor3 = 0;
> +                for(i = 0; i < 4; i++) {
> +                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
> +                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
> +                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
> +                }
> +                x86_cpu_def->vendor_override = 1;
> +            } else if (!strcmp(featurestr, "model_id")) {
> +                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
> +                        val);
> +            } else {
> +                fprintf(stderr, "unrecognized feature %s\n", featurestr);
> +                goto error;
> +            }
> +        } else {
> +            fprintf(stderr, "feature string `%s' not in format "
> +                            "(+feature|-feature|feature=xyz)\n", featurestr);
> +            goto error;
> +        }
> +        featurestr = strtok(NULL, ",");
> +    }
> +    x86_cpu_def->features |= plus_features;
> +    x86_cpu_def->ext_features |= plus_ext_features;
> +    x86_cpu_def->ext2_features |= plus_ext2_features;
> +    x86_cpu_def->ext3_features |= plus_ext3_features;
> +    x86_cpu_def->kvm_features |= plus_kvm_features;
> +    x86_cpu_def->features &= ~minus_features;
> +    x86_cpu_def->ext_features &= ~minus_ext_features;
> +    x86_cpu_def->ext2_features &= ~minus_ext2_features;
> +    x86_cpu_def->ext3_features &= ~minus_ext3_features;
> +    x86_cpu_def->kvm_features &= ~minus_kvm_features;
> +    free(s);
> +    return 0;
> +
> +error:
> +    free(s);
> +    return -1;
> +}
> +
> +void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
> +{
> +    unsigned int i;
> +
> +    for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
> +        (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
> +}
> +
> +int cpu_x86_register (CPUX86State *env, const char *cpu_model)
> +{
> +    x86_def_t def1, *def = &def1;
> +
> +    if (cpu_x86_find_by_name(def, cpu_model) < 0)
> +        return -1;
> +    if (def->vendor1) {
> +        env->cpuid_vendor1 = def->vendor1;
> +        env->cpuid_vendor2 = def->vendor2;
> +        env->cpuid_vendor3 = def->vendor3;
> +    } else {
> +        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
> +        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
> +        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
> +    }
> +    env->cpuid_vendor_override = def->vendor_override;
> +    env->cpuid_level = def->level;
> +    if (def->family > 0x0f)
> +        env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
> +    else
> +        env->cpuid_version = def->family << 8;
> +    env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
> +    env->cpuid_version |= def->stepping;
> +    env->cpuid_features = def->features;
> +    env->pat = 0x0007040600070406ULL;
> +    env->cpuid_ext_features = def->ext_features;
> +    env->cpuid_ext2_features = def->ext2_features;
> +    env->cpuid_xlevel = def->xlevel;
> +    env->cpuid_kvm_features = def->kvm_features;
> +    {
> +        const char *model_id = def->model_id;
> +        int c, len, i;
> +        if (!model_id)
> +            model_id = "";
> +        len = strlen(model_id);
> +        for(i = 0; i < 48; i++) {
> +            if (i >= len)
> +                c = '\0';
> +            else
> +                c = (uint8_t)model_id[i];
> +            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
> +        }
> +    }
> +    return 0;
> +}
> +
> +static void host_cpuid(uint32_t function, uint32_t count,
> +                       uint32_t *eax, uint32_t *ebx,
> +                       uint32_t *ecx, uint32_t *edx)
> +{
> +#if defined(CONFIG_KVM)
> +    uint32_t vec[4];
> +
> +#ifdef __x86_64__
> +    asm volatile("cpuid"
> +                 : "=a"(vec[0]), "=b"(vec[1]),
> +                   "=c"(vec[2]), "=d"(vec[3])
> +                 : "0"(function), "c"(count) : "cc");
> +#else
> +    asm volatile("pusha \n\t"
> +                 "cpuid \n\t"
> +                 "mov %%eax, 0(%2) \n\t"
> +                 "mov %%ebx, 4(%2) \n\t"
> +                 "mov %%ecx, 8(%2) \n\t"
> +                 "mov %%edx, 12(%2) \n\t"
> +                 "popa"
> +                 : : "a"(function), "c"(count), "S"(vec)
> +                 : "memory", "cc");
> +#endif
> +
> +    if (eax)
> +	*eax = vec[0];
> +    if (ebx)
> +	*ebx = vec[1];
> +    if (ecx)
> +	*ecx = vec[2];
> +    if (edx)
> +	*edx = vec[3];
> +#endif
> +}
> +
> +static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
> +                             uint32_t *ecx, uint32_t *edx)
> +{
> +    *ebx = env->cpuid_vendor1;
> +    *edx = env->cpuid_vendor2;
> +    *ecx = env->cpuid_vendor3;
> +
> +    /* sysenter isn't supported on compatibility mode on AMD, syscall
> +     * isn't supported in compatibility mode on Intel.
> +     * Normally we advertise the actual cpu vendor, but you can override
> +     * this if you want to use KVM's sysenter/syscall emulation
> +     * in compatibility mode and when doing cross vendor migration
> +     */
> +    if (kvm_enabled() && env->cpuid_vendor_override) {
> +        host_cpuid(0, 0, NULL, ebx, ecx, edx);
> +    }
> +}
> +
> +void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
> +                   uint32_t *eax, uint32_t *ebx,
> +                   uint32_t *ecx, uint32_t *edx)
> +{
> +    /* test if maximum index reached */
> +    if (index & 0x80000000) {
> +        if (index > env->cpuid_xlevel)
> +            index = env->cpuid_level;
> +    } else {
> +        if (index > env->cpuid_level)
> +            index = env->cpuid_level;
> +    }
> +
> +    switch(index) {
> +    case 0:
> +        *eax = env->cpuid_level;
> +        get_cpuid_vendor(env, ebx, ecx, edx);
> +        break;
> +    case 1:
> +        *eax = env->cpuid_version;
> +        /* CLFLUSH size in quad words, Linux wants it. */
> +        *ebx = (env->cpuid_apic_id << 24) | 8 << 8;
> +        *ecx = env->cpuid_ext_features;
> +        *edx = env->cpuid_features;
> +        if (env->nr_cores * env->nr_threads > 1) {
> +            *ebx |= (env->nr_cores * env->nr_threads) << 16;
> +            *edx |= 1 << 28;    /* HTT bit */
> +        }
> +        break;
> +    case 2:
> +        /* cache info: needed for Pentium Pro compatibility */
> +        *eax = 1;
> +        *ebx = 0;
> +        *ecx = 0;
> +        *edx = 0x2c307d;
> +        break;
> +    case 4:
> +        /* cache info: needed for Core compatibility */
> +        if (env->nr_cores > 1) {
> +        	*eax = (env->nr_cores - 1) << 26;
> +        } else {
> +        	*eax = 0;
> +        }
> +        switch (count) {
> +            case 0: /* L1 dcache info */
> +                *eax |= 0x0000121;
> +                *ebx = 0x1c0003f;
> +                *ecx = 0x000003f;
> +                *edx = 0x0000001;
> +                break;
> +            case 1: /* L1 icache info */
> +                *eax |= 0x0000122;
> +                *ebx = 0x1c0003f;
> +                *ecx = 0x000003f;
> +                *edx = 0x0000001;
> +                break;
> +            case 2: /* L2 cache info */
> +                *eax |= 0x0000143;
> +                if (env->nr_threads > 1) {
> +                    *eax |= (env->nr_threads - 1) << 14;
> +                }
> +                *ebx = 0x3c0003f;
> +                *ecx = 0x0000fff;
> +                *edx = 0x0000001;
> +                break;
> +            default: /* end of info */
> +                *eax = 0;
> +                *ebx = 0;
> +                *ecx = 0;
> +                *edx = 0;
> +                break;
> +        }
> +        break;
> +    case 5:
> +        /* mwait info: needed for Core compatibility */
> +        *eax = 0; /* Smallest monitor-line size in bytes */
> +        *ebx = 0; /* Largest monitor-line size in bytes */
> +        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
> +        *edx = 0;
> +        break;
> +    case 6:
> +        /* Thermal and Power Leaf */
> +        *eax = 0;
> +        *ebx = 0;
> +        *ecx = 0;
> +        *edx = 0;
> +        break;
> +    case 9:
> +        /* Direct Cache Access Information Leaf */
> +        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
> +        *ebx = 0;
> +        *ecx = 0;
> +        *edx = 0;
> +        break;
> +    case 0xA:
> +        /* Architectural Performance Monitoring Leaf */
> +        *eax = 0;
> +        *ebx = 0;
> +        *ecx = 0;
> +        *edx = 0;
> +        break;
> +    case 0x80000000:
> +        *eax = env->cpuid_xlevel;
> +        *ebx = env->cpuid_vendor1;
> +        *edx = env->cpuid_vendor2;
> +        *ecx = env->cpuid_vendor3;
> +        break;
> +    case 0x80000001:
> +        *eax = env->cpuid_version;
> +        *ebx = 0;
> +        *ecx = env->cpuid_ext3_features;
> +        *edx = env->cpuid_ext2_features;
> +
> +        /* The Linux kernel checks for the CMPLegacy bit and
> +         * discards multiple thread information if it is set.
> +         * So dont set it here for Intel to make Linux guests happy.
> +         */
> +        if (env->nr_cores * env->nr_threads > 1) {
> +            uint32_t tebx, tecx, tedx;
> +            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
> +            if (tebx != CPUID_VENDOR_INTEL_1 ||
> +                tedx != CPUID_VENDOR_INTEL_2 ||
> +                tecx != CPUID_VENDOR_INTEL_3) {
> +                *ecx |= 1 << 1;    /* CmpLegacy bit */
> +            }
> +        }
> +
> +        if (kvm_enabled()) {
> +            /* Nested SVM not yet supported in upstream QEMU */
> +            *ecx &= ~CPUID_EXT3_SVM;
> +        }
> +        break;
> +    case 0x80000002:
> +    case 0x80000003:
> +    case 0x80000004:
> +        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
> +        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
> +        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
> +        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
> +        break;
> +    case 0x80000005:
> +        /* cache info (L1 cache) */
> +        *eax = 0x01ff01ff;
> +        *ebx = 0x01ff01ff;
> +        *ecx = 0x40020140;
> +        *edx = 0x40020140;
> +        break;
> +    case 0x80000006:
> +        /* cache info (L2 cache) */
> +        *eax = 0;
> +        *ebx = 0x42004200;
> +        *ecx = 0x02008140;
> +        *edx = 0;
> +        break;
> +    case 0x80000008:
> +        /* virtual & phys address size in low 2 bytes. */
> +/* XXX: This value must match the one used in the MMU code. */ 
> +        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
> +            /* 64 bit processor */
> +/* XXX: The physical address space is limited to 42 bits in exec.c. */
> +            *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */
> +        } else {
> +            if (env->cpuid_features & CPUID_PSE36)
> +                *eax = 0x00000024; /* 36 bits physical */
> +            else
> +                *eax = 0x00000020; /* 32 bits physical */
> +        }
> +        *ebx = 0;
> +        *ecx = 0;
> +        *edx = 0;
> +        if (env->nr_cores * env->nr_threads > 1) {
> +            *ecx |= (env->nr_cores * env->nr_threads) - 1;
> +        }
> +        break;
> +    case 0x8000000A:
> +        *eax = 0x00000001; /* SVM Revision */
> +        *ebx = 0x00000010; /* nr of ASIDs */
> +        *ecx = 0;
> +        *edx = 0; /* optional features */
> +        break;
> +    default:
> +        /* reserved values: zero */
> +        *eax = 0;
> +        *ebx = 0;
> +        *ecx = 0;
> +        *edx = 0;
> +        break;
> +    }
> +}
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 70762bb..b120051 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -30,542 +30,6 @@
>  
>  //#define DEBUG_MMU
>  
> -/* feature flags taken from "Intel Processor Identification and the CPUID
> - * Instruction" and AMD's "CPUID Specification". In cases of disagreement
> - * about feature names, the Linux name is used. */
> -static const char *feature_name[] = {
> -    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
> -    "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
> -    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
> -    "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
> -};
> -static const char *ext_feature_name[] = {
> -    "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux 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, "hypervisor",
> -};
> -static const char *ext2_feature_name[] = {
> -    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
> -    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
> -    "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
> -    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
> -};
> -static const char *ext3_feature_name[] = {
> -    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
> -    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
> -    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> -    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> -};
> -
> -static const char *kvm_feature_name[] = {
> -    "kvmclock", "kvm_nopiodelay", "kvm_mmu", 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, NULL,
> -};
> -
> -static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
> -                                    uint32_t *ext_features,
> -                                    uint32_t *ext2_features,
> -                                    uint32_t *ext3_features,
> -                                    uint32_t *kvm_features)
> -{
> -    int i;
> -    int found = 0;
> -
> -    for ( i = 0 ; i < 32 ; i++ )
> -        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
> -            *features |= 1 << i;
> -            found = 1;
> -        }
> -    for ( i = 0 ; i < 32 ; i++ )
> -        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
> -            *ext_features |= 1 << i;
> -            found = 1;
> -        }
> -    for ( i = 0 ; i < 32 ; i++ )
> -        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
> -            *ext2_features |= 1 << i;
> -            found = 1;
> -        }
> -    for ( i = 0 ; i < 32 ; i++ )
> -        if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
> -            *ext3_features |= 1 << i;
> -            found = 1;
> -        }
> -    for ( i = 0 ; i < 32 ; i++ )
> -        if (kvm_feature_name[i] && !strcmp (flagname, kvm_feature_name[i])) {
> -            *kvm_features |= 1 << i;
> -            found = 1;
> -        }
> -
> -    if (!found) {
> -        fprintf(stderr, "CPU feature %s not found\n", flagname);
> -    }
> -}
> -
> -typedef struct x86_def_t {
> -    const char *name;
> -    uint32_t level;
> -    uint32_t vendor1, vendor2, vendor3;
> -    int family;
> -    int model;
> -    int stepping;
> -    uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
> -    uint32_t xlevel;
> -    char model_id[48];
> -    int vendor_override;
> -} x86_def_t;
> -
> -#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
> -#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
> -          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
> -#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
> -          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
> -          CPUID_PSE36 | CPUID_FXSR)
> -#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
> -#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
> -          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
> -          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
> -          CPUID_PAE | CPUID_SEP | CPUID_APIC)
> -static x86_def_t x86_defs[] = {
> -#ifdef TARGET_X86_64
> -    {
> -        .name = "qemu64",
> -        .level = 4,
> -        .vendor1 = CPUID_VENDOR_AMD_1,
> -        .vendor2 = CPUID_VENDOR_AMD_2,
> -        .vendor3 = CPUID_VENDOR_AMD_3,
> -        .family = 6,
> -        .model = 2,
> -        .stepping = 3,
> -        .features = PPRO_FEATURES | 
> -        /* these features are needed for Win64 and aren't fully implemented */
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> -        /* this feature is needed for Solaris and isn't fully implemented */
> -            CPUID_PSE36,
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
> -        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
> -            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> -        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
> -            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
> -        .xlevel = 0x8000000A,
> -        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
> -    },
> -    {
> -        .name = "phenom",
> -        .level = 5,
> -        .vendor1 = CPUID_VENDOR_AMD_1,
> -        .vendor2 = CPUID_VENDOR_AMD_2,
> -        .vendor3 = CPUID_VENDOR_AMD_3,
> -        .family = 16,
> -        .model = 2,
> -        .stepping = 3,
> -        /* Missing: CPUID_VME, CPUID_HT */
> -        .features = PPRO_FEATURES | 
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> -            CPUID_PSE36,
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
> -            CPUID_EXT_POPCNT,
> -        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
> -        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
> -            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
> -            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
> -            CPUID_EXT2_FFXSR,
> -        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
> -                    CPUID_EXT3_CR8LEG,
> -                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
> -                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
> -        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
> -            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
> -        .xlevel = 0x8000001A,
> -        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
> -    },
> -    {
> -        .name = "core2duo",
> -        .level = 10,
> -        .family = 6,
> -        .model = 15,
> -        .stepping = 11,
> -	/* The original CPU also implements these features:
> -               CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
> -               CPUID_TM, CPUID_PBE */
> -        .features = PPRO_FEATURES |
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> -            CPUID_PSE36,
> -	/* The original CPU also implements these ext features:
> -               CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
> -               CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> -        .ext3_features = CPUID_EXT3_LAHF_LM,
> -        .xlevel = 0x80000008,
> -        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
> -    },
> -    {
> -        .name = "kvm64",
> -        .level = 5,
> -        .vendor1 = CPUID_VENDOR_INTEL_1,
> -        .vendor2 = CPUID_VENDOR_INTEL_2,
> -        .vendor3 = CPUID_VENDOR_INTEL_3,
> -        .family = 15,
> -        .model = 6,
> -        .stepping = 1,
> -        /* Missing: CPUID_VME, CPUID_HT */
> -        .features = PPRO_FEATURES |
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> -            CPUID_PSE36,
> -        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
> -        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
> -        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
> -            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> -        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
> -                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
> -                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
> -                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
> -        .ext3_features = 0,
> -        .xlevel = 0x80000008,
> -        .model_id = "Common KVM processor"
> -    },
> -#endif
> -    {
> -        .name = "qemu32",
> -        .level = 4,
> -        .family = 6,
> -        .model = 3,
> -        .stepping = 3,
> -        .features = PPRO_FEATURES,
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
> -        .xlevel = 0,
> -        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
> -    },
> -    {
> -        .name = "coreduo",
> -        .level = 10,
> -        .family = 6,
> -        .model = 14,
> -        .stepping = 8,
> -        /* The original CPU also implements these features:
> -               CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
> -               CPUID_TM, CPUID_PBE */
> -        .features = PPRO_FEATURES | CPUID_VME |
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
> -        /* The original CPU also implements these ext features:
> -               CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
> -               CPUID_EXT_PDCM */
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
> -        .ext2_features = CPUID_EXT2_NX,
> -        .xlevel = 0x80000008,
> -        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
> -    },
> -    {
> -        .name = "486",
> -        .level = 0,
> -        .family = 4,
> -        .model = 0,
> -        .stepping = 0,
> -        .features = I486_FEATURES,
> -        .xlevel = 0,
> -    },
> -    {
> -        .name = "pentium",
> -        .level = 1,
> -        .family = 5,
> -        .model = 4,
> -        .stepping = 3,
> -        .features = PENTIUM_FEATURES,
> -        .xlevel = 0,
> -    },
> -    {
> -        .name = "pentium2",
> -        .level = 2,
> -        .family = 6,
> -        .model = 5,
> -        .stepping = 2,
> -        .features = PENTIUM2_FEATURES,
> -        .xlevel = 0,
> -    },
> -    {
> -        .name = "pentium3",
> -        .level = 2,
> -        .family = 6,
> -        .model = 7,
> -        .stepping = 3,
> -        .features = PENTIUM3_FEATURES,
> -        .xlevel = 0,
> -    },
> -    {
> -        .name = "athlon",
> -        .level = 2,
> -        .vendor1 = CPUID_VENDOR_AMD_1,
> -        .vendor2 = CPUID_VENDOR_AMD_2,
> -        .vendor3 = CPUID_VENDOR_AMD_3,
> -        .family = 6,
> -        .model = 2,
> -        .stepping = 3,
> -        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
> -        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
> -        .xlevel = 0x80000008,
> -        /* XXX: put another string ? */
> -        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
> -    },
> -    {
> -        .name = "n270",
> -        /* original is on level 10 */
> -        .level = 5,
> -        .family = 6,
> -        .model = 28,
> -        .stepping = 2,
> -        .features = PPRO_FEATURES |
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
> -            /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
> -             * CPUID_HT | CPUID_TM | CPUID_PBE */
> -            /* Some CPUs got no CPUID_SEP */
> -        .ext_features = CPUID_EXT_MONITOR |
> -            CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
> -            /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
> -             * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
> -        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
> -        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
> -        .xlevel = 0x8000000A,
> -        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
> -    },
> -};
> -
> -static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
> -                               uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
> -
> -static int cpu_x86_fill_model_id(char *str)
> -{
> -    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
> -    int i;
> -
> -    for (i = 0; i < 3; i++) {
> -        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
> -        memcpy(str + i * 16 +  0, &eax, 4);
> -        memcpy(str + i * 16 +  4, &ebx, 4);
> -        memcpy(str + i * 16 +  8, &ecx, 4);
> -        memcpy(str + i * 16 + 12, &edx, 4);
> -    }
> -    return 0;
> -}
> -
> -static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
> -{
> -    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
> -
> -    x86_cpu_def->name = "host";
> -    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
> -    x86_cpu_def->level = eax;
> -    x86_cpu_def->vendor1 = ebx;
> -    x86_cpu_def->vendor2 = edx;
> -    x86_cpu_def->vendor3 = ecx;
> -
> -    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
> -    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
> -    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
> -    x86_cpu_def->stepping = eax & 0x0F;
> -    x86_cpu_def->ext_features = ecx;
> -    x86_cpu_def->features = edx;
> -
> -    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
> -    x86_cpu_def->xlevel = eax;
> -
> -    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
> -    x86_cpu_def->ext2_features = edx;
> -    x86_cpu_def->ext3_features = ecx;
> -    cpu_x86_fill_model_id(x86_cpu_def->model_id);
> -    x86_cpu_def->vendor_override = 0;
> -
> -    return 0;
> -}
> -
> -static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
> -{
> -    unsigned int i;
> -    x86_def_t *def;
> -
> -    char *s = strdup(cpu_model);
> -    char *featurestr, *name = strtok(s, ",");
> -    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
> -    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0, minus_kvm_features = 0;
> -    uint32_t numvalue;
> -
> -    def = NULL;
> -    for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
> -        if (strcmp(name, x86_defs[i].name) == 0) {
> -            def = &x86_defs[i];
> -            break;
> -        }
> -    }
> -    if (kvm_enabled() && strcmp(name, "host") == 0) {
> -        cpu_x86_fill_host(x86_cpu_def);
> -    } else if (!def) {
> -        goto error;
> -    } else {
> -        memcpy(x86_cpu_def, def, sizeof(*def));
> -    }
> -
> -    plus_kvm_features = ~0; /* not supported bits will be filtered out later */
> -
> -    add_flagname_to_bitmaps("hypervisor", &plus_features,
> -        &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
> -        &plus_kvm_features);
> -
> -    featurestr = strtok(NULL, ",");
> -
> -    while (featurestr) {
> -        char *val;
> -        if (featurestr[0] == '+') {
> -            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features, &plus_kvm_features);
> -        } else if (featurestr[0] == '-') {
> -            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features, &minus_kvm_features);
> -        } else if ((val = strchr(featurestr, '='))) {
> -            *val = 0; val++;
> -            if (!strcmp(featurestr, "family")) {
> -                char *err;
> -                numvalue = strtoul(val, &err, 0);
> -                if (!*val || *err) {
> -                    fprintf(stderr, "bad numerical value %s\n", val);
> -                    goto error;
> -                }
> -                x86_cpu_def->family = numvalue;
> -            } else if (!strcmp(featurestr, "model")) {
> -                char *err;
> -                numvalue = strtoul(val, &err, 0);
> -                if (!*val || *err || numvalue > 0xff) {
> -                    fprintf(stderr, "bad numerical value %s\n", val);
> -                    goto error;
> -                }
> -                x86_cpu_def->model = numvalue;
> -            } else if (!strcmp(featurestr, "stepping")) {
> -                char *err;
> -                numvalue = strtoul(val, &err, 0);
> -                if (!*val || *err || numvalue > 0xf) {
> -                    fprintf(stderr, "bad numerical value %s\n", val);
> -                    goto error;
> -                }
> -                x86_cpu_def->stepping = numvalue ;
> -            } else if (!strcmp(featurestr, "level")) {
> -                char *err;
> -                numvalue = strtoul(val, &err, 0);
> -                if (!*val || *err) {
> -                    fprintf(stderr, "bad numerical value %s\n", val);
> -                    goto error;
> -                }
> -                x86_cpu_def->level = numvalue;
> -            } else if (!strcmp(featurestr, "xlevel")) {
> -                char *err;
> -                numvalue = strtoul(val, &err, 0);
> -                if (!*val || *err) {
> -                    fprintf(stderr, "bad numerical value %s\n", val);
> -                    goto error;
> -                }
> -                if (numvalue < 0x80000000) {
> -                	numvalue += 0x80000000;
> -                }
> -                x86_cpu_def->xlevel = numvalue;
> -            } else if (!strcmp(featurestr, "vendor")) {
> -                if (strlen(val) != 12) {
> -                    fprintf(stderr, "vendor string must be 12 chars long\n");
> -                    goto error;
> -                }
> -                x86_cpu_def->vendor1 = 0;
> -                x86_cpu_def->vendor2 = 0;
> -                x86_cpu_def->vendor3 = 0;
> -                for(i = 0; i < 4; i++) {
> -                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
> -                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
> -                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
> -                }
> -                x86_cpu_def->vendor_override = 1;
> -            } else if (!strcmp(featurestr, "model_id")) {
> -                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
> -                        val);
> -            } else {
> -                fprintf(stderr, "unrecognized feature %s\n", featurestr);
> -                goto error;
> -            }
> -        } else {
> -            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
> -            goto error;
> -        }
> -        featurestr = strtok(NULL, ",");
> -    }
> -    x86_cpu_def->features |= plus_features;
> -    x86_cpu_def->ext_features |= plus_ext_features;
> -    x86_cpu_def->ext2_features |= plus_ext2_features;
> -    x86_cpu_def->ext3_features |= plus_ext3_features;
> -    x86_cpu_def->kvm_features |= plus_kvm_features;
> -    x86_cpu_def->features &= ~minus_features;
> -    x86_cpu_def->ext_features &= ~minus_ext_features;
> -    x86_cpu_def->ext2_features &= ~minus_ext2_features;
> -    x86_cpu_def->ext3_features &= ~minus_ext3_features;
> -    x86_cpu_def->kvm_features &= ~minus_kvm_features;
> -    free(s);
> -    return 0;
> -
> -error:
> -    free(s);
> -    return -1;
> -}
> -
> -void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
> -{
> -    unsigned int i;
> -
> -    for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
> -        (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
> -}
> -
> -static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
> -{
> -    x86_def_t def1, *def = &def1;
> -
> -    if (cpu_x86_find_by_name(def, cpu_model) < 0)
> -        return -1;
> -    if (def->vendor1) {
> -        env->cpuid_vendor1 = def->vendor1;
> -        env->cpuid_vendor2 = def->vendor2;
> -        env->cpuid_vendor3 = def->vendor3;
> -    } else {
> -        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
> -        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
> -        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
> -    }
> -    env->cpuid_vendor_override = def->vendor_override;
> -    env->cpuid_level = def->level;
> -    if (def->family > 0x0f)
> -        env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
> -    else
> -        env->cpuid_version = def->family << 8;
> -    env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
> -    env->cpuid_version |= def->stepping;
> -    env->cpuid_features = def->features;
> -    env->pat = 0x0007040600070406ULL;
> -    env->cpuid_ext_features = def->ext_features;
> -    env->cpuid_ext2_features = def->ext2_features;
> -    env->cpuid_xlevel = def->xlevel;
> -    env->cpuid_kvm_features = def->kvm_features;
> -    {
> -        const char *model_id = def->model_id;
> -        int c, len, i;
> -        if (!model_id)
> -            model_id = "";
> -        len = strlen(model_id);
> -        for(i = 0; i < 48; i++) {
> -            if (i >= len)
> -                c = '\0';
> -            else
> -                c = (uint8_t)model_id[i];
> -            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
> -        }
> -    }
> -    return 0;
> -}
> -
>  /* NOTE: must be called outside the CPU execute loop */
>  void cpu_reset(CPUX86State *env)
>  {
> @@ -1626,249 +1090,6 @@ static void mce_init(CPUX86State *cenv)
>      }
>  }
>  
> -static void host_cpuid(uint32_t function, uint32_t count,
> -                       uint32_t *eax, uint32_t *ebx,
> -                       uint32_t *ecx, uint32_t *edx)
> -{
> -#if defined(CONFIG_KVM)
> -    uint32_t vec[4];
> -
> -#ifdef __x86_64__
> -    asm volatile("cpuid"
> -                 : "=a"(vec[0]), "=b"(vec[1]),
> -                   "=c"(vec[2]), "=d"(vec[3])
> -                 : "0"(function), "c"(count) : "cc");
> -#else
> -    asm volatile("pusha \n\t"
> -                 "cpuid \n\t"
> -                 "mov %%eax, 0(%2) \n\t"
> -                 "mov %%ebx, 4(%2) \n\t"
> -                 "mov %%ecx, 8(%2) \n\t"
> -                 "mov %%edx, 12(%2) \n\t"
> -                 "popa"
> -                 : : "a"(function), "c"(count), "S"(vec)
> -                 : "memory", "cc");
> -#endif
> -
> -    if (eax)
> -	*eax = vec[0];
> -    if (ebx)
> -	*ebx = vec[1];
> -    if (ecx)
> -	*ecx = vec[2];
> -    if (edx)
> -	*edx = vec[3];
> -#endif
> -}
> -
> -static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
> -                             uint32_t *ecx, uint32_t *edx)
> -{
> -    *ebx = env->cpuid_vendor1;
> -    *edx = env->cpuid_vendor2;
> -    *ecx = env->cpuid_vendor3;
> -
> -    /* sysenter isn't supported on compatibility mode on AMD, syscall
> -     * isn't supported in compatibility mode on Intel.
> -     * Normally we advertise the actual cpu vendor, but you can override
> -     * this if you want to use KVM's sysenter/syscall emulation
> -     * in compatibility mode and when doing cross vendor migration
> -     */
> -    if (kvm_enabled() && env->cpuid_vendor_override) {
> -        host_cpuid(0, 0, NULL, ebx, ecx, edx);
> -    }
> -}
> -
> -void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
> -                   uint32_t *eax, uint32_t *ebx,
> -                   uint32_t *ecx, uint32_t *edx)
> -{
> -    /* test if maximum index reached */
> -    if (index & 0x80000000) {
> -        if (index > env->cpuid_xlevel)
> -            index = env->cpuid_level;
> -    } else {
> -        if (index > env->cpuid_level)
> -            index = env->cpuid_level;
> -    }
> -
> -    switch(index) {
> -    case 0:
> -        *eax = env->cpuid_level;
> -        get_cpuid_vendor(env, ebx, ecx, edx);
> -        break;
> -    case 1:
> -        *eax = env->cpuid_version;
> -        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
> -        *ecx = env->cpuid_ext_features;
> -        *edx = env->cpuid_features;
> -        if (env->nr_cores * env->nr_threads > 1) {
> -            *ebx |= (env->nr_cores * env->nr_threads) << 16;
> -            *edx |= 1 << 28;    /* HTT bit */
> -        }
> -        break;
> -    case 2:
> -        /* cache info: needed for Pentium Pro compatibility */
> -        *eax = 1;
> -        *ebx = 0;
> -        *ecx = 0;
> -        *edx = 0x2c307d;
> -        break;
> -    case 4:
> -        /* cache info: needed for Core compatibility */
> -        if (env->nr_cores > 1) {
> -        	*eax = (env->nr_cores - 1) << 26;
> -        } else {
> -        	*eax = 0;
> -        }
> -        switch (count) {
> -            case 0: /* L1 dcache info */
> -                *eax |= 0x0000121;
> -                *ebx = 0x1c0003f;
> -                *ecx = 0x000003f;
> -                *edx = 0x0000001;
> -                break;
> -            case 1: /* L1 icache info */
> -                *eax |= 0x0000122;
> -                *ebx = 0x1c0003f;
> -                *ecx = 0x000003f;
> -                *edx = 0x0000001;
> -                break;
> -            case 2: /* L2 cache info */
> -                *eax |= 0x0000143;
> -                if (env->nr_threads > 1) {
> -                    *eax |= (env->nr_threads - 1) << 14;
> -                }
> -                *ebx = 0x3c0003f;
> -                *ecx = 0x0000fff;
> -                *edx = 0x0000001;
> -                break;
> -            default: /* end of info */
> -                *eax = 0;
> -                *ebx = 0;
> -                *ecx = 0;
> -                *edx = 0;
> -                break;
> -        }
> -        break;
> -    case 5:
> -        /* mwait info: needed for Core compatibility */
> -        *eax = 0; /* Smallest monitor-line size in bytes */
> -        *ebx = 0; /* Largest monitor-line size in bytes */
> -        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
> -        *edx = 0;
> -        break;
> -    case 6:
> -        /* Thermal and Power Leaf */
> -        *eax = 0;
> -        *ebx = 0;
> -        *ecx = 0;
> -        *edx = 0;
> -        break;
> -    case 9:
> -        /* Direct Cache Access Information Leaf */
> -        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
> -        *ebx = 0;
> -        *ecx = 0;
> -        *edx = 0;
> -        break;
> -    case 0xA:
> -        /* Architectural Performance Monitoring Leaf */
> -        *eax = 0;
> -        *ebx = 0;
> -        *ecx = 0;
> -        *edx = 0;
> -        break;
> -    case 0x80000000:
> -        *eax = env->cpuid_xlevel;
> -        *ebx = env->cpuid_vendor1;
> -        *edx = env->cpuid_vendor2;
> -        *ecx = env->cpuid_vendor3;
> -        break;
> -    case 0x80000001:
> -        *eax = env->cpuid_version;
> -        *ebx = 0;
> -        *ecx = env->cpuid_ext3_features;
> -        *edx = env->cpuid_ext2_features;
> -
> -        /* The Linux kernel checks for the CMPLegacy bit and
> -         * discards multiple thread information if it is set.
> -         * So dont set it here for Intel to make Linux guests happy.
> -         */
> -        if (env->nr_cores * env->nr_threads > 1) {
> -            uint32_t tebx, tecx, tedx;
> -            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
> -            if (tebx != CPUID_VENDOR_INTEL_1 ||
> -                tedx != CPUID_VENDOR_INTEL_2 ||
> -                tecx != CPUID_VENDOR_INTEL_3) {
> -                *ecx |= 1 << 1;    /* CmpLegacy bit */
> -            }
> -        }
> -
> -        if (kvm_enabled()) {
> -            /* Nested SVM not yet supported in upstream QEMU */
> -            *ecx &= ~CPUID_EXT3_SVM;
> -        }
> -        break;
> -    case 0x80000002:
> -    case 0x80000003:
> -    case 0x80000004:
> -        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
> -        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
> -        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
> -        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
> -        break;
> -    case 0x80000005:
> -        /* cache info (L1 cache) */
> -        *eax = 0x01ff01ff;
> -        *ebx = 0x01ff01ff;
> -        *ecx = 0x40020140;
> -        *edx = 0x40020140;
> -        break;
> -    case 0x80000006:
> -        /* cache info (L2 cache) */
> -        *eax = 0;
> -        *ebx = 0x42004200;
> -        *ecx = 0x02008140;
> -        *edx = 0;
> -        break;
> -    case 0x80000008:
> -        /* virtual & phys address size in low 2 bytes. */
> -/* XXX: This value must match the one used in the MMU code. */ 
> -        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
> -            /* 64 bit processor */
> -/* XXX: The physical address space is limited to 42 bits in exec.c. */
> -            *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */
> -        } else {
> -            if (env->cpuid_features & CPUID_PSE36)
> -                *eax = 0x00000024; /* 36 bits physical */
> -            else
> -                *eax = 0x00000020; /* 32 bits physical */
> -        }
> -        *ebx = 0;
> -        *ecx = 0;
> -        *edx = 0;
> -        if (env->nr_cores * env->nr_threads > 1) {
> -            *ecx |= (env->nr_cores * env->nr_threads) - 1;
> -        }
> -        break;
> -    case 0x8000000A:
> -        *eax = 0x00000001; /* SVM Revision */
> -        *ebx = 0x00000010; /* nr of ASIDs */
> -        *ecx = 0;
> -        *edx = 0; /* optional features */
> -        break;
> -    default:
> -        /* reserved values: zero */
> -        *eax = 0;
> -        *ebx = 0;
> -        *ecx = 0;
> -        *edx = 0;
> -        break;
> -    }
> -}
> -
> -
>  int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
>                              target_ulong *base, unsigned int *limit,
>                              unsigned int *flags)
> -- 
> 1.6.4
> 
> 
> 
> 
>

Patch

diff --git a/Makefile.target b/Makefile.target
index 5c0ef1f..37875b8 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -49,6 +49,9 @@  libobj-y += tcg/tcg.o
 libobj-$(CONFIG_SOFTFLOAT) += fpu/softfloat.o
 libobj-$(CONFIG_NOSOFTFLOAT) += fpu/softfloat-native.o
 libobj-y += op_helper.o helper.o
+ifeq ($(TARGET_BASE_ARCH), i386)
+libobj-y += cpuid.o
+endif
 libobj-$(CONFIG_NEED_MMU) += mmu.o
 libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
 libobj-$(TARGET_ALPHA) += alpha_palcode.o
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 216b00e..f826d3d 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -825,9 +825,12 @@  int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
                              int is_write, int mmu_idx, int is_softmmu);
 #define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault
 void cpu_x86_set_a20(CPUX86State *env, int a20_state);
+
+/* cpuid.c */
 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                    uint32_t *eax, uint32_t *ebx,
                    uint32_t *ecx, uint32_t *edx);
+int cpu_x86_register (CPUX86State *env, const char *cpu_model);
 
 static inline int hw_breakpoint_enabled(unsigned long dr7, int index)
 {
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
new file mode 100644
index 0000000..aaa14ba
--- /dev/null
+++ b/target-i386/cpuid.c
@@ -0,0 +1,821 @@ 
+/*
+ *  i386 CPUID helper functions
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "cpu.h"
+#include "kvm.h"
+
+/* feature flags taken from "Intel Processor Identification and the CPUID
+ * Instruction" and AMD's "CPUID Specification". In cases of disagreement
+ * about feature names, the Linux name is used. */
+static const char *feature_name[] = {
+    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+    "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
+    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
+        NULL, "ds" /* Intel dts */, "acpi", "mmx",
+    "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
+};
+static const char *ext_feature_name[] = {
+    "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor",
+        "ds_cpl", "vmx", NULL /* Linux 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, "hypervisor",
+};
+static const char *ext2_feature_name[] = {
+    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall",
+        "mtrr", "pge", "mca", "cmov",
+    "pat", "pse36", NULL, NULL /* Linux mp */,
+        "nx" /* Intel xd */, NULL, "mmxext", "mmx",
+    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp",
+        NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
+};
+static const char *ext3_feature_name[] = {
+    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy",
+        "svm", "extapic" /* AMD ExtApicSpace */,
+        "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
+    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
+static const char *kvm_feature_name[] = {
+    "kvmclock", "kvm_nopiodelay", "kvm_mmu", 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, NULL,
+};
+
+static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
+                                    uint32_t *ext_features,
+                                    uint32_t *ext2_features,
+                                    uint32_t *ext3_features,
+                                    uint32_t *kvm_features)
+{
+    int i;
+    int found = 0;
+
+    for ( i = 0 ; i < 32 ; i++ )
+        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
+            *features |= 1 << i;
+            found = 1;
+        }
+    for ( i = 0 ; i < 32 ; i++ )
+        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
+            *ext_features |= 1 << i;
+            found = 1;
+        }
+    for ( i = 0 ; i < 32 ; i++ )
+        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
+            *ext2_features |= 1 << i;
+            found = 1;
+        }
+    for ( i = 0 ; i < 32 ; i++ )
+        if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
+            *ext3_features |= 1 << i;
+            found = 1;
+        }
+    for ( i = 0 ; i < 32 ; i++ )
+        if (kvm_feature_name[i] && !strcmp (flagname, kvm_feature_name[i])) {
+            *kvm_features |= 1 << i;
+            found = 1;
+        }
+
+    if (!found) {
+        fprintf(stderr, "CPU feature %s not found\n", flagname);
+    }
+}
+
+typedef struct x86_def_t {
+    const char *name;
+    uint32_t level;
+    uint32_t vendor1, vendor2, vendor3;
+    int family;
+    int model;
+    int stepping;
+    uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
+    uint32_t xlevel;
+    char model_id[48];
+    int vendor_override;
+} x86_def_t;
+
+#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
+#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
+          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
+#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
+          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
+          CPUID_PSE36 | CPUID_FXSR)
+#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
+#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
+          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
+          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
+          CPUID_PAE | CPUID_SEP | CPUID_APIC)
+static x86_def_t x86_defs[] = {
+#ifdef TARGET_X86_64
+    {
+        .name = "qemu64",
+        .level = 4,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 6,
+        .model = 2,
+        .stepping = 3,
+        .features = PPRO_FEATURES | 
+        /* these features are needed for Win64 and aren't fully implemented */
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+        /* this feature is needed for Solaris and isn't fully implemented */
+            CPUID_PSE36,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
+            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
+            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
+        .xlevel = 0x8000000A,
+        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
+    },
+    {
+        .name = "phenom",
+        .level = 5,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 16,
+        .model = 2,
+        .stepping = 3,
+        /* Missing: CPUID_VME, CPUID_HT */
+        .features = PPRO_FEATURES | 
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+            CPUID_PSE36,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
+            CPUID_EXT_POPCNT,
+        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
+            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
+            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
+            CPUID_EXT2_FFXSR,
+        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
+                    CPUID_EXT3_CR8LEG,
+                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
+                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
+        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
+            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
+        .xlevel = 0x8000001A,
+        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
+    },
+    {
+        .name = "core2duo",
+        .level = 10,
+        .family = 6,
+        .model = 15,
+        .stepping = 11,
+	/* The original CPU also implements these features:
+               CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
+               CPUID_TM, CPUID_PBE */
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+            CPUID_PSE36,
+	/* The original CPU also implements these ext features:
+               CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
+               CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        .ext3_features = CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x80000008,
+        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
+    },
+    {
+        .name = "kvm64",
+        .level = 5,
+        .vendor1 = CPUID_VENDOR_INTEL_1,
+        .vendor2 = CPUID_VENDOR_INTEL_2,
+        .vendor3 = CPUID_VENDOR_INTEL_3,
+        .family = 15,
+        .model = 6,
+        .stepping = 1,
+        /* Missing: CPUID_VME, CPUID_HT */
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+            CPUID_PSE36,
+        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
+        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
+            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
+                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
+                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
+                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
+        .ext3_features = 0,
+        .xlevel = 0x80000008,
+        .model_id = "Common KVM processor"
+    },
+#endif
+    {
+        .name = "qemu32",
+        .level = 4,
+        .family = 6,
+        .model = 3,
+        .stepping = 3,
+        .features = PPRO_FEATURES,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
+        .xlevel = 0,
+        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
+    },
+    {
+        .name = "coreduo",
+        .level = 10,
+        .family = 6,
+        .model = 14,
+        .stepping = 8,
+        /* The original CPU also implements these features:
+               CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
+               CPUID_TM, CPUID_PBE */
+        .features = PPRO_FEATURES | CPUID_VME |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
+        /* The original CPU also implements these ext features:
+               CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
+               CPUID_EXT_PDCM */
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
+        .ext2_features = CPUID_EXT2_NX,
+        .xlevel = 0x80000008,
+        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
+    },
+    {
+        .name = "486",
+        .level = 0,
+        .family = 4,
+        .model = 0,
+        .stepping = 0,
+        .features = I486_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium",
+        .level = 1,
+        .family = 5,
+        .model = 4,
+        .stepping = 3,
+        .features = PENTIUM_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium2",
+        .level = 2,
+        .family = 6,
+        .model = 5,
+        .stepping = 2,
+        .features = PENTIUM2_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium3",
+        .level = 2,
+        .family = 6,
+        .model = 7,
+        .stepping = 3,
+        .features = PENTIUM3_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "athlon",
+        .level = 2,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 6,
+        .model = 2,
+        .stepping = 3,
+        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME |
+                    CPUID_MTRR | CPUID_MCA,
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT |
+                          CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
+        .xlevel = 0x80000008,
+        /* XXX: put another string ? */
+        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
+    },
+    {
+        .name = "n270",
+        /* original is on level 10 */
+        .level = 5,
+        .family = 6,
+        .model = 28,
+        .stepping = 2,
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
+            /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
+             * CPUID_HT | CPUID_TM | CPUID_PBE */
+            /* Some CPUs got no CPUID_SEP */
+        .ext_features = CPUID_EXT_MONITOR |
+            CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
+            /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
+             * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
+        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
+        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
+        .xlevel = 0x8000000A,
+        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
+    },
+};
+
+static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
+                               uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
+
+static int cpu_x86_fill_model_id(char *str)
+{
+    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+    int i;
+
+    for (i = 0; i < 3; i++) {
+        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
+        memcpy(str + i * 16 +  0, &eax, 4);
+        memcpy(str + i * 16 +  4, &ebx, 4);
+        memcpy(str + i * 16 +  8, &ecx, 4);
+        memcpy(str + i * 16 + 12, &edx, 4);
+    }
+    return 0;
+}
+
+static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
+{
+    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+
+    x86_cpu_def->name = "host";
+    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->level = eax;
+    x86_cpu_def->vendor1 = ebx;
+    x86_cpu_def->vendor2 = edx;
+    x86_cpu_def->vendor3 = ecx;
+
+    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
+    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
+    x86_cpu_def->stepping = eax & 0x0F;
+    x86_cpu_def->ext_features = ecx;
+    x86_cpu_def->features = edx;
+
+    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->xlevel = eax;
+
+    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->ext2_features = edx;
+    x86_cpu_def->ext3_features = ecx;
+    cpu_x86_fill_model_id(x86_cpu_def->model_id);
+    x86_cpu_def->vendor_override = 0;
+
+    return 0;
+}
+
+static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
+{
+    unsigned int i;
+    x86_def_t *def;
+
+    char *s = strdup(cpu_model);
+    char *featurestr, *name = strtok(s, ",");
+    uint32_t plus_features = 0, plus_ext_features = 0,
+        plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
+    uint32_t minus_features = 0, minus_ext_features = 0,
+        minus_ext2_features = 0, minus_ext3_features = 0,
+        minus_kvm_features = 0;
+    uint32_t numvalue;
+
+    def = NULL;
+    for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
+        if (strcmp(name, x86_defs[i].name) == 0) {
+            def = &x86_defs[i];
+            break;
+        }
+    }
+    if (kvm_enabled() && strcmp(name, "host") == 0) {
+        cpu_x86_fill_host(x86_cpu_def);
+    } else if (!def) {
+        goto error;
+    } else {
+        memcpy(x86_cpu_def, def, sizeof(*def));
+    }
+
+    plus_kvm_features = ~0; /* not supported bits will be filtered out later */
+
+    add_flagname_to_bitmaps("hypervisor", &plus_features,
+        &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
+        &plus_kvm_features);
+
+    featurestr = strtok(NULL, ",");
+
+    while (featurestr) {
+        char *val;
+        if (featurestr[0] == '+') {
+            add_flagname_to_bitmaps(featurestr + 1, &plus_features,
+                                    &plus_ext_features, &plus_ext2_features,
+                                    &plus_ext3_features, &plus_kvm_features);
+        } else if (featurestr[0] == '-') {
+            add_flagname_to_bitmaps(featurestr + 1, &minus_features,
+                                    &minus_ext_features, &minus_ext2_features,
+                                    &minus_ext3_features, &minus_kvm_features);
+        } else if ((val = strchr(featurestr, '='))) {
+            *val = 0; val++;
+            if (!strcmp(featurestr, "family")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->family = numvalue;
+            } else if (!strcmp(featurestr, "model")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err || numvalue > 0xff) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->model = numvalue;
+            } else if (!strcmp(featurestr, "stepping")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err || numvalue > 0xf) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->stepping = numvalue ;
+            } else if (!strcmp(featurestr, "level")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->level = numvalue;
+            } else if (!strcmp(featurestr, "xlevel")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                if (numvalue < 0x80000000) {
+                	numvalue += 0x80000000;
+                }
+                x86_cpu_def->xlevel = numvalue;
+            } else if (!strcmp(featurestr, "vendor")) {
+                if (strlen(val) != 12) {
+                    fprintf(stderr, "vendor string must be 12 chars long\n");
+                    goto error;
+                }
+                x86_cpu_def->vendor1 = 0;
+                x86_cpu_def->vendor2 = 0;
+                x86_cpu_def->vendor3 = 0;
+                for(i = 0; i < 4; i++) {
+                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
+                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
+                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
+                }
+                x86_cpu_def->vendor_override = 1;
+            } else if (!strcmp(featurestr, "model_id")) {
+                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
+                        val);
+            } else {
+                fprintf(stderr, "unrecognized feature %s\n", featurestr);
+                goto error;
+            }
+        } else {
+            fprintf(stderr, "feature string `%s' not in format "
+                            "(+feature|-feature|feature=xyz)\n", featurestr);
+            goto error;
+        }
+        featurestr = strtok(NULL, ",");
+    }
+    x86_cpu_def->features |= plus_features;
+    x86_cpu_def->ext_features |= plus_ext_features;
+    x86_cpu_def->ext2_features |= plus_ext2_features;
+    x86_cpu_def->ext3_features |= plus_ext3_features;
+    x86_cpu_def->kvm_features |= plus_kvm_features;
+    x86_cpu_def->features &= ~minus_features;
+    x86_cpu_def->ext_features &= ~minus_ext_features;
+    x86_cpu_def->ext2_features &= ~minus_ext2_features;
+    x86_cpu_def->ext3_features &= ~minus_ext3_features;
+    x86_cpu_def->kvm_features &= ~minus_kvm_features;
+    free(s);
+    return 0;
+
+error:
+    free(s);
+    return -1;
+}
+
+void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+{
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
+        (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
+}
+
+int cpu_x86_register (CPUX86State *env, const char *cpu_model)
+{
+    x86_def_t def1, *def = &def1;
+
+    if (cpu_x86_find_by_name(def, cpu_model) < 0)
+        return -1;
+    if (def->vendor1) {
+        env->cpuid_vendor1 = def->vendor1;
+        env->cpuid_vendor2 = def->vendor2;
+        env->cpuid_vendor3 = def->vendor3;
+    } else {
+        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
+        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
+        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
+    }
+    env->cpuid_vendor_override = def->vendor_override;
+    env->cpuid_level = def->level;
+    if (def->family > 0x0f)
+        env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
+    else
+        env->cpuid_version = def->family << 8;
+    env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
+    env->cpuid_version |= def->stepping;
+    env->cpuid_features = def->features;
+    env->pat = 0x0007040600070406ULL;
+    env->cpuid_ext_features = def->ext_features;
+    env->cpuid_ext2_features = def->ext2_features;
+    env->cpuid_xlevel = def->xlevel;
+    env->cpuid_kvm_features = def->kvm_features;
+    {
+        const char *model_id = def->model_id;
+        int c, len, i;
+        if (!model_id)
+            model_id = "";
+        len = strlen(model_id);
+        for(i = 0; i < 48; i++) {
+            if (i >= len)
+                c = '\0';
+            else
+                c = (uint8_t)model_id[i];
+            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
+        }
+    }
+    return 0;
+}
+
+static void host_cpuid(uint32_t function, uint32_t count,
+                       uint32_t *eax, uint32_t *ebx,
+                       uint32_t *ecx, uint32_t *edx)
+{
+#if defined(CONFIG_KVM)
+    uint32_t vec[4];
+
+#ifdef __x86_64__
+    asm volatile("cpuid"
+                 : "=a"(vec[0]), "=b"(vec[1]),
+                   "=c"(vec[2]), "=d"(vec[3])
+                 : "0"(function), "c"(count) : "cc");
+#else
+    asm volatile("pusha \n\t"
+                 "cpuid \n\t"
+                 "mov %%eax, 0(%2) \n\t"
+                 "mov %%ebx, 4(%2) \n\t"
+                 "mov %%ecx, 8(%2) \n\t"
+                 "mov %%edx, 12(%2) \n\t"
+                 "popa"
+                 : : "a"(function), "c"(count), "S"(vec)
+                 : "memory", "cc");
+#endif
+
+    if (eax)
+	*eax = vec[0];
+    if (ebx)
+	*ebx = vec[1];
+    if (ecx)
+	*ecx = vec[2];
+    if (edx)
+	*edx = vec[3];
+#endif
+}
+
+static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
+                             uint32_t *ecx, uint32_t *edx)
+{
+    *ebx = env->cpuid_vendor1;
+    *edx = env->cpuid_vendor2;
+    *ecx = env->cpuid_vendor3;
+
+    /* sysenter isn't supported on compatibility mode on AMD, syscall
+     * isn't supported in compatibility mode on Intel.
+     * Normally we advertise the actual cpu vendor, but you can override
+     * this if you want to use KVM's sysenter/syscall emulation
+     * in compatibility mode and when doing cross vendor migration
+     */
+    if (kvm_enabled() && env->cpuid_vendor_override) {
+        host_cpuid(0, 0, NULL, ebx, ecx, edx);
+    }
+}
+
+void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
+                   uint32_t *eax, uint32_t *ebx,
+                   uint32_t *ecx, uint32_t *edx)
+{
+    /* test if maximum index reached */
+    if (index & 0x80000000) {
+        if (index > env->cpuid_xlevel)
+            index = env->cpuid_level;
+    } else {
+        if (index > env->cpuid_level)
+            index = env->cpuid_level;
+    }
+
+    switch(index) {
+    case 0:
+        *eax = env->cpuid_level;
+        get_cpuid_vendor(env, ebx, ecx, edx);
+        break;
+    case 1:
+        *eax = env->cpuid_version;
+        /* CLFLUSH size in quad words, Linux wants it. */
+        *ebx = (env->cpuid_apic_id << 24) | 8 << 8;
+        *ecx = env->cpuid_ext_features;
+        *edx = env->cpuid_features;
+        if (env->nr_cores * env->nr_threads > 1) {
+            *ebx |= (env->nr_cores * env->nr_threads) << 16;
+            *edx |= 1 << 28;    /* HTT bit */
+        }
+        break;
+    case 2:
+        /* cache info: needed for Pentium Pro compatibility */
+        *eax = 1;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0x2c307d;
+        break;
+    case 4:
+        /* cache info: needed for Core compatibility */
+        if (env->nr_cores > 1) {
+        	*eax = (env->nr_cores - 1) << 26;
+        } else {
+        	*eax = 0;
+        }
+        switch (count) {
+            case 0: /* L1 dcache info */
+                *eax |= 0x0000121;
+                *ebx = 0x1c0003f;
+                *ecx = 0x000003f;
+                *edx = 0x0000001;
+                break;
+            case 1: /* L1 icache info */
+                *eax |= 0x0000122;
+                *ebx = 0x1c0003f;
+                *ecx = 0x000003f;
+                *edx = 0x0000001;
+                break;
+            case 2: /* L2 cache info */
+                *eax |= 0x0000143;
+                if (env->nr_threads > 1) {
+                    *eax |= (env->nr_threads - 1) << 14;
+                }
+                *ebx = 0x3c0003f;
+                *ecx = 0x0000fff;
+                *edx = 0x0000001;
+                break;
+            default: /* end of info */
+                *eax = 0;
+                *ebx = 0;
+                *ecx = 0;
+                *edx = 0;
+                break;
+        }
+        break;
+    case 5:
+        /* mwait info: needed for Core compatibility */
+        *eax = 0; /* Smallest monitor-line size in bytes */
+        *ebx = 0; /* Largest monitor-line size in bytes */
+        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
+        *edx = 0;
+        break;
+    case 6:
+        /* Thermal and Power Leaf */
+        *eax = 0;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    case 9:
+        /* Direct Cache Access Information Leaf */
+        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    case 0xA:
+        /* Architectural Performance Monitoring Leaf */
+        *eax = 0;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    case 0x80000000:
+        *eax = env->cpuid_xlevel;
+        *ebx = env->cpuid_vendor1;
+        *edx = env->cpuid_vendor2;
+        *ecx = env->cpuid_vendor3;
+        break;
+    case 0x80000001:
+        *eax = env->cpuid_version;
+        *ebx = 0;
+        *ecx = env->cpuid_ext3_features;
+        *edx = env->cpuid_ext2_features;
+
+        /* The Linux kernel checks for the CMPLegacy bit and
+         * discards multiple thread information if it is set.
+         * So dont set it here for Intel to make Linux guests happy.
+         */
+        if (env->nr_cores * env->nr_threads > 1) {
+            uint32_t tebx, tecx, tedx;
+            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
+            if (tebx != CPUID_VENDOR_INTEL_1 ||
+                tedx != CPUID_VENDOR_INTEL_2 ||
+                tecx != CPUID_VENDOR_INTEL_3) {
+                *ecx |= 1 << 1;    /* CmpLegacy bit */
+            }
+        }
+
+        if (kvm_enabled()) {
+            /* Nested SVM not yet supported in upstream QEMU */
+            *ecx &= ~CPUID_EXT3_SVM;
+        }
+        break;
+    case 0x80000002:
+    case 0x80000003:
+    case 0x80000004:
+        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
+        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
+        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
+        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
+        break;
+    case 0x80000005:
+        /* cache info (L1 cache) */
+        *eax = 0x01ff01ff;
+        *ebx = 0x01ff01ff;
+        *ecx = 0x40020140;
+        *edx = 0x40020140;
+        break;
+    case 0x80000006:
+        /* cache info (L2 cache) */
+        *eax = 0;
+        *ebx = 0x42004200;
+        *ecx = 0x02008140;
+        *edx = 0;
+        break;
+    case 0x80000008:
+        /* virtual & phys address size in low 2 bytes. */
+/* XXX: This value must match the one used in the MMU code. */ 
+        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
+            /* 64 bit processor */
+/* XXX: The physical address space is limited to 42 bits in exec.c. */
+            *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */
+        } else {
+            if (env->cpuid_features & CPUID_PSE36)
+                *eax = 0x00000024; /* 36 bits physical */
+            else
+                *eax = 0x00000020; /* 32 bits physical */
+        }
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        if (env->nr_cores * env->nr_threads > 1) {
+            *ecx |= (env->nr_cores * env->nr_threads) - 1;
+        }
+        break;
+    case 0x8000000A:
+        *eax = 0x00000001; /* SVM Revision */
+        *ebx = 0x00000010; /* nr of ASIDs */
+        *ecx = 0;
+        *edx = 0; /* optional features */
+        break;
+    default:
+        /* reserved values: zero */
+        *eax = 0;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    }
+}
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 70762bb..b120051 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -30,542 +30,6 @@ 
 
 //#define DEBUG_MMU
 
-/* feature flags taken from "Intel Processor Identification and the CPUID
- * Instruction" and AMD's "CPUID Specification". In cases of disagreement
- * about feature names, the Linux name is used. */
-static const char *feature_name[] = {
-    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-    "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
-    "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
-};
-static const char *ext_feature_name[] = {
-    "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux 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, "hypervisor",
-};
-static const char *ext2_feature_name[] = {
-    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
-    "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
-    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
-};
-static const char *ext3_feature_name[] = {
-    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
-    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-};
-
-static const char *kvm_feature_name[] = {
-    "kvmclock", "kvm_nopiodelay", "kvm_mmu", 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, NULL,
-};
-
-static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
-                                    uint32_t *ext_features,
-                                    uint32_t *ext2_features,
-                                    uint32_t *ext3_features,
-                                    uint32_t *kvm_features)
-{
-    int i;
-    int found = 0;
-
-    for ( i = 0 ; i < 32 ; i++ )
-        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
-            *features |= 1 << i;
-            found = 1;
-        }
-    for ( i = 0 ; i < 32 ; i++ )
-        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
-            *ext_features |= 1 << i;
-            found = 1;
-        }
-    for ( i = 0 ; i < 32 ; i++ )
-        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
-            *ext2_features |= 1 << i;
-            found = 1;
-        }
-    for ( i = 0 ; i < 32 ; i++ )
-        if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
-            *ext3_features |= 1 << i;
-            found = 1;
-        }
-    for ( i = 0 ; i < 32 ; i++ )
-        if (kvm_feature_name[i] && !strcmp (flagname, kvm_feature_name[i])) {
-            *kvm_features |= 1 << i;
-            found = 1;
-        }
-
-    if (!found) {
-        fprintf(stderr, "CPU feature %s not found\n", flagname);
-    }
-}
-
-typedef struct x86_def_t {
-    const char *name;
-    uint32_t level;
-    uint32_t vendor1, vendor2, vendor3;
-    int family;
-    int model;
-    int stepping;
-    uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
-    uint32_t xlevel;
-    char model_id[48];
-    int vendor_override;
-} x86_def_t;
-
-#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
-#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
-          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
-#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
-          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
-          CPUID_PSE36 | CPUID_FXSR)
-#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
-#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
-          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
-          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
-          CPUID_PAE | CPUID_SEP | CPUID_APIC)
-static x86_def_t x86_defs[] = {
-#ifdef TARGET_X86_64
-    {
-        .name = "qemu64",
-        .level = 4,
-        .vendor1 = CPUID_VENDOR_AMD_1,
-        .vendor2 = CPUID_VENDOR_AMD_2,
-        .vendor3 = CPUID_VENDOR_AMD_3,
-        .family = 6,
-        .model = 2,
-        .stepping = 3,
-        .features = PPRO_FEATURES | 
-        /* these features are needed for Win64 and aren't fully implemented */
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-        /* this feature is needed for Solaris and isn't fully implemented */
-            CPUID_PSE36,
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
-            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
-        .xlevel = 0x8000000A,
-        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
-    },
-    {
-        .name = "phenom",
-        .level = 5,
-        .vendor1 = CPUID_VENDOR_AMD_1,
-        .vendor2 = CPUID_VENDOR_AMD_2,
-        .vendor3 = CPUID_VENDOR_AMD_3,
-        .family = 16,
-        .model = 2,
-        .stepping = 3,
-        /* Missing: CPUID_VME, CPUID_HT */
-        .features = PPRO_FEATURES | 
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36,
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
-            CPUID_EXT_POPCNT,
-        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
-            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
-            CPUID_EXT2_FFXSR,
-        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
-                    CPUID_EXT3_CR8LEG,
-                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
-                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
-        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
-            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
-        .xlevel = 0x8000001A,
-        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
-    },
-    {
-        .name = "core2duo",
-        .level = 10,
-        .family = 6,
-        .model = 15,
-        .stepping = 11,
-	/* The original CPU also implements these features:
-               CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
-               CPUID_TM, CPUID_PBE */
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36,
-	/* The original CPU also implements these ext features:
-               CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
-               CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
-        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        .ext3_features = CPUID_EXT3_LAHF_LM,
-        .xlevel = 0x80000008,
-        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
-    },
-    {
-        .name = "kvm64",
-        .level = 5,
-        .vendor1 = CPUID_VENDOR_INTEL_1,
-        .vendor2 = CPUID_VENDOR_INTEL_2,
-        .vendor3 = CPUID_VENDOR_INTEL_3,
-        .family = 15,
-        .model = 6,
-        .stepping = 1,
-        /* Missing: CPUID_VME, CPUID_HT */
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36,
-        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
-        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
-                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
-                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
-                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
-        .ext3_features = 0,
-        .xlevel = 0x80000008,
-        .model_id = "Common KVM processor"
-    },
-#endif
-    {
-        .name = "qemu32",
-        .level = 4,
-        .family = 6,
-        .model = 3,
-        .stepping = 3,
-        .features = PPRO_FEATURES,
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
-        .xlevel = 0,
-        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
-    },
-    {
-        .name = "coreduo",
-        .level = 10,
-        .family = 6,
-        .model = 14,
-        .stepping = 8,
-        /* The original CPU also implements these features:
-               CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
-               CPUID_TM, CPUID_PBE */
-        .features = PPRO_FEATURES | CPUID_VME |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
-        /* The original CPU also implements these ext features:
-               CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
-               CPUID_EXT_PDCM */
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
-        .ext2_features = CPUID_EXT2_NX,
-        .xlevel = 0x80000008,
-        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
-    },
-    {
-        .name = "486",
-        .level = 0,
-        .family = 4,
-        .model = 0,
-        .stepping = 0,
-        .features = I486_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "pentium",
-        .level = 1,
-        .family = 5,
-        .model = 4,
-        .stepping = 3,
-        .features = PENTIUM_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "pentium2",
-        .level = 2,
-        .family = 6,
-        .model = 5,
-        .stepping = 2,
-        .features = PENTIUM2_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "pentium3",
-        .level = 2,
-        .family = 6,
-        .model = 7,
-        .stepping = 3,
-        .features = PENTIUM3_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "athlon",
-        .level = 2,
-        .vendor1 = CPUID_VENDOR_AMD_1,
-        .vendor2 = CPUID_VENDOR_AMD_2,
-        .vendor3 = CPUID_VENDOR_AMD_3,
-        .family = 6,
-        .model = 2,
-        .stepping = 3,
-        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
-        .xlevel = 0x80000008,
-        /* XXX: put another string ? */
-        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
-    },
-    {
-        .name = "n270",
-        /* original is on level 10 */
-        .level = 5,
-        .family = 6,
-        .model = 28,
-        .stepping = 2,
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
-            /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
-             * CPUID_HT | CPUID_TM | CPUID_PBE */
-            /* Some CPUs got no CPUID_SEP */
-        .ext_features = CPUID_EXT_MONITOR |
-            CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
-            /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
-             * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
-        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
-        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
-        .xlevel = 0x8000000A,
-        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
-    },
-};
-
-static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
-                               uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
-
-static int cpu_x86_fill_model_id(char *str)
-{
-    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
-    int i;
-
-    for (i = 0; i < 3; i++) {
-        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
-        memcpy(str + i * 16 +  0, &eax, 4);
-        memcpy(str + i * 16 +  4, &ebx, 4);
-        memcpy(str + i * 16 +  8, &ecx, 4);
-        memcpy(str + i * 16 + 12, &edx, 4);
-    }
-    return 0;
-}
-
-static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
-{
-    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
-
-    x86_cpu_def->name = "host";
-    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->level = eax;
-    x86_cpu_def->vendor1 = ebx;
-    x86_cpu_def->vendor2 = edx;
-    x86_cpu_def->vendor3 = ecx;
-
-    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
-    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
-    x86_cpu_def->stepping = eax & 0x0F;
-    x86_cpu_def->ext_features = ecx;
-    x86_cpu_def->features = edx;
-
-    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->xlevel = eax;
-
-    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->ext2_features = edx;
-    x86_cpu_def->ext3_features = ecx;
-    cpu_x86_fill_model_id(x86_cpu_def->model_id);
-    x86_cpu_def->vendor_override = 0;
-
-    return 0;
-}
-
-static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
-{
-    unsigned int i;
-    x86_def_t *def;
-
-    char *s = strdup(cpu_model);
-    char *featurestr, *name = strtok(s, ",");
-    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
-    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0, minus_kvm_features = 0;
-    uint32_t numvalue;
-
-    def = NULL;
-    for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
-        if (strcmp(name, x86_defs[i].name) == 0) {
-            def = &x86_defs[i];
-            break;
-        }
-    }
-    if (kvm_enabled() && strcmp(name, "host") == 0) {
-        cpu_x86_fill_host(x86_cpu_def);
-    } else if (!def) {
-        goto error;
-    } else {
-        memcpy(x86_cpu_def, def, sizeof(*def));
-    }
-
-    plus_kvm_features = ~0; /* not supported bits will be filtered out later */
-
-    add_flagname_to_bitmaps("hypervisor", &plus_features,
-        &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
-        &plus_kvm_features);
-
-    featurestr = strtok(NULL, ",");
-
-    while (featurestr) {
-        char *val;
-        if (featurestr[0] == '+') {
-            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features, &plus_kvm_features);
-        } else if (featurestr[0] == '-') {
-            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features, &minus_kvm_features);
-        } else if ((val = strchr(featurestr, '='))) {
-            *val = 0; val++;
-            if (!strcmp(featurestr, "family")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->family = numvalue;
-            } else if (!strcmp(featurestr, "model")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err || numvalue > 0xff) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->model = numvalue;
-            } else if (!strcmp(featurestr, "stepping")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err || numvalue > 0xf) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->stepping = numvalue ;
-            } else if (!strcmp(featurestr, "level")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->level = numvalue;
-            } else if (!strcmp(featurestr, "xlevel")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                if (numvalue < 0x80000000) {
-                	numvalue += 0x80000000;
-                }
-                x86_cpu_def->xlevel = numvalue;
-            } else if (!strcmp(featurestr, "vendor")) {
-                if (strlen(val) != 12) {
-                    fprintf(stderr, "vendor string must be 12 chars long\n");
-                    goto error;
-                }
-                x86_cpu_def->vendor1 = 0;
-                x86_cpu_def->vendor2 = 0;
-                x86_cpu_def->vendor3 = 0;
-                for(i = 0; i < 4; i++) {
-                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
-                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
-                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
-                }
-                x86_cpu_def->vendor_override = 1;
-            } else if (!strcmp(featurestr, "model_id")) {
-                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
-                        val);
-            } else {
-                fprintf(stderr, "unrecognized feature %s\n", featurestr);
-                goto error;
-            }
-        } else {
-            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
-            goto error;
-        }
-        featurestr = strtok(NULL, ",");
-    }
-    x86_cpu_def->features |= plus_features;
-    x86_cpu_def->ext_features |= plus_ext_features;
-    x86_cpu_def->ext2_features |= plus_ext2_features;
-    x86_cpu_def->ext3_features |= plus_ext3_features;
-    x86_cpu_def->kvm_features |= plus_kvm_features;
-    x86_cpu_def->features &= ~minus_features;
-    x86_cpu_def->ext_features &= ~minus_ext_features;
-    x86_cpu_def->ext2_features &= ~minus_ext2_features;
-    x86_cpu_def->ext3_features &= ~minus_ext3_features;
-    x86_cpu_def->kvm_features &= ~minus_kvm_features;
-    free(s);
-    return 0;
-
-error:
-    free(s);
-    return -1;
-}
-
-void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
-{
-    unsigned int i;
-
-    for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
-        (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
-}
-
-static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
-{
-    x86_def_t def1, *def = &def1;
-
-    if (cpu_x86_find_by_name(def, cpu_model) < 0)
-        return -1;
-    if (def->vendor1) {
-        env->cpuid_vendor1 = def->vendor1;
-        env->cpuid_vendor2 = def->vendor2;
-        env->cpuid_vendor3 = def->vendor3;
-    } else {
-        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
-        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
-        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
-    }
-    env->cpuid_vendor_override = def->vendor_override;
-    env->cpuid_level = def->level;
-    if (def->family > 0x0f)
-        env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
-    else
-        env->cpuid_version = def->family << 8;
-    env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
-    env->cpuid_version |= def->stepping;
-    env->cpuid_features = def->features;
-    env->pat = 0x0007040600070406ULL;
-    env->cpuid_ext_features = def->ext_features;
-    env->cpuid_ext2_features = def->ext2_features;
-    env->cpuid_xlevel = def->xlevel;
-    env->cpuid_kvm_features = def->kvm_features;
-    {
-        const char *model_id = def->model_id;
-        int c, len, i;
-        if (!model_id)
-            model_id = "";
-        len = strlen(model_id);
-        for(i = 0; i < 48; i++) {
-            if (i >= len)
-                c = '\0';
-            else
-                c = (uint8_t)model_id[i];
-            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
-        }
-    }
-    return 0;
-}
-
 /* NOTE: must be called outside the CPU execute loop */
 void cpu_reset(CPUX86State *env)
 {
@@ -1626,249 +1090,6 @@  static void mce_init(CPUX86State *cenv)
     }
 }
 
-static void host_cpuid(uint32_t function, uint32_t count,
-                       uint32_t *eax, uint32_t *ebx,
-                       uint32_t *ecx, uint32_t *edx)
-{
-#if defined(CONFIG_KVM)
-    uint32_t vec[4];
-
-#ifdef __x86_64__
-    asm volatile("cpuid"
-                 : "=a"(vec[0]), "=b"(vec[1]),
-                   "=c"(vec[2]), "=d"(vec[3])
-                 : "0"(function), "c"(count) : "cc");
-#else
-    asm volatile("pusha \n\t"
-                 "cpuid \n\t"
-                 "mov %%eax, 0(%2) \n\t"
-                 "mov %%ebx, 4(%2) \n\t"
-                 "mov %%ecx, 8(%2) \n\t"
-                 "mov %%edx, 12(%2) \n\t"
-                 "popa"
-                 : : "a"(function), "c"(count), "S"(vec)
-                 : "memory", "cc");
-#endif
-
-    if (eax)
-	*eax = vec[0];
-    if (ebx)
-	*ebx = vec[1];
-    if (ecx)
-	*ecx = vec[2];
-    if (edx)
-	*edx = vec[3];
-#endif
-}
-
-static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
-                             uint32_t *ecx, uint32_t *edx)
-{
-    *ebx = env->cpuid_vendor1;
-    *edx = env->cpuid_vendor2;
-    *ecx = env->cpuid_vendor3;
-
-    /* sysenter isn't supported on compatibility mode on AMD, syscall
-     * isn't supported in compatibility mode on Intel.
-     * Normally we advertise the actual cpu vendor, but you can override
-     * this if you want to use KVM's sysenter/syscall emulation
-     * in compatibility mode and when doing cross vendor migration
-     */
-    if (kvm_enabled() && env->cpuid_vendor_override) {
-        host_cpuid(0, 0, NULL, ebx, ecx, edx);
-    }
-}
-
-void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
-                   uint32_t *eax, uint32_t *ebx,
-                   uint32_t *ecx, uint32_t *edx)
-{
-    /* test if maximum index reached */
-    if (index & 0x80000000) {
-        if (index > env->cpuid_xlevel)
-            index = env->cpuid_level;
-    } else {
-        if (index > env->cpuid_level)
-            index = env->cpuid_level;
-    }
-
-    switch(index) {
-    case 0:
-        *eax = env->cpuid_level;
-        get_cpuid_vendor(env, ebx, ecx, edx);
-        break;
-    case 1:
-        *eax = env->cpuid_version;
-        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
-        *ecx = env->cpuid_ext_features;
-        *edx = env->cpuid_features;
-        if (env->nr_cores * env->nr_threads > 1) {
-            *ebx |= (env->nr_cores * env->nr_threads) << 16;
-            *edx |= 1 << 28;    /* HTT bit */
-        }
-        break;
-    case 2:
-        /* cache info: needed for Pentium Pro compatibility */
-        *eax = 1;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0x2c307d;
-        break;
-    case 4:
-        /* cache info: needed for Core compatibility */
-        if (env->nr_cores > 1) {
-        	*eax = (env->nr_cores - 1) << 26;
-        } else {
-        	*eax = 0;
-        }
-        switch (count) {
-            case 0: /* L1 dcache info */
-                *eax |= 0x0000121;
-                *ebx = 0x1c0003f;
-                *ecx = 0x000003f;
-                *edx = 0x0000001;
-                break;
-            case 1: /* L1 icache info */
-                *eax |= 0x0000122;
-                *ebx = 0x1c0003f;
-                *ecx = 0x000003f;
-                *edx = 0x0000001;
-                break;
-            case 2: /* L2 cache info */
-                *eax |= 0x0000143;
-                if (env->nr_threads > 1) {
-                    *eax |= (env->nr_threads - 1) << 14;
-                }
-                *ebx = 0x3c0003f;
-                *ecx = 0x0000fff;
-                *edx = 0x0000001;
-                break;
-            default: /* end of info */
-                *eax = 0;
-                *ebx = 0;
-                *ecx = 0;
-                *edx = 0;
-                break;
-        }
-        break;
-    case 5:
-        /* mwait info: needed for Core compatibility */
-        *eax = 0; /* Smallest monitor-line size in bytes */
-        *ebx = 0; /* Largest monitor-line size in bytes */
-        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
-        *edx = 0;
-        break;
-    case 6:
-        /* Thermal and Power Leaf */
-        *eax = 0;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    case 9:
-        /* Direct Cache Access Information Leaf */
-        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    case 0xA:
-        /* Architectural Performance Monitoring Leaf */
-        *eax = 0;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    case 0x80000000:
-        *eax = env->cpuid_xlevel;
-        *ebx = env->cpuid_vendor1;
-        *edx = env->cpuid_vendor2;
-        *ecx = env->cpuid_vendor3;
-        break;
-    case 0x80000001:
-        *eax = env->cpuid_version;
-        *ebx = 0;
-        *ecx = env->cpuid_ext3_features;
-        *edx = env->cpuid_ext2_features;
-
-        /* The Linux kernel checks for the CMPLegacy bit and
-         * discards multiple thread information if it is set.
-         * So dont set it here for Intel to make Linux guests happy.
-         */
-        if (env->nr_cores * env->nr_threads > 1) {
-            uint32_t tebx, tecx, tedx;
-            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
-            if (tebx != CPUID_VENDOR_INTEL_1 ||
-                tedx != CPUID_VENDOR_INTEL_2 ||
-                tecx != CPUID_VENDOR_INTEL_3) {
-                *ecx |= 1 << 1;    /* CmpLegacy bit */
-            }
-        }
-
-        if (kvm_enabled()) {
-            /* Nested SVM not yet supported in upstream QEMU */
-            *ecx &= ~CPUID_EXT3_SVM;
-        }
-        break;
-    case 0x80000002:
-    case 0x80000003:
-    case 0x80000004:
-        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
-        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
-        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
-        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
-        break;
-    case 0x80000005:
-        /* cache info (L1 cache) */
-        *eax = 0x01ff01ff;
-        *ebx = 0x01ff01ff;
-        *ecx = 0x40020140;
-        *edx = 0x40020140;
-        break;
-    case 0x80000006:
-        /* cache info (L2 cache) */
-        *eax = 0;
-        *ebx = 0x42004200;
-        *ecx = 0x02008140;
-        *edx = 0;
-        break;
-    case 0x80000008:
-        /* virtual & phys address size in low 2 bytes. */
-/* XXX: This value must match the one used in the MMU code. */ 
-        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
-            /* 64 bit processor */
-/* XXX: The physical address space is limited to 42 bits in exec.c. */
-            *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */
-        } else {
-            if (env->cpuid_features & CPUID_PSE36)
-                *eax = 0x00000024; /* 36 bits physical */
-            else
-                *eax = 0x00000020; /* 32 bits physical */
-        }
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        if (env->nr_cores * env->nr_threads > 1) {
-            *ecx |= (env->nr_cores * env->nr_threads) - 1;
-        }
-        break;
-    case 0x8000000A:
-        *eax = 0x00000001; /* SVM Revision */
-        *ebx = 0x00000010; /* nr of ASIDs */
-        *ecx = 0;
-        *edx = 0; /* optional features */
-        break;
-    default:
-        /* reserved values: zero */
-        *eax = 0;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    }
-}
-
-
 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
                             target_ulong *base, unsigned int *limit,
                             unsigned int *flags)