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