qemu/target/i386/cpu.c
<<
>>
Prefs
   1/*
   2 *  i386 CPUID, CPU class, definitions, models
   3 *
   4 *  Copyright (c) 2003 Fabrice Bellard
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2.1 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "qemu/osdep.h"
  21#include "qemu/units.h"
  22#include "qemu/cutils.h"
  23#include "qemu/qemu-print.h"
  24#include "qemu/hw-version.h"
  25#include "cpu.h"
  26#include "tcg/helper-tcg.h"
  27#include "sysemu/reset.h"
  28#include "sysemu/hvf.h"
  29#include "kvm/kvm_i386.h"
  30#include "sev.h"
  31#include "qapi/error.h"
  32#include "qapi/qapi-visit-machine.h"
  33#include "qapi/qmp/qerror.h"
  34#include "qapi/qapi-commands-machine-target.h"
  35#include "standard-headers/asm-x86/kvm_para.h"
  36#include "hw/qdev-properties.h"
  37#include "hw/i386/topology.h"
  38#ifndef CONFIG_USER_ONLY
  39#include "exec/address-spaces.h"
  40#include "hw/boards.h"
  41#include "hw/i386/sgx-epc.h"
  42#endif
  43
  44#include "disas/capstone.h"
  45#include "cpu-internal.h"
  46
  47/* Helpers for building CPUID[2] descriptors: */
  48
  49struct CPUID2CacheDescriptorInfo {
  50    enum CacheType type;
  51    int level;
  52    int size;
  53    int line_size;
  54    int associativity;
  55};
  56
  57/*
  58 * Known CPUID 2 cache descriptors.
  59 * From Intel SDM Volume 2A, CPUID instruction
  60 */
  61struct CPUID2CacheDescriptorInfo cpuid2_cache_descriptors[] = {
  62    [0x06] = { .level = 1, .type = INSTRUCTION_CACHE, .size =   8 * KiB,
  63               .associativity = 4,  .line_size = 32, },
  64    [0x08] = { .level = 1, .type = INSTRUCTION_CACHE, .size =  16 * KiB,
  65               .associativity = 4,  .line_size = 32, },
  66    [0x09] = { .level = 1, .type = INSTRUCTION_CACHE, .size =  32 * KiB,
  67               .associativity = 4,  .line_size = 64, },
  68    [0x0A] = { .level = 1, .type = DATA_CACHE,        .size =   8 * KiB,
  69               .associativity = 2,  .line_size = 32, },
  70    [0x0C] = { .level = 1, .type = DATA_CACHE,        .size =  16 * KiB,
  71               .associativity = 4,  .line_size = 32, },
  72    [0x0D] = { .level = 1, .type = DATA_CACHE,        .size =  16 * KiB,
  73               .associativity = 4,  .line_size = 64, },
  74    [0x0E] = { .level = 1, .type = DATA_CACHE,        .size =  24 * KiB,
  75               .associativity = 6,  .line_size = 64, },
  76    [0x1D] = { .level = 2, .type = UNIFIED_CACHE,     .size = 128 * KiB,
  77               .associativity = 2,  .line_size = 64, },
  78    [0x21] = { .level = 2, .type = UNIFIED_CACHE,     .size = 256 * KiB,
  79               .associativity = 8,  .line_size = 64, },
  80    /* lines per sector is not supported cpuid2_cache_descriptor(),
  81    * so descriptors 0x22, 0x23 are not included
  82    */
  83    [0x24] = { .level = 2, .type = UNIFIED_CACHE,     .size =   1 * MiB,
  84               .associativity = 16, .line_size = 64, },
  85    /* lines per sector is not supported cpuid2_cache_descriptor(),
  86    * so descriptors 0x25, 0x20 are not included
  87    */
  88    [0x2C] = { .level = 1, .type = DATA_CACHE,        .size =  32 * KiB,
  89               .associativity = 8,  .line_size = 64, },
  90    [0x30] = { .level = 1, .type = INSTRUCTION_CACHE, .size =  32 * KiB,
  91               .associativity = 8,  .line_size = 64, },
  92    [0x41] = { .level = 2, .type = UNIFIED_CACHE,     .size = 128 * KiB,
  93               .associativity = 4,  .line_size = 32, },
  94    [0x42] = { .level = 2, .type = UNIFIED_CACHE,     .size = 256 * KiB,
  95               .associativity = 4,  .line_size = 32, },
  96    [0x43] = { .level = 2, .type = UNIFIED_CACHE,     .size = 512 * KiB,
  97               .associativity = 4,  .line_size = 32, },
  98    [0x44] = { .level = 2, .type = UNIFIED_CACHE,     .size =   1 * MiB,
  99               .associativity = 4,  .line_size = 32, },
 100    [0x45] = { .level = 2, .type = UNIFIED_CACHE,     .size =   2 * MiB,
 101               .associativity = 4,  .line_size = 32, },
 102    [0x46] = { .level = 3, .type = UNIFIED_CACHE,     .size =   4 * MiB,
 103               .associativity = 4,  .line_size = 64, },
 104    [0x47] = { .level = 3, .type = UNIFIED_CACHE,     .size =   8 * MiB,
 105               .associativity = 8,  .line_size = 64, },
 106    [0x48] = { .level = 2, .type = UNIFIED_CACHE,     .size =   3 * MiB,
 107               .associativity = 12, .line_size = 64, },
 108    /* Descriptor 0x49 depends on CPU family/model, so it is not included */
 109    [0x4A] = { .level = 3, .type = UNIFIED_CACHE,     .size =   6 * MiB,
 110               .associativity = 12, .line_size = 64, },
 111    [0x4B] = { .level = 3, .type = UNIFIED_CACHE,     .size =   8 * MiB,
 112               .associativity = 16, .line_size = 64, },
 113    [0x4C] = { .level = 3, .type = UNIFIED_CACHE,     .size =  12 * MiB,
 114               .associativity = 12, .line_size = 64, },
 115    [0x4D] = { .level = 3, .type = UNIFIED_CACHE,     .size =  16 * MiB,
 116               .associativity = 16, .line_size = 64, },
 117    [0x4E] = { .level = 2, .type = UNIFIED_CACHE,     .size =   6 * MiB,
 118               .associativity = 24, .line_size = 64, },
 119    [0x60] = { .level = 1, .type = DATA_CACHE,        .size =  16 * KiB,
 120               .associativity = 8,  .line_size = 64, },
 121    [0x66] = { .level = 1, .type = DATA_CACHE,        .size =   8 * KiB,
 122               .associativity = 4,  .line_size = 64, },
 123    [0x67] = { .level = 1, .type = DATA_CACHE,        .size =  16 * KiB,
 124               .associativity = 4,  .line_size = 64, },
 125    [0x68] = { .level = 1, .type = DATA_CACHE,        .size =  32 * KiB,
 126               .associativity = 4,  .line_size = 64, },
 127    [0x78] = { .level = 2, .type = UNIFIED_CACHE,     .size =   1 * MiB,
 128               .associativity = 4,  .line_size = 64, },
 129    /* lines per sector is not supported cpuid2_cache_descriptor(),
 130    * so descriptors 0x79, 0x7A, 0x7B, 0x7C are not included.
 131    */
 132    [0x7D] = { .level = 2, .type = UNIFIED_CACHE,     .size =   2 * MiB,
 133               .associativity = 8,  .line_size = 64, },
 134    [0x7F] = { .level = 2, .type = UNIFIED_CACHE,     .size = 512 * KiB,
 135               .associativity = 2,  .line_size = 64, },
 136    [0x80] = { .level = 2, .type = UNIFIED_CACHE,     .size = 512 * KiB,
 137               .associativity = 8,  .line_size = 64, },
 138    [0x82] = { .level = 2, .type = UNIFIED_CACHE,     .size = 256 * KiB,
 139               .associativity = 8,  .line_size = 32, },
 140    [0x83] = { .level = 2, .type = UNIFIED_CACHE,     .size = 512 * KiB,
 141               .associativity = 8,  .line_size = 32, },
 142    [0x84] = { .level = 2, .type = UNIFIED_CACHE,     .size =   1 * MiB,
 143               .associativity = 8,  .line_size = 32, },
 144    [0x85] = { .level = 2, .type = UNIFIED_CACHE,     .size =   2 * MiB,
 145               .associativity = 8,  .line_size = 32, },
 146    [0x86] = { .level = 2, .type = UNIFIED_CACHE,     .size = 512 * KiB,
 147               .associativity = 4,  .line_size = 64, },
 148    [0x87] = { .level = 2, .type = UNIFIED_CACHE,     .size =   1 * MiB,
 149               .associativity = 8,  .line_size = 64, },
 150    [0xD0] = { .level = 3, .type = UNIFIED_CACHE,     .size = 512 * KiB,
 151               .associativity = 4,  .line_size = 64, },
 152    [0xD1] = { .level = 3, .type = UNIFIED_CACHE,     .size =   1 * MiB,
 153               .associativity = 4,  .line_size = 64, },
 154    [0xD2] = { .level = 3, .type = UNIFIED_CACHE,     .size =   2 * MiB,
 155               .associativity = 4,  .line_size = 64, },
 156    [0xD6] = { .level = 3, .type = UNIFIED_CACHE,     .size =   1 * MiB,
 157               .associativity = 8,  .line_size = 64, },
 158    [0xD7] = { .level = 3, .type = UNIFIED_CACHE,     .size =   2 * MiB,
 159               .associativity = 8,  .line_size = 64, },
 160    [0xD8] = { .level = 3, .type = UNIFIED_CACHE,     .size =   4 * MiB,
 161               .associativity = 8,  .line_size = 64, },
 162    [0xDC] = { .level = 3, .type = UNIFIED_CACHE,     .size = 1.5 * MiB,
 163               .associativity = 12, .line_size = 64, },
 164    [0xDD] = { .level = 3, .type = UNIFIED_CACHE,     .size =   3 * MiB,
 165               .associativity = 12, .line_size = 64, },
 166    [0xDE] = { .level = 3, .type = UNIFIED_CACHE,     .size =   6 * MiB,
 167               .associativity = 12, .line_size = 64, },
 168    [0xE2] = { .level = 3, .type = UNIFIED_CACHE,     .size =   2 * MiB,
 169               .associativity = 16, .line_size = 64, },
 170    [0xE3] = { .level = 3, .type = UNIFIED_CACHE,     .size =   4 * MiB,
 171               .associativity = 16, .line_size = 64, },
 172    [0xE4] = { .level = 3, .type = UNIFIED_CACHE,     .size =   8 * MiB,
 173               .associativity = 16, .line_size = 64, },
 174    [0xEA] = { .level = 3, .type = UNIFIED_CACHE,     .size =  12 * MiB,
 175               .associativity = 24, .line_size = 64, },
 176    [0xEB] = { .level = 3, .type = UNIFIED_CACHE,     .size =  18 * MiB,
 177               .associativity = 24, .line_size = 64, },
 178    [0xEC] = { .level = 3, .type = UNIFIED_CACHE,     .size =  24 * MiB,
 179               .associativity = 24, .line_size = 64, },
 180};
 181
 182/*
 183 * "CPUID leaf 2 does not report cache descriptor information,
 184 * use CPUID leaf 4 to query cache parameters"
 185 */
 186#define CACHE_DESCRIPTOR_UNAVAILABLE 0xFF
 187
 188/*
 189 * Return a CPUID 2 cache descriptor for a given cache.
 190 * If no known descriptor is found, return CACHE_DESCRIPTOR_UNAVAILABLE
 191 */
 192static uint8_t cpuid2_cache_descriptor(CPUCacheInfo *cache)
 193{
 194    int i;
 195
 196    assert(cache->size > 0);
 197    assert(cache->level > 0);
 198    assert(cache->line_size > 0);
 199    assert(cache->associativity > 0);
 200    for (i = 0; i < ARRAY_SIZE(cpuid2_cache_descriptors); i++) {
 201        struct CPUID2CacheDescriptorInfo *d = &cpuid2_cache_descriptors[i];
 202        if (d->level == cache->level && d->type == cache->type &&
 203            d->size == cache->size && d->line_size == cache->line_size &&
 204            d->associativity == cache->associativity) {
 205                return i;
 206            }
 207    }
 208
 209    return CACHE_DESCRIPTOR_UNAVAILABLE;
 210}
 211
 212/* CPUID Leaf 4 constants: */
 213
 214/* EAX: */
 215#define CACHE_TYPE_D    1
 216#define CACHE_TYPE_I    2
 217#define CACHE_TYPE_UNIFIED   3
 218
 219#define CACHE_LEVEL(l)        (l << 5)
 220
 221#define CACHE_SELF_INIT_LEVEL (1 << 8)
 222
 223/* EDX: */
 224#define CACHE_NO_INVD_SHARING   (1 << 0)
 225#define CACHE_INCLUSIVE       (1 << 1)
 226#define CACHE_COMPLEX_IDX     (1 << 2)
 227
 228/* Encode CacheType for CPUID[4].EAX */
 229#define CACHE_TYPE(t) (((t) == DATA_CACHE) ? CACHE_TYPE_D : \
 230                       ((t) == INSTRUCTION_CACHE) ? CACHE_TYPE_I : \
 231                       ((t) == UNIFIED_CACHE) ? CACHE_TYPE_UNIFIED : \
 232                       0 /* Invalid value */)
 233
 234
 235/* Encode cache info for CPUID[4] */
 236static void encode_cache_cpuid4(CPUCacheInfo *cache,
 237                                int num_apic_ids, int num_cores,
 238                                uint32_t *eax, uint32_t *ebx,
 239                                uint32_t *ecx, uint32_t *edx)
 240{
 241    assert(cache->size == cache->line_size * cache->associativity *
 242                          cache->partitions * cache->sets);
 243
 244    assert(num_apic_ids > 0);
 245    *eax = CACHE_TYPE(cache->type) |
 246           CACHE_LEVEL(cache->level) |
 247           (cache->self_init ? CACHE_SELF_INIT_LEVEL : 0) |
 248           ((num_cores - 1) << 26) |
 249           ((num_apic_ids - 1) << 14);
 250
 251    assert(cache->line_size > 0);
 252    assert(cache->partitions > 0);
 253    assert(cache->associativity > 0);
 254    /* We don't implement fully-associative caches */
 255    assert(cache->associativity < cache->sets);
 256    *ebx = (cache->line_size - 1) |
 257           ((cache->partitions - 1) << 12) |
 258           ((cache->associativity - 1) << 22);
 259
 260    assert(cache->sets > 0);
 261    *ecx = cache->sets - 1;
 262
 263    *edx = (cache->no_invd_sharing ? CACHE_NO_INVD_SHARING : 0) |
 264           (cache->inclusive ? CACHE_INCLUSIVE : 0) |
 265           (cache->complex_indexing ? CACHE_COMPLEX_IDX : 0);
 266}
 267
 268/* Encode cache info for CPUID[0x80000005].ECX or CPUID[0x80000005].EDX */
 269static uint32_t encode_cache_cpuid80000005(CPUCacheInfo *cache)
 270{
 271    assert(cache->size % 1024 == 0);
 272    assert(cache->lines_per_tag > 0);
 273    assert(cache->associativity > 0);
 274    assert(cache->line_size > 0);
 275    return ((cache->size / 1024) << 24) | (cache->associativity << 16) |
 276           (cache->lines_per_tag << 8) | (cache->line_size);
 277}
 278
 279#define ASSOC_FULL 0xFF
 280
 281/* AMD associativity encoding used on CPUID Leaf 0x80000006: */
 282#define AMD_ENC_ASSOC(a) (a <=   1 ? a   : \
 283                          a ==   2 ? 0x2 : \
 284                          a ==   4 ? 0x4 : \
 285                          a ==   8 ? 0x6 : \
 286                          a ==  16 ? 0x8 : \
 287                          a ==  32 ? 0xA : \
 288                          a ==  48 ? 0xB : \
 289                          a ==  64 ? 0xC : \
 290                          a ==  96 ? 0xD : \
 291                          a == 128 ? 0xE : \
 292                          a == ASSOC_FULL ? 0xF : \
 293                          0 /* invalid value */)
 294
 295/*
 296 * Encode cache info for CPUID[0x80000006].ECX and CPUID[0x80000006].EDX
 297 * @l3 can be NULL.
 298 */
 299static void encode_cache_cpuid80000006(CPUCacheInfo *l2,
 300                                       CPUCacheInfo *l3,
 301                                       uint32_t *ecx, uint32_t *edx)
 302{
 303    assert(l2->size % 1024 == 0);
 304    assert(l2->associativity > 0);
 305    assert(l2->lines_per_tag > 0);
 306    assert(l2->line_size > 0);
 307    *ecx = ((l2->size / 1024) << 16) |
 308           (AMD_ENC_ASSOC(l2->associativity) << 12) |
 309           (l2->lines_per_tag << 8) | (l2->line_size);
 310
 311    if (l3) {
 312        assert(l3->size % (512 * 1024) == 0);
 313        assert(l3->associativity > 0);
 314        assert(l3->lines_per_tag > 0);
 315        assert(l3->line_size > 0);
 316        *edx = ((l3->size / (512 * 1024)) << 18) |
 317               (AMD_ENC_ASSOC(l3->associativity) << 12) |
 318               (l3->lines_per_tag << 8) | (l3->line_size);
 319    } else {
 320        *edx = 0;
 321    }
 322}
 323
 324/* Encode cache info for CPUID[8000001D] */
 325static void encode_cache_cpuid8000001d(CPUCacheInfo *cache,
 326                                       X86CPUTopoInfo *topo_info,
 327                                       uint32_t *eax, uint32_t *ebx,
 328                                       uint32_t *ecx, uint32_t *edx)
 329{
 330    uint32_t l3_threads;
 331    assert(cache->size == cache->line_size * cache->associativity *
 332                          cache->partitions * cache->sets);
 333
 334    *eax = CACHE_TYPE(cache->type) | CACHE_LEVEL(cache->level) |
 335               (cache->self_init ? CACHE_SELF_INIT_LEVEL : 0);
 336
 337    /* L3 is shared among multiple cores */
 338    if (cache->level == 3) {
 339        l3_threads = topo_info->cores_per_die * topo_info->threads_per_core;
 340        *eax |= (l3_threads - 1) << 14;
 341    } else {
 342        *eax |= ((topo_info->threads_per_core - 1) << 14);
 343    }
 344
 345    assert(cache->line_size > 0);
 346    assert(cache->partitions > 0);
 347    assert(cache->associativity > 0);
 348    /* We don't implement fully-associative caches */
 349    assert(cache->associativity < cache->sets);
 350    *ebx = (cache->line_size - 1) |
 351           ((cache->partitions - 1) << 12) |
 352           ((cache->associativity - 1) << 22);
 353
 354    assert(cache->sets > 0);
 355    *ecx = cache->sets - 1;
 356
 357    *edx = (cache->no_invd_sharing ? CACHE_NO_INVD_SHARING : 0) |
 358           (cache->inclusive ? CACHE_INCLUSIVE : 0) |
 359           (cache->complex_indexing ? CACHE_COMPLEX_IDX : 0);
 360}
 361
 362/* Encode cache info for CPUID[8000001E] */
 363static void encode_topo_cpuid8000001e(X86CPU *cpu, X86CPUTopoInfo *topo_info,
 364                                      uint32_t *eax, uint32_t *ebx,
 365                                      uint32_t *ecx, uint32_t *edx)
 366{
 367    X86CPUTopoIDs topo_ids;
 368
 369    x86_topo_ids_from_apicid(cpu->apic_id, topo_info, &topo_ids);
 370
 371    *eax = cpu->apic_id;
 372
 373    /*
 374     * CPUID_Fn8000001E_EBX [Core Identifiers] (CoreId)
 375     * Read-only. Reset: 0000_XXXXh.
 376     * See Core::X86::Cpuid::ExtApicId.
 377     * Core::X86::Cpuid::CoreId_lthree[1:0]_core[3:0]_thread[1:0];
 378     * Bits Description
 379     * 31:16 Reserved.
 380     * 15:8 ThreadsPerCore: threads per core. Read-only. Reset: XXh.
 381     *      The number of threads per core is ThreadsPerCore+1.
 382     *  7:0 CoreId: core ID. Read-only. Reset: XXh.
 383     *
 384     *  NOTE: CoreId is already part of apic_id. Just use it. We can
 385     *  use all the 8 bits to represent the core_id here.
 386     */
 387    *ebx = ((topo_info->threads_per_core - 1) << 8) | (topo_ids.core_id & 0xFF);
 388
 389    /*
 390     * CPUID_Fn8000001E_ECX [Node Identifiers] (NodeId)
 391     * Read-only. Reset: 0000_0XXXh.
 392     * Core::X86::Cpuid::NodeId_lthree[1:0]_core[3:0]_thread[1:0];
 393     * Bits Description
 394     * 31:11 Reserved.
 395     * 10:8 NodesPerProcessor: Node per processor. Read-only. Reset: XXXb.
 396     *      ValidValues:
 397     *      Value Description
 398     *      000b  1 node per processor.
 399     *      001b  2 nodes per processor.
 400     *      010b Reserved.
 401     *      011b 4 nodes per processor.
 402     *      111b-100b Reserved.
 403     *  7:0 NodeId: Node ID. Read-only. Reset: XXh.
 404     *
 405     * NOTE: Hardware reserves 3 bits for number of nodes per processor.
 406     * But users can create more nodes than the actual hardware can
 407     * support. To genaralize we can use all the upper 8 bits for nodes.
 408     * NodeId is combination of node and socket_id which is already decoded
 409     * in apic_id. Just use it by shifting.
 410     */
 411    *ecx = ((topo_info->dies_per_pkg - 1) << 8) |
 412           ((cpu->apic_id >> apicid_die_offset(topo_info)) & 0xFF);
 413
 414    *edx = 0;
 415}
 416
 417/*
 418 * Definitions of the hardcoded cache entries we expose:
 419 * These are legacy cache values. If there is a need to change any
 420 * of these values please use builtin_x86_defs
 421 */
 422
 423/* L1 data cache: */
 424static CPUCacheInfo legacy_l1d_cache = {
 425    .type = DATA_CACHE,
 426    .level = 1,
 427    .size = 32 * KiB,
 428    .self_init = 1,
 429    .line_size = 64,
 430    .associativity = 8,
 431    .sets = 64,
 432    .partitions = 1,
 433    .no_invd_sharing = true,
 434};
 435
 436/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
 437static CPUCacheInfo legacy_l1d_cache_amd = {
 438    .type = DATA_CACHE,
 439    .level = 1,
 440    .size = 64 * KiB,
 441    .self_init = 1,
 442    .line_size = 64,
 443    .associativity = 2,
 444    .sets = 512,
 445    .partitions = 1,
 446    .lines_per_tag = 1,
 447    .no_invd_sharing = true,
 448};
 449
 450/* L1 instruction cache: */
 451static CPUCacheInfo legacy_l1i_cache = {
 452    .type = INSTRUCTION_CACHE,
 453    .level = 1,
 454    .size = 32 * KiB,
 455    .self_init = 1,
 456    .line_size = 64,
 457    .associativity = 8,
 458    .sets = 64,
 459    .partitions = 1,
 460    .no_invd_sharing = true,
 461};
 462
 463/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
 464static CPUCacheInfo legacy_l1i_cache_amd = {
 465    .type = INSTRUCTION_CACHE,
 466    .level = 1,
 467    .size = 64 * KiB,
 468    .self_init = 1,
 469    .line_size = 64,
 470    .associativity = 2,
 471    .sets = 512,
 472    .partitions = 1,
 473    .lines_per_tag = 1,
 474    .no_invd_sharing = true,
 475};
 476
 477/* Level 2 unified cache: */
 478static CPUCacheInfo legacy_l2_cache = {
 479    .type = UNIFIED_CACHE,
 480    .level = 2,
 481    .size = 4 * MiB,
 482    .self_init = 1,
 483    .line_size = 64,
 484    .associativity = 16,
 485    .sets = 4096,
 486    .partitions = 1,
 487    .no_invd_sharing = true,
 488};
 489
 490/*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
 491static CPUCacheInfo legacy_l2_cache_cpuid2 = {
 492    .type = UNIFIED_CACHE,
 493    .level = 2,
 494    .size = 2 * MiB,
 495    .line_size = 64,
 496    .associativity = 8,
 497};
 498
 499
 500/*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
 501static CPUCacheInfo legacy_l2_cache_amd = {
 502    .type = UNIFIED_CACHE,
 503    .level = 2,
 504    .size = 512 * KiB,
 505    .line_size = 64,
 506    .lines_per_tag = 1,
 507    .associativity = 16,
 508    .sets = 512,
 509    .partitions = 1,
 510};
 511
 512/* Level 3 unified cache: */
 513static CPUCacheInfo legacy_l3_cache = {
 514    .type = UNIFIED_CACHE,
 515    .level = 3,
 516    .size = 16 * MiB,
 517    .line_size = 64,
 518    .associativity = 16,
 519    .sets = 16384,
 520    .partitions = 1,
 521    .lines_per_tag = 1,
 522    .self_init = true,
 523    .inclusive = true,
 524    .complex_indexing = true,
 525};
 526
 527/* TLB definitions: */
 528
 529#define L1_DTLB_2M_ASSOC       1
 530#define L1_DTLB_2M_ENTRIES   255
 531#define L1_DTLB_4K_ASSOC       1
 532#define L1_DTLB_4K_ENTRIES   255
 533
 534#define L1_ITLB_2M_ASSOC       1
 535#define L1_ITLB_2M_ENTRIES   255
 536#define L1_ITLB_4K_ASSOC       1
 537#define L1_ITLB_4K_ENTRIES   255
 538
 539#define L2_DTLB_2M_ASSOC       0 /* disabled */
 540#define L2_DTLB_2M_ENTRIES     0 /* disabled */
 541#define L2_DTLB_4K_ASSOC       4
 542#define L2_DTLB_4K_ENTRIES   512
 543
 544#define L2_ITLB_2M_ASSOC       0 /* disabled */
 545#define L2_ITLB_2M_ENTRIES     0 /* disabled */
 546#define L2_ITLB_4K_ASSOC       4
 547#define L2_ITLB_4K_ENTRIES   512
 548
 549/* CPUID Leaf 0x14 constants: */
 550#define INTEL_PT_MAX_SUBLEAF     0x1
 551/*
 552 * bit[00]: IA32_RTIT_CTL.CR3 filter can be set to 1 and IA32_RTIT_CR3_MATCH
 553 *          MSR can be accessed;
 554 * bit[01]: Support Configurable PSB and Cycle-Accurate Mode;
 555 * bit[02]: Support IP Filtering, TraceStop filtering, and preservation
 556 *          of Intel PT MSRs across warm reset;
 557 * bit[03]: Support MTC timing packet and suppression of COFI-based packets;
 558 */
 559#define INTEL_PT_MINIMAL_EBX     0xf
 560/*
 561 * bit[00]: Tracing can be enabled with IA32_RTIT_CTL.ToPA = 1 and
 562 *          IA32_RTIT_OUTPUT_BASE and IA32_RTIT_OUTPUT_MASK_PTRS MSRs can be
 563 *          accessed;
 564 * bit[01]: ToPA tables can hold any number of output entries, up to the
 565 *          maximum allowed by the MaskOrTableOffset field of
 566 *          IA32_RTIT_OUTPUT_MASK_PTRS;
 567 * bit[02]: Support Single-Range Output scheme;
 568 */
 569#define INTEL_PT_MINIMAL_ECX     0x7
 570/* generated packets which contain IP payloads have LIP values */
 571#define INTEL_PT_IP_LIP          (1 << 31)
 572#define INTEL_PT_ADDR_RANGES_NUM 0x2 /* Number of configurable address ranges */
 573#define INTEL_PT_ADDR_RANGES_NUM_MASK 0x3
 574#define INTEL_PT_MTC_BITMAP      (0x0249 << 16) /* Support ART(0,3,6,9) */
 575#define INTEL_PT_CYCLE_BITMAP    0x1fff         /* Support 0,2^(0~11) */
 576#define INTEL_PT_PSB_BITMAP      (0x003f << 16) /* Support 2K,4K,8K,16K,32K,64K */
 577
 578/* CPUID Leaf 0x1D constants: */
 579#define INTEL_AMX_TILE_MAX_SUBLEAF     0x1
 580#define INTEL_AMX_TOTAL_TILE_BYTES     0x2000
 581#define INTEL_AMX_BYTES_PER_TILE       0x400
 582#define INTEL_AMX_BYTES_PER_ROW        0x40
 583#define INTEL_AMX_TILE_MAX_NAMES       0x8
 584#define INTEL_AMX_TILE_MAX_ROWS        0x10
 585
 586/* CPUID Leaf 0x1E constants: */
 587#define INTEL_AMX_TMUL_MAX_K           0x10
 588#define INTEL_AMX_TMUL_MAX_N           0x40
 589
 590void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
 591                              uint32_t vendor2, uint32_t vendor3)
 592{
 593    int i;
 594    for (i = 0; i < 4; i++) {
 595        dst[i] = vendor1 >> (8 * i);
 596        dst[i + 4] = vendor2 >> (8 * i);
 597        dst[i + 8] = vendor3 >> (8 * i);
 598    }
 599    dst[CPUID_VENDOR_SZ] = '\0';
 600}
 601
 602#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
 603#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
 604          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
 605#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
 606          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
 607          CPUID_PSE36 | CPUID_FXSR)
 608#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
 609#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
 610          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
 611          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
 612          CPUID_PAE | CPUID_SEP | CPUID_APIC)
 613
 614#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
 615          CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
 616          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
 617          CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
 618          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS | CPUID_DE)
 619          /* partly implemented:
 620          CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64) */
 621          /* missing:
 622          CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
 623#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
 624          CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
 625          CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
 626          CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */   \
 627          CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR | \
 628          CPUID_EXT_RDRAND)
 629          /* missing:
 630          CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
 631          CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
 632          CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
 633          CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_AVX,
 634          CPUID_EXT_F16C */
 635
 636#ifdef TARGET_X86_64
 637#define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM)
 638#else
 639#define TCG_EXT2_X86_64_FEATURES 0
 640#endif
 641
 642#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
 643          CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
 644          CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_PDPE1GB | \
 645          TCG_EXT2_X86_64_FEATURES)
 646#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
 647          CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
 648#define TCG_EXT4_FEATURES 0
 649#define TCG_SVM_FEATURES (CPUID_SVM_NPT | CPUID_SVM_VGIF | \
 650          CPUID_SVM_SVME_ADDR_CHK)
 651#define TCG_KVM_FEATURES 0
 652#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
 653          CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
 654          CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT |            \
 655          CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE | \
 656          CPUID_7_0_EBX_ERMS)
 657          /* missing:
 658          CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
 659          CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
 660          CPUID_7_0_EBX_RDSEED */
 661#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | \
 662          /* CPUID_7_0_ECX_OSPKE is dynamic */ \
 663          CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS)
 664#define TCG_7_0_EDX_FEATURES 0
 665#define TCG_7_1_EAX_FEATURES 0
 666#define TCG_APM_FEATURES 0
 667#define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
 668#define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1)
 669          /* missing:
 670          CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
 671#define TCG_14_0_ECX_FEATURES 0
 672#define TCG_SGX_12_0_EAX_FEATURES 0
 673#define TCG_SGX_12_0_EBX_FEATURES 0
 674#define TCG_SGX_12_1_EAX_FEATURES 0
 675
 676FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 677    [FEAT_1_EDX] = {
 678        .type = CPUID_FEATURE_WORD,
 679        .feat_names = {
 680            "fpu", "vme", "de", "pse",
 681            "tsc", "msr", "pae", "mce",
 682            "cx8", "apic", NULL, "sep",
 683            "mtrr", "pge", "mca", "cmov",
 684            "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
 685            NULL, "ds" /* Intel dts */, "acpi", "mmx",
 686            "fxsr", "sse", "sse2", "ss",
 687            "ht" /* Intel htt */, "tm", "ia64", "pbe",
 688        },
 689        .cpuid = {.eax = 1, .reg = R_EDX, },
 690        .tcg_features = TCG_FEATURES,
 691    },
 692    [FEAT_1_ECX] = {
 693        .type = CPUID_FEATURE_WORD,
 694        .feat_names = {
 695            "pni" /* Intel,AMD sse3 */, "pclmulqdq", "dtes64", "monitor",
 696            "ds-cpl", "vmx", "smx", "est",
 697            "tm2", "ssse3", "cid", NULL,
 698            "fma", "cx16", "xtpr", "pdcm",
 699            NULL, "pcid", "dca", "sse4.1",
 700            "sse4.2", "x2apic", "movbe", "popcnt",
 701            "tsc-deadline", "aes", "xsave", NULL /* osxsave */,
 702            "avx", "f16c", "rdrand", "hypervisor",
 703        },
 704        .cpuid = { .eax = 1, .reg = R_ECX, },
 705        .tcg_features = TCG_EXT_FEATURES,
 706    },
 707    /* Feature names that are already defined on feature_name[] but
 708     * are set on CPUID[8000_0001].EDX on AMD CPUs don't have their
 709     * names on feat_names below. They are copied automatically
 710     * to features[FEAT_8000_0001_EDX] if and only if CPU vendor is AMD.
 711     */
 712    [FEAT_8000_0001_EDX] = {
 713        .type = CPUID_FEATURE_WORD,
 714        .feat_names = {
 715            NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
 716            NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
 717            NULL /* cx8 */, NULL /* apic */, NULL, "syscall",
 718            NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
 719            NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
 720            "nx", NULL, "mmxext", NULL /* mmx */,
 721            NULL /* fxsr */, "fxsr-opt", "pdpe1gb", "rdtscp",
 722            NULL, "lm", "3dnowext", "3dnow",
 723        },
 724        .cpuid = { .eax = 0x80000001, .reg = R_EDX, },
 725        .tcg_features = TCG_EXT2_FEATURES,
 726    },
 727    [FEAT_8000_0001_ECX] = {
 728        .type = CPUID_FEATURE_WORD,
 729        .feat_names = {
 730            "lahf-lm", "cmp-legacy", "svm", "extapic",
 731            "cr8legacy", "abm", "sse4a", "misalignsse",
 732            "3dnowprefetch", "osvw", "ibs", "xop",
 733            "skinit", "wdt", NULL, "lwp",
 734            "fma4", "tce", NULL, "nodeid-msr",
 735            NULL, "tbm", "topoext", "perfctr-core",
 736            "perfctr-nb", NULL, NULL, NULL,
 737            NULL, NULL, NULL, NULL,
 738        },
 739        .cpuid = { .eax = 0x80000001, .reg = R_ECX, },
 740        .tcg_features = TCG_EXT3_FEATURES,
 741        /*
 742         * TOPOEXT is always allowed but can't be enabled blindly by
 743         * "-cpu host", as it requires consistent cache topology info
 744         * to be provided so it doesn't confuse guests.
 745         */
 746        .no_autoenable_flags = CPUID_EXT3_TOPOEXT,
 747    },
 748    [FEAT_C000_0001_EDX] = {
 749        .type = CPUID_FEATURE_WORD,
 750        .feat_names = {
 751            NULL, NULL, "xstore", "xstore-en",
 752            NULL, NULL, "xcrypt", "xcrypt-en",
 753            "ace2", "ace2-en", "phe", "phe-en",
 754            "pmm", "pmm-en", NULL, NULL,
 755            NULL, NULL, NULL, NULL,
 756            NULL, NULL, NULL, NULL,
 757            NULL, NULL, NULL, NULL,
 758            NULL, NULL, NULL, NULL,
 759        },
 760        .cpuid = { .eax = 0xC0000001, .reg = R_EDX, },
 761        .tcg_features = TCG_EXT4_FEATURES,
 762    },
 763    [FEAT_KVM] = {
 764        .type = CPUID_FEATURE_WORD,
 765        .feat_names = {
 766            "kvmclock", "kvm-nopiodelay", "kvm-mmu", "kvmclock",
 767            "kvm-asyncpf", "kvm-steal-time", "kvm-pv-eoi", "kvm-pv-unhalt",
 768            NULL, "kvm-pv-tlb-flush", NULL, "kvm-pv-ipi",
 769            "kvm-poll-control", "kvm-pv-sched-yield", "kvm-asyncpf-int", "kvm-msi-ext-dest-id",
 770            NULL, NULL, NULL, NULL,
 771            NULL, NULL, NULL, NULL,
 772            "kvmclock-stable-bit", NULL, NULL, NULL,
 773            NULL, NULL, NULL, NULL,
 774        },
 775        .cpuid = { .eax = KVM_CPUID_FEATURES, .reg = R_EAX, },
 776        .tcg_features = TCG_KVM_FEATURES,
 777    },
 778    [FEAT_KVM_HINTS] = {
 779        .type = CPUID_FEATURE_WORD,
 780        .feat_names = {
 781            "kvm-hint-dedicated", NULL, NULL, NULL,
 782            NULL, NULL, NULL, NULL,
 783            NULL, NULL, NULL, NULL,
 784            NULL, NULL, NULL, NULL,
 785            NULL, NULL, NULL, NULL,
 786            NULL, NULL, NULL, NULL,
 787            NULL, NULL, NULL, NULL,
 788            NULL, NULL, NULL, NULL,
 789        },
 790        .cpuid = { .eax = KVM_CPUID_FEATURES, .reg = R_EDX, },
 791        .tcg_features = TCG_KVM_FEATURES,
 792        /*
 793         * KVM hints aren't auto-enabled by -cpu host, they need to be
 794         * explicitly enabled in the command-line.
 795         */
 796        .no_autoenable_flags = ~0U,
 797    },
 798    [FEAT_SVM] = {
 799        .type = CPUID_FEATURE_WORD,
 800        .feat_names = {
 801            "npt", "lbrv", "svm-lock", "nrip-save",
 802            "tsc-scale", "vmcb-clean",  "flushbyasid", "decodeassists",
 803            NULL, NULL, "pause-filter", NULL,
 804            "pfthreshold", "avic", NULL, "v-vmsave-vmload",
 805            "vgif", NULL, NULL, NULL,
 806            NULL, NULL, NULL, NULL,
 807            NULL, NULL, NULL, NULL,
 808            "svme-addr-chk", NULL, NULL, NULL,
 809        },
 810        .cpuid = { .eax = 0x8000000A, .reg = R_EDX, },
 811        .tcg_features = TCG_SVM_FEATURES,
 812    },
 813    [FEAT_7_0_EBX] = {
 814        .type = CPUID_FEATURE_WORD,
 815        .feat_names = {
 816            "fsgsbase", "tsc-adjust", "sgx", "bmi1",
 817            "hle", "avx2", NULL, "smep",
 818            "bmi2", "erms", "invpcid", "rtm",
 819            NULL, NULL, "mpx", NULL,
 820            "avx512f", "avx512dq", "rdseed", "adx",
 821            "smap", "avx512ifma", "pcommit", "clflushopt",
 822            "clwb", "intel-pt", "avx512pf", "avx512er",
 823            "avx512cd", "sha-ni", "avx512bw", "avx512vl",
 824        },
 825        .cpuid = {
 826            .eax = 7,
 827            .needs_ecx = true, .ecx = 0,
 828            .reg = R_EBX,
 829        },
 830        .tcg_features = TCG_7_0_EBX_FEATURES,
 831    },
 832    [FEAT_7_0_ECX] = {
 833        .type = CPUID_FEATURE_WORD,
 834        .feat_names = {
 835            NULL, "avx512vbmi", "umip", "pku",
 836            NULL /* ospke */, "waitpkg", "avx512vbmi2", NULL,
 837            "gfni", "vaes", "vpclmulqdq", "avx512vnni",
 838            "avx512bitalg", NULL, "avx512-vpopcntdq", NULL,
 839            "la57", NULL, NULL, NULL,
 840            NULL, NULL, "rdpid", NULL,
 841            "bus-lock-detect", "cldemote", NULL, "movdiri",
 842            "movdir64b", NULL, "sgxlc", "pks",
 843        },
 844        .cpuid = {
 845            .eax = 7,
 846            .needs_ecx = true, .ecx = 0,
 847            .reg = R_ECX,
 848        },
 849        .tcg_features = TCG_7_0_ECX_FEATURES,
 850    },
 851    [FEAT_7_0_EDX] = {
 852        .type = CPUID_FEATURE_WORD,
 853        .feat_names = {
 854            NULL, NULL, "avx512-4vnniw", "avx512-4fmaps",
 855            "fsrm", NULL, NULL, NULL,
 856            "avx512-vp2intersect", NULL, "md-clear", NULL,
 857            NULL, NULL, "serialize", NULL,
 858            "tsx-ldtrk", NULL, NULL /* pconfig */, NULL,
 859            NULL, NULL, "amx-bf16", "avx512-fp16",
 860            "amx-tile", "amx-int8", "spec-ctrl", "stibp",
 861            NULL, "arch-capabilities", "core-capability", "ssbd",
 862        },
 863        .cpuid = {
 864            .eax = 7,
 865            .needs_ecx = true, .ecx = 0,
 866            .reg = R_EDX,
 867        },
 868        .tcg_features = TCG_7_0_EDX_FEATURES,
 869    },
 870    [FEAT_7_1_EAX] = {
 871        .type = CPUID_FEATURE_WORD,
 872        .feat_names = {
 873            NULL, NULL, NULL, NULL,
 874            "avx-vnni", "avx512-bf16", NULL, NULL,
 875            NULL, NULL, NULL, NULL,
 876            NULL, NULL, NULL, NULL,
 877            NULL, NULL, NULL, NULL,
 878            NULL, NULL, NULL, NULL,
 879            NULL, NULL, NULL, NULL,
 880            NULL, NULL, NULL, NULL,
 881        },
 882        .cpuid = {
 883            .eax = 7,
 884            .needs_ecx = true, .ecx = 1,
 885            .reg = R_EAX,
 886        },
 887        .tcg_features = TCG_7_1_EAX_FEATURES,
 888    },
 889    [FEAT_8000_0007_EDX] = {
 890        .type = CPUID_FEATURE_WORD,
 891        .feat_names = {
 892            NULL, NULL, NULL, NULL,
 893            NULL, NULL, NULL, NULL,
 894            "invtsc", NULL, NULL, NULL,
 895            NULL, NULL, NULL, NULL,
 896            NULL, NULL, NULL, NULL,
 897            NULL, NULL, NULL, NULL,
 898            NULL, NULL, NULL, NULL,
 899            NULL, NULL, NULL, NULL,
 900        },
 901        .cpuid = { .eax = 0x80000007, .reg = R_EDX, },
 902        .tcg_features = TCG_APM_FEATURES,
 903        .unmigratable_flags = CPUID_APM_INVTSC,
 904    },
 905    [FEAT_8000_0008_EBX] = {
 906        .type = CPUID_FEATURE_WORD,
 907        .feat_names = {
 908            "clzero", NULL, "xsaveerptr", NULL,
 909            NULL, NULL, NULL, NULL,
 910            NULL, "wbnoinvd", NULL, NULL,
 911            "ibpb", NULL, "ibrs", "amd-stibp",
 912            NULL, NULL, NULL, NULL,
 913            NULL, NULL, NULL, NULL,
 914            "amd-ssbd", "virt-ssbd", "amd-no-ssb", NULL,
 915            NULL, NULL, NULL, NULL,
 916        },
 917        .cpuid = { .eax = 0x80000008, .reg = R_EBX, },
 918        .tcg_features = 0,
 919        .unmigratable_flags = 0,
 920    },
 921    [FEAT_XSAVE] = {
 922        .type = CPUID_FEATURE_WORD,
 923        .feat_names = {
 924            "xsaveopt", "xsavec", "xgetbv1", "xsaves",
 925            "xfd", NULL, NULL, NULL,
 926            NULL, NULL, NULL, NULL,
 927            NULL, NULL, NULL, NULL,
 928            NULL, NULL, NULL, NULL,
 929            NULL, NULL, NULL, NULL,
 930            NULL, NULL, NULL, NULL,
 931            NULL, NULL, NULL, NULL,
 932        },
 933        .cpuid = {
 934            .eax = 0xd,
 935            .needs_ecx = true, .ecx = 1,
 936            .reg = R_EAX,
 937        },
 938        .tcg_features = TCG_XSAVE_FEATURES,
 939    },
 940    [FEAT_6_EAX] = {
 941        .type = CPUID_FEATURE_WORD,
 942        .feat_names = {
 943            NULL, NULL, "arat", NULL,
 944            NULL, NULL, NULL, NULL,
 945            NULL, NULL, NULL, NULL,
 946            NULL, NULL, NULL, NULL,
 947            NULL, NULL, NULL, NULL,
 948            NULL, NULL, NULL, NULL,
 949            NULL, NULL, NULL, NULL,
 950            NULL, NULL, NULL, NULL,
 951        },
 952        .cpuid = { .eax = 6, .reg = R_EAX, },
 953        .tcg_features = TCG_6_EAX_FEATURES,
 954    },
 955    [FEAT_XSAVE_COMP_LO] = {
 956        .type = CPUID_FEATURE_WORD,
 957        .cpuid = {
 958            .eax = 0xD,
 959            .needs_ecx = true, .ecx = 0,
 960            .reg = R_EAX,
 961        },
 962        .tcg_features = ~0U,
 963        .migratable_flags = XSTATE_FP_MASK | XSTATE_SSE_MASK |
 964            XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK |
 965            XSTATE_OPMASK_MASK | XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_MASK |
 966            XSTATE_PKRU_MASK,
 967    },
 968    [FEAT_XSAVE_COMP_HI] = {
 969        .type = CPUID_FEATURE_WORD,
 970        .cpuid = {
 971            .eax = 0xD,
 972            .needs_ecx = true, .ecx = 0,
 973            .reg = R_EDX,
 974        },
 975        .tcg_features = ~0U,
 976    },
 977    /*Below are MSR exposed features*/
 978    [FEAT_ARCH_CAPABILITIES] = {
 979        .type = MSR_FEATURE_WORD,
 980        .feat_names = {
 981            "rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry",
 982            "ssb-no", "mds-no", "pschange-mc-no", "tsx-ctrl",
 983            "taa-no", NULL, NULL, NULL,
 984            NULL, NULL, NULL, NULL,
 985            NULL, NULL, NULL, NULL,
 986            NULL, NULL, NULL, NULL,
 987            NULL, NULL, NULL, NULL,
 988            NULL, NULL, NULL, NULL,
 989        },
 990        .msr = {
 991            .index = MSR_IA32_ARCH_CAPABILITIES,
 992        },
 993    },
 994    [FEAT_CORE_CAPABILITY] = {
 995        .type = MSR_FEATURE_WORD,
 996        .feat_names = {
 997            NULL, NULL, NULL, NULL,
 998            NULL, "split-lock-detect", NULL, NULL,
 999            NULL, NULL, NULL, NULL,
1000            NULL, NULL, NULL, NULL,
1001            NULL, NULL, NULL, NULL,
1002            NULL, NULL, NULL, NULL,
1003            NULL, NULL, NULL, NULL,
1004            NULL, NULL, NULL, NULL,
1005        },
1006        .msr = {
1007            .index = MSR_IA32_CORE_CAPABILITY,
1008        },
1009    },
1010    [FEAT_PERF_CAPABILITIES] = {
1011        .type = MSR_FEATURE_WORD,
1012        .feat_names = {
1013            NULL, NULL, NULL, NULL,
1014            NULL, NULL, NULL, NULL,
1015            NULL, NULL, NULL, NULL,
1016            NULL, "full-width-write", NULL, NULL,
1017            NULL, NULL, NULL, NULL,
1018            NULL, NULL, NULL, NULL,
1019            NULL, NULL, NULL, NULL,
1020            NULL, NULL, NULL, NULL,
1021        },
1022        .msr = {
1023            .index = MSR_IA32_PERF_CAPABILITIES,
1024        },
1025    },
1026
1027    [FEAT_VMX_PROCBASED_CTLS] = {
1028        .type = MSR_FEATURE_WORD,
1029        .feat_names = {
1030            NULL, NULL, "vmx-vintr-pending", "vmx-tsc-offset",
1031            NULL, NULL, NULL, "vmx-hlt-exit",
1032            NULL, "vmx-invlpg-exit", "vmx-mwait-exit", "vmx-rdpmc-exit",
1033            "vmx-rdtsc-exit", NULL, NULL, "vmx-cr3-load-noexit",
1034            "vmx-cr3-store-noexit", NULL, NULL, "vmx-cr8-load-exit",
1035            "vmx-cr8-store-exit", "vmx-flexpriority", "vmx-vnmi-pending", "vmx-movdr-exit",
1036            "vmx-io-exit", "vmx-io-bitmap", NULL, "vmx-mtf",
1037            "vmx-msr-bitmap", "vmx-monitor-exit", "vmx-pause-exit", "vmx-secondary-ctls",
1038        },
1039        .msr = {
1040            .index = MSR_IA32_VMX_TRUE_PROCBASED_CTLS,
1041        }
1042    },
1043
1044    [FEAT_VMX_SECONDARY_CTLS] = {
1045        .type = MSR_FEATURE_WORD,
1046        .feat_names = {
1047            "vmx-apicv-xapic", "vmx-ept", "vmx-desc-exit", "vmx-rdtscp-exit",
1048            "vmx-apicv-x2apic", "vmx-vpid", "vmx-wbinvd-exit", "vmx-unrestricted-guest",
1049            "vmx-apicv-register", "vmx-apicv-vid", "vmx-ple", "vmx-rdrand-exit",
1050            "vmx-invpcid-exit", "vmx-vmfunc", "vmx-shadow-vmcs", "vmx-encls-exit",
1051            "vmx-rdseed-exit", "vmx-pml", NULL, NULL,
1052            "vmx-xsaves", NULL, NULL, NULL,
1053            NULL, "vmx-tsc-scaling", NULL, NULL,
1054            NULL, NULL, NULL, NULL,
1055        },
1056        .msr = {
1057            .index = MSR_IA32_VMX_PROCBASED_CTLS2,
1058        }
1059    },
1060
1061    [FEAT_VMX_PINBASED_CTLS] = {
1062        .type = MSR_FEATURE_WORD,
1063        .feat_names = {
1064            "vmx-intr-exit", NULL, NULL, "vmx-nmi-exit",
1065            NULL, "vmx-vnmi", "vmx-preemption-timer", "vmx-posted-intr",
1066            NULL, NULL, NULL, NULL,
1067            NULL, NULL, NULL, NULL,
1068            NULL, NULL, NULL, NULL,
1069            NULL, NULL, NULL, NULL,
1070            NULL, NULL, NULL, NULL,
1071            NULL, NULL, NULL, NULL,
1072        },
1073        .msr = {
1074            .index = MSR_IA32_VMX_TRUE_PINBASED_CTLS,
1075        }
1076    },
1077
1078    [FEAT_VMX_EXIT_CTLS] = {
1079        .type = MSR_FEATURE_WORD,
1080        /*
1081         * VMX_VM_EXIT_HOST_ADDR_SPACE_SIZE is copied from
1082         * the LM CPUID bit.
1083         */
1084        .feat_names = {
1085            NULL, NULL, "vmx-exit-nosave-debugctl", NULL,
1086            NULL, NULL, NULL, NULL,
1087            NULL, NULL /* vmx-exit-host-addr-space-size */, NULL, NULL,
1088            "vmx-exit-load-perf-global-ctrl", NULL, NULL, "vmx-exit-ack-intr",
1089            NULL, NULL, "vmx-exit-save-pat", "vmx-exit-load-pat",
1090            "vmx-exit-save-efer", "vmx-exit-load-efer",
1091                "vmx-exit-save-preemption-timer", "vmx-exit-clear-bndcfgs",
1092            NULL, "vmx-exit-clear-rtit-ctl", NULL, NULL,
1093            NULL, "vmx-exit-load-pkrs", NULL, NULL,
1094        },
1095        .msr = {
1096            .index = MSR_IA32_VMX_TRUE_EXIT_CTLS,
1097        }
1098    },
1099
1100    [FEAT_VMX_ENTRY_CTLS] = {
1101        .type = MSR_FEATURE_WORD,
1102        .feat_names = {
1103            NULL, NULL, "vmx-entry-noload-debugctl", NULL,
1104            NULL, NULL, NULL, NULL,
1105            NULL, "vmx-entry-ia32e-mode", NULL, NULL,
1106            NULL, "vmx-entry-load-perf-global-ctrl", "vmx-entry-load-pat", "vmx-entry-load-efer",
1107            "vmx-entry-load-bndcfgs", NULL, "vmx-entry-load-rtit-ctl", NULL,
1108            NULL, NULL, "vmx-entry-load-pkrs", NULL,
1109            NULL, NULL, NULL, NULL,
1110            NULL, NULL, NULL, NULL,
1111        },
1112        .msr = {
1113            .index = MSR_IA32_VMX_TRUE_ENTRY_CTLS,
1114        }
1115    },
1116
1117    [FEAT_VMX_MISC] = {
1118        .type = MSR_FEATURE_WORD,
1119        .feat_names = {
1120            NULL, NULL, NULL, NULL,
1121            NULL, "vmx-store-lma", "vmx-activity-hlt", "vmx-activity-shutdown",
1122            "vmx-activity-wait-sipi", NULL, NULL, NULL,
1123            NULL, NULL, NULL, NULL,
1124            NULL, NULL, NULL, NULL,
1125            NULL, NULL, NULL, NULL,
1126            NULL, NULL, NULL, NULL,
1127            NULL, "vmx-vmwrite-vmexit-fields", "vmx-zero-len-inject", NULL,
1128        },
1129        .msr = {
1130            .index = MSR_IA32_VMX_MISC,
1131        }
1132    },
1133
1134    [FEAT_VMX_EPT_VPID_CAPS] = {
1135        .type = MSR_FEATURE_WORD,
1136        .feat_names = {
1137            "vmx-ept-execonly", NULL, NULL, NULL,
1138            NULL, NULL, "vmx-page-walk-4", "vmx-page-walk-5",
1139            NULL, NULL, NULL, NULL,
1140            NULL, NULL, NULL, NULL,
1141            "vmx-ept-2mb", "vmx-ept-1gb", NULL, NULL,
1142            "vmx-invept", "vmx-eptad", "vmx-ept-advanced-exitinfo", NULL,
1143            NULL, "vmx-invept-single-context", "vmx-invept-all-context", NULL,
1144            NULL, NULL, NULL, NULL,
1145            "vmx-invvpid", NULL, NULL, NULL,
1146            NULL, NULL, NULL, NULL,
1147            "vmx-invvpid-single-addr", "vmx-invept-single-context",
1148                "vmx-invvpid-all-context", "vmx-invept-single-context-noglobals",
1149            NULL, NULL, NULL, NULL,
1150            NULL, NULL, NULL, NULL,
1151            NULL, NULL, NULL, NULL,
1152            NULL, NULL, NULL, NULL,
1153            NULL, NULL, NULL, NULL,
1154        },
1155        .msr = {
1156            .index = MSR_IA32_VMX_EPT_VPID_CAP,
1157        }
1158    },
1159
1160    [FEAT_VMX_BASIC] = {
1161        .type = MSR_FEATURE_WORD,
1162        .feat_names = {
1163            [54] = "vmx-ins-outs",
1164            [55] = "vmx-true-ctls",
1165        },
1166        .msr = {
1167            .index = MSR_IA32_VMX_BASIC,
1168        },
1169        /* Just to be safe - we don't support setting the MSEG version field.  */
1170        .no_autoenable_flags = MSR_VMX_BASIC_DUAL_MONITOR,
1171    },
1172
1173    [FEAT_VMX_VMFUNC] = {
1174        .type = MSR_FEATURE_WORD,
1175        .feat_names = {
1176            [0] = "vmx-eptp-switching",
1177        },
1178        .msr = {
1179            .index = MSR_IA32_VMX_VMFUNC,
1180        }
1181    },
1182
1183    [FEAT_14_0_ECX] = {
1184        .type = CPUID_FEATURE_WORD,
1185        .feat_names = {
1186            NULL, NULL, NULL, NULL,
1187            NULL, NULL, NULL, NULL,
1188            NULL, NULL, NULL, NULL,
1189            NULL, NULL, NULL, NULL,
1190            NULL, NULL, NULL, NULL,
1191            NULL, NULL, NULL, NULL,
1192            NULL, NULL, NULL, NULL,
1193            NULL, NULL, NULL, "intel-pt-lip",
1194        },
1195        .cpuid = {
1196            .eax = 0x14,
1197            .needs_ecx = true, .ecx = 0,
1198            .reg = R_ECX,
1199        },
1200        .tcg_features = TCG_14_0_ECX_FEATURES,
1201     },
1202
1203    [FEAT_SGX_12_0_EAX] = {
1204        .type = CPUID_FEATURE_WORD,
1205        .feat_names = {
1206            "sgx1", "sgx2", NULL, NULL,
1207            NULL, NULL, NULL, NULL,
1208            NULL, NULL, NULL, NULL,
1209            NULL, NULL, NULL, NULL,
1210            NULL, NULL, NULL, NULL,
1211            NULL, NULL, NULL, NULL,
1212            NULL, NULL, NULL, NULL,
1213            NULL, NULL, NULL, NULL,
1214        },
1215        .cpuid = {
1216            .eax = 0x12,
1217            .needs_ecx = true, .ecx = 0,
1218            .reg = R_EAX,
1219        },
1220        .tcg_features = TCG_SGX_12_0_EAX_FEATURES,
1221    },
1222
1223    [FEAT_SGX_12_0_EBX] = {
1224        .type = CPUID_FEATURE_WORD,
1225        .feat_names = {
1226            "sgx-exinfo" , NULL, NULL, NULL,
1227            NULL, NULL, NULL, NULL,
1228            NULL, NULL, NULL, NULL,
1229            NULL, NULL, NULL, NULL,
1230            NULL, NULL, NULL, NULL,
1231            NULL, NULL, NULL, NULL,
1232            NULL, NULL, NULL, NULL,
1233            NULL, NULL, NULL, NULL,
1234        },
1235        .cpuid = {
1236            .eax = 0x12,
1237            .needs_ecx = true, .ecx = 0,
1238            .reg = R_EBX,
1239        },
1240        .tcg_features = TCG_SGX_12_0_EBX_FEATURES,
1241    },
1242
1243    [FEAT_SGX_12_1_EAX] = {
1244        .type = CPUID_FEATURE_WORD,
1245        .feat_names = {
1246            NULL, "sgx-debug", "sgx-mode64", NULL,
1247            "sgx-provisionkey", "sgx-tokenkey", NULL, "sgx-kss",
1248            NULL, NULL, NULL, NULL,
1249            NULL, NULL, NULL, NULL,
1250            NULL, NULL, NULL, NULL,
1251            NULL, NULL, NULL, NULL,
1252            NULL, NULL, NULL, NULL,
1253            NULL, NULL, NULL, NULL,
1254        },
1255        .cpuid = {
1256            .eax = 0x12,
1257            .needs_ecx = true, .ecx = 1,
1258            .reg = R_EAX,
1259        },
1260        .tcg_features = TCG_SGX_12_1_EAX_FEATURES,
1261    },
1262};
1263
1264typedef struct FeatureMask {
1265    FeatureWord index;
1266    uint64_t mask;
1267} FeatureMask;
1268
1269typedef struct FeatureDep {
1270    FeatureMask from, to;
1271} FeatureDep;
1272
1273static FeatureDep feature_dependencies[] = {
1274    {
1275        .from = { FEAT_7_0_EDX,             CPUID_7_0_EDX_ARCH_CAPABILITIES },
1276        .to = { FEAT_ARCH_CAPABILITIES,     ~0ull },
1277    },
1278    {
1279        .from = { FEAT_7_0_EDX,             CPUID_7_0_EDX_CORE_CAPABILITY },
1280        .to = { FEAT_CORE_CAPABILITY,       ~0ull },
1281    },
1282    {
1283        .from = { FEAT_1_ECX,             CPUID_EXT_PDCM },
1284        .to = { FEAT_PERF_CAPABILITIES,       ~0ull },
1285    },
1286    {
1287        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
1288        .to = { FEAT_VMX_PROCBASED_CTLS,    ~0ull },
1289    },
1290    {
1291        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
1292        .to = { FEAT_VMX_PINBASED_CTLS,     ~0ull },
1293    },
1294    {
1295        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
1296        .to = { FEAT_VMX_EXIT_CTLS,         ~0ull },
1297    },
1298    {
1299        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
1300        .to = { FEAT_VMX_ENTRY_CTLS,        ~0ull },
1301    },
1302    {
1303        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
1304        .to = { FEAT_VMX_MISC,              ~0ull },
1305    },
1306    {
1307        .from = { FEAT_1_ECX,               CPUID_EXT_VMX },
1308        .to = { FEAT_VMX_BASIC,             ~0ull },
1309    },
1310    {
1311        .from = { FEAT_8000_0001_EDX,       CPUID_EXT2_LM },
1312        .to = { FEAT_VMX_ENTRY_CTLS,        VMX_VM_ENTRY_IA32E_MODE },
1313    },
1314    {
1315        .from = { FEAT_VMX_PROCBASED_CTLS,  VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS },
1316        .to = { FEAT_VMX_SECONDARY_CTLS,    ~0ull },
1317    },
1318    {
1319        .from = { FEAT_XSAVE,               CPUID_XSAVE_XSAVES },
1320        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_XSAVES },
1321    },
1322    {
1323        .from = { FEAT_1_ECX,               CPUID_EXT_RDRAND },
1324        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_RDRAND_EXITING },
1325    },
1326    {
1327        .from = { FEAT_7_0_EBX,             CPUID_7_0_EBX_INVPCID },
1328        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_ENABLE_INVPCID },
1329    },
1330    {
1331        .from = { FEAT_7_0_EBX,             CPUID_7_0_EBX_RDSEED },
1332        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_RDSEED_EXITING },
1333    },
1334    {
1335        .from = { FEAT_7_0_EBX,             CPUID_7_0_EBX_INTEL_PT },
1336        .to = { FEAT_14_0_ECX,              ~0ull },
1337    },
1338    {
1339        .from = { FEAT_8000_0001_EDX,       CPUID_EXT2_RDTSCP },
1340        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_RDTSCP },
1341    },
1342    {
1343        .from = { FEAT_VMX_SECONDARY_CTLS,  VMX_SECONDARY_EXEC_ENABLE_EPT },
1344        .to = { FEAT_VMX_EPT_VPID_CAPS,     0xffffffffull },
1345    },
1346    {
1347        .from = { FEAT_VMX_SECONDARY_CTLS,  VMX_SECONDARY_EXEC_ENABLE_EPT },
1348        .to = { FEAT_VMX_SECONDARY_CTLS,    VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST },
1349    },
1350    {
1351        .from = { FEAT_VMX_SECONDARY_CTLS,  VMX_SECONDARY_EXEC_ENABLE_VPID },
1352        .to = { FEAT_VMX_EPT_VPID_CAPS,     0xffffffffull << 32 },
1353    },
1354    {
1355        .from = { FEAT_VMX_SECONDARY_CTLS,  VMX_SECONDARY_EXEC_ENABLE_VMFUNC },
1356        .to = { FEAT_VMX_VMFUNC,            ~0ull },
1357    },
1358    {
1359        .from = { FEAT_8000_0001_ECX,       CPUID_EXT3_SVM },
1360        .to = { FEAT_SVM,                   ~0ull },
1361    },
1362};
1363
1364typedef struct X86RegisterInfo32 {
1365    /* Name of register */
1366    const char *name;
1367    /* QAPI enum value register */
1368    X86CPURegister32 qapi_enum;
1369} X86RegisterInfo32;
1370
1371#define REGISTER(reg) \
1372    [R_##reg] = { .name = #reg, .qapi_enum = X86_CPU_REGISTER32_##reg }
1373static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
1374    REGISTER(EAX),
1375    REGISTER(ECX),
1376    REGISTER(EDX),
1377    REGISTER(EBX),
1378    REGISTER(ESP),
1379    REGISTER(EBP),
1380    REGISTER(ESI),
1381    REGISTER(EDI),
1382};
1383#undef REGISTER
1384
1385ExtSaveArea x86_ext_save_areas[XSAVE_STATE_AREA_COUNT] = {
1386    [XSTATE_FP_BIT] = {
1387        /* x87 FP state component is always enabled if XSAVE is supported */
1388        .feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
1389        .size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
1390    },
1391    [XSTATE_SSE_BIT] = {
1392        /* SSE state component is always enabled if XSAVE is supported */
1393        .feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
1394        .size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
1395    },
1396    [XSTATE_YMM_BIT] =
1397          { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
1398            .size = sizeof(XSaveAVX) },
1399    [XSTATE_BNDREGS_BIT] =
1400          { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
1401            .size = sizeof(XSaveBNDREG)  },
1402    [XSTATE_BNDCSR_BIT] =
1403          { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
1404            .size = sizeof(XSaveBNDCSR)  },
1405    [XSTATE_OPMASK_BIT] =
1406          { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
1407            .size = sizeof(XSaveOpmask) },
1408    [XSTATE_ZMM_Hi256_BIT] =
1409          { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
1410            .size = sizeof(XSaveZMM_Hi256) },
1411    [XSTATE_Hi16_ZMM_BIT] =
1412          { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
1413            .size = sizeof(XSaveHi16_ZMM) },
1414    [XSTATE_PKRU_BIT] =
1415          { .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU,
1416            .size = sizeof(XSavePKRU) },
1417    [XSTATE_XTILE_CFG_BIT] = {
1418        .feature = FEAT_7_0_EDX, .bits = CPUID_7_0_EDX_AMX_TILE,
1419        .size = sizeof(XSaveXTILECFG),
1420    },
1421    [XSTATE_XTILE_DATA_BIT] = {
1422        .feature = FEAT_7_0_EDX, .bits = CPUID_7_0_EDX_AMX_TILE,
1423        .size = sizeof(XSaveXTILEDATA)
1424    },
1425};
1426
1427static uint32_t xsave_area_size(uint64_t mask)
1428{
1429    int i;
1430    uint64_t ret = 0;
1431
1432    for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
1433        const ExtSaveArea *esa = &x86_ext_save_areas[i];
1434        if ((mask >> i) & 1) {
1435            ret = MAX(ret, esa->offset + esa->size);
1436        }
1437    }
1438    return ret;
1439}
1440
1441static inline bool accel_uses_host_cpuid(void)
1442{
1443    return kvm_enabled() || hvf_enabled();
1444}
1445
1446static inline uint64_t x86_cpu_xsave_components(X86CPU *cpu)
1447{
1448    return ((uint64_t)cpu->env.features[FEAT_XSAVE_COMP_HI]) << 32 |
1449           cpu->env.features[FEAT_XSAVE_COMP_LO];
1450}
1451
1452/* Return name of 32-bit register, from a R_* constant */
1453static const char *get_register_name_32(unsigned int reg)
1454{
1455    if (reg >= CPU_NB_REGS32) {
1456        return NULL;
1457    }
1458    return x86_reg_info_32[reg].name;
1459}
1460
1461/*
1462 * Returns the set of feature flags that are supported and migratable by
1463 * QEMU, for a given FeatureWord.
1464 */
1465static uint64_t x86_cpu_get_migratable_flags(FeatureWord w)
1466{
1467    FeatureWordInfo *wi = &feature_word_info[w];
1468    uint64_t r = 0;
1469    int i;
1470
1471    for (i = 0; i < 64; i++) {
1472        uint64_t f = 1ULL << i;
1473
1474        /* If the feature name is known, it is implicitly considered migratable,
1475         * unless it is explicitly set in unmigratable_flags */
1476        if ((wi->migratable_flags & f) ||
1477            (wi->feat_names[i] && !(wi->unmigratable_flags & f))) {
1478            r |= f;
1479        }
1480    }
1481    return r;
1482}
1483
1484void host_cpuid(uint32_t function, uint32_t count,
1485                uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
1486{
1487    uint32_t vec[4];
1488
1489#ifdef __x86_64__
1490    asm volatile("cpuid"
1491                 : "=a"(vec[0]), "=b"(vec[1]),
1492                   "=c"(vec[2]), "=d"(vec[3])
1493                 : "0"(function), "c"(count) : "cc");
1494#elif defined(__i386__)
1495    asm volatile("pusha \n\t"
1496                 "cpuid \n\t"
1497                 "mov %%eax, 0(%2) \n\t"
1498                 "mov %%ebx, 4(%2) \n\t"
1499                 "mov %%ecx, 8(%2) \n\t"
1500                 "mov %%edx, 12(%2) \n\t"
1501                 "popa"
1502                 : : "a"(function), "c"(count), "S"(vec)
1503                 : "memory", "cc");
1504#else
1505    abort();
1506#endif
1507
1508    if (eax)
1509        *eax = vec[0];
1510    if (ebx)
1511        *ebx = vec[1];
1512    if (ecx)
1513        *ecx = vec[2];
1514    if (edx)
1515        *edx = vec[3];
1516}
1517
1518/* CPU class name definitions: */
1519
1520/* Return type name for a given CPU model name
1521 * Caller is responsible for freeing the returned string.
1522 */
1523static char *x86_cpu_type_name(const char *model_name)
1524{
1525    return g_strdup_printf(X86_CPU_TYPE_NAME("%s"), model_name);
1526}
1527
1528static ObjectClass *x86_cpu_class_by_name(const char *cpu_model)
1529{
1530    g_autofree char *typename = x86_cpu_type_name(cpu_model);
1531    return object_class_by_name(typename);
1532}
1533
1534static char *x86_cpu_class_get_model_name(X86CPUClass *cc)
1535{
1536    const char *class_name = object_class_get_name(OBJECT_CLASS(cc));
1537    assert(g_str_has_suffix(class_name, X86_CPU_TYPE_SUFFIX));
1538    return g_strndup(class_name,
1539                     strlen(class_name) - strlen(X86_CPU_TYPE_SUFFIX));
1540}
1541
1542typedef struct X86CPUVersionDefinition {
1543    X86CPUVersion version;
1544    const char *alias;
1545    const char *note;
1546    PropValue *props;
1547} X86CPUVersionDefinition;
1548
1549/* Base definition for a CPU model */
1550typedef struct X86CPUDefinition {
1551    const char *name;
1552    uint32_t level;
1553    uint32_t xlevel;
1554    /* vendor is zero-terminated, 12 character ASCII string */
1555    char vendor[CPUID_VENDOR_SZ + 1];
1556    int family;
1557    int model;
1558    int stepping;
1559    FeatureWordArray features;
1560    const char *model_id;
1561    const CPUCaches *const cache_info;
1562    /*
1563     * Definitions for alternative versions of CPU model.
1564     * List is terminated by item with version == 0.
1565     * If NULL, version 1 will be registered automatically.
1566     */
1567    const X86CPUVersionDefinition *versions;
1568    const char *deprecation_note;
1569} X86CPUDefinition;
1570
1571/* Reference to a specific CPU model version */
1572struct X86CPUModel {
1573    /* Base CPU definition */
1574    const X86CPUDefinition *cpudef;
1575    /* CPU model version */
1576    X86CPUVersion version;
1577    const char *note;
1578    /*
1579     * If true, this is an alias CPU model.
1580     * This matters only for "-cpu help" and query-cpu-definitions
1581     */
1582    bool is_alias;
1583};
1584
1585/* Get full model name for CPU version */
1586static char *x86_cpu_versioned_model_name(const X86CPUDefinition *cpudef,
1587                                          X86CPUVersion version)
1588{
1589    assert(version > 0);
1590    return g_strdup_printf("%s-v%d", cpudef->name, (int)version);
1591}
1592
1593static const X86CPUVersionDefinition *
1594x86_cpu_def_get_versions(const X86CPUDefinition *def)
1595{
1596    /* When X86CPUDefinition::versions is NULL, we register only v1 */
1597    static const X86CPUVersionDefinition default_version_list[] = {
1598        { 1 },
1599        { /* end of list */ }
1600    };
1601
1602    return def->versions ?: default_version_list;
1603}
1604
1605static const CPUCaches epyc_cache_info = {
1606    .l1d_cache = &(CPUCacheInfo) {
1607        .type = DATA_CACHE,
1608        .level = 1,
1609        .size = 32 * KiB,
1610        .line_size = 64,
1611        .associativity = 8,
1612        .partitions = 1,
1613        .sets = 64,
1614        .lines_per_tag = 1,
1615        .self_init = 1,
1616        .no_invd_sharing = true,
1617    },
1618    .l1i_cache = &(CPUCacheInfo) {
1619        .type = INSTRUCTION_CACHE,
1620        .level = 1,
1621        .size = 64 * KiB,
1622        .line_size = 64,
1623        .associativity = 4,
1624        .partitions = 1,
1625        .sets = 256,
1626        .lines_per_tag = 1,
1627        .self_init = 1,
1628        .no_invd_sharing = true,
1629    },
1630    .l2_cache = &(CPUCacheInfo) {
1631        .type = UNIFIED_CACHE,
1632        .level = 2,
1633        .size = 512 * KiB,
1634        .line_size = 64,
1635        .associativity = 8,
1636        .partitions = 1,
1637        .sets = 1024,
1638        .lines_per_tag = 1,
1639    },
1640    .l3_cache = &(CPUCacheInfo) {
1641        .type = UNIFIED_CACHE,
1642        .level = 3,
1643        .size = 8 * MiB,
1644        .line_size = 64,
1645        .associativity = 16,
1646        .partitions = 1,
1647        .sets = 8192,
1648        .lines_per_tag = 1,
1649        .self_init = true,
1650        .inclusive = true,
1651        .complex_indexing = true,
1652    },
1653};
1654
1655static const CPUCaches epyc_rome_cache_info = {
1656    .l1d_cache = &(CPUCacheInfo) {
1657        .type = DATA_CACHE,
1658        .level = 1,
1659        .size = 32 * KiB,
1660        .line_size = 64,
1661        .associativity = 8,
1662        .partitions = 1,
1663        .sets = 64,
1664        .lines_per_tag = 1,
1665        .self_init = 1,
1666        .no_invd_sharing = true,
1667    },
1668    .l1i_cache = &(CPUCacheInfo) {
1669        .type = INSTRUCTION_CACHE,
1670        .level = 1,
1671        .size = 32 * KiB,
1672        .line_size = 64,
1673        .associativity = 8,
1674        .partitions = 1,
1675        .sets = 64,
1676        .lines_per_tag = 1,
1677        .self_init = 1,
1678        .no_invd_sharing = true,
1679    },
1680    .l2_cache = &(CPUCacheInfo) {
1681        .type = UNIFIED_CACHE,
1682        .level = 2,
1683        .size = 512 * KiB,
1684        .line_size = 64,
1685        .associativity = 8,
1686        .partitions = 1,
1687        .sets = 1024,
1688        .lines_per_tag = 1,
1689    },
1690    .l3_cache = &(CPUCacheInfo) {
1691        .type = UNIFIED_CACHE,
1692        .level = 3,
1693        .size = 16 * MiB,
1694        .line_size = 64,
1695        .associativity = 16,
1696        .partitions = 1,
1697        .sets = 16384,
1698        .lines_per_tag = 1,
1699        .self_init = true,
1700        .inclusive = true,
1701        .complex_indexing = true,
1702    },
1703};
1704
1705static const CPUCaches epyc_milan_cache_info = {
1706    .l1d_cache = &(CPUCacheInfo) {
1707        .type = DATA_CACHE,
1708        .level = 1,
1709        .size = 32 * KiB,
1710        .line_size = 64,
1711        .associativity = 8,
1712        .partitions = 1,
1713        .sets = 64,
1714        .lines_per_tag = 1,
1715        .self_init = 1,
1716        .no_invd_sharing = true,
1717    },
1718    .l1i_cache = &(CPUCacheInfo) {
1719        .type = INSTRUCTION_CACHE,
1720        .level = 1,
1721        .size = 32 * KiB,
1722        .line_size = 64,
1723        .associativity = 8,
1724        .partitions = 1,
1725        .sets = 64,
1726        .lines_per_tag = 1,
1727        .self_init = 1,
1728        .no_invd_sharing = true,
1729    },
1730    .l2_cache = &(CPUCacheInfo) {
1731        .type = UNIFIED_CACHE,
1732        .level = 2,
1733        .size = 512 * KiB,
1734        .line_size = 64,
1735        .associativity = 8,
1736        .partitions = 1,
1737        .sets = 1024,
1738        .lines_per_tag = 1,
1739    },
1740    .l3_cache = &(CPUCacheInfo) {
1741        .type = UNIFIED_CACHE,
1742        .level = 3,
1743        .size = 32 * MiB,
1744        .line_size = 64,
1745        .associativity = 16,
1746        .partitions = 1,
1747        .sets = 32768,
1748        .lines_per_tag = 1,
1749        .self_init = true,
1750        .inclusive = true,
1751        .complex_indexing = true,
1752    },
1753};
1754
1755/* The following VMX features are not supported by KVM and are left out in the
1756 * CPU definitions:
1757 *
1758 *  Dual-monitor support (all processors)
1759 *  Entry to SMM
1760 *  Deactivate dual-monitor treatment
1761 *  Number of CR3-target values
1762 *  Shutdown activity state
1763 *  Wait-for-SIPI activity state
1764 *  PAUSE-loop exiting (Westmere and newer)
1765 *  EPT-violation #VE (Broadwell and newer)
1766 *  Inject event with insn length=0 (Skylake and newer)
1767 *  Conceal non-root operation from PT
1768 *  Conceal VM exits from PT
1769 *  Conceal VM entries from PT
1770 *  Enable ENCLS exiting
1771 *  Mode-based execute control (XS/XU)
1772 s  TSC scaling (Skylake Server and newer)
1773 *  GPA translation for PT (IceLake and newer)
1774 *  User wait and pause
1775 *  ENCLV exiting
1776 *  Load IA32_RTIT_CTL
1777 *  Clear IA32_RTIT_CTL
1778 *  Advanced VM-exit information for EPT violations
1779 *  Sub-page write permissions
1780 *  PT in VMX operation
1781 */
1782
1783static const X86CPUDefinition builtin_x86_defs[] = {
1784    {
1785        .name = "qemu64",
1786        .level = 0xd,
1787        .vendor = CPUID_VENDOR_AMD,
1788        .family = 15,
1789        .model = 107,
1790        .stepping = 1,
1791        .features[FEAT_1_EDX] =
1792            PPRO_FEATURES |
1793            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
1794            CPUID_PSE36,
1795        .features[FEAT_1_ECX] =
1796            CPUID_EXT_SSE3 | CPUID_EXT_CX16,
1797        .features[FEAT_8000_0001_EDX] =
1798            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1799        .features[FEAT_8000_0001_ECX] =
1800            CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM,
1801        .xlevel = 0x8000000A,
1802        .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
1803    },
1804    {
1805        .name = "phenom",
1806        .level = 5,
1807        .vendor = CPUID_VENDOR_AMD,
1808        .family = 16,
1809        .model = 2,
1810        .stepping = 3,
1811        /* Missing: CPUID_HT */
1812        .features[FEAT_1_EDX] =
1813            PPRO_FEATURES |
1814            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
1815            CPUID_PSE36 | CPUID_VME,
1816        .features[FEAT_1_ECX] =
1817            CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
1818            CPUID_EXT_POPCNT,
1819        .features[FEAT_8000_0001_EDX] =
1820            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
1821            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
1822            CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
1823        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
1824                    CPUID_EXT3_CR8LEG,
1825                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
1826                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
1827        .features[FEAT_8000_0001_ECX] =
1828            CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
1829            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
1830        /* Missing: CPUID_SVM_LBRV */
1831        .features[FEAT_SVM] =
1832            CPUID_SVM_NPT,
1833        .xlevel = 0x8000001A,
1834        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
1835    },
1836    {
1837        .name = "core2duo",
1838        .level = 10,
1839        .vendor = CPUID_VENDOR_INTEL,
1840        .family = 6,
1841        .model = 15,
1842        .stepping = 11,
1843        /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
1844        .features[FEAT_1_EDX] =
1845            PPRO_FEATURES |
1846            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
1847            CPUID_PSE36 | CPUID_VME | CPUID_ACPI | CPUID_SS,
1848        /* Missing: CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_EST,
1849         * CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_VMX */
1850        .features[FEAT_1_ECX] =
1851            CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
1852            CPUID_EXT_CX16,
1853        .features[FEAT_8000_0001_EDX] =
1854            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1855        .features[FEAT_8000_0001_ECX] =
1856            CPUID_EXT3_LAHF_LM,
1857        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS,
1858        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE,
1859        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT,
1860        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
1861        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
1862             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS,
1863        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
1864             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
1865             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
1866             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
1867             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
1868             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
1869             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
1870             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
1871             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
1872             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
1873        .features[FEAT_VMX_SECONDARY_CTLS] =
1874             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES,
1875        .xlevel = 0x80000008,
1876        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
1877    },
1878    {
1879        .name = "kvm64",
1880        .level = 0xd,
1881        .vendor = CPUID_VENDOR_INTEL,
1882        .family = 15,
1883        .model = 6,
1884        .stepping = 1,
1885        /* Missing: CPUID_HT */
1886        .features[FEAT_1_EDX] =
1887            PPRO_FEATURES | CPUID_VME |
1888            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
1889            CPUID_PSE36,
1890        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
1891        .features[FEAT_1_ECX] =
1892            CPUID_EXT_SSE3 | CPUID_EXT_CX16,
1893        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
1894        .features[FEAT_8000_0001_EDX] =
1895            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1896        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
1897                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
1898                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
1899                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
1900        .features[FEAT_8000_0001_ECX] =
1901            0,
1902        /* VMX features from Cedar Mill/Prescott */
1903        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE,
1904        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT,
1905        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
1906        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
1907             VMX_PIN_BASED_NMI_EXITING,
1908        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
1909             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
1910             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
1911             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
1912             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
1913             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
1914             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
1915             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING,
1916        .xlevel = 0x80000008,
1917        .model_id = "Common KVM processor"
1918    },
1919    {
1920        .name = "qemu32",
1921        .level = 4,
1922        .vendor = CPUID_VENDOR_INTEL,
1923        .family = 6,
1924        .model = 6,
1925        .stepping = 3,
1926        .features[FEAT_1_EDX] =
1927            PPRO_FEATURES,
1928        .features[FEAT_1_ECX] =
1929            CPUID_EXT_SSE3,
1930        .xlevel = 0x80000004,
1931        .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
1932    },
1933    {
1934        .name = "kvm32",
1935        .level = 5,
1936        .vendor = CPUID_VENDOR_INTEL,
1937        .family = 15,
1938        .model = 6,
1939        .stepping = 1,
1940        .features[FEAT_1_EDX] =
1941            PPRO_FEATURES | CPUID_VME |
1942            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
1943        .features[FEAT_1_ECX] =
1944            CPUID_EXT_SSE3,
1945        .features[FEAT_8000_0001_ECX] =
1946            0,
1947        /* VMX features from Yonah */
1948        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE,
1949        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT,
1950        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
1951        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
1952             VMX_PIN_BASED_NMI_EXITING,
1953        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
1954             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
1955             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
1956             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
1957             VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING |
1958             VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING |
1959             VMX_CPU_BASED_PAUSE_EXITING | VMX_CPU_BASED_USE_MSR_BITMAPS,
1960        .xlevel = 0x80000008,
1961        .model_id = "Common 32-bit KVM processor"
1962    },
1963    {
1964        .name = "coreduo",
1965        .level = 10,
1966        .vendor = CPUID_VENDOR_INTEL,
1967        .family = 6,
1968        .model = 14,
1969        .stepping = 8,
1970        /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
1971        .features[FEAT_1_EDX] =
1972            PPRO_FEATURES | CPUID_VME |
1973            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_ACPI |
1974            CPUID_SS,
1975        /* Missing: CPUID_EXT_EST, CPUID_EXT_TM2 , CPUID_EXT_XTPR,
1976         * CPUID_EXT_PDCM, CPUID_EXT_VMX */
1977        .features[FEAT_1_ECX] =
1978            CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
1979        .features[FEAT_8000_0001_EDX] =
1980            CPUID_EXT2_NX,
1981        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE,
1982        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT,
1983        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
1984        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
1985             VMX_PIN_BASED_NMI_EXITING,
1986        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
1987             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
1988             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
1989             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
1990             VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING |
1991             VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING |
1992             VMX_CPU_BASED_PAUSE_EXITING | VMX_CPU_BASED_USE_MSR_BITMAPS,
1993        .xlevel = 0x80000008,
1994        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
1995    },
1996    {
1997        .name = "486",
1998        .level = 1,
1999        .vendor = CPUID_VENDOR_INTEL,
2000        .family = 4,
2001        .model = 8,
2002        .stepping = 0,
2003        .features[FEAT_1_EDX] =
2004            I486_FEATURES,
2005        .xlevel = 0,
2006        .model_id = "",
2007    },
2008    {
2009        .name = "pentium",
2010        .level = 1,
2011        .vendor = CPUID_VENDOR_INTEL,
2012        .family = 5,
2013        .model = 4,
2014        .stepping = 3,
2015        .features[FEAT_1_EDX] =
2016            PENTIUM_FEATURES,
2017        .xlevel = 0,
2018        .model_id = "",
2019    },
2020    {
2021        .name = "pentium2",
2022        .level = 2,
2023        .vendor = CPUID_VENDOR_INTEL,
2024        .family = 6,
2025        .model = 5,
2026        .stepping = 2,
2027        .features[FEAT_1_EDX] =
2028            PENTIUM2_FEATURES,
2029        .xlevel = 0,
2030        .model_id = "",
2031    },
2032    {
2033        .name = "pentium3",
2034        .level = 3,
2035        .vendor = CPUID_VENDOR_INTEL,
2036        .family = 6,
2037        .model = 7,
2038        .stepping = 3,
2039        .features[FEAT_1_EDX] =
2040            PENTIUM3_FEATURES,
2041        .xlevel = 0,
2042        .model_id = "",
2043    },
2044    {
2045        .name = "athlon",
2046        .level = 2,
2047        .vendor = CPUID_VENDOR_AMD,
2048        .family = 6,
2049        .model = 2,
2050        .stepping = 3,
2051        .features[FEAT_1_EDX] =
2052            PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
2053            CPUID_MCA,
2054        .features[FEAT_8000_0001_EDX] =
2055            CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
2056        .xlevel = 0x80000008,
2057        .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
2058    },
2059    {
2060        .name = "n270",
2061        .level = 10,
2062        .vendor = CPUID_VENDOR_INTEL,
2063        .family = 6,
2064        .model = 28,
2065        .stepping = 2,
2066        /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
2067        .features[FEAT_1_EDX] =
2068            PPRO_FEATURES |
2069            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME |
2070            CPUID_ACPI | CPUID_SS,
2071            /* Some CPUs got no CPUID_SEP */
2072        /* Missing: CPUID_EXT_DSCPL, CPUID_EXT_EST, CPUID_EXT_TM2,
2073         * CPUID_EXT_XTPR */
2074        .features[FEAT_1_ECX] =
2075            CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
2076            CPUID_EXT_MOVBE,
2077        .features[FEAT_8000_0001_EDX] =
2078            CPUID_EXT2_NX,
2079        .features[FEAT_8000_0001_ECX] =
2080            CPUID_EXT3_LAHF_LM,
2081        .xlevel = 0x80000008,
2082        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
2083    },
2084    {
2085        .name = "Conroe",
2086        .level = 10,
2087        .vendor = CPUID_VENDOR_INTEL,
2088        .family = 6,
2089        .model = 15,
2090        .stepping = 3,
2091        .features[FEAT_1_EDX] =
2092            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2093            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2094            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2095            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2096            CPUID_DE | CPUID_FP87,
2097        .features[FEAT_1_ECX] =
2098            CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
2099        .features[FEAT_8000_0001_EDX] =
2100            CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
2101        .features[FEAT_8000_0001_ECX] =
2102            CPUID_EXT3_LAHF_LM,
2103        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS,
2104        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE,
2105        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT,
2106        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
2107        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
2108             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS,
2109        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
2110             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
2111             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
2112             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
2113             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
2114             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
2115             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
2116             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
2117             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
2118             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
2119        .features[FEAT_VMX_SECONDARY_CTLS] =
2120             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES,
2121        .xlevel = 0x80000008,
2122        .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
2123    },
2124    {
2125        .name = "Penryn",
2126        .level = 10,
2127        .vendor = CPUID_VENDOR_INTEL,
2128        .family = 6,
2129        .model = 23,
2130        .stepping = 3,
2131        .features[FEAT_1_EDX] =
2132            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2133            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2134            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2135            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2136            CPUID_DE | CPUID_FP87,
2137        .features[FEAT_1_ECX] =
2138            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2139            CPUID_EXT_SSE3,
2140        .features[FEAT_8000_0001_EDX] =
2141            CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
2142        .features[FEAT_8000_0001_ECX] =
2143            CPUID_EXT3_LAHF_LM,
2144        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS,
2145        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
2146             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL,
2147        .features[FEAT_VMX_EXIT_CTLS] = VMX_VM_EXIT_ACK_INTR_ON_EXIT |
2148             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL,
2149        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
2150        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
2151             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS,
2152        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
2153             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
2154             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
2155             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
2156             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
2157             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
2158             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
2159             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
2160             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
2161             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
2162        .features[FEAT_VMX_SECONDARY_CTLS] =
2163             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
2164             VMX_SECONDARY_EXEC_WBINVD_EXITING,
2165        .xlevel = 0x80000008,
2166        .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
2167    },
2168    {
2169        .name = "Nehalem",
2170        .level = 11,
2171        .vendor = CPUID_VENDOR_INTEL,
2172        .family = 6,
2173        .model = 26,
2174        .stepping = 3,
2175        .features[FEAT_1_EDX] =
2176            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2177            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2178            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2179            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2180            CPUID_DE | CPUID_FP87,
2181        .features[FEAT_1_ECX] =
2182            CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
2183            CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
2184        .features[FEAT_8000_0001_EDX] =
2185            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
2186        .features[FEAT_8000_0001_ECX] =
2187            CPUID_EXT3_LAHF_LM,
2188        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
2189             MSR_VMX_BASIC_TRUE_CTLS,
2190        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
2191             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
2192             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
2193        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
2194             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
2195             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
2196             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
2197             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
2198             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
2199             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
2200        .features[FEAT_VMX_EXIT_CTLS] =
2201             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
2202             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
2203             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
2204             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
2205             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
2206        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT,
2207        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
2208             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
2209             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
2210        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
2211             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
2212             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
2213             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
2214             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
2215             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
2216             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
2217             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
2218             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
2219             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
2220             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
2221             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
2222        .features[FEAT_VMX_SECONDARY_CTLS] =
2223             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
2224             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
2225             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
2226             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
2227             VMX_SECONDARY_EXEC_ENABLE_VPID,
2228        .xlevel = 0x80000008,
2229        .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
2230        .versions = (X86CPUVersionDefinition[]) {
2231            { .version = 1 },
2232            {
2233                .version = 2,
2234                .alias = "Nehalem-IBRS",
2235                .props = (PropValue[]) {
2236                    { "spec-ctrl", "on" },
2237                    { "model-id",
2238                      "Intel Core i7 9xx (Nehalem Core i7, IBRS update)" },
2239                    { /* end of list */ }
2240                }
2241            },
2242            { /* end of list */ }
2243        }
2244    },
2245    {
2246        .name = "Westmere",
2247        .level = 11,
2248        .vendor = CPUID_VENDOR_INTEL,
2249        .family = 6,
2250        .model = 44,
2251        .stepping = 1,
2252        .features[FEAT_1_EDX] =
2253            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2254            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2255            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2256            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2257            CPUID_DE | CPUID_FP87,
2258        .features[FEAT_1_ECX] =
2259            CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
2260            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2261            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
2262        .features[FEAT_8000_0001_EDX] =
2263            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
2264        .features[FEAT_8000_0001_ECX] =
2265            CPUID_EXT3_LAHF_LM,
2266        .features[FEAT_6_EAX] =
2267            CPUID_6_EAX_ARAT,
2268        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
2269             MSR_VMX_BASIC_TRUE_CTLS,
2270        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
2271             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
2272             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
2273        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
2274             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
2275             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
2276             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
2277             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
2278             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
2279             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
2280        .features[FEAT_VMX_EXIT_CTLS] =
2281             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
2282             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
2283             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
2284             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
2285             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
2286        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
2287             MSR_VMX_MISC_STORE_LMA,
2288        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
2289             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
2290             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
2291        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
2292             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
2293             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
2294             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
2295             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
2296             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
2297             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
2298             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
2299             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
2300             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
2301             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
2302             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
2303        .features[FEAT_VMX_SECONDARY_CTLS] =
2304             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
2305             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
2306             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
2307             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
2308             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST,
2309        .xlevel = 0x80000008,
2310        .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
2311        .versions = (X86CPUVersionDefinition[]) {
2312            { .version = 1 },
2313            {
2314                .version = 2,
2315                .alias = "Westmere-IBRS",
2316                .props = (PropValue[]) {
2317                    { "spec-ctrl", "on" },
2318                    { "model-id",
2319                      "Westmere E56xx/L56xx/X56xx (IBRS update)" },
2320                    { /* end of list */ }
2321                }
2322            },
2323            { /* end of list */ }
2324        }
2325    },
2326    {
2327        .name = "SandyBridge",
2328        .level = 0xd,
2329        .vendor = CPUID_VENDOR_INTEL,
2330        .family = 6,
2331        .model = 42,
2332        .stepping = 1,
2333        .features[FEAT_1_EDX] =
2334            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2335            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2336            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2337            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2338            CPUID_DE | CPUID_FP87,
2339        .features[FEAT_1_ECX] =
2340            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2341            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
2342            CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
2343            CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
2344            CPUID_EXT_SSE3,
2345        .features[FEAT_8000_0001_EDX] =
2346            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2347            CPUID_EXT2_SYSCALL,
2348        .features[FEAT_8000_0001_ECX] =
2349            CPUID_EXT3_LAHF_LM,
2350        .features[FEAT_XSAVE] =
2351            CPUID_XSAVE_XSAVEOPT,
2352        .features[FEAT_6_EAX] =
2353            CPUID_6_EAX_ARAT,
2354        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
2355             MSR_VMX_BASIC_TRUE_CTLS,
2356        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
2357             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
2358             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
2359        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
2360             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
2361             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
2362             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
2363             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
2364             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
2365             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
2366        .features[FEAT_VMX_EXIT_CTLS] =
2367             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
2368             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
2369             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
2370             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
2371             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
2372        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
2373             MSR_VMX_MISC_STORE_LMA,
2374        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
2375             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
2376             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
2377        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
2378             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
2379             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
2380             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
2381             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
2382             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
2383             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
2384             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
2385             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
2386             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
2387             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
2388             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
2389        .features[FEAT_VMX_SECONDARY_CTLS] =
2390             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
2391             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
2392             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
2393             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
2394             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST,
2395        .xlevel = 0x80000008,
2396        .model_id = "Intel Xeon E312xx (Sandy Bridge)",
2397        .versions = (X86CPUVersionDefinition[]) {
2398            { .version = 1 },
2399            {
2400                .version = 2,
2401                .alias = "SandyBridge-IBRS",
2402                .props = (PropValue[]) {
2403                    { "spec-ctrl", "on" },
2404                    { "model-id",
2405                      "Intel Xeon E312xx (Sandy Bridge, IBRS update)" },
2406                    { /* end of list */ }
2407                }
2408            },
2409            { /* end of list */ }
2410        }
2411    },
2412    {
2413        .name = "IvyBridge",
2414        .level = 0xd,
2415        .vendor = CPUID_VENDOR_INTEL,
2416        .family = 6,
2417        .model = 58,
2418        .stepping = 9,
2419        .features[FEAT_1_EDX] =
2420            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2421            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2422            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2423            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2424            CPUID_DE | CPUID_FP87,
2425        .features[FEAT_1_ECX] =
2426            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2427            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
2428            CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
2429            CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
2430            CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2431        .features[FEAT_7_0_EBX] =
2432            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
2433            CPUID_7_0_EBX_ERMS,
2434        .features[FEAT_8000_0001_EDX] =
2435            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2436            CPUID_EXT2_SYSCALL,
2437        .features[FEAT_8000_0001_ECX] =
2438            CPUID_EXT3_LAHF_LM,
2439        .features[FEAT_XSAVE] =
2440            CPUID_XSAVE_XSAVEOPT,
2441        .features[FEAT_6_EAX] =
2442            CPUID_6_EAX_ARAT,
2443        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
2444             MSR_VMX_BASIC_TRUE_CTLS,
2445        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
2446             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
2447             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
2448        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
2449             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
2450             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
2451             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
2452             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
2453             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
2454             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
2455        .features[FEAT_VMX_EXIT_CTLS] =
2456             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
2457             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
2458             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
2459             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
2460             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
2461        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
2462             MSR_VMX_MISC_STORE_LMA,
2463        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
2464             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
2465             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
2466        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
2467             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
2468             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
2469             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
2470             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
2471             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
2472             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
2473             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
2474             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
2475             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
2476             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
2477             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
2478        .features[FEAT_VMX_SECONDARY_CTLS] =
2479             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
2480             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
2481             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
2482             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
2483             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
2484             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
2485             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
2486             VMX_SECONDARY_EXEC_RDRAND_EXITING,
2487        .xlevel = 0x80000008,
2488        .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
2489        .versions = (X86CPUVersionDefinition[]) {
2490            { .version = 1 },
2491            {
2492                .version = 2,
2493                .alias = "IvyBridge-IBRS",
2494                .props = (PropValue[]) {
2495                    { "spec-ctrl", "on" },
2496                    { "model-id",
2497                      "Intel Xeon E3-12xx v2 (Ivy Bridge, IBRS)" },
2498                    { /* end of list */ }
2499                }
2500            },
2501            { /* end of list */ }
2502        }
2503    },
2504    {
2505        .name = "Haswell",
2506        .level = 0xd,
2507        .vendor = CPUID_VENDOR_INTEL,
2508        .family = 6,
2509        .model = 60,
2510        .stepping = 4,
2511        .features[FEAT_1_EDX] =
2512            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2513            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2514            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2515            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2516            CPUID_DE | CPUID_FP87,
2517        .features[FEAT_1_ECX] =
2518            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2519            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2520            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2521            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2522            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2523            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2524        .features[FEAT_8000_0001_EDX] =
2525            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2526            CPUID_EXT2_SYSCALL,
2527        .features[FEAT_8000_0001_ECX] =
2528            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
2529        .features[FEAT_7_0_EBX] =
2530            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2531            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2532            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2533            CPUID_7_0_EBX_RTM,
2534        .features[FEAT_XSAVE] =
2535            CPUID_XSAVE_XSAVEOPT,
2536        .features[FEAT_6_EAX] =
2537            CPUID_6_EAX_ARAT,
2538        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
2539             MSR_VMX_BASIC_TRUE_CTLS,
2540        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
2541             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
2542             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
2543        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
2544             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
2545             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
2546             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
2547             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
2548             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
2549             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
2550        .features[FEAT_VMX_EXIT_CTLS] =
2551             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
2552             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
2553             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
2554             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
2555             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
2556        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
2557             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
2558        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
2559             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
2560             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
2561        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
2562             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
2563             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
2564             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
2565             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
2566             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
2567             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
2568             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
2569             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
2570             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
2571             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
2572             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
2573        .features[FEAT_VMX_SECONDARY_CTLS] =
2574             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
2575             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
2576             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
2577             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
2578             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
2579             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
2580             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
2581             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
2582             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS,
2583        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
2584        .xlevel = 0x80000008,
2585        .model_id = "Intel Core Processor (Haswell)",
2586        .versions = (X86CPUVersionDefinition[]) {
2587            { .version = 1 },
2588            {
2589                .version = 2,
2590                .alias = "Haswell-noTSX",
2591                .props = (PropValue[]) {
2592                    { "hle", "off" },
2593                    { "rtm", "off" },
2594                    { "stepping", "1" },
2595                    { "model-id", "Intel Core Processor (Haswell, no TSX)", },
2596                    { /* end of list */ }
2597                },
2598            },
2599            {
2600                .version = 3,
2601                .alias = "Haswell-IBRS",
2602                .props = (PropValue[]) {
2603                    /* Restore TSX features removed by -v2 above */
2604                    { "hle", "on" },
2605                    { "rtm", "on" },
2606                    /*
2607                     * Haswell and Haswell-IBRS had stepping=4 in
2608                     * QEMU 4.0 and older
2609                     */
2610                    { "stepping", "4" },
2611                    { "spec-ctrl", "on" },
2612                    { "model-id",
2613                      "Intel Core Processor (Haswell, IBRS)" },
2614                    { /* end of list */ }
2615                }
2616            },
2617            {
2618                .version = 4,
2619                .alias = "Haswell-noTSX-IBRS",
2620                .props = (PropValue[]) {
2621                    { "hle", "off" },
2622                    { "rtm", "off" },
2623                    /* spec-ctrl was already enabled by -v3 above */
2624                    { "stepping", "1" },
2625                    { "model-id",
2626                      "Intel Core Processor (Haswell, no TSX, IBRS)" },
2627                    { /* end of list */ }
2628                }
2629            },
2630            { /* end of list */ }
2631        }
2632    },
2633    {
2634        .name = "Broadwell",
2635        .level = 0xd,
2636        .vendor = CPUID_VENDOR_INTEL,
2637        .family = 6,
2638        .model = 61,
2639        .stepping = 2,
2640        .features[FEAT_1_EDX] =
2641            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2642            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2643            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2644            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2645            CPUID_DE | CPUID_FP87,
2646        .features[FEAT_1_ECX] =
2647            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2648            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2649            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2650            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2651            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2652            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2653        .features[FEAT_8000_0001_EDX] =
2654            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2655            CPUID_EXT2_SYSCALL,
2656        .features[FEAT_8000_0001_ECX] =
2657            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2658        .features[FEAT_7_0_EBX] =
2659            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2660            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2661            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2662            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2663            CPUID_7_0_EBX_SMAP,
2664        .features[FEAT_XSAVE] =
2665            CPUID_XSAVE_XSAVEOPT,
2666        .features[FEAT_6_EAX] =
2667            CPUID_6_EAX_ARAT,
2668        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
2669             MSR_VMX_BASIC_TRUE_CTLS,
2670        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
2671             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
2672             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
2673        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
2674             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
2675             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
2676             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
2677             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
2678             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
2679             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
2680        .features[FEAT_VMX_EXIT_CTLS] =
2681             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
2682             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
2683             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
2684             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
2685             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
2686        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
2687             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
2688        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
2689             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
2690             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
2691        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
2692             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
2693             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
2694             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
2695             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
2696             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
2697             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
2698             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
2699             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
2700             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
2701             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
2702             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
2703        .features[FEAT_VMX_SECONDARY_CTLS] =
2704             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
2705             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
2706             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
2707             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
2708             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
2709             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
2710             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
2711             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
2712             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
2713             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
2714        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
2715        .xlevel = 0x80000008,
2716        .model_id = "Intel Core Processor (Broadwell)",
2717        .versions = (X86CPUVersionDefinition[]) {
2718            { .version = 1 },
2719            {
2720                .version = 2,
2721                .alias = "Broadwell-noTSX",
2722                .props = (PropValue[]) {
2723                    { "hle", "off" },
2724                    { "rtm", "off" },
2725                    { "model-id", "Intel Core Processor (Broadwell, no TSX)", },
2726                    { /* end of list */ }
2727                },
2728            },
2729            {
2730                .version = 3,
2731                .alias = "Broadwell-IBRS",
2732                .props = (PropValue[]) {
2733                    /* Restore TSX features removed by -v2 above */
2734                    { "hle", "on" },
2735                    { "rtm", "on" },
2736                    { "spec-ctrl", "on" },
2737                    { "model-id",
2738                      "Intel Core Processor (Broadwell, IBRS)" },
2739                    { /* end of list */ }
2740                }
2741            },
2742            {
2743                .version = 4,
2744                .alias = "Broadwell-noTSX-IBRS",
2745                .props = (PropValue[]) {
2746                    { "hle", "off" },
2747                    { "rtm", "off" },
2748                    /* spec-ctrl was already enabled by -v3 above */
2749                    { "model-id",
2750                      "Intel Core Processor (Broadwell, no TSX, IBRS)" },
2751                    { /* end of list */ }
2752                }
2753            },
2754            { /* end of list */ }
2755        }
2756    },
2757    {
2758        .name = "Skylake-Client",
2759        .level = 0xd,
2760        .vendor = CPUID_VENDOR_INTEL,
2761        .family = 6,
2762        .model = 94,
2763        .stepping = 3,
2764        .features[FEAT_1_EDX] =
2765            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2766            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2767            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2768            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2769            CPUID_DE | CPUID_FP87,
2770        .features[FEAT_1_ECX] =
2771            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2772            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2773            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2774            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2775            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2776            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2777        .features[FEAT_8000_0001_EDX] =
2778            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2779            CPUID_EXT2_SYSCALL,
2780        .features[FEAT_8000_0001_ECX] =
2781            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2782        .features[FEAT_7_0_EBX] =
2783            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2784            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2785            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2786            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2787            CPUID_7_0_EBX_SMAP,
2788        /* XSAVES is added in version 4 */
2789        .features[FEAT_XSAVE] =
2790            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2791            CPUID_XSAVE_XGETBV1,
2792        .features[FEAT_6_EAX] =
2793            CPUID_6_EAX_ARAT,
2794        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
2795        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
2796             MSR_VMX_BASIC_TRUE_CTLS,
2797        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
2798             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
2799             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
2800        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
2801             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
2802             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
2803             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
2804             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
2805             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
2806             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
2807        .features[FEAT_VMX_EXIT_CTLS] =
2808             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
2809             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
2810             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
2811             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
2812             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
2813        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
2814             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
2815        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
2816             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
2817             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
2818        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
2819             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
2820             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
2821             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
2822             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
2823             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
2824             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
2825             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
2826             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
2827             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
2828             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
2829             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
2830        .features[FEAT_VMX_SECONDARY_CTLS] =
2831             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
2832             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
2833             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
2834             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
2835             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
2836             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
2837             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
2838        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
2839        .xlevel = 0x80000008,
2840        .model_id = "Intel Core Processor (Skylake)",
2841        .versions = (X86CPUVersionDefinition[]) {
2842            { .version = 1 },
2843            {
2844                .version = 2,
2845                .alias = "Skylake-Client-IBRS",
2846                .props = (PropValue[]) {
2847                    { "spec-ctrl", "on" },
2848                    { "model-id",
2849                      "Intel Core Processor (Skylake, IBRS)" },
2850                    { /* end of list */ }
2851                }
2852            },
2853            {
2854                .version = 3,
2855                .alias = "Skylake-Client-noTSX-IBRS",
2856                .props = (PropValue[]) {
2857                    { "hle", "off" },
2858                    { "rtm", "off" },
2859                    { "model-id",
2860                      "Intel Core Processor (Skylake, IBRS, no TSX)" },
2861                    { /* end of list */ }
2862                }
2863            },
2864            {
2865                .version = 4,
2866                .note = "IBRS, XSAVES, no TSX",
2867                .props = (PropValue[]) {
2868                    { "xsaves", "on" },
2869                    { "vmx-xsaves", "on" },
2870                    { /* end of list */ }
2871                }
2872            },
2873            { /* end of list */ }
2874        }
2875    },
2876    {
2877        .name = "Skylake-Server",
2878        .level = 0xd,
2879        .vendor = CPUID_VENDOR_INTEL,
2880        .family = 6,
2881        .model = 85,
2882        .stepping = 4,
2883        .features[FEAT_1_EDX] =
2884            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2885            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2886            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2887            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2888            CPUID_DE | CPUID_FP87,
2889        .features[FEAT_1_ECX] =
2890            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2891            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2892            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2893            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2894            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2895            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2896        .features[FEAT_8000_0001_EDX] =
2897            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
2898            CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
2899        .features[FEAT_8000_0001_ECX] =
2900            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2901        .features[FEAT_7_0_EBX] =
2902            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2903            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2904            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2905            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2906            CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB |
2907            CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
2908            CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
2909            CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
2910        .features[FEAT_7_0_ECX] =
2911            CPUID_7_0_ECX_PKU,
2912        /* XSAVES is added in version 5 */
2913        .features[FEAT_XSAVE] =
2914            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2915            CPUID_XSAVE_XGETBV1,
2916        .features[FEAT_6_EAX] =
2917            CPUID_6_EAX_ARAT,
2918        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
2919        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
2920             MSR_VMX_BASIC_TRUE_CTLS,
2921        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
2922             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
2923             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
2924        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
2925             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
2926             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
2927             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
2928             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
2929             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
2930             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
2931        .features[FEAT_VMX_EXIT_CTLS] =
2932             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
2933             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
2934             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
2935             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
2936             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
2937        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
2938             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
2939        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
2940             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
2941             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
2942        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
2943             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
2944             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
2945             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
2946             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
2947             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
2948             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
2949             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
2950             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
2951             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
2952             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
2953             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
2954        .features[FEAT_VMX_SECONDARY_CTLS] =
2955             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
2956             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
2957             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
2958             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
2959             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
2960             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
2961             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
2962             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
2963             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
2964             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
2965        .xlevel = 0x80000008,
2966        .model_id = "Intel Xeon Processor (Skylake)",
2967        .versions = (X86CPUVersionDefinition[]) {
2968            { .version = 1 },
2969            {
2970                .version = 2,
2971                .alias = "Skylake-Server-IBRS",
2972                .props = (PropValue[]) {
2973                    /* clflushopt was not added to Skylake-Server-IBRS */
2974                    /* TODO: add -v3 including clflushopt */
2975                    { "clflushopt", "off" },
2976                    { "spec-ctrl", "on" },
2977                    { "model-id",
2978                      "Intel Xeon Processor (Skylake, IBRS)" },
2979                    { /* end of list */ }
2980                }
2981            },
2982            {
2983                .version = 3,
2984                .alias = "Skylake-Server-noTSX-IBRS",
2985                .props = (PropValue[]) {
2986                    { "hle", "off" },
2987                    { "rtm", "off" },
2988                    { "model-id",
2989                      "Intel Xeon Processor (Skylake, IBRS, no TSX)" },
2990                    { /* end of list */ }
2991                }
2992            },
2993            {
2994                .version = 4,
2995                .props = (PropValue[]) {
2996                    { "vmx-eptp-switching", "on" },
2997                    { /* end of list */ }
2998                }
2999            },
3000            {
3001                .version = 5,
3002                .note = "IBRS, XSAVES, EPT switching, no TSX",
3003                .props = (PropValue[]) {
3004                    { "xsaves", "on" },
3005                    { "vmx-xsaves", "on" },
3006                    { /* end of list */ }
3007                }
3008            },
3009            { /* end of list */ }
3010        }
3011    },
3012    {
3013        .name = "Cascadelake-Server",
3014        .level = 0xd,
3015        .vendor = CPUID_VENDOR_INTEL,
3016        .family = 6,
3017        .model = 85,
3018        .stepping = 6,
3019        .features[FEAT_1_EDX] =
3020            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3021            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
3022            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
3023            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
3024            CPUID_DE | CPUID_FP87,
3025        .features[FEAT_1_ECX] =
3026            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
3027            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
3028            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
3029            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
3030            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
3031            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
3032        .features[FEAT_8000_0001_EDX] =
3033            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
3034            CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
3035        .features[FEAT_8000_0001_ECX] =
3036            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
3037        .features[FEAT_7_0_EBX] =
3038            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
3039            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
3040            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
3041            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
3042            CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB |
3043            CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
3044            CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
3045            CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
3046        .features[FEAT_7_0_ECX] =
3047            CPUID_7_0_ECX_PKU |
3048            CPUID_7_0_ECX_AVX512VNNI,
3049        .features[FEAT_7_0_EDX] =
3050            CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
3051        /* XSAVES is added in version 5 */
3052        .features[FEAT_XSAVE] =
3053            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
3054            CPUID_XSAVE_XGETBV1,
3055        .features[FEAT_6_EAX] =
3056            CPUID_6_EAX_ARAT,
3057        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
3058        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
3059             MSR_VMX_BASIC_TRUE_CTLS,
3060        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
3061             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
3062             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
3063        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
3064             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
3065             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
3066             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
3067             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
3068             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
3069             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
3070        .features[FEAT_VMX_EXIT_CTLS] =
3071             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
3072             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
3073             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
3074             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
3075             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
3076        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
3077             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
3078        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
3079             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
3080             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
3081        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
3082             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
3083             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
3084             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
3085             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
3086             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
3087             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
3088             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
3089             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
3090             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
3091             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
3092             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
3093        .features[FEAT_VMX_SECONDARY_CTLS] =
3094             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
3095             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
3096             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
3097             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
3098             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
3099             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
3100             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
3101             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
3102             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
3103             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
3104        .xlevel = 0x80000008,
3105        .model_id = "Intel Xeon Processor (Cascadelake)",
3106        .versions = (X86CPUVersionDefinition[]) {
3107            { .version = 1 },
3108            { .version = 2,
3109              .note = "ARCH_CAPABILITIES",
3110              .props = (PropValue[]) {
3111                  { "arch-capabilities", "on" },
3112                  { "rdctl-no", "on" },
3113                  { "ibrs-all", "on" },
3114                  { "skip-l1dfl-vmentry", "on" },
3115                  { "mds-no", "on" },
3116                  { /* end of list */ }
3117              },
3118            },
3119            { .version = 3,
3120              .alias = "Cascadelake-Server-noTSX",
3121              .note = "ARCH_CAPABILITIES, no TSX",
3122              .props = (PropValue[]) {
3123                  { "hle", "off" },
3124                  { "rtm", "off" },
3125                  { /* end of list */ }
3126              },
3127            },
3128            { .version = 4,
3129              .note = "ARCH_CAPABILITIES, no TSX",
3130              .props = (PropValue[]) {
3131                  { "vmx-eptp-switching", "on" },
3132                  { /* end of list */ }
3133              },
3134            },
3135            { .version = 5,
3136              .note = "ARCH_CAPABILITIES, EPT switching, XSAVES, no TSX",
3137              .props = (PropValue[]) {
3138                  { "xsaves", "on" },
3139                  { "vmx-xsaves", "on" },
3140                  { /* end of list */ }
3141              },
3142            },
3143            { /* end of list */ }
3144        }
3145    },
3146    {
3147        .name = "Cooperlake",
3148        .level = 0xd,
3149        .vendor = CPUID_VENDOR_INTEL,
3150        .family = 6,
3151        .model = 85,
3152        .stepping = 10,
3153        .features[FEAT_1_EDX] =
3154            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3155            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
3156            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
3157            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
3158            CPUID_DE | CPUID_FP87,
3159        .features[FEAT_1_ECX] =
3160            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
3161            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
3162            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
3163            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
3164            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
3165            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
3166        .features[FEAT_8000_0001_EDX] =
3167            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
3168            CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
3169        .features[FEAT_8000_0001_ECX] =
3170            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
3171        .features[FEAT_7_0_EBX] =
3172            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
3173            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
3174            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
3175            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
3176            CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB |
3177            CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
3178            CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
3179            CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
3180        .features[FEAT_7_0_ECX] =
3181            CPUID_7_0_ECX_PKU |
3182            CPUID_7_0_ECX_AVX512VNNI,
3183        .features[FEAT_7_0_EDX] =
3184            CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_STIBP |
3185            CPUID_7_0_EDX_SPEC_CTRL_SSBD | CPUID_7_0_EDX_ARCH_CAPABILITIES,
3186        .features[FEAT_ARCH_CAPABILITIES] =
3187            MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL |
3188            MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO |
3189            MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO,
3190        .features[FEAT_7_1_EAX] =
3191            CPUID_7_1_EAX_AVX512_BF16,
3192        /* XSAVES is added in version 2 */
3193        .features[FEAT_XSAVE] =
3194            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
3195            CPUID_XSAVE_XGETBV1,
3196        .features[FEAT_6_EAX] =
3197            CPUID_6_EAX_ARAT,
3198        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
3199        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
3200             MSR_VMX_BASIC_TRUE_CTLS,
3201        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
3202             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
3203             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
3204        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
3205             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
3206             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
3207             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
3208             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
3209             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
3210             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
3211        .features[FEAT_VMX_EXIT_CTLS] =
3212             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
3213             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
3214             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
3215             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
3216             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
3217        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
3218             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
3219        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
3220             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
3221             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
3222        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
3223             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
3224             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
3225             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
3226             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
3227             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
3228             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
3229             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
3230             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
3231             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
3232             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
3233             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
3234        .features[FEAT_VMX_SECONDARY_CTLS] =
3235             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
3236             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
3237             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
3238             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
3239             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
3240             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
3241             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
3242             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
3243             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
3244             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
3245        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
3246        .xlevel = 0x80000008,
3247        .model_id = "Intel Xeon Processor (Cooperlake)",
3248        .versions = (X86CPUVersionDefinition[]) {
3249            { .version = 1 },
3250            { .version = 2,
3251              .note = "XSAVES",
3252              .props = (PropValue[]) {
3253                  { "xsaves", "on" },
3254                  { "vmx-xsaves", "on" },
3255                  { /* end of list */ }
3256              },
3257            },
3258            { /* end of list */ }
3259        }
3260    },
3261    {
3262        .name = "Icelake-Client",
3263        .level = 0xd,
3264        .vendor = CPUID_VENDOR_INTEL,
3265        .family = 6,
3266        .model = 126,
3267        .stepping = 0,
3268        .features[FEAT_1_EDX] =
3269            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3270            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
3271            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
3272            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
3273            CPUID_DE | CPUID_FP87,
3274        .features[FEAT_1_ECX] =
3275            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
3276            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
3277            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
3278            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
3279            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
3280            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
3281        .features[FEAT_8000_0001_EDX] =
3282            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
3283            CPUID_EXT2_SYSCALL,
3284        .features[FEAT_8000_0001_ECX] =
3285            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
3286        .features[FEAT_8000_0008_EBX] =
3287            CPUID_8000_0008_EBX_WBNOINVD,
3288        .features[FEAT_7_0_EBX] =
3289            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
3290            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
3291            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
3292            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
3293            CPUID_7_0_EBX_SMAP,
3294        .features[FEAT_7_0_ECX] =
3295            CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
3296            CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI |
3297            CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
3298            CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
3299            CPUID_7_0_ECX_AVX512_VPOPCNTDQ,
3300        .features[FEAT_7_0_EDX] =
3301            CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
3302        /* XSAVES is added in version 3 */
3303        .features[FEAT_XSAVE] =
3304            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
3305            CPUID_XSAVE_XGETBV1,
3306        .features[FEAT_6_EAX] =
3307            CPUID_6_EAX_ARAT,
3308        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
3309        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
3310             MSR_VMX_BASIC_TRUE_CTLS,
3311        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
3312             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
3313             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
3314        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
3315             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
3316             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
3317             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
3318             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
3319             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
3320             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
3321        .features[FEAT_VMX_EXIT_CTLS] =
3322             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
3323             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
3324             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
3325             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
3326             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
3327        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
3328             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
3329        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
3330             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
3331             VMX_PIN_BASED_VMX_PREEMPTION_TIMER,
3332        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
3333             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
3334             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
3335             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
3336             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
3337             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
3338             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
3339             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
3340             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
3341             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
3342             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
3343             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
3344        .features[FEAT_VMX_SECONDARY_CTLS] =
3345             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
3346             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
3347             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
3348             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
3349             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
3350             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
3351             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
3352        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
3353        .xlevel = 0x80000008,
3354        .model_id = "Intel Core Processor (Icelake)",
3355        .versions = (X86CPUVersionDefinition[]) {
3356            {
3357                .version = 1,
3358                .note = "deprecated"
3359            },
3360            {
3361                .version = 2,
3362                .note = "no TSX, deprecated",
3363                .alias = "Icelake-Client-noTSX",
3364                .props = (PropValue[]) {
3365                    { "hle", "off" },
3366                    { "rtm", "off" },
3367                    { /* end of list */ }
3368                },
3369            },
3370            {
3371                .version = 3,
3372                .note = "no TSX, XSAVES, deprecated",
3373                .props = (PropValue[]) {
3374                    { "xsaves", "on" },
3375                    { "vmx-xsaves", "on" },
3376                    { /* end of list */ }
3377                },
3378            },
3379            { /* end of list */ }
3380        },
3381        .deprecation_note = "use Icelake-Server instead"
3382    },
3383    {
3384        .name = "Icelake-Server",
3385        .level = 0xd,
3386        .vendor = CPUID_VENDOR_INTEL,
3387        .family = 6,
3388        .model = 134,
3389        .stepping = 0,
3390        .features[FEAT_1_EDX] =
3391            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3392            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
3393            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
3394            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
3395            CPUID_DE | CPUID_FP87,
3396        .features[FEAT_1_ECX] =
3397            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
3398            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
3399            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
3400            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
3401            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
3402            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
3403        .features[FEAT_8000_0001_EDX] =
3404            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
3405            CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
3406        .features[FEAT_8000_0001_ECX] =
3407            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
3408        .features[FEAT_8000_0008_EBX] =
3409            CPUID_8000_0008_EBX_WBNOINVD,
3410        .features[FEAT_7_0_EBX] =
3411            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
3412            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
3413            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
3414            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
3415            CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB |
3416            CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
3417            CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
3418            CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
3419        .features[FEAT_7_0_ECX] =
3420            CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
3421            CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI |
3422            CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
3423            CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
3424            CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57,
3425        .features[FEAT_7_0_EDX] =
3426            CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
3427        /* XSAVES is added in version 5 */
3428        .features[FEAT_XSAVE] =
3429            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
3430            CPUID_XSAVE_XGETBV1,
3431        .features[FEAT_6_EAX] =
3432            CPUID_6_EAX_ARAT,
3433        /* Missing: Mode-based execute control (XS/XU), processor tracing, TSC scaling */
3434        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
3435             MSR_VMX_BASIC_TRUE_CTLS,
3436        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
3437             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
3438             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
3439        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
3440             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
3441             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
3442             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
3443             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
3444             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
3445             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
3446        .features[FEAT_VMX_EXIT_CTLS] =
3447             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
3448             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
3449             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
3450             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
3451             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
3452        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
3453             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
3454        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
3455             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
3456             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
3457        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
3458             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
3459             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
3460             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
3461             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
3462             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
3463             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
3464             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
3465             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
3466             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
3467             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
3468             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
3469        .features[FEAT_VMX_SECONDARY_CTLS] =
3470             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
3471             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
3472             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
3473             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
3474             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
3475             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
3476             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
3477             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
3478             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS,
3479        .xlevel = 0x80000008,
3480        .model_id = "Intel Xeon Processor (Icelake)",
3481        .versions = (X86CPUVersionDefinition[]) {
3482            { .version = 1 },
3483            {
3484                .version = 2,
3485                .note = "no TSX",
3486                .alias = "Icelake-Server-noTSX",
3487                .props = (PropValue[]) {
3488                    { "hle", "off" },
3489                    { "rtm", "off" },
3490                    { /* end of list */ }
3491                },
3492            },
3493            {
3494                .version = 3,
3495                .props = (PropValue[]) {
3496                    { "arch-capabilities", "on" },
3497                    { "rdctl-no", "on" },
3498                    { "ibrs-all", "on" },
3499                    { "skip-l1dfl-vmentry", "on" },
3500                    { "mds-no", "on" },
3501                    { "pschange-mc-no", "on" },
3502                    { "taa-no", "on" },
3503                    { /* end of list */ }
3504                },
3505            },
3506            {
3507                .version = 4,
3508                .props = (PropValue[]) {
3509                    { "sha-ni", "on" },
3510                    { "avx512ifma", "on" },
3511                    { "rdpid", "on" },
3512                    { "fsrm", "on" },
3513                    { "vmx-rdseed-exit", "on" },
3514                    { "vmx-pml", "on" },
3515                    { "vmx-eptp-switching", "on" },
3516                    { "model", "106" },
3517                    { /* end of list */ }
3518                },
3519            },
3520            {
3521                .version = 5,
3522                .note = "XSAVES",
3523                .props = (PropValue[]) {
3524                    { "xsaves", "on" },
3525                    { "vmx-xsaves", "on" },
3526                    { /* end of list */ }
3527                },
3528            },
3529            {
3530                .version = 6,
3531                .note = "5-level EPT",
3532                .props = (PropValue[]) {
3533                    { "vmx-page-walk-5", "on" },
3534                    { /* end of list */ }
3535                },
3536            },
3537            { /* end of list */ }
3538        }
3539    },
3540    {
3541        .name = "Denverton",
3542        .level = 21,
3543        .vendor = CPUID_VENDOR_INTEL,
3544        .family = 6,
3545        .model = 95,
3546        .stepping = 1,
3547        .features[FEAT_1_EDX] =
3548            CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC |
3549            CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC |
3550            CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
3551            CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR |
3552            CPUID_SSE | CPUID_SSE2,
3553        .features[FEAT_1_ECX] =
3554            CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_MONITOR |
3555            CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | CPUID_EXT_SSE41 |
3556            CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE |
3557            CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER |
3558            CPUID_EXT_AES | CPUID_EXT_XSAVE | CPUID_EXT_RDRAND,
3559        .features[FEAT_8000_0001_EDX] =
3560            CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB |
3561            CPUID_EXT2_RDTSCP | CPUID_EXT2_LM,
3562        .features[FEAT_8000_0001_ECX] =
3563            CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
3564        .features[FEAT_7_0_EBX] =
3565            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_ERMS |
3566            CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_SMAP |
3567            CPUID_7_0_EBX_CLFLUSHOPT | CPUID_7_0_EBX_SHA_NI,
3568        .features[FEAT_7_0_EDX] =
3569            CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_ARCH_CAPABILITIES |
3570            CPUID_7_0_EDX_SPEC_CTRL_SSBD,
3571        /* XSAVES is added in version 3 */
3572        .features[FEAT_XSAVE] =
3573            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | CPUID_XSAVE_XGETBV1,
3574        .features[FEAT_6_EAX] =
3575            CPUID_6_EAX_ARAT,
3576        .features[FEAT_ARCH_CAPABILITIES] =
3577            MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY,
3578        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
3579             MSR_VMX_BASIC_TRUE_CTLS,
3580        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
3581             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
3582             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
3583        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
3584             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
3585             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
3586             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
3587             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
3588             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
3589             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
3590        .features[FEAT_VMX_EXIT_CTLS] =
3591             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
3592             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
3593             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
3594             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
3595             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
3596        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
3597             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
3598        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
3599             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
3600             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
3601        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
3602             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
3603             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
3604             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
3605             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
3606             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
3607             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
3608             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
3609             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
3610             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
3611             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
3612             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
3613        .features[FEAT_VMX_SECONDARY_CTLS] =
3614             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
3615             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
3616             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
3617             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
3618             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
3619             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
3620             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
3621             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
3622             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
3623             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
3624        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
3625        .xlevel = 0x80000008,
3626        .model_id = "Intel Atom Processor (Denverton)",
3627        .versions = (X86CPUVersionDefinition[]) {
3628            { .version = 1 },
3629            {
3630                .version = 2,
3631                .note = "no MPX, no MONITOR",
3632                .props = (PropValue[]) {
3633                    { "monitor", "off" },
3634                    { "mpx", "off" },
3635                    { /* end of list */ },
3636                },
3637            },
3638            {
3639                .version = 3,
3640                .note = "XSAVES, no MPX, no MONITOR",
3641                .props = (PropValue[]) {
3642                    { "xsaves", "on" },
3643                    { "vmx-xsaves", "on" },
3644                    { /* end of list */ },
3645                },
3646            },
3647            { /* end of list */ },
3648        },
3649    },
3650    {
3651        .name = "Snowridge",
3652        .level = 27,
3653        .vendor = CPUID_VENDOR_INTEL,
3654        .family = 6,
3655        .model = 134,
3656        .stepping = 1,
3657        .features[FEAT_1_EDX] =
3658            /* missing: CPUID_PN CPUID_IA64 */
3659            /* missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
3660            CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE |
3661            CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE |
3662            CPUID_CX8 | CPUID_APIC | CPUID_SEP |
3663            CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
3664            CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH |
3665            CPUID_MMX |
3666            CPUID_FXSR | CPUID_SSE | CPUID_SSE2,
3667        .features[FEAT_1_ECX] =
3668            CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_MONITOR |
3669            CPUID_EXT_SSSE3 |
3670            CPUID_EXT_CX16 |
3671            CPUID_EXT_SSE41 |
3672            CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE |
3673            CPUID_EXT_POPCNT |
3674            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES | CPUID_EXT_XSAVE |
3675            CPUID_EXT_RDRAND,
3676        .features[FEAT_8000_0001_EDX] =
3677            CPUID_EXT2_SYSCALL |
3678            CPUID_EXT2_NX |
3679            CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
3680            CPUID_EXT2_LM,
3681        .features[FEAT_8000_0001_ECX] =
3682            CPUID_EXT3_LAHF_LM |
3683            CPUID_EXT3_3DNOWPREFETCH,
3684        .features[FEAT_7_0_EBX] =
3685            CPUID_7_0_EBX_FSGSBASE |
3686            CPUID_7_0_EBX_SMEP |
3687            CPUID_7_0_EBX_ERMS |
3688            CPUID_7_0_EBX_MPX |  /* missing bits 13, 15 */
3689            CPUID_7_0_EBX_RDSEED |
3690            CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
3691            CPUID_7_0_EBX_CLWB |
3692            CPUID_7_0_EBX_SHA_NI,
3693        .features[FEAT_7_0_ECX] =
3694            CPUID_7_0_ECX_UMIP |
3695            /* missing bit 5 */
3696            CPUID_7_0_ECX_GFNI |
3697            CPUID_7_0_ECX_MOVDIRI | CPUID_7_0_ECX_CLDEMOTE |
3698            CPUID_7_0_ECX_MOVDIR64B,
3699        .features[FEAT_7_0_EDX] =
3700            CPUID_7_0_EDX_SPEC_CTRL |
3701            CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID_7_0_EDX_SPEC_CTRL_SSBD |
3702            CPUID_7_0_EDX_CORE_CAPABILITY,
3703        .features[FEAT_CORE_CAPABILITY] =
3704            MSR_CORE_CAP_SPLIT_LOCK_DETECT,
3705        /* XSAVES is is added in version 3 */
3706        .features[FEAT_XSAVE] =
3707            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
3708            CPUID_XSAVE_XGETBV1,
3709        .features[FEAT_6_EAX] =
3710            CPUID_6_EAX_ARAT,
3711        .features[FEAT_VMX_BASIC] = MSR_VMX_BASIC_INS_OUTS |
3712             MSR_VMX_BASIC_TRUE_CTLS,
3713        .features[FEAT_VMX_ENTRY_CTLS] = VMX_VM_ENTRY_IA32E_MODE |
3714             VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | VMX_VM_ENTRY_LOAD_IA32_PAT |
3715             VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_LOAD_IA32_EFER,
3716        .features[FEAT_VMX_EPT_VPID_CAPS] = MSR_VMX_EPT_EXECONLY |
3717             MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB |
3718             MSR_VMX_EPT_1GB | MSR_VMX_EPT_INVEPT |
3719             MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
3720             MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
3721             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
3722             MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS | MSR_VMX_EPT_AD_BITS,
3723        .features[FEAT_VMX_EXIT_CTLS] =
3724             VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
3725             VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
3726             VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_LOAD_IA32_EFER |
3727             VMX_VM_EXIT_SAVE_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
3728             VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
3729        .features[FEAT_VMX_MISC] = MSR_VMX_MISC_ACTIVITY_HLT |
3730             MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_VMWRITE_VMEXIT,
3731        .features[FEAT_VMX_PINBASED_CTLS] = VMX_PIN_BASED_EXT_INTR_MASK |
3732             VMX_PIN_BASED_NMI_EXITING | VMX_PIN_BASED_VIRTUAL_NMIS |
3733             VMX_PIN_BASED_VMX_PREEMPTION_TIMER | VMX_PIN_BASED_POSTED_INTR,
3734        .features[FEAT_VMX_PROCBASED_CTLS] = VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
3735             VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
3736             VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
3737             VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
3738             VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
3739             VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_MOV_DR_EXITING |
3740             VMX_CPU_BASED_UNCOND_IO_EXITING | VMX_CPU_BASED_USE_IO_BITMAPS |
3741             VMX_CPU_BASED_MONITOR_EXITING | VMX_CPU_BASED_PAUSE_EXITING |
3742             VMX_CPU_BASED_VIRTUAL_NMI_PENDING | VMX_CPU_BASED_USE_MSR_BITMAPS |
3743             VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
3744             VMX_CPU_BASED_MONITOR_TRAP_FLAG |
3745             VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
3746        .features[FEAT_VMX_SECONDARY_CTLS] =
3747             VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
3748             VMX_SECONDARY_EXEC_WBINVD_EXITING | VMX_SECONDARY_EXEC_ENABLE_EPT |
3749             VMX_SECONDARY_EXEC_DESC | VMX_SECONDARY_EXEC_RDTSCP |
3750             VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
3751             VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
3752             VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
3753             VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
3754             VMX_SECONDARY_EXEC_RDRAND_EXITING | VMX_SECONDARY_EXEC_ENABLE_INVPCID |
3755             VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
3756             VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML,
3757        .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
3758        .xlevel = 0x80000008,
3759        .model_id = "Intel Atom Processor (SnowRidge)",
3760        .versions = (X86CPUVersionDefinition[]) {
3761            { .version = 1 },
3762            {
3763                .version = 2,
3764                .props = (PropValue[]) {
3765                    { "mpx", "off" },
3766                    { "model-id", "Intel Atom Processor (Snowridge, no MPX)" },
3767                    { /* end of list */ },
3768                },
3769            },
3770            {
3771                .version = 3,
3772                .note = "XSAVES, no MPX",
3773                .props = (PropValue[]) {
3774                    { "xsaves", "on" },
3775                    { "vmx-xsaves", "on" },
3776                    { /* end of list */ },
3777                },
3778            },
3779            {
3780                .version = 4,
3781                .note = "no split lock detect, no core-capability",
3782                .props = (PropValue[]) {
3783                    { "split-lock-detect", "off" },
3784                    { "core-capability", "off" },
3785                    { /* end of list */ },
3786                },
3787            },
3788            { /* end of list */ },
3789        },
3790    },
3791    {
3792        .name = "KnightsMill",
3793        .level = 0xd,
3794        .vendor = CPUID_VENDOR_INTEL,
3795        .family = 6,
3796        .model = 133,
3797        .stepping = 0,
3798        .features[FEAT_1_EDX] =
3799            CPUID_VME | CPUID_SS | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
3800            CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV |
3801            CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
3802            CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
3803            CPUID_PSE | CPUID_DE | CPUID_FP87,
3804        .features[FEAT_1_ECX] =
3805            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
3806            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
3807            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
3808            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
3809            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
3810            CPUID_EXT_F16C | CPUID_EXT_RDRAND,
3811        .features[FEAT_8000_0001_EDX] =
3812            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
3813            CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
3814        .features[FEAT_8000_0001_ECX] =
3815            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
3816        .features[FEAT_7_0_EBX] =
3817            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
3818            CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS |
3819            CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_AVX512F |
3820            CPUID_7_0_EBX_AVX512CD | CPUID_7_0_EBX_AVX512PF |
3821            CPUID_7_0_EBX_AVX512ER,
3822        .features[FEAT_7_0_ECX] =
3823            CPUID_7_0_ECX_AVX512_VPOPCNTDQ,
3824        .features[FEAT_7_0_EDX] =
3825            CPUID_7_0_EDX_AVX512_4VNNIW | CPUID_7_0_EDX_AVX512_4FMAPS,
3826        .features[FEAT_XSAVE] =
3827            CPUID_XSAVE_XSAVEOPT,
3828        .features[FEAT_6_EAX] =
3829            CPUID_6_EAX_ARAT,
3830        .xlevel = 0x80000008,
3831        .model_id = "Intel Xeon Phi Processor (Knights Mill)",
3832    },
3833    {
3834        .name = "Opteron_G1",
3835        .level = 5,
3836        .vendor = CPUID_VENDOR_AMD,
3837        .family = 15,
3838        .model = 6,
3839        .stepping = 1,
3840        .features[FEAT_1_EDX] =
3841            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3842            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
3843            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
3844            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
3845            CPUID_DE | CPUID_FP87,
3846        .features[FEAT_1_ECX] =
3847            CPUID_EXT_SSE3,
3848        .features[FEAT_8000_0001_EDX] =
3849            CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
3850        .xlevel = 0x80000008,
3851        .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
3852    },
3853    {
3854        .name = "Opteron_G2",
3855        .level = 5,
3856        .vendor = CPUID_VENDOR_AMD,
3857        .family = 15,
3858        .model = 6,
3859        .stepping = 1,
3860        .features[FEAT_1_EDX] =
3861            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3862            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
3863            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
3864            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
3865            CPUID_DE | CPUID_FP87,
3866        .features[FEAT_1_ECX] =
3867            CPUID_EXT_CX16 | CPUID_EXT_SSE3,
3868        .features[FEAT_8000_0001_EDX] =
3869            CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
3870        .features[FEAT_8000_0001_ECX] =
3871            CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
3872        .xlevel = 0x80000008,
3873        .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
3874    },
3875    {
3876        .name = "Opteron_G3",
3877        .level = 5,
3878        .vendor = CPUID_VENDOR_AMD,
3879        .family = 16,
3880        .model = 2,
3881        .stepping = 3,
3882        .features[FEAT_1_EDX] =
3883            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3884            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
3885            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
3886            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
3887            CPUID_DE | CPUID_FP87,
3888        .features[FEAT_1_ECX] =
3889            CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
3890            CPUID_EXT_SSE3,
3891        .features[FEAT_8000_0001_EDX] =
3892            CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL |
3893            CPUID_EXT2_RDTSCP,
3894        .features[FEAT_8000_0001_ECX] =
3895            CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
3896            CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
3897        .xlevel = 0x80000008,
3898        .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
3899    },
3900    {
3901        .name = "Opteron_G4",
3902        .level = 0xd,
3903        .vendor = CPUID_VENDOR_AMD,
3904        .family = 21,
3905        .model = 1,
3906        .stepping = 2,
3907        .features[FEAT_1_EDX] =
3908            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3909            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
3910            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
3911            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
3912            CPUID_DE | CPUID_FP87,
3913        .features[FEAT_1_ECX] =
3914            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
3915            CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
3916            CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
3917            CPUID_EXT_SSE3,
3918        .features[FEAT_8000_0001_EDX] =
3919            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_NX |
3920            CPUID_EXT2_SYSCALL | CPUID_EXT2_RDTSCP,
3921        .features[FEAT_8000_0001_ECX] =
3922            CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
3923            CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
3924            CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
3925            CPUID_EXT3_LAHF_LM,
3926        .features[FEAT_SVM] =
3927            CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE,
3928        /* no xsaveopt! */
3929        .xlevel = 0x8000001A,
3930        .model_id = "AMD Opteron 62xx class CPU",
3931    },
3932    {
3933        .name = "Opteron_G5",
3934        .level = 0xd,
3935        .vendor = CPUID_VENDOR_AMD,
3936        .family = 21,
3937        .model = 2,
3938        .stepping = 0,
3939        .features[FEAT_1_EDX] =
3940            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3941            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
3942            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
3943            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
3944            CPUID_DE | CPUID_FP87,
3945        .features[FEAT_1_ECX] =
3946            CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
3947            CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
3948            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
3949            CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
3950        .features[FEAT_8000_0001_EDX] =
3951            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_NX |
3952            CPUID_EXT2_SYSCALL | CPUID_EXT2_RDTSCP,
3953        .features[FEAT_8000_0001_ECX] =
3954            CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
3955            CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
3956            CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
3957            CPUID_EXT3_LAHF_LM,
3958        .features[FEAT_SVM] =
3959            CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE,
3960        /* no xsaveopt! */
3961        .xlevel = 0x8000001A,
3962        .model_id = "AMD Opteron 63xx class CPU",
3963    },
3964    {
3965        .name = "EPYC",
3966        .level = 0xd,
3967        .vendor = CPUID_VENDOR_AMD,
3968        .family = 23,
3969        .model = 1,
3970        .stepping = 2,
3971        .features[FEAT_1_EDX] =
3972            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
3973            CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
3974            CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
3975            CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
3976            CPUID_VME | CPUID_FP87,
3977        .features[FEAT_1_ECX] =
3978            CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
3979            CPUID_EXT_XSAVE | CPUID_EXT_AES |  CPUID_EXT_POPCNT |
3980            CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
3981            CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
3982            CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
3983        .features[FEAT_8000_0001_EDX] =
3984            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
3985            CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
3986            CPUID_EXT2_SYSCALL,
3987        .features[FEAT_8000_0001_ECX] =
3988            CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
3989            CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
3990            CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
3991            CPUID_EXT3_TOPOEXT,
3992        .features[FEAT_7_0_EBX] =
3993            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
3994            CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
3995            CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
3996            CPUID_7_0_EBX_SHA_NI,
3997        .features[FEAT_XSAVE] =
3998            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
3999            CPUID_XSAVE_XGETBV1,
4000        .features[FEAT_6_EAX] =
4001            CPUID_6_EAX_ARAT,
4002        .features[FEAT_SVM] =
4003            CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE,
4004        .xlevel = 0x8000001E,
4005        .model_id = "AMD EPYC Processor",
4006        .cache_info = &epyc_cache_info,
4007        .versions = (X86CPUVersionDefinition[]) {
4008            { .version = 1 },
4009            {
4010                .version = 2,
4011                .alias = "EPYC-IBPB",
4012                .props = (PropValue[]) {
4013                    { "ibpb", "on" },
4014                    { "model-id",
4015                      "AMD EPYC Processor (with IBPB)" },
4016                    { /* end of list */ }
4017                }
4018            },
4019            {
4020                .version = 3,
4021                .props = (PropValue[]) {
4022                    { "ibpb", "on" },
4023                    { "perfctr-core", "on" },
4024                    { "clzero", "on" },
4025                    { "xsaveerptr", "on" },
4026                    { "xsaves", "on" },
4027                    { "model-id",
4028                      "AMD EPYC Processor" },
4029                    { /* end of list */ }
4030                }
4031            },
4032            { /* end of list */ }
4033        }
4034    },
4035    {
4036        .name = "Dhyana",
4037        .level = 0xd,
4038        .vendor = CPUID_VENDOR_HYGON,
4039        .family = 24,
4040        .model = 0,
4041        .stepping = 1,
4042        .features[FEAT_1_EDX] =
4043            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
4044            CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
4045            CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
4046            CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
4047            CPUID_VME | CPUID_FP87,
4048        .features[FEAT_1_ECX] =
4049            CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
4050            CPUID_EXT_XSAVE | CPUID_EXT_POPCNT |
4051            CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
4052            CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
4053            CPUID_EXT_MONITOR | CPUID_EXT_SSE3,
4054        .features[FEAT_8000_0001_EDX] =
4055            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
4056            CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
4057            CPUID_EXT2_SYSCALL,
4058        .features[FEAT_8000_0001_ECX] =
4059            CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
4060            CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
4061            CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
4062            CPUID_EXT3_TOPOEXT,
4063        .features[FEAT_8000_0008_EBX] =
4064            CPUID_8000_0008_EBX_IBPB,
4065        .features[FEAT_7_0_EBX] =
4066            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
4067            CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
4068            CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT,
4069        /* XSAVES is added in version 2 */
4070        .features[FEAT_XSAVE] =
4071            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
4072            CPUID_XSAVE_XGETBV1,
4073        .features[FEAT_6_EAX] =
4074            CPUID_6_EAX_ARAT,
4075        .features[FEAT_SVM] =
4076            CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE,
4077        .xlevel = 0x8000001E,
4078        .model_id = "Hygon Dhyana Processor",
4079        .cache_info = &epyc_cache_info,
4080        .versions = (X86CPUVersionDefinition[]) {
4081            { .version = 1 },
4082            { .version = 2,
4083              .note = "XSAVES",
4084              .props = (PropValue[]) {
4085                  { "xsaves", "on" },
4086                  { /* end of list */ }
4087              },
4088            },
4089            { /* end of list */ }
4090        }
4091    },
4092    {
4093        .name = "EPYC-Rome",
4094        .level = 0xd,
4095        .vendor = CPUID_VENDOR_AMD,
4096        .family = 23,
4097        .model = 49,
4098        .stepping = 0,
4099        .features[FEAT_1_EDX] =
4100            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
4101            CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
4102            CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
4103            CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
4104            CPUID_VME | CPUID_FP87,
4105        .features[FEAT_1_ECX] =
4106            CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
4107            CPUID_EXT_XSAVE | CPUID_EXT_AES |  CPUID_EXT_POPCNT |
4108            CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
4109            CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
4110            CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
4111        .features[FEAT_8000_0001_EDX] =
4112            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
4113            CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
4114            CPUID_EXT2_SYSCALL,
4115        .features[FEAT_8000_0001_ECX] =
4116            CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
4117            CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
4118            CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
4119            CPUID_EXT3_TOPOEXT | CPUID_EXT3_PERFCORE,
4120        .features[FEAT_8000_0008_EBX] =
4121            CPUID_8000_0008_EBX_CLZERO | CPUID_8000_0008_EBX_XSAVEERPTR |
4122            CPUID_8000_0008_EBX_WBNOINVD | CPUID_8000_0008_EBX_IBPB |
4123            CPUID_8000_0008_EBX_STIBP,
4124        .features[FEAT_7_0_EBX] =
4125            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
4126            CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
4127            CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
4128            CPUID_7_0_EBX_SHA_NI | CPUID_7_0_EBX_CLWB,
4129        .features[FEAT_7_0_ECX] =
4130            CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_RDPID,
4131        .features[FEAT_XSAVE] =
4132            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
4133            CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES,
4134        .features[FEAT_6_EAX] =
4135            CPUID_6_EAX_ARAT,
4136        .features[FEAT_SVM] =
4137            CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE,
4138        .xlevel = 0x8000001E,
4139        .model_id = "AMD EPYC-Rome Processor",
4140        .cache_info = &epyc_rome_cache_info,
4141        .versions = (X86CPUVersionDefinition[]) {
4142            { .version = 1 },
4143            {
4144                .version = 2,
4145                .props = (PropValue[]) {
4146                    { "ibrs", "on" },
4147                    { "amd-ssbd", "on" },
4148                    { /* end of list */ }
4149                }
4150            },
4151            { /* end of list */ }
4152        }
4153    },
4154    {
4155        .name = "EPYC-Milan",
4156        .level = 0xd,
4157        .vendor = CPUID_VENDOR_AMD,
4158        .family = 25,
4159        .model = 1,
4160        .stepping = 1,
4161        .features[FEAT_1_EDX] =
4162            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
4163            CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
4164            CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
4165            CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
4166            CPUID_VME | CPUID_FP87,
4167        .features[FEAT_1_ECX] =
4168            CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
4169            CPUID_EXT_XSAVE | CPUID_EXT_AES |  CPUID_EXT_POPCNT |
4170            CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
4171            CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
4172            CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
4173            CPUID_EXT_PCID,
4174        .features[FEAT_8000_0001_EDX] =
4175            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
4176            CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
4177            CPUID_EXT2_SYSCALL,
4178        .features[FEAT_8000_0001_ECX] =
4179            CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
4180            CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
4181            CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
4182            CPUID_EXT3_TOPOEXT | CPUID_EXT3_PERFCORE,
4183        .features[FEAT_8000_0008_EBX] =
4184            CPUID_8000_0008_EBX_CLZERO | CPUID_8000_0008_EBX_XSAVEERPTR |
4185            CPUID_8000_0008_EBX_WBNOINVD | CPUID_8000_0008_EBX_IBPB |
4186            CPUID_8000_0008_EBX_IBRS | CPUID_8000_0008_EBX_STIBP |
4187            CPUID_8000_0008_EBX_AMD_SSBD,
4188        .features[FEAT_7_0_EBX] =
4189            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
4190            CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
4191            CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
4192            CPUID_7_0_EBX_SHA_NI | CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_ERMS |
4193            CPUID_7_0_EBX_INVPCID,
4194        .features[FEAT_7_0_ECX] =
4195            CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_PKU,
4196        .features[FEAT_7_0_EDX] =
4197            CPUID_7_0_EDX_FSRM,
4198        .features[FEAT_XSAVE] =
4199            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
4200            CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES,
4201        .features[FEAT_6_EAX] =
4202            CPUID_6_EAX_ARAT,
4203        .features[FEAT_SVM] =
4204            CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE | CPUID_SVM_SVME_ADDR_CHK,
4205        .xlevel = 0x8000001E,
4206        .model_id = "AMD EPYC-Milan Processor",
4207        .cache_info = &epyc_milan_cache_info,
4208    },
4209};
4210
4211/*
4212 * We resolve CPU model aliases using -v1 when using "-machine
4213 * none", but this is just for compatibility while libvirt isn't
4214 * adapted to resolve CPU model versions before creating VMs.
4215 * See "Runnability guarantee of CPU models" at
4216 * docs/about/deprecated.rst.
4217 */
4218X86CPUVersion default_cpu_version = 1;
4219
4220void x86_cpu_set_default_version(X86CPUVersion version)
4221{
4222    /* Translating CPU_VERSION_AUTO to CPU_VERSION_AUTO doesn't make sense */
4223    assert(version != CPU_VERSION_AUTO);
4224    default_cpu_version = version;
4225}
4226
4227static X86CPUVersion x86_cpu_model_last_version(const X86CPUModel *model)
4228{
4229    int v = 0;
4230    const X86CPUVersionDefinition *vdef =
4231        x86_cpu_def_get_versions(model->cpudef);
4232    while (vdef->version) {
4233        v = vdef->version;
4234        vdef++;
4235    }
4236    return v;
4237}
4238
4239/* Return the actual version being used for a specific CPU model */
4240static X86CPUVersion x86_cpu_model_resolve_version(const X86CPUModel *model)
4241{
4242    X86CPUVersion v = model->version;
4243    if (v == CPU_VERSION_AUTO) {
4244        v = default_cpu_version;
4245    }
4246    if (v == CPU_VERSION_LATEST) {
4247        return x86_cpu_model_last_version(model);
4248    }
4249    return v;
4250}
4251
4252static Property max_x86_cpu_properties[] = {
4253    DEFINE_PROP_BOOL("migratable", X86CPU, migratable, true),
4254    DEFINE_PROP_BOOL("host-cache-info", X86CPU, cache_info_passthrough, false),
4255    DEFINE_PROP_END_OF_LIST()
4256};
4257
4258static void max_x86_cpu_class_init(ObjectClass *oc, void *data)
4259{
4260    DeviceClass *dc = DEVICE_CLASS(oc);
4261    X86CPUClass *xcc = X86_CPU_CLASS(oc);
4262
4263    xcc->ordering = 9;
4264
4265    xcc->model_description =
4266        "Enables all features supported by the accelerator in the current host";
4267
4268    device_class_set_props(dc, max_x86_cpu_properties);
4269}
4270
4271static void max_x86_cpu_initfn(Object *obj)
4272{
4273    X86CPU *cpu = X86_CPU(obj);
4274
4275    /* We can't fill the features array here because we don't know yet if
4276     * "migratable" is true or false.
4277     */
4278    cpu->max_features = true;
4279    object_property_set_bool(OBJECT(cpu), "pmu", true, &error_abort);
4280
4281    /*
4282     * these defaults are used for TCG and all other accelerators
4283     * besides KVM and HVF, which overwrite these values
4284     */
4285    object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD,
4286                            &error_abort);
4287#ifdef TARGET_X86_64
4288    object_property_set_int(OBJECT(cpu), "family", 15, &error_abort);
4289    object_property_set_int(OBJECT(cpu), "model", 107, &error_abort);
4290    object_property_set_int(OBJECT(cpu), "stepping", 1, &error_abort);
4291#else
4292    object_property_set_int(OBJECT(cpu), "family", 6, &error_abort);
4293    object_property_set_int(OBJECT(cpu), "model", 6, &error_abort);
4294    object_property_set_int(OBJECT(cpu), "stepping", 3, &error_abort);
4295#endif
4296    object_property_set_str(OBJECT(cpu), "model-id",
4297                            "QEMU TCG CPU version " QEMU_HW_VERSION,
4298                            &error_abort);
4299}
4300
4301static const TypeInfo max_x86_cpu_type_info = {
4302    .name = X86_CPU_TYPE_NAME("max"),
4303    .parent = TYPE_X86_CPU,
4304    .instance_init = max_x86_cpu_initfn,
4305    .class_init = max_x86_cpu_class_init,
4306};
4307
4308static char *feature_word_description(FeatureWordInfo *f, uint32_t bit)
4309{
4310    assert(f->type == CPUID_FEATURE_WORD || f->type == MSR_FEATURE_WORD);
4311
4312    switch (f->type) {
4313    case CPUID_FEATURE_WORD:
4314        {
4315            const char *reg = get_register_name_32(f->cpuid.reg);
4316            assert(reg);
4317            return g_strdup_printf("CPUID.%02XH:%s",
4318                                   f->cpuid.eax, reg);
4319        }
4320    case MSR_FEATURE_WORD:
4321        return g_strdup_printf("MSR(%02XH)",
4322                               f->msr.index);
4323    }
4324
4325    return NULL;
4326}
4327
4328static bool x86_cpu_have_filtered_features(X86CPU *cpu)
4329{
4330    FeatureWord w;
4331
4332    for (w = 0; w < FEATURE_WORDS; w++) {
4333        if (cpu->filtered_features[w]) {
4334            return true;
4335        }
4336    }
4337
4338    return false;
4339}
4340
4341static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t mask,
4342                                      const char *verbose_prefix)
4343{
4344    CPUX86State *env = &cpu->env;
4345    FeatureWordInfo *f = &feature_word_info[w];
4346    int i;
4347
4348    if (!cpu->force_features) {
4349        env->features[w] &= ~mask;
4350    }
4351    cpu->filtered_features[w] |= mask;
4352
4353    if (!verbose_prefix) {
4354        return;
4355    }
4356
4357    for (i = 0; i < 64; ++i) {
4358        if ((1ULL << i) & mask) {
4359            g_autofree char *feat_word_str = feature_word_description(f, i);
4360            warn_report("%s: %s%s%s [bit %d]",
4361                        verbose_prefix,
4362                        feat_word_str,
4363                        f->feat_names[i] ? "." : "",
4364                        f->feat_names[i] ? f->feat_names[i] : "", i);
4365        }
4366    }
4367}
4368
4369static void x86_cpuid_version_get_family(Object *obj, Visitor *v,
4370                                         const char *name, void *opaque,
4371                                         Error **errp)
4372{
4373    X86CPU *cpu = X86_CPU(obj);
4374    CPUX86State *env = &cpu->env;
4375    int64_t value;
4376
4377    value = (env->cpuid_version >> 8) & 0xf;
4378    if (value == 0xf) {
4379        value += (env->cpuid_version >> 20) & 0xff;
4380    }
4381    visit_type_int(v, name, &value, errp);
4382}
4383
4384static void x86_cpuid_version_set_family(Object *obj, Visitor *v,
4385                                         const char *name, void *opaque,
4386                                         Error **errp)
4387{
4388    X86CPU *cpu = X86_CPU(obj);
4389    CPUX86State *env = &cpu->env;
4390    const int64_t min = 0;
4391    const int64_t max = 0xff + 0xf;
4392    int64_t value;
4393
4394    if (!visit_type_int(v, name, &value, errp)) {
4395        return;
4396    }
4397    if (value < min || value > max) {
4398        error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
4399                   name ? name : "null", value, min, max);
4400        return;
4401    }
4402
4403    env->cpuid_version &= ~0xff00f00;
4404    if (value > 0x0f) {
4405        env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
4406    } else {
4407        env->cpuid_version |= value << 8;
4408    }
4409}
4410
4411static void x86_cpuid_version_get_model(Object *obj, Visitor *v,
4412                                        const char *name, void *opaque,
4413                                        Error **errp)
4414{
4415    X86CPU *cpu = X86_CPU(obj);
4416    CPUX86State *env = &cpu->env;
4417    int64_t value;
4418
4419    value = (env->cpuid_version >> 4) & 0xf;
4420    value |= ((env->cpuid_version >> 16) & 0xf) << 4;
4421    visit_type_int(v, name, &value, errp);
4422}
4423
4424static void x86_cpuid_version_set_model(Object *obj, Visitor *v,
4425                                        const char *name, void *opaque,
4426                                        Error **errp)
4427{
4428    X86CPU *cpu = X86_CPU(obj);
4429    CPUX86State *env = &cpu->env;
4430    const int64_t min = 0;
4431    const int64_t max = 0xff;
4432    int64_t value;
4433
4434    if (!visit_type_int(v, name, &value, errp)) {
4435        return;
4436    }
4437    if (value < min || value > max) {
4438        error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
4439                   name ? name : "null", value, min, max);
4440        return;
4441    }
4442
4443    env->cpuid_version &= ~0xf00f0;
4444    env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
4445}
4446
4447static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
4448                                           const char *name, void *opaque,
4449                                           Error **errp)
4450{
4451    X86CPU *cpu = X86_CPU(obj);
4452    CPUX86State *env = &cpu->env;
4453    int64_t value;
4454
4455    value = env->cpuid_version & 0xf;
4456    visit_type_int(v, name, &value, errp);
4457}
4458
4459static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
4460                                           const char *name, void *opaque,
4461                                           Error **errp)
4462{
4463    X86CPU *cpu = X86_CPU(obj);
4464    CPUX86State *env = &cpu->env;
4465    const int64_t min = 0;
4466    const int64_t max = 0xf;
4467    int64_t value;
4468
4469    if (!visit_type_int(v, name, &value, errp)) {
4470        return;
4471    }
4472    if (value < min || value > max) {
4473        error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
4474                   name ? name : "null", value, min, max);
4475        return;
4476    }
4477
4478    env->cpuid_version &= ~0xf;
4479    env->cpuid_version |= value & 0xf;
4480}
4481
4482static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
4483{
4484    X86CPU *cpu = X86_CPU(obj);
4485    CPUX86State *env = &cpu->env;
4486    char *value;
4487
4488    value = g_malloc(CPUID_VENDOR_SZ + 1);
4489    x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
4490                             env->cpuid_vendor3);
4491    return value;
4492}
4493
4494static void x86_cpuid_set_vendor(Object *obj, const char *value,
4495                                 Error **errp)
4496{
4497    X86CPU *cpu = X86_CPU(obj);
4498    CPUX86State *env = &cpu->env;
4499    int i;
4500
4501    if (strlen(value) != CPUID_VENDOR_SZ) {
4502        error_setg(errp, QERR_PROPERTY_VALUE_BAD, "", "vendor", value);
4503        return;
4504    }
4505
4506    env->cpuid_vendor1 = 0;
4507    env->cpuid_vendor2 = 0;
4508    env->cpuid_vendor3 = 0;
4509    for (i = 0; i < 4; i++) {
4510        env->cpuid_vendor1 |= ((uint8_t)value[i    ]) << (8 * i);
4511        env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
4512        env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
4513    }
4514}
4515
4516static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
4517{
4518    X86CPU *cpu = X86_CPU(obj);
4519    CPUX86State *env = &cpu->env;
4520    char *value;
4521    int i;
4522
4523    value = g_malloc(48 + 1);
4524    for (i = 0; i < 48; i++) {
4525        value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
4526    }
4527    value[48] = '\0';
4528    return value;
4529}
4530
4531static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
4532                                   Error **errp)
4533{
4534    X86CPU *cpu = X86_CPU(obj);
4535    CPUX86State *env = &cpu->env;
4536    int c, len, i;
4537
4538    if (model_id == NULL) {
4539        model_id = "";
4540    }
4541    len = strlen(model_id);
4542    memset(env->cpuid_model, 0, 48);
4543    for (i = 0; i < 48; i++) {
4544        if (i >= len) {
4545            c = '\0';
4546        } else {
4547            c = (uint8_t)model_id[i];
4548        }
4549        env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
4550    }
4551}
4552
4553static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, const char *name,
4554                                   void *opaque, Error **errp)
4555{
4556    X86CPU *cpu = X86_CPU(obj);
4557    int64_t value;
4558
4559    value = cpu->env.tsc_khz * 1000;
4560    visit_type_int(v, name, &value, errp);
4561}
4562
4563static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
4564                                   void *opaque, Error **errp)
4565{
4566    X86CPU *cpu = X86_CPU(obj);
4567    const int64_t min = 0;
4568    const int64_t max = INT64_MAX;
4569    int64_t value;
4570
4571    if (!visit_type_int(v, name, &value, errp)) {
4572        return;
4573    }
4574    if (value < min || value > max) {
4575        error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
4576                   name ? name : "null", value, min, max);
4577        return;
4578    }
4579
4580    cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
4581}
4582
4583/* Generic getter for "feature-words" and "filtered-features" properties */
4584static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
4585                                      const char *name, void *opaque,
4586                                      Error **errp)
4587{
4588    uint64_t *array = (uint64_t *)opaque;
4589    FeatureWord w;
4590    X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
4591    X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
4592    X86CPUFeatureWordInfoList *list = NULL;
4593
4594    for (w = 0; w < FEATURE_WORDS; w++) {
4595        FeatureWordInfo *wi = &feature_word_info[w];
4596        /*
4597                * We didn't have MSR features when "feature-words" was
4598                *  introduced. Therefore skipped other type entries.
4599                */
4600        if (wi->type != CPUID_FEATURE_WORD) {
4601            continue;
4602        }
4603        X86CPUFeatureWordInfo *qwi = &word_infos[w];
4604        qwi->cpuid_input_eax = wi->cpuid.eax;
4605        qwi->has_cpuid_input_ecx = wi->cpuid.needs_ecx;
4606        qwi->cpuid_input_ecx = wi->cpuid.ecx;
4607        qwi->cpuid_register = x86_reg_info_32[wi->cpuid.reg].qapi_enum;
4608        qwi->features = array[w];
4609
4610        /* List will be in reverse order, but order shouldn't matter */
4611        list_entries[w].next = list;
4612        list_entries[w].value = &word_infos[w];
4613        list = &list_entries[w];
4614    }
4615
4616    visit_type_X86CPUFeatureWordInfoList(v, "feature-words", &list, errp);
4617}
4618
4619/* Convert all '_' in a feature string option name to '-', to make feature
4620 * name conform to QOM property naming rule, which uses '-' instead of '_'.
4621 */
4622static inline void feat2prop(char *s)
4623{
4624    while ((s = strchr(s, '_'))) {
4625        *s = '-';
4626    }
4627}
4628
4629/* Return the feature property name for a feature flag bit */
4630static const char *x86_cpu_feature_name(FeatureWord w, int bitnr)
4631{
4632    const char *name;
4633    /* XSAVE components are automatically enabled by other features,
4634     * so return the original feature name instead
4635     */
4636    if (w == FEAT_XSAVE_COMP_LO || w == FEAT_XSAVE_COMP_HI) {
4637        int comp = (w == FEAT_XSAVE_COMP_HI) ? bitnr + 32 : bitnr;
4638
4639        if (comp < ARRAY_SIZE(x86_ext_save_areas) &&
4640            x86_ext_save_areas[comp].bits) {
4641            w = x86_ext_save_areas[comp].feature;
4642            bitnr = ctz32(x86_ext_save_areas[comp].bits);
4643        }
4644    }
4645
4646    assert(bitnr < 64);
4647    assert(w < FEATURE_WORDS);
4648    name = feature_word_info[w].feat_names[bitnr];
4649    assert(bitnr < 32 || !(name && feature_word_info[w].type == CPUID_FEATURE_WORD));
4650    return name;
4651}
4652
4653/* Compatibily hack to maintain legacy +-feat semantic,
4654 * where +-feat overwrites any feature set by
4655 * feat=on|feat even if the later is parsed after +-feat
4656 * (i.e. "-x2apic,x2apic=on" will result in x2apic disabled)
4657 */
4658static GList *plus_features, *minus_features;
4659
4660static gint compare_string(gconstpointer a, gconstpointer b)
4661{
4662    return g_strcmp0(a, b);
4663}
4664
4665/* Parse "+feature,-feature,feature=foo" CPU feature string
4666 */
4667static void x86_cpu_parse_featurestr(const char *typename, char *features,
4668                                     Error **errp)
4669{
4670    char *featurestr; /* Single 'key=value" string being parsed */
4671    static bool cpu_globals_initialized;
4672    bool ambiguous = false;
4673
4674    if (cpu_globals_initialized) {
4675        return;
4676    }
4677    cpu_globals_initialized = true;
4678
4679    if (!features) {
4680        return;
4681    }
4682
4683    for (featurestr = strtok(features, ",");
4684         featurestr;
4685         featurestr = strtok(NULL, ",")) {
4686        const char *name;
4687        const char *val = NULL;
4688        char *eq = NULL;
4689        char num[32];
4690        GlobalProperty *prop;
4691
4692        /* Compatibility syntax: */
4693        if (featurestr[0] == '+') {
4694            plus_features = g_list_append(plus_features,
4695                                          g_strdup(featurestr + 1));
4696            continue;
4697        } else if (featurestr[0] == '-') {
4698            minus_features = g_list_append(minus_features,
4699                                           g_strdup(featurestr + 1));
4700            continue;
4701        }
4702
4703        eq = strchr(featurestr, '=');
4704        if (eq) {
4705            *eq++ = 0;
4706            val = eq;
4707        } else {
4708            val = "on";
4709        }
4710
4711        feat2prop(featurestr);
4712        name = featurestr;
4713
4714        if (g_list_find_custom(plus_features, name, compare_string)) {
4715            warn_report("Ambiguous CPU model string. "
4716                        "Don't mix both \"+%s\" and \"%s=%s\"",
4717                        name, name, val);
4718            ambiguous = true;
4719        }
4720        if (g_list_find_custom(minus_features, name, compare_string)) {
4721            warn_report("Ambiguous CPU model string. "
4722                        "Don't mix both \"-%s\" and \"%s=%s\"",
4723                        name, name, val);
4724            ambiguous = true;
4725        }
4726
4727        /* Special case: */
4728        if (!strcmp(name, "tsc-freq")) {
4729            int ret;
4730            uint64_t tsc_freq;
4731
4732            ret = qemu_strtosz_metric(val, NULL, &tsc_freq);
4733            if (ret < 0 || tsc_freq > INT64_MAX) {
4734                error_setg(errp, "bad numerical value %s", val);
4735                return;
4736            }
4737            snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
4738            val = num;
4739            name = "tsc-frequency";
4740        }
4741
4742        prop = g_new0(typeof(*prop), 1);
4743        prop->driver = typename;
4744        prop->property = g_strdup(name);
4745        prop->value = g_strdup(val);
4746        qdev_prop_register_global(prop);
4747    }
4748
4749    if (ambiguous) {
4750        warn_report("Compatibility of ambiguous CPU model "
4751                    "strings won't be kept on future QEMU versions");
4752    }
4753}
4754
4755static void x86_cpu_filter_features(X86CPU *cpu, bool verbose);
4756
4757/* Build a list with the name of all features on a feature word array */
4758static void x86_cpu_list_feature_names(FeatureWordArray features,
4759                                       strList **list)
4760{
4761    strList **tail = list;
4762    FeatureWord w;
4763
4764    for (w = 0; w < FEATURE_WORDS; w++) {
4765        uint64_t filtered = features[w];
4766        int i;
4767        for (i = 0; i < 64; i++) {
4768            if (filtered & (1ULL << i)) {
4769                QAPI_LIST_APPEND(tail, g_strdup(x86_cpu_feature_name(w, i)));
4770            }
4771        }
4772    }
4773}
4774
4775static void x86_cpu_get_unavailable_features(Object *obj, Visitor *v,
4776                                             const char *name, void *opaque,
4777                                             Error **errp)
4778{
4779    X86CPU *xc = X86_CPU(obj);
4780    strList *result = NULL;
4781
4782    x86_cpu_list_feature_names(xc->filtered_features, &result);
4783    visit_type_strList(v, "unavailable-features", &result, errp);
4784}
4785
4786/* Check for missing features that may prevent the CPU class from
4787 * running using the current machine and accelerator.
4788 */
4789static void x86_cpu_class_check_missing_features(X86CPUClass *xcc,
4790                                                 strList **list)
4791{
4792    strList **tail = list;
4793    X86CPU *xc;
4794    Error *err = NULL;
4795
4796    if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
4797        QAPI_LIST_APPEND(tail, g_strdup("kvm"));
4798        return;
4799    }
4800
4801    xc = X86_CPU(object_new_with_class(OBJECT_CLASS(xcc)));
4802
4803    x86_cpu_expand_features(xc, &err);
4804    if (err) {
4805        /* Errors at x86_cpu_expand_features should never happen,
4806         * but in case it does, just report the model as not
4807         * runnable at all using the "type" property.
4808         */
4809        QAPI_LIST_APPEND(tail, g_strdup("type"));
4810        error_free(err);
4811    }
4812
4813    x86_cpu_filter_features(xc, false);
4814
4815    x86_cpu_list_feature_names(xc->filtered_features, tail);
4816
4817    object_unref(OBJECT(xc));
4818}
4819
4820/* Print all cpuid feature names in featureset
4821 */
4822static void listflags(GList *features)
4823{
4824    size_t len = 0;
4825    GList *tmp;
4826
4827    for (tmp = features; tmp; tmp = tmp->next) {
4828        const char *name = tmp->data;
4829        if ((len + strlen(name) + 1) >= 75) {
4830            qemu_printf("\n");
4831            len = 0;
4832        }
4833        qemu_printf("%s%s", len == 0 ? "  " : " ", name);
4834        len += strlen(name) + 1;
4835    }
4836    qemu_printf("\n");
4837}
4838
4839/* Sort alphabetically by type name, respecting X86CPUClass::ordering. */
4840static gint x86_cpu_list_compare(gconstpointer a, gconstpointer b)
4841{
4842    ObjectClass *class_a = (ObjectClass *)a;
4843    ObjectClass *class_b = (ObjectClass *)b;
4844    X86CPUClass *cc_a = X86_CPU_CLASS(class_a);
4845    X86CPUClass *cc_b = X86_CPU_CLASS(class_b);
4846    int ret;
4847
4848    if (cc_a->ordering != cc_b->ordering) {
4849        ret = cc_a->ordering - cc_b->ordering;
4850    } else {
4851        g_autofree char *name_a = x86_cpu_class_get_model_name(cc_a);
4852        g_autofree char *name_b = x86_cpu_class_get_model_name(cc_b);
4853        ret = strcmp(name_a, name_b);
4854    }
4855    return ret;
4856}
4857
4858static GSList *get_sorted_cpu_model_list(void)
4859{
4860    GSList *list = object_class_get_list(TYPE_X86_CPU, false);
4861    list = g_slist_sort(list, x86_cpu_list_compare);
4862    return list;
4863}
4864
4865static char *x86_cpu_class_get_model_id(X86CPUClass *xc)
4866{
4867    Object *obj = object_new_with_class(OBJECT_CLASS(xc));
4868    char *r = object_property_get_str(obj, "model-id", &error_abort);
4869    object_unref(obj);
4870    return r;
4871}
4872
4873static char *x86_cpu_class_get_alias_of(X86CPUClass *cc)
4874{
4875    X86CPUVersion version;
4876
4877    if (!cc->model || !cc->model->is_alias) {
4878        return NULL;
4879    }
4880    version = x86_cpu_model_resolve_version(cc->model);
4881    if (version <= 0) {
4882        return NULL;
4883    }
4884    return x86_cpu_versioned_model_name(cc->model->cpudef, version);
4885}
4886
4887static void x86_cpu_list_entry(gpointer data, gpointer user_data)
4888{
4889    ObjectClass *oc = data;
4890    X86CPUClass *cc = X86_CPU_CLASS(oc);
4891    g_autofree char *name = x86_cpu_class_get_model_name(cc);
4892    g_autofree char *desc = g_strdup(cc->model_description);
4893    g_autofree char *alias_of = x86_cpu_class_get_alias_of(cc);
4894    g_autofree char *model_id = x86_cpu_class_get_model_id(cc);
4895
4896    if (!desc && alias_of) {
4897        if (cc->model && cc->model->version == CPU_VERSION_AUTO) {
4898            desc = g_strdup("(alias configured by machine type)");
4899        } else {
4900            desc = g_strdup_printf("(alias of %s)", alias_of);
4901        }
4902    }
4903    if (!desc && cc->model && cc->model->note) {
4904        desc = g_strdup_printf("%s [%s]", model_id, cc->model->note);
4905    }
4906    if (!desc) {
4907        desc = g_strdup_printf("%s", model_id);
4908    }
4909
4910    qemu_printf("x86 %-20s  %s\n", name, desc);
4911}
4912
4913/* list available CPU models and flags */
4914void x86_cpu_list(void)
4915{
4916    int i, j;
4917    GSList *list;
4918    GList *names = NULL;
4919
4920    qemu_printf("Available CPUs:\n");
4921    list = get_sorted_cpu_model_list();
4922    g_slist_foreach(list, x86_cpu_list_entry, NULL);
4923    g_slist_free(list);
4924
4925    names = NULL;
4926    for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
4927        FeatureWordInfo *fw = &feature_word_info[i];
4928        for (j = 0; j < 64; j++) {
4929            if (fw->feat_names[j]) {
4930                names = g_list_append(names, (gpointer)fw->feat_names[j]);
4931            }
4932        }
4933    }
4934
4935    names = g_list_sort(names, (GCompareFunc)strcmp);
4936
4937    qemu_printf("\nRecognized CPUID flags:\n");
4938    listflags(names);
4939    qemu_printf("\n");
4940    g_list_free(names);
4941}
4942
4943static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
4944{
4945    ObjectClass *oc = data;
4946    X86CPUClass *cc = X86_CPU_CLASS(oc);
4947    CpuDefinitionInfoList **cpu_list = user_data;
4948    CpuDefinitionInfo *info;
4949
4950    info = g_malloc0(sizeof(*info));
4951    info->name = x86_cpu_class_get_model_name(cc);
4952    x86_cpu_class_check_missing_features(cc, &info->unavailable_features);
4953    info->has_unavailable_features = true;
4954    info->q_typename = g_strdup(object_class_get_name(oc));
4955    info->migration_safe = cc->migration_safe;
4956    info->has_migration_safe = true;
4957    info->q_static = cc->static_model;
4958    if (cc->model && cc->model->cpudef->deprecation_note) {
4959        info->deprecated = true;
4960    } else {
4961        info->deprecated = false;
4962    }
4963    /*
4964     * Old machine types won't report aliases, so that alias translation
4965     * doesn't break compatibility with previous QEMU versions.
4966     */
4967    if (default_cpu_version != CPU_VERSION_LEGACY) {
4968        info->alias_of = x86_cpu_class_get_alias_of(cc);
4969        info->has_alias_of = !!info->alias_of;
4970    }
4971
4972    QAPI_LIST_PREPEND(*cpu_list, info);
4973}
4974
4975CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
4976{
4977    CpuDefinitionInfoList *cpu_list = NULL;
4978    GSList *list = get_sorted_cpu_model_list();
4979    g_slist_foreach(list, x86_cpu_definition_entry, &cpu_list);
4980    g_slist_free(list);
4981    return cpu_list;
4982}
4983
4984uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
4985                                            bool migratable_only)
4986{
4987    FeatureWordInfo *wi = &feature_word_info[w];
4988    uint64_t r = 0;
4989
4990    if (kvm_enabled()) {
4991        switch (wi->type) {
4992        case CPUID_FEATURE_WORD:
4993            r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid.eax,
4994                                                        wi->cpuid.ecx,
4995                                                        wi->cpuid.reg);
4996            break;
4997        case MSR_FEATURE_WORD:
4998            r = kvm_arch_get_supported_msr_feature(kvm_state,
4999                        wi->msr.index);
5000            break;
5001        }
5002    } else if (hvf_enabled()) {
5003        if (wi->type != CPUID_FEATURE_WORD) {
5004            return 0;
5005        }
5006        r = hvf_get_supported_cpuid(wi->cpuid.eax,
5007                                    wi->cpuid.ecx,
5008                                    wi->cpuid.reg);
5009    } else if (tcg_enabled()) {
5010        r = wi->tcg_features;
5011    } else {
5012        return ~0;
5013    }
5014#ifndef TARGET_X86_64
5015    if (w == FEAT_8000_0001_EDX) {
5016        r &= ~CPUID_EXT2_LM;
5017    }
5018#endif
5019    if (migratable_only) {
5020        r &= x86_cpu_get_migratable_flags(w);
5021    }
5022    return r;
5023}
5024
5025/*
5026 * Only for builtin_x86_defs models initialized with x86_register_cpudef_types.
5027 */
5028void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
5029{
5030    PropValue *pv;
5031    for (pv = props; pv->prop; pv++) {
5032        if (!pv->value) {
5033            continue;
5034        }
5035        object_property_parse(OBJECT(cpu), pv->prop, pv->value,
5036                              &error_abort);
5037    }
5038}
5039
5040/*
5041 * Apply properties for the CPU model version specified in model.
5042 * Only for builtin_x86_defs models initialized with x86_register_cpudef_types.
5043 */
5044
5045static void x86_cpu_apply_version_props(X86CPU *cpu, X86CPUModel *model)
5046{
5047    const X86CPUVersionDefinition *vdef;
5048    X86CPUVersion version = x86_cpu_model_resolve_version(model);
5049
5050    if (version == CPU_VERSION_LEGACY) {
5051        return;
5052    }
5053
5054    for (vdef = x86_cpu_def_get_versions(model->cpudef); vdef->version; vdef++) {
5055        PropValue *p;
5056
5057        for (p = vdef->props; p && p->prop; p++) {
5058            object_property_parse(OBJECT(cpu), p->prop, p->value,
5059                                  &error_abort);
5060        }
5061
5062        if (vdef->version == version) {
5063            break;
5064        }
5065    }
5066
5067    /*
5068     * If we reached the end of the list, version number was invalid
5069     */
5070    assert(vdef->version == version);
5071}
5072
5073/*
5074 * Load data from X86CPUDefinition into a X86CPU object.
5075 * Only for builtin_x86_defs models initialized with x86_register_cpudef_types.
5076 */
5077static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model)
5078{
5079    const X86CPUDefinition *def = model->cpudef;
5080    CPUX86State *env = &cpu->env;
5081    FeatureWord w;
5082
5083    /*NOTE: any property set by this function should be returned by
5084     * x86_cpu_static_props(), so static expansion of
5085     * query-cpu-model-expansion is always complete.
5086     */
5087
5088    /* CPU models only set _minimum_ values for level/xlevel: */
5089    object_property_set_uint(OBJECT(cpu), "min-level", def->level,
5090                             &error_abort);
5091    object_property_set_uint(OBJECT(cpu), "min-xlevel", def->xlevel,
5092                             &error_abort);
5093
5094    object_property_set_int(OBJECT(cpu), "family", def->family, &error_abort);
5095    object_property_set_int(OBJECT(cpu), "model", def->model, &error_abort);
5096    object_property_set_int(OBJECT(cpu), "stepping", def->stepping,
5097                            &error_abort);
5098    object_property_set_str(OBJECT(cpu), "model-id", def->model_id,
5099                            &error_abort);
5100    for (w = 0; w < FEATURE_WORDS; w++) {
5101        env->features[w] = def->features[w];
5102    }
5103
5104    /* legacy-cache defaults to 'off' if CPU model provides cache info */
5105    cpu->legacy_cache = !def->cache_info;
5106
5107    env->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
5108
5109    /* sysenter isn't supported in compatibility mode on AMD,
5110     * syscall isn't supported in compatibility mode on Intel.
5111     * Normally we advertise the actual CPU vendor, but you can
5112     * override this using the 'vendor' property if you want to use
5113     * KVM's sysenter/syscall emulation in compatibility mode and
5114     * when doing cross vendor migration
5115     */
5116
5117    /*
5118     * vendor property is set here but then overloaded with the
5119     * host cpu vendor for KVM and HVF.
5120     */
5121    object_property_set_str(OBJECT(cpu), "vendor", def->vendor, &error_abort);
5122
5123    x86_cpu_apply_version_props(cpu, model);
5124
5125    /*
5126     * Properties in versioned CPU model are not user specified features.
5127     * We can simply clear env->user_features here since it will be filled later
5128     * in x86_cpu_expand_features() based on plus_features and minus_features.
5129     */
5130    memset(&env->user_features, 0, sizeof(env->user_features));
5131}
5132
5133static gchar *x86_gdb_arch_name(CPUState *cs)
5134{
5135#ifdef TARGET_X86_64
5136    return g_strdup("i386:x86-64");
5137#else
5138    return g_strdup("i386");
5139#endif
5140}
5141
5142static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
5143{
5144    X86CPUModel *model = data;
5145    X86CPUClass *xcc = X86_CPU_CLASS(oc);
5146    CPUClass *cc = CPU_CLASS(oc);
5147
5148    xcc->model = model;
5149    xcc->migration_safe = true;
5150    cc->deprecation_note = model->cpudef->deprecation_note;
5151}
5152
5153static void x86_register_cpu_model_type(const char *name, X86CPUModel *model)
5154{
5155    g_autofree char *typename = x86_cpu_type_name(name);
5156    TypeInfo ti = {
5157        .name = typename,
5158        .parent = TYPE_X86_CPU,
5159        .class_init = x86_cpu_cpudef_class_init,
5160        .class_data = model,
5161    };
5162
5163    type_register(&ti);
5164}
5165
5166
5167/*
5168 * register builtin_x86_defs;
5169 * "max", "base" and subclasses ("host") are not registered here.
5170 * See x86_cpu_register_types for all model registrations.
5171 */
5172static void x86_register_cpudef_types(const X86CPUDefinition *def)
5173{
5174    X86CPUModel *m;
5175    const X86CPUVersionDefinition *vdef;
5176
5177    /* AMD aliases are handled at runtime based on CPUID vendor, so
5178     * they shouldn't be set on the CPU model table.
5179     */
5180    assert(!(def->features[FEAT_8000_0001_EDX] & CPUID_EXT2_AMD_ALIASES));
5181    /* catch mistakes instead of silently truncating model_id when too long */
5182    assert(def->model_id && strlen(def->model_id) <= 48);
5183
5184    /* Unversioned model: */
5185    m = g_new0(X86CPUModel, 1);
5186    m->cpudef = def;
5187    m->version = CPU_VERSION_AUTO;
5188    m->is_alias = true;
5189    x86_register_cpu_model_type(def->name, m);
5190
5191    /* Versioned models: */
5192
5193    for (vdef = x86_cpu_def_get_versions(def); vdef->version; vdef++) {
5194        X86CPUModel *m = g_new0(X86CPUModel, 1);
5195        g_autofree char *name =
5196            x86_cpu_versioned_model_name(def, vdef->version);
5197        m->cpudef = def;
5198        m->version = vdef->version;
5199        m->note = vdef->note;
5200        x86_register_cpu_model_type(name, m);
5201
5202        if (vdef->alias) {
5203            X86CPUModel *am = g_new0(X86CPUModel, 1);
5204            am->cpudef = def;
5205            am->version = vdef->version;
5206            am->is_alias = true;
5207            x86_register_cpu_model_type(vdef->alias, am);
5208        }
5209    }
5210
5211}
5212
5213uint32_t cpu_x86_virtual_addr_width(CPUX86State *env)
5214{
5215    if  (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_LA57) {
5216        return 57; /* 57 bits virtual */
5217    } else {
5218        return 48; /* 48 bits virtual */
5219    }
5220}
5221
5222void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
5223                   uint32_t *eax, uint32_t *ebx,
5224                   uint32_t *ecx, uint32_t *edx)
5225{
5226    X86CPU *cpu = env_archcpu(env);
5227    CPUState *cs = env_cpu(env);
5228    uint32_t die_offset;
5229    uint32_t limit;
5230    uint32_t signature[3];
5231    X86CPUTopoInfo topo_info;
5232
5233    topo_info.dies_per_pkg = env->nr_dies;
5234    topo_info.cores_per_die = cs->nr_cores;
5235    topo_info.threads_per_core = cs->nr_threads;
5236
5237    /* Calculate & apply limits for different index ranges */
5238    if (index >= 0xC0000000) {
5239        limit = env->cpuid_xlevel2;
5240    } else if (index >= 0x80000000) {
5241        limit = env->cpuid_xlevel;
5242    } else if (index >= 0x40000000) {
5243        limit = 0x40000001;
5244    } else {
5245        limit = env->cpuid_level;
5246    }
5247
5248    if (index > limit) {
5249        /* Intel documentation states that invalid EAX input will
5250         * return the same information as EAX=cpuid_level
5251         * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
5252         */
5253        index = env->cpuid_level;
5254    }
5255
5256    switch(index) {
5257    case 0:
5258        *eax = env->cpuid_level;
5259        *ebx = env->cpuid_vendor1;
5260        *edx = env->cpuid_vendor2;
5261        *ecx = env->cpuid_vendor3;
5262        break;
5263    case 1:
5264        *eax = env->cpuid_version;
5265        *ebx = (cpu->apic_id << 24) |
5266               8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
5267        *ecx = env->features[FEAT_1_ECX];
5268        if ((*ecx & CPUID_EXT_XSAVE) && (env->cr[4] & CR4_OSXSAVE_MASK)) {
5269            *ecx |= CPUID_EXT_OSXSAVE;
5270        }
5271        *edx = env->features[FEAT_1_EDX];
5272        if (cs->nr_cores * cs->nr_threads > 1) {
5273            *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
5274            *edx |= CPUID_HT;
5275        }
5276        if (!cpu->enable_pmu) {
5277            *ecx &= ~CPUID_EXT_PDCM;
5278        }
5279        break;
5280    case 2:
5281        /* cache info: needed for Pentium Pro compatibility */
5282        if (cpu->cache_info_passthrough) {
5283            host_cpuid(index, 0, eax, ebx, ecx, edx);
5284            break;
5285        } else if (cpu->vendor_cpuid_only && IS_AMD_CPU(env)) {
5286            *eax = *ebx = *ecx = *edx = 0;
5287            break;
5288        }
5289        *eax = 1; /* Number of CPUID[EAX=2] calls required */
5290        *ebx = 0;
5291        if (!cpu->enable_l3_cache) {
5292            *ecx = 0;
5293        } else {
5294            *ecx = cpuid2_cache_descriptor(env->cache_info_cpuid2.l3_cache);
5295        }
5296        *edx = (cpuid2_cache_descriptor(env->cache_info_cpuid2.l1d_cache) << 16) |
5297               (cpuid2_cache_descriptor(env->cache_info_cpuid2.l1i_cache) <<  8) |
5298               (cpuid2_cache_descriptor(env->cache_info_cpuid2.l2_cache));
5299        break;
5300    case 4:
5301        /* cache info: needed for Core compatibility */
5302        if (cpu->cache_info_passthrough) {
5303            host_cpuid(index, count, eax, ebx, ecx, edx);
5304            /* QEMU gives out its own APIC IDs, never pass down bits 31..26.  */
5305            *eax &= ~0xFC000000;
5306            if ((*eax & 31) && cs->nr_cores > 1) {
5307                *eax |= (cs->nr_cores - 1) << 26;
5308            }
5309        } else if (cpu->vendor_cpuid_only && IS_AMD_CPU(env)) {
5310            *eax = *ebx = *ecx = *edx = 0;
5311        } else {
5312            *eax = 0;
5313            switch (count) {
5314            case 0: /* L1 dcache info */
5315                encode_cache_cpuid4(env->cache_info_cpuid4.l1d_cache,
5316                                    1, cs->nr_cores,
5317                                    eax, ebx, ecx, edx);
5318                break;
5319            case 1: /* L1 icache info */
5320                encode_cache_cpuid4(env->cache_info_cpuid4.l1i_cache,
5321                                    1, cs->nr_cores,
5322                                    eax, ebx, ecx, edx);
5323                break;
5324            case 2: /* L2 cache info */
5325                encode_cache_cpuid4(env->cache_info_cpuid4.l2_cache,
5326                                    cs->nr_threads, cs->nr_cores,
5327                                    eax, ebx, ecx, edx);
5328                break;
5329            case 3: /* L3 cache info */
5330                die_offset = apicid_die_offset(&topo_info);
5331                if (cpu->enable_l3_cache) {
5332                    encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache,
5333                                        (1 << die_offset), cs->nr_cores,
5334                                        eax, ebx, ecx, edx);
5335                    break;
5336                }
5337                /* fall through */
5338            default: /* end of info */
5339                *eax = *ebx = *ecx = *edx = 0;
5340                break;
5341            }
5342        }
5343        break;
5344    case 5:
5345        /* MONITOR/MWAIT Leaf */
5346        *eax = cpu->mwait.eax; /* Smallest monitor-line size in bytes */
5347        *ebx = cpu->mwait.ebx; /* Largest monitor-line size in bytes */
5348        *ecx = cpu->mwait.ecx; /* flags */
5349        *edx = cpu->mwait.edx; /* mwait substates */
5350        break;
5351    case 6:
5352        /* Thermal and Power Leaf */
5353        *eax = env->features[FEAT_6_EAX];
5354        *ebx = 0;
5355        *ecx = 0;
5356        *edx = 0;
5357        break;
5358    case 7:
5359        /* Structured Extended Feature Flags Enumeration Leaf */
5360        if (count == 0) {
5361            /* Maximum ECX value for sub-leaves */
5362            *eax = env->cpuid_level_func7;
5363            *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
5364            *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */
5365            if ((*ecx & CPUID_7_0_ECX_PKU) && env->cr[4] & CR4_PKE_MASK) {
5366                *ecx |= CPUID_7_0_ECX_OSPKE;
5367            }
5368            *edx = env->features[FEAT_7_0_EDX]; /* Feature flags */
5369
5370            /*
5371             * SGX cannot be emulated in software.  If hardware does not
5372             * support enabling SGX and/or SGX flexible launch control,
5373             * then we need to update the VM's CPUID values accordingly.
5374             */
5375            if ((*ebx & CPUID_7_0_EBX_SGX) &&
5376                (!kvm_enabled() ||
5377                 !(kvm_arch_get_supported_cpuid(cs->kvm_state, 0x7, 0, R_EBX) &
5378                    CPUID_7_0_EBX_SGX))) {
5379                *ebx &= ~CPUID_7_0_EBX_SGX;
5380            }
5381
5382            if ((*ecx & CPUID_7_0_ECX_SGX_LC) &&
5383                (!(*ebx & CPUID_7_0_EBX_SGX) || !kvm_enabled() ||
5384                 !(kvm_arch_get_supported_cpuid(cs->kvm_state, 0x7, 0, R_ECX) &
5385                    CPUID_7_0_ECX_SGX_LC))) {
5386                *ecx &= ~CPUID_7_0_ECX_SGX_LC;
5387            }
5388        } else if (count == 1) {
5389            *eax = env->features[FEAT_7_1_EAX];
5390            *ebx = 0;
5391            *ecx = 0;
5392            *edx = 0;
5393        } else {
5394            *eax = 0;
5395            *ebx = 0;
5396            *ecx = 0;
5397            *edx = 0;
5398        }
5399        break;
5400    case 9:
5401        /* Direct Cache Access Information Leaf */
5402        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
5403        *ebx = 0;
5404        *ecx = 0;
5405        *edx = 0;
5406        break;
5407    case 0xA:
5408        /* Architectural Performance Monitoring Leaf */
5409        if (kvm_enabled() && cpu->enable_pmu) {
5410            KVMState *s = cs->kvm_state;
5411
5412            *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
5413            *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
5414            *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
5415            *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
5416        } else if (hvf_enabled() && cpu->enable_pmu) {
5417            *eax = hvf_get_supported_cpuid(0xA, count, R_EAX);
5418            *ebx = hvf_get_supported_cpuid(0xA, count, R_EBX);
5419            *ecx = hvf_get_supported_cpuid(0xA, count, R_ECX);
5420            *edx = hvf_get_supported_cpuid(0xA, count, R_EDX);
5421        } else {
5422            *eax = 0;
5423            *ebx = 0;
5424            *ecx = 0;
5425            *edx = 0;
5426        }
5427        break;
5428    case 0xB:
5429        /* Extended Topology Enumeration Leaf */
5430        if (!cpu->enable_cpuid_0xb) {
5431                *eax = *ebx = *ecx = *edx = 0;
5432                break;
5433        }
5434
5435        *ecx = count & 0xff;
5436        *edx = cpu->apic_id;
5437
5438        switch (count) {
5439        case 0:
5440            *eax = apicid_core_offset(&topo_info);
5441            *ebx = cs->nr_threads;
5442            *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
5443            break;
5444        case 1:
5445            *eax = apicid_pkg_offset(&topo_info);
5446            *ebx = cs->nr_cores * cs->nr_threads;
5447            *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
5448            break;
5449        default:
5450            *eax = 0;
5451            *ebx = 0;
5452            *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
5453        }
5454
5455        assert(!(*eax & ~0x1f));
5456        *ebx &= 0xffff; /* The count doesn't need to be reliable. */
5457        break;
5458    case 0x1F:
5459        /* V2 Extended Topology Enumeration Leaf */
5460        if (env->nr_dies < 2) {
5461            *eax = *ebx = *ecx = *edx = 0;
5462            break;
5463        }
5464
5465        *ecx = count & 0xff;
5466        *edx = cpu->apic_id;
5467        switch (count) {
5468        case 0:
5469            *eax = apicid_core_offset(&topo_info);
5470            *ebx = cs->nr_threads;
5471            *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
5472            break;
5473        case 1:
5474            *eax = apicid_die_offset(&topo_info);
5475            *ebx = cs->nr_cores * cs->nr_threads;
5476            *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
5477            break;
5478        case 2:
5479            *eax = apicid_pkg_offset(&topo_info);
5480            *ebx = env->nr_dies * cs->nr_cores * cs->nr_threads;
5481            *ecx |= CPUID_TOPOLOGY_LEVEL_DIE;
5482            break;
5483        default:
5484            *eax = 0;
5485            *ebx = 0;
5486            *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
5487        }
5488        assert(!(*eax & ~0x1f));
5489        *ebx &= 0xffff; /* The count doesn't need to be reliable. */
5490        break;
5491    case 0xD: {
5492        /* Processor Extended State */
5493        *eax = 0;
5494        *ebx = 0;
5495        *ecx = 0;
5496        *edx = 0;
5497        if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
5498            break;
5499        }
5500
5501        if (count == 0) {
5502            *ecx = xsave_area_size(x86_cpu_xsave_components(cpu));
5503            *eax = env->features[FEAT_XSAVE_COMP_LO];
5504            *edx = env->features[FEAT_XSAVE_COMP_HI];
5505            /*
5506             * The initial value of xcr0 and ebx == 0, On host without kvm
5507             * commit 412a3c41(e.g., CentOS 6), the ebx's value always == 0
5508             * even through guest update xcr0, this will crash some legacy guest
5509             * (e.g., CentOS 6), So set ebx == ecx to workaroud it.
5510             */
5511            *ebx = kvm_enabled() ? *ecx : xsave_area_size(env->xcr0);
5512        } else if (count == 1) {
5513            *eax = env->features[FEAT_XSAVE];
5514        } else if (count < ARRAY_SIZE(x86_ext_save_areas)) {
5515            if ((x86_cpu_xsave_components(cpu) >> count) & 1) {
5516                const ExtSaveArea *esa = &x86_ext_save_areas[count];
5517                *eax = esa->size;
5518                *ebx = esa->offset;
5519                *ecx = esa->ecx &
5520                       (ESA_FEATURE_ALIGN64_MASK | ESA_FEATURE_XFD_MASK);
5521            }
5522        }
5523        break;
5524    }
5525    case 0x12:
5526#ifndef CONFIG_USER_ONLY
5527        if (!kvm_enabled() ||
5528            !(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SGX)) {
5529            *eax = *ebx = *ecx = *edx = 0;
5530            break;
5531        }
5532
5533        /*
5534         * SGX sub-leafs CPUID.0x12.{0x2..N} enumerate EPC sections.  Retrieve
5535         * the EPC properties, e.g. confidentiality and integrity, from the
5536         * host's first EPC section, i.e. assume there is one EPC section or
5537         * that all EPC sections have the same security properties.
5538         */
5539        if (count > 1) {
5540            uint64_t epc_addr, epc_size;
5541
5542            if (sgx_epc_get_section(count - 2, &epc_addr, &epc_size)) {
5543                *eax = *ebx = *ecx = *edx = 0;
5544                break;
5545            }
5546            host_cpuid(index, 2, eax, ebx, ecx, edx);
5547            *eax = (uint32_t)(epc_addr & 0xfffff000) | 0x1;
5548            *ebx = (uint32_t)(epc_addr >> 32);
5549            *ecx = (uint32_t)(epc_size & 0xfffff000) | (*ecx & 0xf);
5550            *edx = (uint32_t)(epc_size >> 32);
5551            break;
5552        }
5553
5554        /*
5555         * SGX sub-leafs CPUID.0x12.{0x0,0x1} are heavily dependent on hardware
5556         * and KVM, i.e. QEMU cannot emulate features to override what KVM
5557         * supports.  Features can be further restricted by userspace, but not
5558         * made more permissive.
5559         */
5560        *eax = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_EAX);
5561        *ebx = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_EBX);
5562        *ecx = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_ECX);
5563        *edx = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x12, count, R_EDX);
5564
5565        if (count == 0) {
5566            *eax &= env->features[FEAT_SGX_12_0_EAX];
5567            *ebx &= env->features[FEAT_SGX_12_0_EBX];
5568        } else {
5569            *eax &= env->features[FEAT_SGX_12_1_EAX];
5570            *ebx &= 0; /* ebx reserve */
5571            *ecx &= env->features[FEAT_XSAVE_COMP_LO];
5572            *edx &= env->features[FEAT_XSAVE_COMP_HI];
5573
5574            /* FP and SSE are always allowed regardless of XSAVE/XCR0. */
5575            *ecx |= XSTATE_FP_MASK | XSTATE_SSE_MASK;
5576
5577            /* Access to PROVISIONKEY requires additional credentials. */
5578            if ((*eax & (1U << 4)) &&
5579                !kvm_enable_sgx_provisioning(cs->kvm_state)) {
5580                *eax &= ~(1U << 4);
5581            }
5582        }
5583#endif
5584        break;
5585    case 0x14: {
5586        /* Intel Processor Trace Enumeration */
5587        *eax = 0;
5588        *ebx = 0;
5589        *ecx = 0;
5590        *edx = 0;
5591        if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) ||
5592            !kvm_enabled()) {
5593            break;
5594        }
5595
5596        if (count == 0) {
5597            *eax = INTEL_PT_MAX_SUBLEAF;
5598            *ebx = INTEL_PT_MINIMAL_EBX;
5599            *ecx = INTEL_PT_MINIMAL_ECX;
5600            if (env->features[FEAT_14_0_ECX] & CPUID_14_0_ECX_LIP) {
5601                *ecx |= CPUID_14_0_ECX_LIP;
5602            }
5603        } else if (count == 1) {
5604            *eax = INTEL_PT_MTC_BITMAP | INTEL_PT_ADDR_RANGES_NUM;
5605            *ebx = INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP;
5606        }
5607        break;
5608    }
5609    case 0x1D: {
5610        /* AMX TILE */
5611        *eax = 0;
5612        *ebx = 0;
5613        *ecx = 0;
5614        *edx = 0;
5615        if (!(env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_AMX_TILE)) {
5616            break;
5617        }
5618
5619        if (count == 0) {
5620            /* Highest numbered palette subleaf */
5621            *eax = INTEL_AMX_TILE_MAX_SUBLEAF;
5622        } else if (count == 1) {
5623            *eax = INTEL_AMX_TOTAL_TILE_BYTES |
5624                   (INTEL_AMX_BYTES_PER_TILE << 16);
5625            *ebx = INTEL_AMX_BYTES_PER_ROW | (INTEL_AMX_TILE_MAX_NAMES << 16);
5626            *ecx = INTEL_AMX_TILE_MAX_ROWS;
5627        }
5628        break;
5629    }
5630    case 0x1E: {
5631        /* AMX TMUL */
5632        *eax = 0;
5633        *ebx = 0;
5634        *ecx = 0;
5635        *edx = 0;
5636        if (!(env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_AMX_TILE)) {
5637            break;
5638        }
5639
5640        if (count == 0) {
5641            /* Highest numbered palette subleaf */
5642            *ebx = INTEL_AMX_TMUL_MAX_K | (INTEL_AMX_TMUL_MAX_N << 8);
5643        }
5644        break;
5645    }
5646    case 0x40000000:
5647        /*
5648         * CPUID code in kvm_arch_init_vcpu() ignores stuff
5649         * set here, but we restrict to TCG none the less.
5650         */
5651        if (tcg_enabled() && cpu->expose_tcg) {
5652            memcpy(signature, "TCGTCGTCGTCG", 12);
5653            *eax = 0x40000001;
5654            *ebx = signature[0];
5655            *ecx = signature[1];
5656            *edx = signature[2];
5657        } else {
5658            *eax = 0;
5659            *ebx = 0;
5660            *ecx = 0;
5661            *edx = 0;
5662        }
5663        break;
5664    case 0x40000001:
5665        *eax = 0;
5666        *ebx = 0;
5667        *ecx = 0;
5668        *edx = 0;
5669        break;
5670    case 0x80000000:
5671        *eax = env->cpuid_xlevel;
5672        *ebx = env->cpuid_vendor1;
5673        *edx = env->cpuid_vendor2;
5674        *ecx = env->cpuid_vendor3;
5675        break;
5676    case 0x80000001:
5677        *eax = env->cpuid_version;
5678        *ebx = 0;
5679        *ecx = env->features[FEAT_8000_0001_ECX];
5680        *edx = env->features[FEAT_8000_0001_EDX];
5681
5682        /* The Linux kernel checks for the CMPLegacy bit and
5683         * discards multiple thread information if it is set.
5684         * So don't set it here for Intel to make Linux guests happy.
5685         */
5686        if (cs->nr_cores * cs->nr_threads > 1) {
5687            if (env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1 ||
5688                env->cpuid_vendor2 != CPUID_VENDOR_INTEL_2 ||
5689                env->cpuid_vendor3 != CPUID_VENDOR_INTEL_3) {
5690                *ecx |= 1 << 1;    /* CmpLegacy bit */
5691            }
5692        }
5693        break;
5694    case 0x80000002:
5695    case 0x80000003:
5696    case 0x80000004:
5697        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
5698        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
5699        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
5700        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
5701        break;
5702    case 0x80000005:
5703        /* cache info (L1 cache) */
5704        if (cpu->cache_info_passthrough) {
5705            host_cpuid(index, 0, eax, ebx, ecx, edx);
5706            break;
5707        }
5708        *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) |
5709               (L1_ITLB_2M_ASSOC <<  8) | (L1_ITLB_2M_ENTRIES);
5710        *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) |
5711               (L1_ITLB_4K_ASSOC <<  8) | (L1_ITLB_4K_ENTRIES);
5712        *ecx = encode_cache_cpuid80000005(env->cache_info_amd.l1d_cache);
5713        *edx = encode_cache_cpuid80000005(env->cache_info_amd.l1i_cache);
5714        break;
5715    case 0x80000006:
5716        /* cache info (L2 cache) */
5717        if (cpu->cache_info_passthrough) {
5718            host_cpuid(index, 0, eax, ebx, ecx, edx);
5719            break;
5720        }
5721        *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) |
5722               (L2_DTLB_2M_ENTRIES << 16) |
5723               (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) |
5724               (L2_ITLB_2M_ENTRIES);
5725        *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) |
5726               (L2_DTLB_4K_ENTRIES << 16) |
5727               (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) |
5728               (L2_ITLB_4K_ENTRIES);
5729        encode_cache_cpuid80000006(env->cache_info_amd.l2_cache,
5730                                   cpu->enable_l3_cache ?
5731                                   env->cache_info_amd.l3_cache : NULL,
5732                                   ecx, edx);
5733        break;
5734    case 0x80000007:
5735        *eax = 0;
5736        *ebx = 0;
5737        *ecx = 0;
5738        *edx = env->features[FEAT_8000_0007_EDX];
5739        break;
5740    case 0x80000008:
5741        /* virtual & phys address size in low 2 bytes. */
5742        *eax = cpu->phys_bits;
5743        if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
5744            /* 64 bit processor */
5745             *eax |= (cpu_x86_virtual_addr_width(env) << 8);
5746        }
5747        *ebx = env->features[FEAT_8000_0008_EBX];
5748        if (cs->nr_cores * cs->nr_threads > 1) {
5749            /*
5750             * Bits 15:12 is "The number of bits in the initial
5751             * Core::X86::Apic::ApicId[ApicId] value that indicate
5752             * thread ID within a package".
5753             * Bits 7:0 is "The number of threads in the package is NC+1"
5754             */
5755            *ecx = (apicid_pkg_offset(&topo_info) << 12) |
5756                   ((cs->nr_cores * cs->nr_threads) - 1);
5757        } else {
5758            *ecx = 0;
5759        }
5760        *edx = 0;
5761        break;
5762    case 0x8000000A:
5763        if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
5764            *eax = 0x00000001; /* SVM Revision */
5765            *ebx = 0x00000010; /* nr of ASIDs */
5766            *ecx = 0;
5767            *edx = env->features[FEAT_SVM]; /* optional features */
5768        } else {
5769            *eax = 0;
5770            *ebx = 0;
5771            *ecx = 0;
5772            *edx = 0;
5773        }
5774        break;
5775    case 0x8000001D:
5776        *eax = 0;
5777        if (cpu->cache_info_passthrough) {
5778            host_cpuid(index, count, eax, ebx, ecx, edx);
5779            break;
5780        }
5781        switch (count) {
5782        case 0: /* L1 dcache info */
5783            encode_cache_cpuid8000001d(env->cache_info_amd.l1d_cache,
5784                                       &topo_info, eax, ebx, ecx, edx);
5785            break;
5786        case 1: /* L1 icache info */
5787            encode_cache_cpuid8000001d(env->cache_info_amd.l1i_cache,
5788                                       &topo_info, eax, ebx, ecx, edx);
5789            break;
5790        case 2: /* L2 cache info */
5791            encode_cache_cpuid8000001d(env->cache_info_amd.l2_cache,
5792                                       &topo_info, eax, ebx, ecx, edx);
5793            break;
5794        case 3: /* L3 cache info */
5795            encode_cache_cpuid8000001d(env->cache_info_amd.l3_cache,
5796                                       &topo_info, eax, ebx, ecx, edx);
5797            break;
5798        default: /* end of info */
5799            *eax = *ebx = *ecx = *edx = 0;
5800            break;
5801        }
5802        break;
5803    case 0x8000001E:
5804        if (cpu->core_id <= 255) {
5805            encode_topo_cpuid8000001e(cpu, &topo_info, eax, ebx, ecx, edx);
5806        } else {
5807            *eax = 0;
5808            *ebx = 0;
5809            *ecx = 0;
5810            *edx = 0;
5811        }
5812        break;
5813    case 0xC0000000:
5814        *eax = env->cpuid_xlevel2;
5815        *ebx = 0;
5816        *ecx = 0;
5817        *edx = 0;
5818        break;
5819    case 0xC0000001:
5820        /* Support for VIA CPU's CPUID instruction */
5821        *eax = env->cpuid_version;
5822        *ebx = 0;
5823        *ecx = 0;
5824        *edx = env->features[FEAT_C000_0001_EDX];
5825        break;
5826    case 0xC0000002:
5827    case 0xC0000003:
5828    case 0xC0000004:
5829        /* Reserved for the future, and now filled with zero */
5830        *eax = 0;
5831        *ebx = 0;
5832        *ecx = 0;
5833        *edx = 0;
5834        break;
5835    case 0x8000001F:
5836        *eax = *ebx = *ecx = *edx = 0;
5837        if (sev_enabled()) {
5838            *eax = 0x2;
5839            *eax |= sev_es_enabled() ? 0x8 : 0;
5840            *ebx = sev_get_cbit_position();
5841            *ebx |= sev_get_reduced_phys_bits() << 6;
5842        }
5843        break;
5844    default:
5845        /* reserved values: zero */
5846        *eax = 0;
5847        *ebx = 0;
5848        *ecx = 0;
5849        *edx = 0;
5850        break;
5851    }
5852}
5853
5854static void x86_cpu_set_sgxlepubkeyhash(CPUX86State *env)
5855{
5856#ifndef CONFIG_USER_ONLY
5857    /* Those default values are defined in Skylake HW */
5858    env->msr_ia32_sgxlepubkeyhash[0] = 0xa6053e051270b7acULL;
5859    env->msr_ia32_sgxlepubkeyhash[1] = 0x6cfbe8ba8b3b413dULL;
5860    env->msr_ia32_sgxlepubkeyhash[2] = 0xc4916d99f2b3735dULL;
5861    env->msr_ia32_sgxlepubkeyhash[3] = 0xd4f8c05909f9bb3bULL;
5862#endif
5863}
5864
5865static void x86_cpu_reset(DeviceState *dev)
5866{
5867    CPUState *s = CPU(dev);
5868    X86CPU *cpu = X86_CPU(s);
5869    X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
5870    CPUX86State *env = &cpu->env;
5871    target_ulong cr4;
5872    uint64_t xcr0;
5873    int i;
5874
5875    xcc->parent_reset(dev);
5876
5877    memset(env, 0, offsetof(CPUX86State, end_reset_fields));
5878
5879    env->old_exception = -1;
5880
5881    /* init to reset state */
5882    env->int_ctl = 0;
5883    env->hflags2 |= HF2_GIF_MASK;
5884    env->hflags2 |= HF2_VGIF_MASK;
5885    env->hflags &= ~HF_GUEST_MASK;
5886
5887    cpu_x86_update_cr0(env, 0x60000010);
5888    env->a20_mask = ~0x0;
5889    env->smbase = 0x30000;
5890    env->msr_smi_count = 0;
5891
5892    env->idt.limit = 0xffff;
5893    env->gdt.limit = 0xffff;
5894    env->ldt.limit = 0xffff;
5895    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
5896    env->tr.limit = 0xffff;
5897    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
5898
5899    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
5900                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
5901                           DESC_R_MASK | DESC_A_MASK);
5902    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
5903                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
5904                           DESC_A_MASK);
5905    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
5906                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
5907                           DESC_A_MASK);
5908    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
5909                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
5910                           DESC_A_MASK);
5911    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
5912                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
5913                           DESC_A_MASK);
5914    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
5915                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
5916                           DESC_A_MASK);
5917
5918    env->eip = 0xfff0;
5919    env->regs[R_EDX] = env->cpuid_version;
5920
5921    env->eflags = 0x2;
5922
5923    /* FPU init */
5924    for (i = 0; i < 8; i++) {
5925        env->fptags[i] = 1;
5926    }
5927    cpu_set_fpuc(env, 0x37f);
5928
5929    env->mxcsr = 0x1f80;
5930    /* All units are in INIT state.  */
5931    env->xstate_bv = 0;
5932
5933    env->pat = 0x0007040600070406ULL;
5934
5935    if (kvm_enabled()) {
5936        /*
5937         * KVM handles TSC = 0 specially and thinks we are hot-plugging
5938         * a new CPU, use 1 instead to force a reset.
5939         */
5940        if (env->tsc != 0) {
5941            env->tsc = 1;
5942        }
5943    } else {
5944        env->tsc = 0;
5945    }
5946
5947    env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
5948    if (env->features[FEAT_1_ECX] & CPUID_EXT_MONITOR) {
5949        env->msr_ia32_misc_enable |= MSR_IA32_MISC_ENABLE_MWAIT;
5950    }
5951
5952    memset(env->dr, 0, sizeof(env->dr));
5953    env->dr[6] = DR6_FIXED_1;
5954    env->dr[7] = DR7_FIXED_1;
5955    cpu_breakpoint_remove_all(s, BP_CPU);
5956    cpu_watchpoint_remove_all(s, BP_CPU);
5957
5958    cr4 = 0;
5959    xcr0 = XSTATE_FP_MASK;
5960
5961#ifdef CONFIG_USER_ONLY
5962    /* Enable all the features for user-mode.  */
5963    if (env->features[FEAT_1_EDX] & CPUID_SSE) {
5964        xcr0 |= XSTATE_SSE_MASK;
5965    }
5966    for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
5967        const ExtSaveArea *esa = &x86_ext_save_areas[i];
5968        if (env->features[esa->feature] & esa->bits) {
5969            xcr0 |= 1ull << i;
5970        }
5971    }
5972
5973    if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) {
5974        cr4 |= CR4_OSFXSR_MASK | CR4_OSXSAVE_MASK;
5975    }
5976    if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_FSGSBASE) {
5977        cr4 |= CR4_FSGSBASE_MASK;
5978    }
5979#endif
5980
5981    env->xcr0 = xcr0;
5982    cpu_x86_update_cr4(env, cr4);
5983
5984    /*
5985     * SDM 11.11.5 requires:
5986     *  - IA32_MTRR_DEF_TYPE MSR.E = 0
5987     *  - IA32_MTRR_PHYSMASKn.V = 0
5988     * All other bits are undefined.  For simplification, zero it all.
5989     */
5990    env->mtrr_deftype = 0;
5991    memset(env->mtrr_var, 0, sizeof(env->mtrr_var));
5992    memset(env->mtrr_fixed, 0, sizeof(env->mtrr_fixed));
5993
5994    env->interrupt_injected = -1;
5995    env->exception_nr = -1;
5996    env->exception_pending = 0;
5997    env->exception_injected = 0;
5998    env->exception_has_payload = false;
5999    env->exception_payload = 0;
6000    env->nmi_injected = false;
6001#if !defined(CONFIG_USER_ONLY)
6002    /* We hard-wire the BSP to the first CPU. */
6003    apic_designate_bsp(cpu->apic_state, s->cpu_index == 0);
6004
6005    s->halted = !cpu_is_bsp(cpu);
6006
6007    if (kvm_enabled()) {
6008        kvm_arch_reset_vcpu(cpu);
6009    }
6010
6011    x86_cpu_set_sgxlepubkeyhash(env);
6012
6013    env->amd_tsc_scale_msr =  MSR_AMD64_TSC_RATIO_DEFAULT;
6014
6015#endif
6016}
6017
6018static void mce_init(X86CPU *cpu)
6019{
6020    CPUX86State *cenv = &cpu->env;
6021    unsigned int bank;
6022
6023    if (((cenv->cpuid_version >> 8) & 0xf) >= 6
6024        && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
6025            (CPUID_MCE | CPUID_MCA)) {
6026        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF |
6027                        (cpu->enable_lmce ? MCG_LMCE_P : 0);
6028        cenv->mcg_ctl = ~(uint64_t)0;
6029        for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
6030            cenv->mce_banks[bank * 4] = ~(uint64_t)0;
6031        }
6032    }
6033}
6034
6035static void x86_cpu_adjust_level(X86CPU *cpu, uint32_t *min, uint32_t value)
6036{
6037    if (*min < value) {
6038        *min = value;
6039    }
6040}
6041
6042/* Increase cpuid_min_{level,xlevel,xlevel2} automatically, if appropriate */
6043static void x86_cpu_adjust_feat_level(X86CPU *cpu, FeatureWord w)
6044{
6045    CPUX86State *env = &cpu->env;
6046    FeatureWordInfo *fi = &feature_word_info[w];
6047    uint32_t eax = fi->cpuid.eax;
6048    uint32_t region = eax & 0xF0000000;
6049
6050    assert(feature_word_info[w].type == CPUID_FEATURE_WORD);
6051    if (!env->features[w]) {
6052        return;
6053    }
6054
6055    switch (region) {
6056    case 0x00000000:
6057        x86_cpu_adjust_level(cpu, &env->cpuid_min_level, eax);
6058    break;
6059    case 0x80000000:
6060        x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, eax);
6061    break;
6062    case 0xC0000000:
6063        x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel2, eax);
6064    break;
6065    }
6066
6067    if (eax == 7) {
6068        x86_cpu_adjust_level(cpu, &env->cpuid_min_level_func7,
6069                             fi->cpuid.ecx);
6070    }
6071}
6072
6073/* Calculate XSAVE components based on the configured CPU feature flags */
6074static void x86_cpu_enable_xsave_components(X86CPU *cpu)
6075{
6076    CPUX86State *env = &cpu->env;
6077    int i;
6078    uint64_t mask;
6079    static bool request_perm;
6080
6081    if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
6082        env->features[FEAT_XSAVE_COMP_LO] = 0;
6083        env->features[FEAT_XSAVE_COMP_HI] = 0;
6084        return;
6085    }
6086
6087    mask = 0;
6088    for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
6089        const ExtSaveArea *esa = &x86_ext_save_areas[i];
6090        if (env->features[esa->feature] & esa->bits) {
6091            mask |= (1ULL << i);
6092        }
6093    }
6094
6095    /* Only request permission for first vcpu */
6096    if (kvm_enabled() && !request_perm) {
6097        kvm_request_xsave_components(cpu, mask);
6098        request_perm = true;
6099    }
6100
6101    env->features[FEAT_XSAVE_COMP_LO] = mask;
6102    env->features[FEAT_XSAVE_COMP_HI] = mask >> 32;
6103}
6104
6105/***** Steps involved on loading and filtering CPUID data
6106 *
6107 * When initializing and realizing a CPU object, the steps
6108 * involved in setting up CPUID data are:
6109 *
6110 * 1) Loading CPU model definition (X86CPUDefinition). This is
6111 *    implemented by x86_cpu_load_model() and should be completely
6112 *    transparent, as it is done automatically by instance_init.
6113 *    No code should need to look at X86CPUDefinition structs
6114 *    outside instance_init.
6115 *
6116 * 2) CPU expansion. This is done by realize before CPUID
6117 *    filtering, and will make sure host/accelerator data is
6118 *    loaded for CPU models that depend on host capabilities
6119 *    (e.g. "host"). Done by x86_cpu_expand_features().
6120 *
6121 * 3) CPUID filtering. This initializes extra data related to
6122 *    CPUID, and checks if the host supports all capabilities
6123 *    required by the CPU. Runnability of a CPU model is
6124 *    determined at this step. Done by x86_cpu_filter_features().
6125 *
6126 * Some operations don't require all steps to be performed.
6127 * More precisely:
6128 *
6129 * - CPU instance creation (instance_init) will run only CPU
6130 *   model loading. CPU expansion can't run at instance_init-time
6131 *   because host/accelerator data may be not available yet.
6132 * - CPU realization will perform both CPU model expansion and CPUID
6133 *   filtering, and return an error in case one of them fails.
6134 * - query-cpu-definitions needs to run all 3 steps. It needs
6135 *   to run CPUID filtering, as the 'unavailable-features'
6136 *   field is set based on the filtering results.
6137 * - The query-cpu-model-expansion QMP command only needs to run
6138 *   CPU model loading and CPU expansion. It should not filter
6139 *   any CPUID data based on host capabilities.
6140 */
6141
6142/* Expand CPU configuration data, based on configured features
6143 * and host/accelerator capabilities when appropriate.
6144 */
6145void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
6146{
6147    CPUX86State *env = &cpu->env;
6148    FeatureWord w;
6149    int i;
6150    GList *l;
6151
6152    for (l = plus_features; l; l = l->next) {
6153        const char *prop = l->data;
6154        if (!object_property_set_bool(OBJECT(cpu), prop, true, errp)) {
6155            return;
6156        }
6157    }
6158
6159    for (l = minus_features; l; l = l->next) {
6160        const char *prop = l->data;
6161        if (!object_property_set_bool(OBJECT(cpu), prop, false, errp)) {
6162            return;
6163        }
6164    }
6165
6166    /*TODO: Now cpu->max_features doesn't overwrite features
6167     * set using QOM properties, and we can convert
6168     * plus_features & minus_features to global properties
6169     * inside x86_cpu_parse_featurestr() too.
6170     */
6171    if (cpu->max_features) {
6172        for (w = 0; w < FEATURE_WORDS; w++) {
6173            /* Override only features that weren't set explicitly
6174             * by the user.
6175             */
6176            env->features[w] |=
6177                x86_cpu_get_supported_feature_word(w, cpu->migratable) &
6178                ~env->user_features[w] &
6179                ~feature_word_info[w].no_autoenable_flags;
6180        }
6181    }
6182
6183    for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
6184        FeatureDep *d = &feature_dependencies[i];
6185        if (!(env->features[d->from.index] & d->from.mask)) {
6186            uint64_t unavailable_features = env->features[d->to.index] & d->to.mask;
6187
6188            /* Not an error unless the dependent feature was added explicitly.  */
6189            mark_unavailable_features(cpu, d->to.index,
6190                                      unavailable_features & env->user_features[d->to.index],
6191                                      "This feature depends on other features that were not requested");
6192
6193            env->features[d->to.index] &= ~unavailable_features;
6194        }
6195    }
6196
6197    if (!kvm_enabled() || !cpu->expose_kvm) {
6198        env->features[FEAT_KVM] = 0;
6199    }
6200
6201    x86_cpu_enable_xsave_components(cpu);
6202
6203    /* CPUID[EAX=7,ECX=0].EBX always increased level automatically: */
6204    x86_cpu_adjust_feat_level(cpu, FEAT_7_0_EBX);
6205    if (cpu->full_cpuid_auto_level) {
6206        x86_cpu_adjust_feat_level(cpu, FEAT_1_EDX);
6207        x86_cpu_adjust_feat_level(cpu, FEAT_1_ECX);
6208        x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX);
6209        x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX);
6210        x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EAX);
6211        x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX);
6212        x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX);
6213        x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX);
6214        x86_cpu_adjust_feat_level(cpu, FEAT_8000_0008_EBX);
6215        x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX);
6216        x86_cpu_adjust_feat_level(cpu, FEAT_SVM);
6217        x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);
6218
6219        /* Intel Processor Trace requires CPUID[0x14] */
6220        if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT)) {
6221            if (cpu->intel_pt_auto_level) {
6222                x86_cpu_adjust_level(cpu, &cpu->env.cpuid_min_level, 0x14);
6223            } else if (cpu->env.cpuid_min_level < 0x14) {
6224                mark_unavailable_features(cpu, FEAT_7_0_EBX,
6225                    CPUID_7_0_EBX_INTEL_PT,
6226                    "Intel PT need CPUID leaf 0x14, please set by \"-cpu ...,intel-pt=on,min-level=0x14\"");
6227            }
6228        }
6229
6230        /*
6231         * Intel CPU topology with multi-dies support requires CPUID[0x1F].
6232         * For AMD Rome/Milan, cpuid level is 0x10, and guest OS should detect
6233         * extended toplogy by leaf 0xB. Only adjust it for Intel CPU, unless
6234         * cpu->vendor_cpuid_only has been unset for compatibility with older
6235         * machine types.
6236         */
6237        if ((env->nr_dies > 1) &&
6238            (IS_INTEL_CPU(env) || !cpu->vendor_cpuid_only)) {
6239            x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x1F);
6240        }
6241
6242        /* SVM requires CPUID[0x8000000A] */
6243        if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
6244            x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);
6245        }
6246
6247        /* SEV requires CPUID[0x8000001F] */
6248        if (sev_enabled()) {
6249            x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000001F);
6250        }
6251
6252        /* SGX requires CPUID[0x12] for EPC enumeration */
6253        if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SGX) {
6254            x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x12);
6255        }
6256    }
6257
6258    /* Set cpuid_*level* based on cpuid_min_*level, if not explicitly set */
6259    if (env->cpuid_level_func7 == UINT32_MAX) {
6260        env->cpuid_level_func7 = env->cpuid_min_level_func7;
6261    }
6262    if (env->cpuid_level == UINT32_MAX) {
6263        env->cpuid_level = env->cpuid_min_level;
6264    }
6265    if (env->cpuid_xlevel == UINT32_MAX) {
6266        env->cpuid_xlevel = env->cpuid_min_xlevel;
6267    }
6268    if (env->cpuid_xlevel2 == UINT32_MAX) {
6269        env->cpuid_xlevel2 = env->cpuid_min_xlevel2;
6270    }
6271
6272    if (kvm_enabled()) {
6273        kvm_hyperv_expand_features(cpu, errp);
6274    }
6275}
6276
6277/*
6278 * Finishes initialization of CPUID data, filters CPU feature
6279 * words based on host availability of each feature.
6280 *
6281 * Returns: 0 if all flags are supported by the host, non-zero otherwise.
6282 */
6283static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
6284{
6285    CPUX86State *env = &cpu->env;
6286    FeatureWord w;
6287    const char *prefix = NULL;
6288
6289    if (verbose) {
6290        prefix = accel_uses_host_cpuid()
6291                 ? "host doesn't support requested feature"
6292                 : "TCG doesn't support requested feature";
6293    }
6294
6295    for (w = 0; w < FEATURE_WORDS; w++) {
6296        uint64_t host_feat =
6297            x86_cpu_get_supported_feature_word(w, false);
6298        uint64_t requested_features = env->features[w];
6299        uint64_t unavailable_features = requested_features & ~host_feat;
6300        mark_unavailable_features(cpu, w, unavailable_features, prefix);
6301    }
6302
6303    if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) &&
6304        kvm_enabled()) {
6305        KVMState *s = CPU(cpu)->kvm_state;
6306        uint32_t eax_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_EAX);
6307        uint32_t ebx_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_EBX);
6308        uint32_t ecx_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_ECX);
6309        uint32_t eax_1 = kvm_arch_get_supported_cpuid(s, 0x14, 1, R_EAX);
6310        uint32_t ebx_1 = kvm_arch_get_supported_cpuid(s, 0x14, 1, R_EBX);
6311
6312        if (!eax_0 ||
6313           ((ebx_0 & INTEL_PT_MINIMAL_EBX) != INTEL_PT_MINIMAL_EBX) ||
6314           ((ecx_0 & INTEL_PT_MINIMAL_ECX) != INTEL_PT_MINIMAL_ECX) ||
6315           ((eax_1 & INTEL_PT_MTC_BITMAP) != INTEL_PT_MTC_BITMAP) ||
6316           ((eax_1 & INTEL_PT_ADDR_RANGES_NUM_MASK) <
6317                                           INTEL_PT_ADDR_RANGES_NUM) ||
6318           ((ebx_1 & (INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP)) !=
6319                (INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP)) ||
6320           ((ecx_0 & CPUID_14_0_ECX_LIP) !=
6321                (env->features[FEAT_14_0_ECX] & CPUID_14_0_ECX_LIP))) {
6322            /*
6323             * Processor Trace capabilities aren't configurable, so if the
6324             * host can't emulate the capabilities we report on
6325             * cpu_x86_cpuid(), intel-pt can't be enabled on the current host.
6326             */
6327            mark_unavailable_features(cpu, FEAT_7_0_EBX, CPUID_7_0_EBX_INTEL_PT, prefix);
6328        }
6329    }
6330}
6331
6332static void x86_cpu_hyperv_realize(X86CPU *cpu)
6333{
6334    size_t len;
6335
6336    /* Hyper-V vendor id */
6337    if (!cpu->hyperv_vendor) {
6338        object_property_set_str(OBJECT(cpu), "hv-vendor-id", "Microsoft Hv",
6339                                &error_abort);
6340    }
6341    len = strlen(cpu->hyperv_vendor);
6342    if (len > 12) {
6343        warn_report("hv-vendor-id truncated to 12 characters");
6344        len = 12;
6345    }
6346    memset(cpu->hyperv_vendor_id, 0, 12);
6347    memcpy(cpu->hyperv_vendor_id, cpu->hyperv_vendor, len);
6348
6349    /* 'Hv#1' interface identification*/
6350    cpu->hyperv_interface_id[0] = 0x31237648;
6351    cpu->hyperv_interface_id[1] = 0;
6352    cpu->hyperv_interface_id[2] = 0;
6353    cpu->hyperv_interface_id[3] = 0;
6354
6355    /* Hypervisor implementation limits */
6356    cpu->hyperv_limits[0] = 64;
6357    cpu->hyperv_limits[1] = 0;
6358    cpu->hyperv_limits[2] = 0;
6359}
6360
6361static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
6362{
6363    CPUState *cs = CPU(dev);
6364    X86CPU *cpu = X86_CPU(dev);
6365    X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
6366    CPUX86State *env = &cpu->env;
6367    Error *local_err = NULL;
6368    static bool ht_warned;
6369
6370    if (cpu->apic_id == UNASSIGNED_APIC_ID) {
6371        error_setg(errp, "apic-id property was not initialized properly");
6372        return;
6373    }
6374
6375    /*
6376     * Process Hyper-V enlightenments.
6377     * Note: this currently has to happen before the expansion of CPU features.
6378     */
6379    x86_cpu_hyperv_realize(cpu);
6380
6381    x86_cpu_expand_features(cpu, &local_err);
6382    if (local_err) {
6383        goto out;
6384    }
6385
6386    x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid);
6387
6388    if (cpu->enforce_cpuid && x86_cpu_have_filtered_features(cpu)) {
6389        error_setg(&local_err,
6390                   accel_uses_host_cpuid() ?
6391                       "Host doesn't support requested features" :
6392                       "TCG doesn't support requested features");
6393        goto out;
6394    }
6395
6396    /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
6397     * CPUID[1].EDX.
6398     */
6399    if (IS_AMD_CPU(env)) {
6400        env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
6401        env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
6402           & CPUID_EXT2_AMD_ALIASES);
6403    }
6404
6405    x86_cpu_set_sgxlepubkeyhash(env);
6406
6407    /*
6408     * note: the call to the framework needs to happen after feature expansion,
6409     * but before the checks/modifications to ucode_rev, mwait, phys_bits.
6410     * These may be set by the accel-specific code,
6411     * and the results are subsequently checked / assumed in this function.
6412     */
6413    cpu_exec_realizefn(cs, &local_err);
6414    if (local_err != NULL) {
6415        error_propagate(errp, local_err);
6416        return;
6417    }
6418
6419    if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
6420        g_autofree char *name = x86_cpu_class_get_model_name(xcc);
6421        error_setg(&local_err, "CPU model '%s' requires KVM or HVF", name);
6422        goto out;
6423    }
6424
6425    if (cpu->ucode_rev == 0) {
6426        /*
6427         * The default is the same as KVM's. Note that this check
6428         * needs to happen after the evenual setting of ucode_rev in
6429         * accel-specific code in cpu_exec_realizefn.
6430         */
6431        if (IS_AMD_CPU(env)) {
6432            cpu->ucode_rev = 0x01000065;
6433        } else {
6434            cpu->ucode_rev = 0x100000000ULL;
6435        }
6436    }
6437
6438    /*
6439     * mwait extended info: needed for Core compatibility
6440     * We always wake on interrupt even if host does not have the capability.
6441     *
6442     * requires the accel-specific code in cpu_exec_realizefn to
6443     * have already acquired the CPUID data into cpu->mwait.
6444     */
6445    cpu->mwait.ecx |= CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
6446
6447    /* For 64bit systems think about the number of physical bits to present.
6448     * ideally this should be the same as the host; anything other than matching
6449     * the host can cause incorrect guest behaviour.
6450     * QEMU used to pick the magic value of 40 bits that corresponds to
6451     * consumer AMD devices but nothing else.
6452     *
6453     * Note that this code assumes features expansion has already been done
6454     * (as it checks for CPUID_EXT2_LM), and also assumes that potential
6455     * phys_bits adjustments to match the host have been already done in
6456     * accel-specific code in cpu_exec_realizefn.
6457     */
6458    if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
6459        if (cpu->phys_bits &&
6460            (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
6461            cpu->phys_bits < 32)) {
6462            error_setg(errp, "phys-bits should be between 32 and %u "
6463                             " (but is %u)",
6464                             TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bits);
6465            return;
6466        }
6467        /*
6468         * 0 means it was not explicitly set by the user (or by machine
6469         * compat_props or by the host code in host-cpu.c).
6470         * In this case, the default is the value used by TCG (40).
6471         */
6472        if (cpu->phys_bits == 0) {
6473            cpu->phys_bits = TCG_PHYS_ADDR_BITS;
6474        }
6475    } else {
6476        /* For 32 bit systems don't use the user set value, but keep
6477         * phys_bits consistent with what we tell the guest.
6478         */
6479        if (cpu->phys_bits != 0) {
6480            error_setg(errp, "phys-bits is not user-configurable in 32 bit");
6481            return;
6482        }
6483
6484        if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
6485            cpu->phys_bits = 36;
6486        } else {
6487            cpu->phys_bits = 32;
6488        }
6489    }
6490
6491    /* Cache information initialization */
6492    if (!cpu->legacy_cache) {
6493        if (!xcc->model || !xcc->model->cpudef->cache_info) {
6494            g_autofree char *name = x86_cpu_class_get_model_name(xcc);
6495            error_setg(errp,
6496                       "CPU model '%s' doesn't support legacy-cache=off", name);
6497            return;
6498        }
6499        env->cache_info_cpuid2 = env->cache_info_cpuid4 = env->cache_info_amd =
6500            *xcc->model->cpudef->cache_info;
6501    } else {
6502        /* Build legacy cache information */
6503        env->cache_info_cpuid2.l1d_cache = &legacy_l1d_cache;
6504        env->cache_info_cpuid2.l1i_cache = &legacy_l1i_cache;
6505        env->cache_info_cpuid2.l2_cache = &legacy_l2_cache_cpuid2;
6506        env->cache_info_cpuid2.l3_cache = &legacy_l3_cache;
6507
6508        env->cache_info_cpuid4.l1d_cache = &legacy_l1d_cache;
6509        env->cache_info_cpuid4.l1i_cache = &legacy_l1i_cache;
6510        env->cache_info_cpuid4.l2_cache = &legacy_l2_cache;
6511        env->cache_info_cpuid4.l3_cache = &legacy_l3_cache;
6512
6513        env->cache_info_amd.l1d_cache = &legacy_l1d_cache_amd;
6514        env->cache_info_amd.l1i_cache = &legacy_l1i_cache_amd;
6515        env->cache_info_amd.l2_cache = &legacy_l2_cache_amd;
6516        env->cache_info_amd.l3_cache = &legacy_l3_cache;
6517    }
6518
6519#ifndef CONFIG_USER_ONLY
6520    MachineState *ms = MACHINE(qdev_get_machine());
6521    qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
6522
6523    if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || ms->smp.cpus > 1) {
6524        x86_cpu_apic_create(cpu, &local_err);
6525        if (local_err != NULL) {
6526            goto out;
6527        }
6528    }
6529#endif
6530
6531    mce_init(cpu);
6532
6533    qemu_init_vcpu(cs);
6534
6535    /*
6536     * Most Intel and certain AMD CPUs support hyperthreading. Even though QEMU
6537     * fixes this issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX
6538     * based on inputs (sockets,cores,threads), it is still better to give
6539     * users a warning.
6540     *
6541     * NOTE: the following code has to follow qemu_init_vcpu(). Otherwise
6542     * cs->nr_threads hasn't be populated yet and the checking is incorrect.
6543     */
6544    if (IS_AMD_CPU(env) &&
6545        !(env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT) &&
6546        cs->nr_threads > 1 && !ht_warned) {
6547            warn_report("This family of AMD CPU doesn't support "
6548                        "hyperthreading(%d)",
6549                        cs->nr_threads);
6550            error_printf("Please configure -smp options properly"
6551                         " or try enabling topoext feature.\n");
6552            ht_warned = true;
6553    }
6554
6555#ifndef CONFIG_USER_ONLY
6556    x86_cpu_apic_realize(cpu, &local_err);
6557    if (local_err != NULL) {
6558        goto out;
6559    }
6560#endif /* !CONFIG_USER_ONLY */
6561    cpu_reset(cs);
6562
6563    xcc->parent_realize(dev, &local_err);
6564
6565out:
6566    if (local_err != NULL) {
6567        error_propagate(errp, local_err);
6568        return;
6569    }
6570}
6571
6572static void x86_cpu_unrealizefn(DeviceState *dev)
6573{
6574    X86CPU *cpu = X86_CPU(dev);
6575    X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
6576
6577#ifndef CONFIG_USER_ONLY
6578    cpu_remove_sync(CPU(dev));
6579    qemu_unregister_reset(x86_cpu_machine_reset_cb, dev);
6580#endif
6581
6582    if (cpu->apic_state) {
6583        object_unparent(OBJECT(cpu->apic_state));
6584        cpu->apic_state = NULL;
6585    }
6586
6587    xcc->parent_unrealize(dev);
6588}
6589
6590typedef struct BitProperty {
6591    FeatureWord w;
6592    uint64_t mask;
6593} BitProperty;
6594
6595static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
6596                                 void *opaque, Error **errp)
6597{
6598    X86CPU *cpu = X86_CPU(obj);
6599    BitProperty *fp = opaque;
6600    uint64_t f = cpu->env.features[fp->w];
6601    bool value = (f & fp->mask) == fp->mask;
6602    visit_type_bool(v, name, &value, errp);
6603}
6604
6605static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
6606                                 void *opaque, Error **errp)
6607{
6608    DeviceState *dev = DEVICE(obj);
6609    X86CPU *cpu = X86_CPU(obj);
6610    BitProperty *fp = opaque;
6611    bool value;
6612
6613    if (dev->realized) {
6614        qdev_prop_set_after_realize(dev, name, errp);
6615        return;
6616    }
6617
6618    if (!visit_type_bool(v, name, &value, errp)) {
6619        return;
6620    }
6621
6622    if (value) {
6623        cpu->env.features[fp->w] |= fp->mask;
6624    } else {
6625        cpu->env.features[fp->w] &= ~fp->mask;
6626    }
6627    cpu->env.user_features[fp->w] |= fp->mask;
6628}
6629
6630/* Register a boolean property to get/set a single bit in a uint32_t field.
6631 *
6632 * The same property name can be registered multiple times to make it affect
6633 * multiple bits in the same FeatureWord. In that case, the getter will return
6634 * true only if all bits are set.
6635 */
6636static void x86_cpu_register_bit_prop(X86CPUClass *xcc,
6637                                      const char *prop_name,
6638                                      FeatureWord w,
6639                                      int bitnr)
6640{
6641    ObjectClass *oc = OBJECT_CLASS(xcc);
6642    BitProperty *fp;
6643    ObjectProperty *op;
6644    uint64_t mask = (1ULL << bitnr);
6645
6646    op = object_class_property_find(oc, prop_name);
6647    if (op) {
6648        fp = op->opaque;
6649        assert(fp->w == w);
6650        fp->mask |= mask;
6651    } else {
6652        fp = g_new0(BitProperty, 1);
6653        fp->w = w;
6654        fp->mask = mask;
6655        object_class_property_add(oc, prop_name, "bool",
6656                                  x86_cpu_get_bit_prop,
6657                                  x86_cpu_set_bit_prop,
6658                                  NULL, fp);
6659    }
6660}
6661
6662static void x86_cpu_register_feature_bit_props(X86CPUClass *xcc,
6663                                               FeatureWord w,
6664                                               int bitnr)
6665{
6666    FeatureWordInfo *fi = &feature_word_info[w];
6667    const char *name = fi->feat_names[bitnr];
6668
6669    if (!name) {
6670        return;
6671    }
6672
6673    /* Property names should use "-" instead of "_".
6674     * Old names containing underscores are registered as aliases
6675     * using object_property_add_alias()
6676     */
6677    assert(!strchr(name, '_'));
6678    /* aliases don't use "|" delimiters anymore, they are registered
6679     * manually using object_property_add_alias() */
6680    assert(!strchr(name, '|'));
6681    x86_cpu_register_bit_prop(xcc, name, w, bitnr);
6682}
6683
6684static void x86_cpu_post_initfn(Object *obj)
6685{
6686    accel_cpu_instance_init(CPU(obj));
6687}
6688
6689static void x86_cpu_initfn(Object *obj)
6690{
6691    X86CPU *cpu = X86_CPU(obj);
6692    X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
6693    CPUX86State *env = &cpu->env;
6694
6695    env->nr_dies = 1;
6696    cpu_set_cpustate_pointers(cpu);
6697
6698    object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
6699                        x86_cpu_get_feature_words,
6700                        NULL, NULL, (void *)env->features);
6701    object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
6702                        x86_cpu_get_feature_words,
6703                        NULL, NULL, (void *)cpu->filtered_features);
6704
6705    object_property_add_alias(obj, "sse3", obj, "pni");
6706    object_property_add_alias(obj, "pclmuldq", obj, "pclmulqdq");
6707    object_property_add_alias(obj, "sse4-1", obj, "sse4.1");
6708    object_property_add_alias(obj, "sse4-2", obj, "sse4.2");
6709    object_property_add_alias(obj, "xd", obj, "nx");
6710    object_property_add_alias(obj, "ffxsr", obj, "fxsr-opt");
6711    object_property_add_alias(obj, "i64", obj, "lm");
6712
6713    object_property_add_alias(obj, "ds_cpl", obj, "ds-cpl");
6714    object_property_add_alias(obj, "tsc_adjust", obj, "tsc-adjust");
6715    object_property_add_alias(obj, "fxsr_opt", obj, "fxsr-opt");
6716    object_property_add_alias(obj, "lahf_lm", obj, "lahf-lm");
6717    object_property_add_alias(obj, "cmp_legacy", obj, "cmp-legacy");
6718    object_property_add_alias(obj, "nodeid_msr", obj, "nodeid-msr");
6719    object_property_add_alias(obj, "perfctr_core", obj, "perfctr-core");
6720    object_property_add_alias(obj, "perfctr_nb", obj, "perfctr-nb");
6721    object_property_add_alias(obj, "kvm_nopiodelay", obj, "kvm-nopiodelay");
6722    object_property_add_alias(obj, "kvm_mmu", obj, "kvm-mmu");
6723    object_property_add_alias(obj, "kvm_asyncpf", obj, "kvm-asyncpf");
6724    object_property_add_alias(obj, "kvm_asyncpf_int", obj, "kvm-asyncpf-int");
6725    object_property_add_alias(obj, "kvm_steal_time", obj, "kvm-steal-time");
6726    object_property_add_alias(obj, "kvm_pv_eoi", obj, "kvm-pv-eoi");
6727    object_property_add_alias(obj, "kvm_pv_unhalt", obj, "kvm-pv-unhalt");
6728    object_property_add_alias(obj, "kvm_poll_control", obj, "kvm-poll-control");
6729    object_property_add_alias(obj, "svm_lock", obj, "svm-lock");
6730    object_property_add_alias(obj, "nrip_save", obj, "nrip-save");
6731    object_property_add_alias(obj, "tsc_scale", obj, "tsc-scale");
6732    object_property_add_alias(obj, "vmcb_clean", obj, "vmcb-clean");
6733    object_property_add_alias(obj, "pause_filter", obj, "pause-filter");
6734    object_property_add_alias(obj, "sse4_1", obj, "sse4.1");
6735    object_property_add_alias(obj, "sse4_2", obj, "sse4.2");
6736
6737    object_property_add_alias(obj, "hv-apicv", obj, "hv-avic");
6738
6739    if (xcc->model) {
6740        x86_cpu_load_model(cpu, xcc->model);
6741    }
6742}
6743
6744static int64_t x86_cpu_get_arch_id(CPUState *cs)
6745{
6746    X86CPU *cpu = X86_CPU(cs);
6747
6748    return cpu->apic_id;
6749}
6750
6751#if !defined(CONFIG_USER_ONLY)
6752static bool x86_cpu_get_paging_enabled(const CPUState *cs)
6753{
6754    X86CPU *cpu = X86_CPU(cs);
6755
6756    return cpu->env.cr[0] & CR0_PG_MASK;
6757}
6758#endif /* !CONFIG_USER_ONLY */
6759
6760static void x86_cpu_set_pc(CPUState *cs, vaddr value)
6761{
6762    X86CPU *cpu = X86_CPU(cs);
6763
6764    cpu->env.eip = value;
6765}
6766
6767int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request)
6768{
6769    X86CPU *cpu = X86_CPU(cs);
6770    CPUX86State *env = &cpu->env;
6771
6772#if !defined(CONFIG_USER_ONLY)
6773    if (interrupt_request & CPU_INTERRUPT_POLL) {
6774        return CPU_INTERRUPT_POLL;
6775    }
6776#endif
6777    if (interrupt_request & CPU_INTERRUPT_SIPI) {
6778        return CPU_INTERRUPT_SIPI;
6779    }
6780
6781    if (env->hflags2 & HF2_GIF_MASK) {
6782        if ((interrupt_request & CPU_INTERRUPT_SMI) &&
6783            !(env->hflags & HF_SMM_MASK)) {
6784            return CPU_INTERRUPT_SMI;
6785        } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
6786                   !(env->hflags2 & HF2_NMI_MASK)) {
6787            return CPU_INTERRUPT_NMI;
6788        } else if (interrupt_request & CPU_INTERRUPT_MCE) {
6789            return CPU_INTERRUPT_MCE;
6790        } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
6791                   (((env->hflags2 & HF2_VINTR_MASK) &&
6792                     (env->hflags2 & HF2_HIF_MASK)) ||
6793                    (!(env->hflags2 & HF2_VINTR_MASK) &&
6794                     (env->eflags & IF_MASK &&
6795                      !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
6796            return CPU_INTERRUPT_HARD;
6797#if !defined(CONFIG_USER_ONLY)
6798        } else if (env->hflags2 & HF2_VGIF_MASK) {
6799            if((interrupt_request & CPU_INTERRUPT_VIRQ) &&
6800                   (env->eflags & IF_MASK) &&
6801                   !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
6802                        return CPU_INTERRUPT_VIRQ;
6803            }
6804#endif
6805        }
6806    }
6807
6808    return 0;
6809}
6810
6811static bool x86_cpu_has_work(CPUState *cs)
6812{
6813    return x86_cpu_pending_interrupt(cs, cs->interrupt_request) != 0;
6814}
6815
6816static void x86_disas_set_info(CPUState *cs, disassemble_info *info)
6817{
6818    X86CPU *cpu = X86_CPU(cs);
6819    CPUX86State *env = &cpu->env;
6820
6821    info->mach = (env->hflags & HF_CS64_MASK ? bfd_mach_x86_64
6822                  : env->hflags & HF_CS32_MASK ? bfd_mach_i386_i386
6823                  : bfd_mach_i386_i8086);
6824    info->print_insn = print_insn_i386;
6825
6826    info->cap_arch = CS_ARCH_X86;
6827    info->cap_mode = (env->hflags & HF_CS64_MASK ? CS_MODE_64
6828                      : env->hflags & HF_CS32_MASK ? CS_MODE_32
6829                      : CS_MODE_16);
6830    info->cap_insn_unit = 1;
6831    info->cap_insn_split = 8;
6832}
6833
6834void x86_update_hflags(CPUX86State *env)
6835{
6836   uint32_t hflags;
6837#define HFLAG_COPY_MASK \
6838    ~( HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
6839       HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
6840       HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
6841       HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)
6842
6843    hflags = env->hflags & HFLAG_COPY_MASK;
6844    hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
6845    hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
6846    hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
6847                (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
6848    hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
6849
6850    if (env->cr[4] & CR4_OSFXSR_MASK) {
6851        hflags |= HF_OSFXSR_MASK;
6852    }
6853
6854    if (env->efer & MSR_EFER_LMA) {
6855        hflags |= HF_LMA_MASK;
6856    }
6857
6858    if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
6859        hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
6860    } else {
6861        hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
6862                    (DESC_B_SHIFT - HF_CS32_SHIFT);
6863        hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
6864                    (DESC_B_SHIFT - HF_SS32_SHIFT);
6865        if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK) ||
6866            !(hflags & HF_CS32_MASK)) {
6867            hflags |= HF_ADDSEG_MASK;
6868        } else {
6869            hflags |= ((env->segs[R_DS].base | env->segs[R_ES].base |
6870                        env->segs[R_SS].base) != 0) << HF_ADDSEG_SHIFT;
6871        }
6872    }
6873    env->hflags = hflags;
6874}
6875
6876static Property x86_cpu_properties[] = {
6877#ifdef CONFIG_USER_ONLY
6878    /* apic_id = 0 by default for *-user, see commit 9886e834 */
6879    DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, 0),
6880    DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, 0),
6881    DEFINE_PROP_INT32("core-id", X86CPU, core_id, 0),
6882    DEFINE_PROP_INT32("die-id", X86CPU, die_id, 0),
6883    DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, 0),
6884#else
6885    DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, UNASSIGNED_APIC_ID),
6886    DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, -1),
6887    DEFINE_PROP_INT32("core-id", X86CPU, core_id, -1),
6888    DEFINE_PROP_INT32("die-id", X86CPU, die_id, -1),
6889    DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, -1),
6890#endif
6891    DEFINE_PROP_INT32("node-id", X86CPU, node_id, CPU_UNSET_NUMA_NODE_ID),
6892    DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
6893
6894    DEFINE_PROP_UINT32("hv-spinlocks", X86CPU, hyperv_spinlock_attempts,
6895                       HYPERV_SPINLOCK_NEVER_NOTIFY),
6896    DEFINE_PROP_BIT64("hv-relaxed", X86CPU, hyperv_features,
6897                      HYPERV_FEAT_RELAXED, 0),
6898    DEFINE_PROP_BIT64("hv-vapic", X86CPU, hyperv_features,
6899                      HYPERV_FEAT_VAPIC, 0),
6900    DEFINE_PROP_BIT64("hv-time", X86CPU, hyperv_features,
6901                      HYPERV_FEAT_TIME, 0),
6902    DEFINE_PROP_BIT64("hv-crash", X86CPU, hyperv_features,
6903                      HYPERV_FEAT_CRASH, 0),
6904    DEFINE_PROP_BIT64("hv-reset", X86CPU, hyperv_features,
6905                      HYPERV_FEAT_RESET, 0),
6906    DEFINE_PROP_BIT64("hv-vpindex", X86CPU, hyperv_features,
6907                      HYPERV_FEAT_VPINDEX, 0),
6908    DEFINE_PROP_BIT64("hv-runtime", X86CPU, hyperv_features,
6909                      HYPERV_FEAT_RUNTIME, 0),
6910    DEFINE_PROP_BIT64("hv-synic", X86CPU, hyperv_features,
6911                      HYPERV_FEAT_SYNIC, 0),
6912    DEFINE_PROP_BIT64("hv-stimer", X86CPU, hyperv_features,
6913                      HYPERV_FEAT_STIMER, 0),
6914    DEFINE_PROP_BIT64("hv-frequencies", X86CPU, hyperv_features,
6915                      HYPERV_FEAT_FREQUENCIES, 0),
6916    DEFINE_PROP_BIT64("hv-reenlightenment", X86CPU, hyperv_features,
6917                      HYPERV_FEAT_REENLIGHTENMENT, 0),
6918    DEFINE_PROP_BIT64("hv-tlbflush", X86CPU, hyperv_features,
6919                      HYPERV_FEAT_TLBFLUSH, 0),
6920    DEFINE_PROP_BIT64("hv-evmcs", X86CPU, hyperv_features,
6921                      HYPERV_FEAT_EVMCS, 0),
6922    DEFINE_PROP_BIT64("hv-ipi", X86CPU, hyperv_features,
6923                      HYPERV_FEAT_IPI, 0),
6924    DEFINE_PROP_BIT64("hv-stimer-direct", X86CPU, hyperv_features,
6925                      HYPERV_FEAT_STIMER_DIRECT, 0),
6926    DEFINE_PROP_BIT64("hv-avic", X86CPU, hyperv_features,
6927                      HYPERV_FEAT_AVIC, 0),
6928    DEFINE_PROP_ON_OFF_AUTO("hv-no-nonarch-coresharing", X86CPU,
6929                            hyperv_no_nonarch_cs, ON_OFF_AUTO_OFF),
6930    DEFINE_PROP_BOOL("hv-passthrough", X86CPU, hyperv_passthrough, false),
6931    DEFINE_PROP_BOOL("hv-enforce-cpuid", X86CPU, hyperv_enforce_cpuid, false),
6932
6933    /* WS2008R2 identify by default */
6934    DEFINE_PROP_UINT32("hv-version-id-build", X86CPU, hyperv_ver_id_build,
6935                       0x3839),
6936    DEFINE_PROP_UINT16("hv-version-id-major", X86CPU, hyperv_ver_id_major,
6937                       0x000A),
6938    DEFINE_PROP_UINT16("hv-version-id-minor", X86CPU, hyperv_ver_id_minor,
6939                       0x0000),
6940    DEFINE_PROP_UINT32("hv-version-id-spack", X86CPU, hyperv_ver_id_sp, 0),
6941    DEFINE_PROP_UINT8("hv-version-id-sbranch", X86CPU, hyperv_ver_id_sb, 0),
6942    DEFINE_PROP_UINT32("hv-version-id-snumber", X86CPU, hyperv_ver_id_sn, 0),
6943
6944    DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
6945    DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
6946    DEFINE_PROP_BOOL("x-force-features", X86CPU, force_features, false),
6947    DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
6948    DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0),
6949    DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false),
6950    DEFINE_PROP_UINT8("host-phys-bits-limit", X86CPU, host_phys_bits_limit, 0),
6951    DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true),
6952    DEFINE_PROP_UINT32("level-func7", X86CPU, env.cpuid_level_func7,
6953                       UINT32_MAX),
6954    DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, UINT32_MAX),
6955    DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, UINT32_MAX),
6956    DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, UINT32_MAX),
6957    DEFINE_PROP_UINT32("min-level", X86CPU, env.cpuid_min_level, 0),
6958    DEFINE_PROP_UINT32("min-xlevel", X86CPU, env.cpuid_min_xlevel, 0),
6959    DEFINE_PROP_UINT32("min-xlevel2", X86CPU, env.cpuid_min_xlevel2, 0),
6960    DEFINE_PROP_UINT64("ucode-rev", X86CPU, ucode_rev, 0),
6961    DEFINE_PROP_BOOL("full-cpuid-auto-level", X86CPU, full_cpuid_auto_level, true),
6962    DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor),
6963    DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
6964    DEFINE_PROP_BOOL("x-vendor-cpuid-only", X86CPU, vendor_cpuid_only, true),
6965    DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false),
6966    DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true),
6967    DEFINE_PROP_BOOL("kvm-no-smi-migration", X86CPU, kvm_no_smi_migration,
6968                     false),
6969    DEFINE_PROP_BOOL("kvm-pv-enforce-cpuid", X86CPU, kvm_pv_enforce_cpuid,
6970                     false),
6971    DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
6972    DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
6973    DEFINE_PROP_BOOL("x-migrate-smi-count", X86CPU, migrate_smi_count,
6974                     true),
6975    /*
6976     * lecacy_cache defaults to true unless the CPU model provides its
6977     * own cache information (see x86_cpu_load_def()).
6978     */
6979    DEFINE_PROP_BOOL("legacy-cache", X86CPU, legacy_cache, true),
6980
6981    /*
6982     * From "Requirements for Implementing the Microsoft
6983     * Hypervisor Interface":
6984     * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs
6985     *
6986     * "Starting with Windows Server 2012 and Windows 8, if
6987     * CPUID.40000005.EAX contains a value of -1, Windows assumes that
6988     * the hypervisor imposes no specific limit to the number of VPs.
6989     * In this case, Windows Server 2012 guest VMs may use more than
6990     * 64 VPs, up to the maximum supported number of processors applicable
6991     * to the specific Windows version being used."
6992     */
6993    DEFINE_PROP_INT32("x-hv-max-vps", X86CPU, hv_max_vps, -1),
6994    DEFINE_PROP_BOOL("x-hv-synic-kvm-only", X86CPU, hyperv_synic_kvm_only,
6995                     false),
6996    DEFINE_PROP_BOOL("x-intel-pt-auto-level", X86CPU, intel_pt_auto_level,
6997                     true),
6998    DEFINE_PROP_END_OF_LIST()
6999};
7000
7001#ifndef CONFIG_USER_ONLY
7002#include "hw/core/sysemu-cpu-ops.h"
7003
7004static const struct SysemuCPUOps i386_sysemu_ops = {
7005    .get_memory_mapping = x86_cpu_get_memory_mapping,
7006    .get_paging_enabled = x86_cpu_get_paging_enabled,
7007    .get_phys_page_attrs_debug = x86_cpu_get_phys_page_attrs_debug,
7008    .asidx_from_attrs = x86_asidx_from_attrs,
7009    .get_crash_info = x86_cpu_get_crash_info,
7010    .write_elf32_note = x86_cpu_write_elf32_note,
7011    .write_elf64_note = x86_cpu_write_elf64_note,
7012    .write_elf32_qemunote = x86_cpu_write_elf32_qemunote,
7013    .write_elf64_qemunote = x86_cpu_write_elf64_qemunote,
7014    .legacy_vmsd = &vmstate_x86_cpu,
7015};
7016#endif
7017
7018static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
7019{
7020    X86CPUClass *xcc = X86_CPU_CLASS(oc);
7021    CPUClass *cc = CPU_CLASS(oc);
7022    DeviceClass *dc = DEVICE_CLASS(oc);
7023    FeatureWord w;
7024
7025    device_class_set_parent_realize(dc, x86_cpu_realizefn,
7026                                    &xcc->parent_realize);
7027    device_class_set_parent_unrealize(dc, x86_cpu_unrealizefn,
7028                                      &xcc->parent_unrealize);
7029    device_class_set_props(dc, x86_cpu_properties);
7030
7031    device_class_set_parent_reset(dc, x86_cpu_reset, &xcc->parent_reset);
7032    cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
7033
7034    cc->class_by_name = x86_cpu_class_by_name;
7035    cc->parse_features = x86_cpu_parse_featurestr;
7036    cc->has_work = x86_cpu_has_work;
7037    cc->dump_state = x86_cpu_dump_state;
7038    cc->set_pc = x86_cpu_set_pc;
7039    cc->gdb_read_register = x86_cpu_gdb_read_register;
7040    cc->gdb_write_register = x86_cpu_gdb_write_register;
7041    cc->get_arch_id = x86_cpu_get_arch_id;
7042
7043#ifndef CONFIG_USER_ONLY
7044    cc->sysemu_ops = &i386_sysemu_ops;
7045#endif /* !CONFIG_USER_ONLY */
7046
7047    cc->gdb_arch_name = x86_gdb_arch_name;
7048#ifdef TARGET_X86_64
7049    cc->gdb_core_xml_file = "i386-64bit.xml";
7050    cc->gdb_num_core_regs = 66;
7051#else
7052    cc->gdb_core_xml_file = "i386-32bit.xml";
7053    cc->gdb_num_core_regs = 50;
7054#endif
7055    cc->disas_set_info = x86_disas_set_info;
7056
7057    dc->user_creatable = true;
7058
7059    object_class_property_add(oc, "family", "int",
7060                              x86_cpuid_version_get_family,
7061                              x86_cpuid_version_set_family, NULL, NULL);
7062    object_class_property_add(oc, "model", "int",
7063                              x86_cpuid_version_get_model,
7064                              x86_cpuid_version_set_model, NULL, NULL);
7065    object_class_property_add(oc, "stepping", "int",
7066                              x86_cpuid_version_get_stepping,
7067                              x86_cpuid_version_set_stepping, NULL, NULL);
7068    object_class_property_add_str(oc, "vendor",
7069                                  x86_cpuid_get_vendor,
7070                                  x86_cpuid_set_vendor);
7071    object_class_property_add_str(oc, "model-id",
7072                                  x86_cpuid_get_model_id,
7073                                  x86_cpuid_set_model_id);
7074    object_class_property_add(oc, "tsc-frequency", "int",
7075                              x86_cpuid_get_tsc_freq,
7076                              x86_cpuid_set_tsc_freq, NULL, NULL);
7077    /*
7078     * The "unavailable-features" property has the same semantics as
7079     * CpuDefinitionInfo.unavailable-features on the "query-cpu-definitions"
7080     * QMP command: they list the features that would have prevented the
7081     * CPU from running if the "enforce" flag was set.
7082     */
7083    object_class_property_add(oc, "unavailable-features", "strList",
7084                              x86_cpu_get_unavailable_features,
7085                              NULL, NULL, NULL);
7086
7087#if !defined(CONFIG_USER_ONLY)
7088    object_class_property_add(oc, "crash-information", "GuestPanicInformation",
7089                              x86_cpu_get_crash_info_qom, NULL, NULL, NULL);
7090#endif
7091
7092    for (w = 0; w < FEATURE_WORDS; w++) {
7093        int bitnr;
7094        for (bitnr = 0; bitnr < 64; bitnr++) {
7095            x86_cpu_register_feature_bit_props(xcc, w, bitnr);
7096        }
7097    }
7098}
7099
7100static const TypeInfo x86_cpu_type_info = {
7101    .name = TYPE_X86_CPU,
7102    .parent = TYPE_CPU,
7103    .instance_size = sizeof(X86CPU),
7104    .instance_init = x86_cpu_initfn,
7105    .instance_post_init = x86_cpu_post_initfn,
7106
7107    .abstract = true,
7108    .class_size = sizeof(X86CPUClass),
7109    .class_init = x86_cpu_common_class_init,
7110};
7111
7112/* "base" CPU model, used by query-cpu-model-expansion */
7113static void x86_cpu_base_class_init(ObjectClass *oc, void *data)
7114{
7115    X86CPUClass *xcc = X86_CPU_CLASS(oc);
7116
7117    xcc->static_model = true;
7118    xcc->migration_safe = true;
7119    xcc->model_description = "base CPU model type with no features enabled";
7120    xcc->ordering = 8;
7121}
7122
7123static const TypeInfo x86_base_cpu_type_info = {
7124        .name = X86_CPU_TYPE_NAME("base"),
7125        .parent = TYPE_X86_CPU,
7126        .class_init = x86_cpu_base_class_init,
7127};
7128
7129static void x86_cpu_register_types(void)
7130{
7131    int i;
7132
7133    type_register_static(&x86_cpu_type_info);
7134    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
7135        x86_register_cpudef_types(&builtin_x86_defs[i]);
7136    }
7137    type_register_static(&max_x86_cpu_type_info);
7138    type_register_static(&x86_base_cpu_type_info);
7139}
7140
7141type_init(x86_cpu_register_types)
7142