qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH qom-cpu 2/2] target-i386: Replace cpuid_*feature


From: li guang
Subject: Re: [Qemu-devel] [PATCH qom-cpu 2/2] target-i386: Replace cpuid_*features fields with a feature word array
Date: Wed, 16 Jan 2013 15:18:35 +0800

Reviewed-by: Li Guang <address@hidden>

在 2013-01-11五的 00:18 -0200,Eduardo Habkost写道:
> This replaces the feature-bit fields on both X86CPU and x86_def_t
> structs with an array.
> 
> With this, we will be able to simplify code that simply does the same
> operation on all feature words (e.g. kvm_check_features_against_host(),
> filter_features_for_kvm(), add_flagname_to_bitmaps(), and CPU
> feature-bit property lookup/registration).
> 
> This should also help avoid bugs like the ones introduced when we added
> cpuid_7_0_ebx_features. Today, adding a new feature word to the code
> requires chaning 5 or 6 different places in the code, and it's very easy
> to miss a problem when we forget to update one of those parts. See, for
> example:
> 
>  * The bug solved by commit ffa8c11f0bbf47e1b7a3a62f97bc1da591c6734a;
>  * The fact that check_features_against_host() wasn't checking all
>    feature words as it is supposed to, until very recently.
> 
> Signed-off-by: Eduardo Habkost <address@hidden>
> ---
> This patch was created solely using a sed script and no manual changes,
> to try to avoid mistakes while converting the code, and make it easier
> to rebase if necessary. The sed script can be seen at:
>   https://gist.github.com/4271991
> ---
>  bsd-user/elfload.c        |   2 +-
>  bsd-user/main.c           |   4 +-
>  hw/kvm/clock.c            |   2 +-
>  linux-user/elfload.c      |   2 +-
>  linux-user/main.c         |   4 +-
>  target-i386/cpu.c         | 592 
> ++++++++++++++++++++++++----------------------
>  target-i386/cpu.h         |  15 +-
>  target-i386/helper.c      |   4 +-
>  target-i386/kvm.c         |   5 +-
>  target-i386/misc_helper.c |  14 +-
>  target-i386/translate.c   |  10 +-
>  11 files changed, 332 insertions(+), 322 deletions(-)
> 
> diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
> index a6cd3ab..44e1568 100644
> --- a/bsd-user/elfload.c
> +++ b/bsd-user/elfload.c
> @@ -110,7 +110,7 @@ static const char *get_elf_platform(void)
>  
>  static uint32_t get_elf_hwcap(void)
>  {
> -  return thread_env->cpuid_features;
> +  return thread_env->features[FEAT_1_EDX];
>  }
>  
>  #ifdef TARGET_X86_64
> diff --git a/bsd-user/main.c b/bsd-user/main.c
> index 1dc0330..8b8b1f1 100644
> --- a/bsd-user/main.c
> +++ b/bsd-user/main.c
> @@ -1010,13 +1010,13 @@ int main(int argc, char **argv)
>  
>      env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
>      env->hflags |= HF_PE_MASK;
> -    if (env->cpuid_features & CPUID_SSE) {
> +    if (env->features[FEAT_1_EDX] & CPUID_SSE) {
>          env->cr[4] |= CR4_OSFXSR_MASK;
>          env->hflags |= HF_OSFXSR_MASK;
>      }
>  #ifndef TARGET_ABI32
>      /* enable 64 bit mode if possible */
> -    if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) {
> +    if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
>          fprintf(stderr, "The selected x86 CPU does not support 64 bit 
> mode\n");
>          exit(1);
>      }
> diff --git a/hw/kvm/clock.c b/hw/kvm/clock.c
> index be24973..6d0777a 100644
> --- a/hw/kvm/clock.c
> +++ b/hw/kvm/clock.c
> @@ -129,7 +129,7 @@ static TypeInfo kvmclock_info = {
>  void kvmclock_create(void)
>  {
>      if (kvm_enabled() &&
> -        first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
> +        first_cpu->features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
>                                           (1ULL << 
> KVM_FEATURE_CLOCKSOURCE2))) {
>          sysbus_create_simple("kvmclock", -1, NULL);
>      }
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index 89db49c..04755de 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -130,7 +130,7 @@ static const char *get_elf_platform(void)
>  
>  static uint32_t get_elf_hwcap(void)
>  {
> -    return thread_env->cpuid_features;
> +    return thread_env->features[FEAT_1_EDX];
>  }
>  
>  #ifdef TARGET_X86_64
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 9ade1bf..faed8c8 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -3630,13 +3630,13 @@ int main(int argc, char **argv, char **envp)
>  
>      env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
>      env->hflags |= HF_PE_MASK;
> -    if (env->cpuid_features & CPUID_SSE) {
> +    if (env->features[FEAT_1_EDX] & CPUID_SSE) {
>          env->cr[4] |= CR4_OSFXSR_MASK;
>          env->hflags |= HF_OSFXSR_MASK;
>      }
>  #ifndef TARGET_ABI32
>      /* enable 64 bit mode if possible */
> -    if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) {
> +    if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
>          fprintf(stderr, "The selected x86 CPU does not support 64 bit 
> mode\n");
>          exit(1);
>      }
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 0b44dea..f4878bf 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -340,22 +340,15 @@ static void add_flagname_to_bitmaps(const char 
> *flagname,
>  typedef struct x86_def_t {
>      struct x86_def_t *next;
>      const char *name;
> -    uint32_t level;
> +    uint32_t level, xlevel, xlevel2;
> +    FeatureWordArray features;
>      uint32_t vendor1, vendor2, vendor3;
>      int family;
>      int model;
>      int stepping;
>      int tsc_khz;
> -    uint32_t features, ext_features, ext2_features, ext3_features;
> -    uint32_t kvm_features, svm_features;
> -    uint32_t xlevel;
>      char model_id[48];
>      int vendor_override;
> -    /* Store the results of Centaur's CPUID instructions */
> -    uint32_t ext4_features;
> -    uint32_t xlevel2;
> -    /* The feature bits on CPUID[EAX=7,ECX=0].EBX */
> -    uint32_t cpuid_7_0_ebx_features;
>  } x86_def_t;
>  
>  #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
> @@ -412,13 +405,14 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 2,
>          .stepping = 3,
> -        .features = PPRO_FEATURES |
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> -            CPUID_PSE36,
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
> -        .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
> -            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> -        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
> +        .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH |
> +            CPUID_MCA | CPUID_PSE36,
> +        .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_CX16 |
> +            CPUID_EXT_POPCNT,
> +        .features[FEAT_8000_0001_EDX] =
> +            (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | CPUID_EXT2_LM |
> +            CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
>              CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
>          .xlevel = 0x8000000A,
>      },
> @@ -431,22 +425,22 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 16,
>          .model = 2,
>          .stepping = 3,
> -        .features = PPRO_FEATURES |
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> -            CPUID_PSE36 | CPUID_VME | CPUID_HT,
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
> -            CPUID_EXT_POPCNT,
> -        .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
> -            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
> -            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
> -            CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
> +        .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH |
> +            CPUID_MCA | CPUID_PSE36 | CPUID_VME | CPUID_HT,
> +        .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR |
> +            CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
> +        .features[FEAT_8000_0001_EDX] =
> +            (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | CPUID_EXT2_LM |
> +            CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_3DNOW |
> +            CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT | CPUID_EXT2_FFXSR |
> +            CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
>          /* 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 |
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
>              CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
> -        .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV,
> +        .features[FEAT_SVM] = CPUID_SVM_NPT | CPUID_SVM_LBRV,
>          .xlevel = 0x8000001A,
>          .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
>      },
> @@ -459,15 +453,16 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 15,
>          .stepping = 11,
> -        .features = PPRO_FEATURES |
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> -            CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
> -            CPUID_HT | CPUID_TM | CPUID_PBE,
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 
> |
> -            CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | 
> CPUID_EXT_EST |
> -            CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> -        .ext3_features = CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH |
> +            CPUID_MCA | CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI |
> +            CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
> +        .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR |
> +            CPUID_EXT_SSSE3 | CPUID_EXT_DTES64 | CPUID_EXT_DSCPL |
> +            CPUID_EXT_VMX | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_CX16 |
> +            CPUID_EXT_XTPR | CPUID_EXT_PDCM,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL |
> +            CPUID_EXT2_NX,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM,
>          .xlevel = 0x80000008,
>          .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
>      },
> @@ -481,19 +476,19 @@ static x86_def_t builtin_x86_defs[] = {
>          .model = 6,
>          .stepping = 1,
>          /* Missing: CPUID_VME, CPUID_HT */
> -        .features = PPRO_FEATURES |
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
> -            CPUID_PSE36,
> +        .features[FEAT_1_EDX] = 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,
> +        .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
>          /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
> -        .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
> -            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> +        .features[FEAT_8000_0001_EDX] =
> +            (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | 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,
> +        .features[FEAT_8000_0001_ECX] = 0,
>          .xlevel = 0x80000008,
>          .model_id = "Common KVM processor"
>      },
> @@ -506,8 +501,8 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 3,
>          .stepping = 3,
> -        .features = PPRO_FEATURES,
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
> +        .features[FEAT_1_EDX] = PPRO_FEATURES,
> +        .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
>          .xlevel = 0x80000004,
>      },
>      {
> @@ -519,11 +514,11 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 15,
>          .model = 6,
>          .stepping = 1,
> -        .features = PPRO_FEATURES |
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
> -        .ext_features = CPUID_EXT_SSE3,
> -        .ext2_features = PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES,
> -        .ext3_features = 0,
> +        .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH |
> +            CPUID_MCA | CPUID_PSE36,
> +        .features[FEAT_1_ECX] = CPUID_EXT_SSE3,
> +        .features[FEAT_8000_0001_EDX] = PPRO_FEATURES & 
> CPUID_EXT2_AMD_ALIASES,
> +        .features[FEAT_8000_0001_ECX] = 0,
>          .xlevel = 0x80000008,
>          .model_id = "Common 32-bit KVM processor"
>      },
> @@ -536,12 +531,13 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 14,
>          .stepping = 8,
> -        .features = PPRO_FEATURES | CPUID_VME |
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
> -            CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
> -            CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
> -        .ext2_features = CPUID_EXT2_NX,
> +        .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_VME | CPUID_MTRR |
> +            CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI | CPUID_SS |
> +            CPUID_HT | CPUID_TM | CPUID_PBE,
> +        .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR |
> +            CPUID_EXT_VMX | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR |
> +            CPUID_EXT_PDCM,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_NX,
>          .xlevel = 0x80000008,
>          .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
>      },
> @@ -554,7 +550,7 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 4,
>          .model = 0,
>          .stepping = 0,
> -        .features = I486_FEATURES,
> +        .features[FEAT_1_EDX] = I486_FEATURES,
>          .xlevel = 0,
>      },
>      {
> @@ -566,7 +562,7 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 5,
>          .model = 4,
>          .stepping = 3,
> -        .features = PENTIUM_FEATURES,
> +        .features[FEAT_1_EDX] = PENTIUM_FEATURES,
>          .xlevel = 0,
>      },
>      {
> @@ -578,7 +574,7 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 5,
>          .stepping = 2,
> -        .features = PENTIUM2_FEATURES,
> +        .features[FEAT_1_EDX] = PENTIUM2_FEATURES,
>          .xlevel = 0,
>      },
>      {
> @@ -590,7 +586,7 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 7,
>          .stepping = 3,
> -        .features = PENTIUM3_FEATURES,
> +        .features[FEAT_1_EDX] = PENTIUM3_FEATURES,
>          .xlevel = 0,
>      },
>      {
> @@ -602,10 +598,11 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 2,
>          .stepping = 3,
> -        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
> -            CPUID_MCA,
> -        .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
> -            CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
> +        .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME |
> +            CPUID_MTRR | CPUID_MCA,
> +        .features[FEAT_8000_0001_EDX] =
> +            (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | CPUID_EXT2_MMXEXT |
> +            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
>          .xlevel = 0x80000008,
>      },
>      {
> @@ -618,15 +615,16 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 28,
>          .stepping = 2,
> -        .features = PPRO_FEATURES |
> -            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
> -            CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
> +        .features[FEAT_1_EDX] = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH |
> +            CPUID_MCA | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
> +            CPUID_HT | CPUID_TM | CPUID_PBE,
>              /* Some CPUs got no CPUID_SEP */
> -        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 
> |
> -            CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR,
> -        .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
> -            CPUID_EXT2_NX,
> -        .ext3_features = CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_1_ECX] = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR |
> +            CPUID_EXT_SSSE3 | CPUID_EXT_DSCPL | CPUID_EXT_EST | 
> CPUID_EXT_TM2 |
> +            CPUID_EXT_XTPR,
> +        .features[FEAT_8000_0001_EDX] =
> +            (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) | CPUID_EXT2_NX,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM,
>          .xlevel = 0x8000000A,
>          .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
>      },
> @@ -639,14 +637,15 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 2,
>          .stepping = 3,
> -        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> -             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> CPUID_MCA |
> -             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> -             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> -             CPUID_DE | CPUID_FP87,
> -        .ext_features = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
> -        .ext3_features = CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> +            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV 
> |
> +            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
> +            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
> +            CPUID_PSE | CPUID_DE | CPUID_FP87,
> +        .features[FEAT_1_ECX] = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_NX |
> +            CPUID_EXT2_SYSCALL,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM,
>          .xlevel = 0x8000000A,
>          .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
>      },
> @@ -659,15 +658,16 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 2,
>          .stepping = 3,
> -        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> -             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> CPUID_MCA |
> -             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> -             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> -             CPUID_DE | CPUID_FP87,
> -        .ext_features = CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
> -             CPUID_EXT_SSE3,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
> -        .ext3_features = CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> +            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV 
> |
> +            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
> +            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
> +            CPUID_PSE | CPUID_DE | CPUID_FP87,
> +        .features[FEAT_1_ECX] = CPUID_EXT_SSE41 | CPUID_EXT_CX16 |
> +            CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_NX |
> +            CPUID_EXT2_SYSCALL,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM,
>          .xlevel = 0x8000000A,
>          .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
>      },
> @@ -680,15 +680,17 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 2,
>          .stepping = 3,
> -        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> -             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> CPUID_MCA |
> -             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> -             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> -             CPUID_DE | CPUID_FP87,
> -        .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 
> |
> -             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> -        .ext3_features = CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> +            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV 
> |
> +            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
> +            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
> +            CPUID_PSE | CPUID_DE | CPUID_FP87,
> +        .features[FEAT_1_ECX] = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
> +            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
> +            CPUID_EXT_SSE3,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL |
> +            CPUID_EXT2_NX,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM,
>          .xlevel = 0x8000000A,
>          .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
>      },
> @@ -701,16 +703,17 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 44,
>          .stepping = 1,
> -        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> -             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> CPUID_MCA |
> -             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> -             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> -             CPUID_DE | CPUID_FP87,
> -        .ext_features = CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
> -             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
> -             CPUID_EXT_SSE3,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
> -        .ext3_features = CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> +            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV 
> |
> +            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
> +            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
> +            CPUID_PSE | CPUID_DE | CPUID_FP87,
> +        .features[FEAT_1_ECX] = CPUID_EXT_AES | CPUID_EXT_POPCNT |
> +            CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | CPUID_EXT_CX16 |
> +            CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL |
> +            CPUID_EXT2_NX,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM,
>          .xlevel = 0x8000000A,
>          .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
>      },
> @@ -723,19 +726,19 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 42,
>          .stepping = 1,
> -        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> -             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> CPUID_MCA |
> -             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> -             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> -             CPUID_DE | CPUID_FP87,
> -        .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
> -             CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
> -             CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
> -             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
> -             CPUID_EXT_SSE3,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
> -             CPUID_EXT2_SYSCALL,
> -        .ext3_features = CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> +            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV 
> |
> +            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
> +            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
> +            CPUID_PSE | CPUID_DE | CPUID_FP87,
> +        .features[FEAT_1_ECX] = CPUID_EXT_AVX | CPUID_EXT_XSAVE |
> +            CPUID_EXT_AES | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
> +            CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
> +            CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
> +            CPUID_EXT_SSE3,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
> +            CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM,
>          .xlevel = 0x8000000A,
>          .model_id = "Intel Xeon E312xx (Sandy Bridge)",
>      },
> @@ -748,21 +751,21 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 6,
>          .model = 60,
>          .stepping = 1,
> -        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> -             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> CPUID_MCA |
> -             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> -             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> -             CPUID_DE | CPUID_FP87,
> -        .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
> -             CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
> -             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
> -             CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
> -             CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
> -             CPUID_EXT_PCID,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
> -             CPUID_EXT2_SYSCALL,
> -        .ext3_features = CPUID_EXT3_LAHF_LM,
> -        .cpuid_7_0_ebx_features = CPUID_7_0_EBX_FSGSBASE | 
> CPUID_7_0_EBX_BMI1 |
> +        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> +            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV 
> |
> +            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
> +            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
> +            CPUID_PSE | CPUID_DE | CPUID_FP87,
> +        .features[FEAT_1_ECX] = CPUID_EXT_AVX | CPUID_EXT_XSAVE |
> +            CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_X2APIC |
> +            CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | CPUID_EXT_CX16 |
> +            CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
> +            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
> +            CPUID_EXT_PCID,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
> +            CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_7_0_EBX] = CPUID_7_0_EBX_FSGSBASE | 
> CPUID_7_0_EBX_BMI1 |
>              CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
>              CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
>              CPUID_7_0_EBX_RTM,
> @@ -778,18 +781,18 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 15,
>          .model = 6,
>          .stepping = 1,
> -        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> -             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> CPUID_MCA |
> -             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> -             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> -             CPUID_DE | CPUID_FP87,
> -        .ext_features = CPUID_EXT_SSE3,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
> -             CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
> +        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> +            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV 
> |
> +            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
> +            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
> +            CPUID_PSE | CPUID_DE | CPUID_FP87,
> +        .features[FEAT_1_ECX] = CPUID_EXT_SSE3,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_FXSR |
> +            CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | 
> CPUID_EXT2_PAT |
>               CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
> -             CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
> -             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | 
> CPUID_EXT2_MSR |
> -             CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | 
> CPUID_EXT2_FPU,
> +            CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
> +            CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | 
> CPUID_EXT2_MSR |
> +            CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
>          .xlevel = 0x80000008,
>          .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
>      },
> @@ -802,20 +805,20 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 15,
>          .model = 6,
>          .stepping = 1,
> -        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> -             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> CPUID_MCA |
> -             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> -             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> -             CPUID_DE | CPUID_FP87,
> -        .ext_features = CPUID_EXT_CX16 | CPUID_EXT_SSE3,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR 
> |
> -             CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
> -             CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
> -             CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
> -             CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
> -             CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | 
> CPUID_EXT2_PSE |
> -             CPUID_EXT2_DE | CPUID_EXT2_FPU,
> -        .ext3_features = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> +            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV 
> |
> +            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
> +            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
> +            CPUID_PSE | CPUID_DE | CPUID_FP87,
> +        .features[FEAT_1_ECX] = CPUID_EXT_CX16 | CPUID_EXT_SSE3,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
> +            CPUID_EXT2_FXSR | CPUID_EXT2_MMX | CPUID_EXT2_NX |
> +            CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | CPUID_EXT2_CMOV |
> +            CPUID_EXT2_MCA | CPUID_EXT2_PGE | CPUID_EXT2_MTRR |
> +            CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | CPUID_EXT2_CX8 |
> +            CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | 
> CPUID_EXT2_TSC |
> +            CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
>          .xlevel = 0x80000008,
>          .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
>      },
> @@ -828,22 +831,23 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 15,
>          .model = 6,
>          .stepping = 1,
> -        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> -             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> CPUID_MCA |
> -             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> -             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> -             CPUID_DE | CPUID_FP87,
> -        .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_CX16 | 
> CPUID_EXT_MONITOR |
> -             CPUID_EXT_SSE3,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR 
> |
> -             CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
> -             CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
> -             CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
> -             CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
> -             CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | 
> CPUID_EXT2_PSE |
> -             CPUID_EXT2_DE | CPUID_EXT2_FPU,
> -        .ext3_features = CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
> -             CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> +            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV 
> |
> +            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
> +            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
> +            CPUID_PSE | CPUID_DE | CPUID_FP87,
> +        .features[FEAT_1_ECX] = CPUID_EXT_POPCNT | CPUID_EXT_CX16 |
> +            CPUID_EXT_MONITOR | CPUID_EXT_SSE3,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
> +            CPUID_EXT2_FXSR | CPUID_EXT2_MMX | CPUID_EXT2_NX |
> +            CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | CPUID_EXT2_CMOV |
> +            CPUID_EXT2_MCA | CPUID_EXT2_PGE | CPUID_EXT2_MTRR |
> +            CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | CPUID_EXT2_CX8 |
> +            CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | 
> CPUID_EXT2_TSC |
> +            CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_MISALIGNSSE |
> +            CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
> +            CPUID_EXT3_LAHF_LM,
>          .xlevel = 0x80000008,
>          .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
>      },
> @@ -856,26 +860,26 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 21,
>          .model = 1,
>          .stepping = 2,
> -        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> -             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> CPUID_MCA |
> -             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> -             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> -             CPUID_DE | CPUID_FP87,
> -        .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
> -             CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
> -             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
> -             CPUID_EXT_SSE3,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
> -             CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
> -             CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
> -             CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
> -             CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
> -             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | 
> CPUID_EXT2_MSR |
> -             CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | 
> CPUID_EXT2_FPU,
> -        .ext3_features = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
> -             CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
> -             CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
> -             CPUID_EXT3_LAHF_LM,
> +        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> +            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV 
> |
> +            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
> +            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
> +            CPUID_PSE | CPUID_DE | CPUID_FP87,
> +        .features[FEAT_1_ECX] = CPUID_EXT_AVX | CPUID_EXT_XSAVE |
> +            CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
> +            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
> +            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
> +            CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
> +            CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
> +            CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
> +            CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
> +            CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | 
> CPUID_EXT2_MSR |
> +            CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
> +            CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
> +            CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
> +            CPUID_EXT3_LAHF_LM,
>          .xlevel = 0x8000001A,
>          .model_id = "AMD Opteron 62xx class CPU",
>      },
> @@ -888,26 +892,26 @@ static x86_def_t builtin_x86_defs[] = {
>          .family = 21,
>          .model = 2,
>          .stepping = 0,
> -        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> -             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> CPUID_MCA |
> -             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> -             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> -             CPUID_DE | CPUID_FP87,
> -        .ext_features = CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
> -             CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
> -             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
> +        .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> +            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV 
> |
> +            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
> +            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
> +            CPUID_PSE | CPUID_DE | CPUID_FP87,
> +        .features[FEAT_1_ECX] = CPUID_EXT_F16C | CPUID_EXT_AVX |
> +            CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT |
> +            CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | CPUID_EXT_CX16 | 
> CPUID_EXT_FMA |
>               CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
> -        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
> -             CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
> -             CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
> -             CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
> -             CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
> -             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | 
> CPUID_EXT2_MSR |
> -             CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | 
> CPUID_EXT2_FPU,
> -        .ext3_features = CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
> -             CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
> +        .features[FEAT_8000_0001_EDX] = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
> +            CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
> +            CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
> +            CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
> +            CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
> +            CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | 
> CPUID_EXT2_MSR |
> +            CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
> +        .features[FEAT_8000_0001_ECX] = CPUID_EXT3_TBM | CPUID_EXT3_FMA4 |
> +            CPUID_EXT3_XOP | CPUID_EXT3_3DNOWPREFETCH | 
> CPUID_EXT3_MISALIGNSSE |
>               CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
> -             CPUID_EXT3_LAHF_LM,
> +            CPUID_EXT3_LAHF_LM,
>          .xlevel = 0x8000001A,
>          .model_id = "AMD Opteron 63xx class CPU",
>      },
> @@ -955,20 +959,22 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
>      x86_cpu_def->stepping = eax & 0x0F;
>  
>      x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
> -    x86_cpu_def->features = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX);
> -    x86_cpu_def->ext_features = kvm_arch_get_supported_cpuid(s, 0x1, 0, 
> R_ECX);
> +    x86_cpu_def->features[FEAT_1_EDX] =
> +                kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX);
> +    x86_cpu_def->features[FEAT_1_ECX] =
> +                kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX);
>  
>      if (x86_cpu_def->level >= 7) {
> -        x86_cpu_def->cpuid_7_0_ebx_features =
> +        x86_cpu_def->features[FEAT_7_0_EBX] =
>                      kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX);
>      } else {
> -        x86_cpu_def->cpuid_7_0_ebx_features = 0;
> +        x86_cpu_def->features[FEAT_7_0_EBX] = 0;
>      }
>  
>      x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, 
> R_EAX);
> -    x86_cpu_def->ext2_features =
> +    x86_cpu_def->features[FEAT_8000_0001_EDX] =
>                  kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
> -    x86_cpu_def->ext3_features =
> +    x86_cpu_def->features[FEAT_8000_0001_ECX] =
>                  kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
>  
>      cpu_x86_fill_model_id(x86_cpu_def->model_id);
> @@ -984,15 +990,15 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
>              /* Support VIA max extended level */
>              x86_cpu_def->xlevel2 = eax;
>              host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
> -            x86_cpu_def->ext4_features =
> +            x86_cpu_def->features[FEAT_C000_0001_EDX] =
>                      kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
>          }
>      }
>  
>      /* Other KVM-specific feature fields: */
> -    x86_cpu_def->svm_features =
> +    x86_cpu_def->features[FEAT_SVM] =
>          kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
> -    x86_cpu_def->kvm_features =
> +    x86_cpu_def->features[FEAT_KVM] =
>          kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
>  
>  #endif /* CONFIG_KVM */
> @@ -1028,21 +1034,29 @@ static int kvm_check_features_against_host(x86_def_t 
> *guest_def)
>      uint32_t mask;
>      int rv, i;
>      struct model_features_t ft[] = {
> -        {&guest_def->features, &host_def.features,
> +        {&guest_def->features[FEAT_1_EDX],
> +            &host_def.features[FEAT_1_EDX],
>              FEAT_1_EDX },
> -        {&guest_def->ext_features, &host_def.ext_features,
> +        {&guest_def->features[FEAT_1_ECX],
> +            &host_def.features[FEAT_1_ECX],
>              FEAT_1_ECX },
> -        {&guest_def->ext2_features, &host_def.ext2_features,
> +        {&guest_def->features[FEAT_8000_0001_EDX],
> +            &host_def.features[FEAT_8000_0001_EDX],
>              FEAT_8000_0001_EDX },
> -        {&guest_def->ext3_features, &host_def.ext3_features,
> +        {&guest_def->features[FEAT_8000_0001_ECX],
> +            &host_def.features[FEAT_8000_0001_ECX],
>              FEAT_8000_0001_ECX },
> -        {&guest_def->ext4_features, &host_def.ext4_features,
> +        {&guest_def->features[FEAT_C000_0001_EDX],
> +            &host_def.features[FEAT_C000_0001_EDX],
>              FEAT_C000_0001_EDX },
> -        {&guest_def->cpuid_7_0_ebx_features, 
> &host_def.cpuid_7_0_ebx_features,
> +        {&guest_def->features[FEAT_7_0_EBX],
> +            &host_def.features[FEAT_7_0_EBX],
>              FEAT_7_0_EBX },
> -        {&guest_def->svm_features, &host_def.svm_features,
> +        {&guest_def->features[FEAT_SVM],
> +            &host_def.features[FEAT_SVM],
>              FEAT_SVM },
> -        {&guest_def->kvm_features, &host_def.kvm_features,
> +        {&guest_def->features[FEAT_KVM],
> +            &host_def.features[FEAT_KVM],
>              FEAT_KVM },
>      };
>  
> @@ -1459,22 +1473,28 @@ static int cpu_x86_parse_featurestr(x86_def_t 
> *x86_cpu_def, char *features)
>          }
>          featurestr = strtok(NULL, ",");
>      }
> -    x86_cpu_def->features |= plus_features[FEAT_1_EDX];
> -    x86_cpu_def->ext_features |= plus_features[FEAT_1_ECX];
> -    x86_cpu_def->ext2_features |= plus_features[FEAT_8000_0001_EDX];
> -    x86_cpu_def->ext3_features |= plus_features[FEAT_8000_0001_ECX];
> -    x86_cpu_def->ext4_features |= plus_features[FEAT_C000_0001_EDX];
> -    x86_cpu_def->kvm_features |= plus_features[FEAT_KVM];
> -    x86_cpu_def->svm_features |= plus_features[FEAT_SVM];
> -    x86_cpu_def->cpuid_7_0_ebx_features |= plus_features[FEAT_7_0_EBX];
> -    x86_cpu_def->features &= ~minus_features[FEAT_1_EDX];
> -    x86_cpu_def->ext_features &= ~minus_features[FEAT_1_ECX];
> -    x86_cpu_def->ext2_features &= ~minus_features[FEAT_8000_0001_EDX];
> -    x86_cpu_def->ext3_features &= ~minus_features[FEAT_8000_0001_ECX];
> -    x86_cpu_def->ext4_features &= ~minus_features[FEAT_C000_0001_EDX];
> -    x86_cpu_def->kvm_features &= ~minus_features[FEAT_KVM];
> -    x86_cpu_def->svm_features &= ~minus_features[FEAT_SVM];
> -    x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_features[FEAT_7_0_EBX];
> +    x86_cpu_def->features[FEAT_1_EDX] |= plus_features[FEAT_1_EDX];
> +    x86_cpu_def->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX];
> +    x86_cpu_def->features[FEAT_8000_0001_EDX] |=
> +         plus_features[FEAT_8000_0001_EDX];
> +    x86_cpu_def->features[FEAT_8000_0001_ECX] |=
> +         plus_features[FEAT_8000_0001_ECX];
> +    x86_cpu_def->features[FEAT_C000_0001_EDX] |=
> +         plus_features[FEAT_C000_0001_EDX];
> +    x86_cpu_def->features[FEAT_KVM] |= plus_features[FEAT_KVM];
> +    x86_cpu_def->features[FEAT_SVM] |= plus_features[FEAT_SVM];
> +    x86_cpu_def->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
> +    x86_cpu_def->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
> +    x86_cpu_def->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
> +    x86_cpu_def->features[FEAT_8000_0001_EDX] &=
> +         ~minus_features[FEAT_8000_0001_EDX];
> +    x86_cpu_def->features[FEAT_8000_0001_ECX] &=
> +         ~minus_features[FEAT_8000_0001_ECX];
> +    x86_cpu_def->features[FEAT_C000_0001_EDX] &=
> +         ~minus_features[FEAT_C000_0001_EDX];
> +    x86_cpu_def->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
> +    x86_cpu_def->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
> +    x86_cpu_def->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
>      if (check_cpuid && kvm_enabled()) {
>          if (kvm_check_features_against_host(x86_cpu_def) && enforce_cpuid)
>              goto error;
> @@ -1566,21 +1586,21 @@ static void filter_features_for_kvm(X86CPU *cpu)
>      CPUX86State *env = &cpu->env;
>      KVMState *s = kvm_state;
>  
> -    env->cpuid_features &=
> +    env->features[FEAT_1_EDX] &=
>          kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
> -    env->cpuid_ext_features &=
> +    env->features[FEAT_1_ECX] &=
>          kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX);
> -    env->cpuid_ext2_features &=
> +    env->features[FEAT_8000_0001_EDX] &=
>          kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
> -    env->cpuid_ext3_features &=
> +    env->features[FEAT_8000_0001_ECX] &=
>          kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
> -    env->cpuid_svm_features  &=
> +    env->features[FEAT_SVM]  &=
>          kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
> -    env->cpuid_7_0_ebx_features &=
> +    env->features[FEAT_7_0_EBX] &=
>          kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX);
> -    env->cpuid_kvm_features &=
> +    env->features[FEAT_KVM] &=
>          kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
> -    env->cpuid_ext4_features &=
> +    env->features[FEAT_C000_0001_EDX] &=
>          kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
>  
>  }
> @@ -1619,15 +1639,15 @@ int cpu_x86_register(X86CPU *cpu, const char 
> *cpu_model)
>      object_property_set_int(OBJECT(cpu), def->family, "family", &error);
>      object_property_set_int(OBJECT(cpu), def->model, "model", &error);
>      object_property_set_int(OBJECT(cpu), def->stepping, "stepping", &error);
> -    env->cpuid_features = def->features;
> -    env->cpuid_ext_features = def->ext_features;
> -    env->cpuid_ext2_features = def->ext2_features;
> -    env->cpuid_ext3_features = def->ext3_features;
> +    env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX];
> +    env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX];
> +    env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX];
> +    env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX];
>      object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", &error);
> -    env->cpuid_kvm_features = def->kvm_features;
> -    env->cpuid_svm_features = def->svm_features;
> -    env->cpuid_ext4_features = def->ext4_features;
> -    env->cpuid_7_0_ebx_features = def->cpuid_7_0_ebx_features;
> +    env->features[FEAT_KVM] = def->features[FEAT_KVM];
> +    env->features[FEAT_SVM] = def->features[FEAT_SVM];
> +    env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
> +    env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
>      env->cpuid_xlevel2 = def->xlevel2;
>      object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
>                              "tsc-frequency", &error);
> @@ -1650,7 +1670,7 @@ error:
>  
>  void cpu_clear_apic_feature(CPUX86State *env)
>  {
> -    env->cpuid_features &= ~CPUID_APIC;
> +    env->features[FEAT_1_EDX] &= ~CPUID_APIC;
>  }
>  
>  #endif /* !CONFIG_USER_ONLY */
> @@ -1738,8 +1758,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>      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;
> +        *ecx = env->features[FEAT_1_ECX];
> +        *edx = env->features[FEAT_1_EDX];
>          if (cs->nr_cores * cs->nr_threads > 1) {
>              *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
>              *edx |= 1 << 28;    /* HTT bit */
> @@ -1807,7 +1827,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>          /* Structured Extended Feature Flags Enumeration Leaf */
>          if (count == 0) {
>              *eax = 0; /* Maximum ECX value for sub-leaves */
> -            *ebx = env->cpuid_7_0_ebx_features; /* Feature flags */
> +            *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
>              *ecx = 0; /* Reserved */
>              *edx = 0; /* Reserved */
>          } else {
> @@ -1842,7 +1862,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>          break;
>      case 0xD:
>          /* Processor Extended State */
> -        if (!(env->cpuid_ext_features & CPUID_EXT_XSAVE)) {
> +        if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
>              *eax = 0;
>              *ebx = 0;
>              *ecx = 0;
> @@ -1872,8 +1892,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>      case 0x80000001:
>          *eax = env->cpuid_version;
>          *ebx = 0;
> -        *ecx = env->cpuid_ext3_features;
> -        *edx = env->cpuid_ext2_features;
> +        *ecx = env->features[FEAT_8000_0001_ECX];
> +        *edx = env->features[FEAT_8000_0001_EDX];
>  
>          /* The Linux kernel checks for the CMPLegacy bit and
>           * discards multiple thread information if it is set.
> @@ -1914,12 +1934,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>      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) {
> +        if (env->features[FEAT_8000_0001_EDX] & 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) {
> +            if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
>                  *eax = 0x00000024; /* 36 bits physical */
>              } else {
>                  *eax = 0x00000020; /* 32 bits physical */
> @@ -1933,11 +1953,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>          }
>          break;
>      case 0x8000000A:
> -        if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
> +        if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
>              *eax = 0x00000001; /* SVM Revision */
>              *ebx = 0x00000010; /* nr of ASIDs */
>              *ecx = 0;
> -            *edx = env->cpuid_svm_features; /* optional features */
> +            *edx = env->features[FEAT_SVM]; /* optional features */
>          } else {
>              *eax = 0;
>              *ebx = 0;
> @@ -1956,7 +1976,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>          *eax = env->cpuid_version;
>          *ebx = 0;
>          *ecx = 0;
> -        *edx = env->cpuid_ext4_features;
> +        *edx = env->features[FEAT_C000_0001_EDX];
>          break;
>      case 0xC0000002:
>      case 0xC0000003:
> @@ -2088,7 +2108,7 @@ static void mce_init(X86CPU *cpu)
>      unsigned int bank;
>  
>      if (((cenv->cpuid_version >> 8) & 0xf) >= 6
> -        && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
> +        && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
>              (CPUID_MCE | CPUID_MCA)) {
>          cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
>          cenv->mcg_ctl = ~(uint64_t)0;
> @@ -2149,7 +2169,7 @@ void x86_cpu_realize(Object *obj, Error **errp)
>      X86CPU *cpu = X86_CPU(obj);
>      CPUX86State *env = &cpu->env;
>  
> -    if (env->cpuid_7_0_ebx_features && env->cpuid_level < 7) {
> +    if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
>          env->cpuid_level = 7;
>      }
>  
> @@ -2159,21 +2179,21 @@ void x86_cpu_realize(Object *obj, Error **errp)
>      if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
>          env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
>          env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
> -        env->cpuid_ext2_features &= ~CPUID_EXT2_AMD_ALIASES;
> -        env->cpuid_ext2_features |= (env->cpuid_features
> +        env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
> +        env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
>             & CPUID_EXT2_AMD_ALIASES);
>      }
>  
>      if (!kvm_enabled()) {
> -        env->cpuid_features &= TCG_FEATURES;
> -        env->cpuid_ext_features &= TCG_EXT_FEATURES;
> -        env->cpuid_ext2_features &= (TCG_EXT2_FEATURES
> +        env->features[FEAT_1_EDX] &= TCG_FEATURES;
> +        env->features[FEAT_1_ECX] &= TCG_EXT_FEATURES;
> +        env->features[FEAT_8000_0001_EDX] &= (TCG_EXT2_FEATURES
>  #ifdef TARGET_X86_64
>              | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
>  #endif
>              );
> -        env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
> -        env->cpuid_svm_features &= TCG_SVM_FEATURES;
> +        env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES;
> +        env->features[FEAT_SVM] &= TCG_SVM_FEATURES;
>      } else {
>  #ifdef CONFIG_KVM
>          filter_features_for_kvm(cpu);
> @@ -2183,7 +2203,7 @@ void x86_cpu_realize(Object *obj, Error **errp)
>  #ifndef CONFIG_USER_ONLY
>      qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
>  
> -    if (cpu->env.cpuid_features & CPUID_APIC || smp_cpus > 1) {
> +    if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
>          x86_cpu_apic_init(cpu, errp);
>          if (error_is_set(errp)) {
>              return;
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index e4a7c50..b202427 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -817,24 +817,15 @@ typedef struct CPUX86State {
>      uint64_t pat;
>  
>      /* processor features (e.g. for CPUID insn) */
> -    uint32_t cpuid_level;
> +    uint32_t cpuid_level, cpuid_xlevel, cpuid_xlevel2;
> +    FeatureWordArray features;
>      uint32_t cpuid_vendor1;
>      uint32_t cpuid_vendor2;
>      uint32_t cpuid_vendor3;
>      uint32_t cpuid_version;
> -    uint32_t cpuid_features;
> -    uint32_t cpuid_ext_features;
> -    uint32_t cpuid_xlevel;
>      uint32_t cpuid_model[12];
> -    uint32_t cpuid_ext2_features;
> -    uint32_t cpuid_ext3_features;
>      uint32_t cpuid_apic_id;
>      int cpuid_vendor_override;
> -    /* Store the results of Centaur's CPUID instructions */
> -    uint32_t cpuid_xlevel2;
> -    uint32_t cpuid_ext4_features;
> -    /* Flags from CPUID[EAX=7,ECX=0].EBX */
> -    uint32_t cpuid_7_0_ebx_features;
>  
>      /* MTRRs */
>      uint64_t mtrr_fixed[11];
> @@ -848,8 +839,6 @@ typedef struct CPUX86State {
>      uint8_t soft_interrupt;
>      uint8_t has_error_code;
>      uint32_t sipi_vector;
> -    uint32_t cpuid_kvm_features;
> -    uint32_t cpuid_svm_features;
>      bool tsc_valid;
>      int tsc_khz;
>      void *kvm_xsave_buf;
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index fa622e1..99da02e 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -449,7 +449,7 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t 
> new_cr4)
>          tlb_flush(env, 1);
>      }
>      /* SSE handling */
> -    if (!(env->cpuid_features & CPUID_SSE)) {
> +    if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
>          new_cr4 &= ~CR4_OSFXSR_MASK;
>      }
>      env->hflags &= ~HF_OSFXSR_MASK;
> @@ -457,7 +457,7 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t 
> new_cr4)
>          env->hflags |= HF_OSFXSR_MASK;
>      }
>  
> -    if (!(env->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)) {
> +    if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) {
>          new_cr4 &= ~CR4_SMAP_MASK;
>      }
>      env->hflags &= ~HF_SMAP_MASK;
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 3acff40..11bd906 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -445,7 +445,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
>      c = &cpuid_data.entries[cpuid_i++];
>      memset(c, 0, sizeof(*c));
>      c->function = KVM_CPUID_FEATURES;
> -    c->eax = env->cpuid_kvm_features;
> +    c->eax = env->features[FEAT_KVM];
>  
>      if (hyperv_enabled()) {
>          memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12);
> @@ -580,7 +580,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
>      cpuid_data.cpuid.nent = cpuid_i;
>  
>      if (((env->cpuid_version >> 8)&0xF) >= 6
> -        && (env->cpuid_features&(CPUID_MCE|CPUID_MCA)) == 
> (CPUID_MCE|CPUID_MCA)
> +        && (env->features[FEAT_1_EDX] & (CPUID_MCE|CPUID_MCA)) ==
> +            (CPUID_MCE|CPUID_MCA)
>          && kvm_check_extension(cs->kvm_state, KVM_CAP_MCE) > 0) {
>          uint64_t mcg_cap;
>          int banks;
> diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
> index 719cacd..4fc4261 100644
> --- a/target-i386/misc_helper.c
> +++ b/target-i386/misc_helper.c
> @@ -291,22 +291,22 @@ void helper_wrmsr(CPUX86State *env)
>              uint64_t update_mask;
>  
>              update_mask = 0;
> -            if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL) {
> +            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_SYSCALL) {
>                  update_mask |= MSR_EFER_SCE;
>              }
> -            if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
> +            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
>                  update_mask |= MSR_EFER_LME;
>              }
> -            if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) {
> +            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
>                  update_mask |= MSR_EFER_FFXSR;
>              }
> -            if (env->cpuid_ext2_features & CPUID_EXT2_NX) {
> +            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_NX) {
>                  update_mask |= MSR_EFER_NXE;
>              }
> -            if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
> +            if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
>                  update_mask |= MSR_EFER_SVME;
>              }
> -            if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) {
> +            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
>                  update_mask |= MSR_EFER_FFXSR;
>              }
>              cpu_load_efer(env, (env->efer & ~update_mask) |
> @@ -513,7 +513,7 @@ void helper_rdmsr(CPUX86State *env)
>          val = env->mtrr_deftype;
>          break;
>      case MSR_MTRRcap:
> -        if (env->cpuid_features & CPUID_MTRR) {
> +        if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
>              val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT |
>                  MSR_MTRRcap_WC_SUPPORTED;
>          } else {
> diff --git a/target-i386/translate.c b/target-i386/translate.c
> index 32d21f5..2d45ad4 100644
> --- a/target-i386/translate.c
> +++ b/target-i386/translate.c
> @@ -7926,11 +7926,11 @@ static inline void 
> gen_intermediate_code_internal(CPUX86State *env,
>      if (flags & HF_SOFTMMU_MASK) {
>          dc->mem_index = (cpu_mmu_index(env) + 1) << 2;
>      }
> -    dc->cpuid_features = env->cpuid_features;
> -    dc->cpuid_ext_features = env->cpuid_ext_features;
> -    dc->cpuid_ext2_features = env->cpuid_ext2_features;
> -    dc->cpuid_ext3_features = env->cpuid_ext3_features;
> -    dc->cpuid_7_0_ebx_features = env->cpuid_7_0_ebx_features;
> +    dc->cpuid_features = env->features[FEAT_1_EDX];
> +    dc->cpuid_ext_features = env->features[FEAT_1_ECX];
> +    dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
> +    dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
> +    dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
>  #ifdef TARGET_X86_64
>      dc->lma = (flags >> HF_LMA_SHIFT) & 1;
>      dc->code64 = (flags >> HF_CS64_SHIFT) & 1;

-- 
regards!
li guang




reply via email to

[Prev in Thread] Current Thread [Next in Thread]