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