xref: /openbmc/qemu/target/i386/cpu.c (revision e052944a)
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 
48 static void x86_cpu_realizefn(DeviceState *dev, Error **errp);
49 
50 /* Helpers for building CPUID[2] descriptors: */
51 
52 struct 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  */
64 struct 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  */
195 static 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] */
239 static 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 */
272 static 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  */
302 static 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] */
328 static 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] */
366 static 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: */
427 static 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 */
440 static 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: */
454 static 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 */
467 static 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: */
481 static 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 */
494 static 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 */
504 static 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: */
516 static 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 
593 void 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 
765 FeatureWordInfo 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 
1442 typedef struct FeatureMask {
1443     FeatureWord index;
1444     uint64_t mask;
1445 } FeatureMask;
1446 
1447 typedef struct FeatureDep {
1448     FeatureMask from, to;
1449 } FeatureDep;
1450 
1451 static 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 
1550 typedef 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 }
1559 static 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 
1574 ExtSaveArea 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 
1620 uint32_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 
1637 static inline bool accel_uses_host_cpuid(void)
1638 {
1639     return kvm_enabled() || hvf_enabled();
1640 }
1641 
1642 static 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 */
1649 static 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 
1657 static 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  */
1667 static 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 
1686 void 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  */
1725 static char *x86_cpu_type_name(const char *model_name)
1726 {
1727     return g_strdup_printf(X86_CPU_TYPE_NAME("%s"), model_name);
1728 }
1729 
1730 static 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 
1736 static 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 
1744 typedef 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 */
1753 typedef 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 */
1775 struct 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 */
1789 static 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 
1796 static const X86CPUVersionDefinition *
1797 x86_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 
1808 static 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 
1858 static 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 
1908 static 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 
1958 static 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 
2008 static 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 
2058 static 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 
2108 static 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 
2186 static 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  */
4893 X86CPUVersion default_cpu_version = 1;
4894 
4895 void 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 
4902 static 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 */
4915 static 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 
4927 static 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 
4933 static 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 
4952 static 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 
4966 static 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 
4987 static 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 
4994 static 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 
5014 static 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 
5027 static 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 
5055 static 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 
5070 static 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 
5097 static 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 
5110 static 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 
5133 static 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 
5145 static 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 
5168 static 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 
5180 static 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 
5202 static 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 
5217 static 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 
5239 static 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 
5249 static 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 */
5270 static 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  */
5308 static 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 */
5316 static 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  */
5344 static GList *plus_features, *minus_features;
5345 
5346 static 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  */
5353 static 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 
5441 static 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 */
5444 static 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 
5461 static 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  */
5474 static 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. */
5492 static 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 
5510 static 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 
5517 static 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 
5525 static 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 
5539 static 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 */
5571 void 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  */
5605 static 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 
5636 static 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 
5667 CpuDefinitionInfoList *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 
5678 uint64_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 
5727 static 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 
5749 static 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  */
5783 void 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 
5800 static 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 
5828 static 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  */
5857 static 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 
5913 static 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 
5922 static 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 
5933 static 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  */
5952 static 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 
5993 uint32_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 
6002 void 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 
6675 static 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 
6686 static 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 
6845 void 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 
6858 static 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 
6875 static 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 */
6883 static 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 */
6914 static 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  */
6987 void 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  */
7131 static 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 
7180 static 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 
7209 static 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 
7458 out:
7459     if (local_err != NULL) {
7460         error_propagate(errp, local_err);
7461         return;
7462     }
7463 }
7464 
7465 static 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 
7483 typedef struct BitProperty {
7484     FeatureWord w;
7485     uint64_t mask;
7486 } BitProperty;
7487 
7488 static 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 
7498 static 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  */
7529 static 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 
7555 static 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 
7577 static void x86_cpu_post_initfn(Object *obj)
7578 {
7579     accel_cpu_instance_init(CPU(obj));
7580 }
7581 
7582 static 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 
7639 static 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)
7647 static 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 
7655 static void x86_cpu_set_pc(CPUState *cs, vaddr value)
7656 {
7657     X86CPU *cpu = X86_CPU(cs);
7658 
7659     cpu->env.eip = value;
7660 }
7661 
7662 static 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 
7670 int 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 
7714 static bool x86_cpu_has_work(CPUState *cs)
7715 {
7716     return x86_cpu_pending_interrupt(cs, cs->interrupt_request) != 0;
7717 }
7718 
7719 static 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 
7736 void 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 
7778 static 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 
7918 static 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 
7932 static 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 
8017 static 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 */
8030 static 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 
8040 static 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 
8046 static 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 
8058 type_init(x86_cpu_register_types)
8059