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