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