i386: use better matching family/model/stepping for 'max' CPU
[qemu/ar7.git] / target / i386 / cpu.c
blobd150378c400665c496b3d1f018b73df07bf8d277
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 = 15,
1807 .model = 107,
1808 .stepping = 1,
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 #ifdef TARGET_X86_64
4289 object_property_set_int(OBJECT(cpu), "family", 15, &error_abort);
4290 object_property_set_int(OBJECT(cpu), "model", 107, &error_abort);
4291 object_property_set_int(OBJECT(cpu), "stepping", 1, &error_abort);
4292 #else
4293 object_property_set_int(OBJECT(cpu), "family", 6, &error_abort);
4294 object_property_set_int(OBJECT(cpu), "model", 6, &error_abort);
4295 object_property_set_int(OBJECT(cpu), "stepping", 3, &error_abort);
4296 #endif
4297 object_property_set_str(OBJECT(cpu), "model-id",
4298 "QEMU TCG CPU version " QEMU_HW_VERSION,
4299 &error_abort);
4302 static const TypeInfo max_x86_cpu_type_info = {
4303 .name = X86_CPU_TYPE_NAME("max"),
4304 .parent = TYPE_X86_CPU,
4305 .instance_init = max_x86_cpu_initfn,
4306 .class_init = max_x86_cpu_class_init,
4309 static char *feature_word_description(FeatureWordInfo *f, uint32_t bit)
4311 assert(f->type == CPUID_FEATURE_WORD || f->type == MSR_FEATURE_WORD);
4313 switch (f->type) {
4314 case CPUID_FEATURE_WORD:
4316 const char *reg = get_register_name_32(f->cpuid.reg);
4317 assert(reg);
4318 return g_strdup_printf("CPUID.%02XH:%s",
4319 f->cpuid.eax, reg);
4321 case MSR_FEATURE_WORD:
4322 return g_strdup_printf("MSR(%02XH)",
4323 f->msr.index);
4326 return NULL;
4329 static bool x86_cpu_have_filtered_features(X86CPU *cpu)
4331 FeatureWord w;
4333 for (w = 0; w < FEATURE_WORDS; w++) {
4334 if (cpu->filtered_features[w]) {
4335 return true;
4339 return false;
4342 static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t mask,
4343 const char *verbose_prefix)
4345 CPUX86State *env = &cpu->env;
4346 FeatureWordInfo *f = &feature_word_info[w];
4347 int i;
4349 if (!cpu->force_features) {
4350 env->features[w] &= ~mask;
4352 cpu->filtered_features[w] |= mask;
4354 if (!verbose_prefix) {
4355 return;
4358 for (i = 0; i < 64; ++i) {
4359 if ((1ULL << i) & mask) {
4360 g_autofree char *feat_word_str = feature_word_description(f, i);
4361 warn_report("%s: %s%s%s [bit %d]",
4362 verbose_prefix,
4363 feat_word_str,
4364 f->feat_names[i] ? "." : "",
4365 f->feat_names[i] ? f->feat_names[i] : "", i);
4370 static void x86_cpuid_version_get_family(Object *obj, Visitor *v,
4371 const char *name, void *opaque,
4372 Error **errp)
4374 X86CPU *cpu = X86_CPU(obj);
4375 CPUX86State *env = &cpu->env;
4376 int64_t value;
4378 value = (env->cpuid_version >> 8) & 0xf;
4379 if (value == 0xf) {
4380 value += (env->cpuid_version >> 20) & 0xff;
4382 visit_type_int(v, name, &value, errp);
4385 static void x86_cpuid_version_set_family(Object *obj, Visitor *v,
4386 const char *name, void *opaque,
4387 Error **errp)
4389 X86CPU *cpu = X86_CPU(obj);
4390 CPUX86State *env = &cpu->env;
4391 const int64_t min = 0;
4392 const int64_t max = 0xff + 0xf;
4393 int64_t value;
4395 if (!visit_type_int(v, name, &value, errp)) {
4396 return;
4398 if (value < min || value > max) {
4399 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
4400 name ? name : "null", value, min, max);
4401 return;
4404 env->cpuid_version &= ~0xff00f00;
4405 if (value > 0x0f) {
4406 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
4407 } else {
4408 env->cpuid_version |= value << 8;
4412 static void x86_cpuid_version_get_model(Object *obj, Visitor *v,
4413 const char *name, void *opaque,
4414 Error **errp)
4416 X86CPU *cpu = X86_CPU(obj);
4417 CPUX86State *env = &cpu->env;
4418 int64_t value;
4420 value = (env->cpuid_version >> 4) & 0xf;
4421 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
4422 visit_type_int(v, name, &value, errp);
4425 static void x86_cpuid_version_set_model(Object *obj, Visitor *v,
4426 const char *name, void *opaque,
4427 Error **errp)
4429 X86CPU *cpu = X86_CPU(obj);
4430 CPUX86State *env = &cpu->env;
4431 const int64_t min = 0;
4432 const int64_t max = 0xff;
4433 int64_t value;
4435 if (!visit_type_int(v, name, &value, errp)) {
4436 return;
4438 if (value < min || value > max) {
4439 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
4440 name ? name : "null", value, min, max);
4441 return;
4444 env->cpuid_version &= ~0xf00f0;
4445 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
4448 static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
4449 const char *name, void *opaque,
4450 Error **errp)
4452 X86CPU *cpu = X86_CPU(obj);
4453 CPUX86State *env = &cpu->env;
4454 int64_t value;
4456 value = env->cpuid_version & 0xf;
4457 visit_type_int(v, name, &value, errp);
4460 static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
4461 const char *name, void *opaque,
4462 Error **errp)
4464 X86CPU *cpu = X86_CPU(obj);
4465 CPUX86State *env = &cpu->env;
4466 const int64_t min = 0;
4467 const int64_t max = 0xf;
4468 int64_t value;
4470 if (!visit_type_int(v, name, &value, errp)) {
4471 return;
4473 if (value < min || value > max) {
4474 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
4475 name ? name : "null", value, min, max);
4476 return;
4479 env->cpuid_version &= ~0xf;
4480 env->cpuid_version |= value & 0xf;
4483 static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
4485 X86CPU *cpu = X86_CPU(obj);
4486 CPUX86State *env = &cpu->env;
4487 char *value;
4489 value = g_malloc(CPUID_VENDOR_SZ + 1);
4490 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
4491 env->cpuid_vendor3);
4492 return value;
4495 static void x86_cpuid_set_vendor(Object *obj, const char *value,
4496 Error **errp)
4498 X86CPU *cpu = X86_CPU(obj);
4499 CPUX86State *env = &cpu->env;
4500 int i;
4502 if (strlen(value) != CPUID_VENDOR_SZ) {
4503 error_setg(errp, QERR_PROPERTY_VALUE_BAD, "", "vendor", value);
4504 return;
4507 env->cpuid_vendor1 = 0;
4508 env->cpuid_vendor2 = 0;
4509 env->cpuid_vendor3 = 0;
4510 for (i = 0; i < 4; i++) {
4511 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
4512 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
4513 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
4517 static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
4519 X86CPU *cpu = X86_CPU(obj);
4520 CPUX86State *env = &cpu->env;
4521 char *value;
4522 int i;
4524 value = g_malloc(48 + 1);
4525 for (i = 0; i < 48; i++) {
4526 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
4528 value[48] = '\0';
4529 return value;
4532 static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
4533 Error **errp)
4535 X86CPU *cpu = X86_CPU(obj);
4536 CPUX86State *env = &cpu->env;
4537 int c, len, i;
4539 if (model_id == NULL) {
4540 model_id = "";
4542 len = strlen(model_id);
4543 memset(env->cpuid_model, 0, 48);
4544 for (i = 0; i < 48; i++) {
4545 if (i >= len) {
4546 c = '\0';
4547 } else {
4548 c = (uint8_t)model_id[i];
4550 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
4554 static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, const char *name,
4555 void *opaque, Error **errp)
4557 X86CPU *cpu = X86_CPU(obj);
4558 int64_t value;
4560 value = cpu->env.tsc_khz * 1000;
4561 visit_type_int(v, name, &value, errp);
4564 static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
4565 void *opaque, Error **errp)
4567 X86CPU *cpu = X86_CPU(obj);
4568 const int64_t min = 0;
4569 const int64_t max = INT64_MAX;
4570 int64_t value;
4572 if (!visit_type_int(v, name, &value, errp)) {
4573 return;
4575 if (value < min || value > max) {
4576 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
4577 name ? name : "null", value, min, max);
4578 return;
4581 cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
4584 /* Generic getter for "feature-words" and "filtered-features" properties */
4585 static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
4586 const char *name, void *opaque,
4587 Error **errp)
4589 uint64_t *array = (uint64_t *)opaque;
4590 FeatureWord w;
4591 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
4592 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
4593 X86CPUFeatureWordInfoList *list = NULL;
4595 for (w = 0; w < FEATURE_WORDS; w++) {
4596 FeatureWordInfo *wi = &feature_word_info[w];
4598 * We didn't have MSR features when "feature-words" was
4599 * introduced. Therefore skipped other type entries.
4601 if (wi->type != CPUID_FEATURE_WORD) {
4602 continue;
4604 X86CPUFeatureWordInfo *qwi = &word_infos[w];
4605 qwi->cpuid_input_eax = wi->cpuid.eax;
4606 qwi->has_cpuid_input_ecx = wi->cpuid.needs_ecx;
4607 qwi->cpuid_input_ecx = wi->cpuid.ecx;
4608 qwi->cpuid_register = x86_reg_info_32[wi->cpuid.reg].qapi_enum;
4609 qwi->features = array[w];
4611 /* List will be in reverse order, but order shouldn't matter */
4612 list_entries[w].next = list;
4613 list_entries[w].value = &word_infos[w];
4614 list = &list_entries[w];
4617 visit_type_X86CPUFeatureWordInfoList(v, "feature-words", &list, errp);
4620 /* Convert all '_' in a feature string option name to '-', to make feature
4621 * name conform to QOM property naming rule, which uses '-' instead of '_'.
4623 static inline void feat2prop(char *s)
4625 while ((s = strchr(s, '_'))) {
4626 *s = '-';
4630 /* Return the feature property name for a feature flag bit */
4631 static const char *x86_cpu_feature_name(FeatureWord w, int bitnr)
4633 const char *name;
4634 /* XSAVE components are automatically enabled by other features,
4635 * so return the original feature name instead
4637 if (w == FEAT_XSAVE_COMP_LO || w == FEAT_XSAVE_COMP_HI) {
4638 int comp = (w == FEAT_XSAVE_COMP_HI) ? bitnr + 32 : bitnr;
4640 if (comp < ARRAY_SIZE(x86_ext_save_areas) &&
4641 x86_ext_save_areas[comp].bits) {
4642 w = x86_ext_save_areas[comp].feature;
4643 bitnr = ctz32(x86_ext_save_areas[comp].bits);
4647 assert(bitnr < 64);
4648 assert(w < FEATURE_WORDS);
4649 name = feature_word_info[w].feat_names[bitnr];
4650 assert(bitnr < 32 || !(name && feature_word_info[w].type == CPUID_FEATURE_WORD));
4651 return name;
4654 /* Compatibily hack to maintain legacy +-feat semantic,
4655 * where +-feat overwrites any feature set by
4656 * feat=on|feat even if the later is parsed after +-feat
4657 * (i.e. "-x2apic,x2apic=on" will result in x2apic disabled)
4659 static GList *plus_features, *minus_features;
4661 static gint compare_string(gconstpointer a, gconstpointer b)
4663 return g_strcmp0(a, b);
4666 /* Parse "+feature,-feature,feature=foo" CPU feature string
4668 static void x86_cpu_parse_featurestr(const char *typename, char *features,
4669 Error **errp)
4671 char *featurestr; /* Single 'key=value" string being parsed */
4672 static bool cpu_globals_initialized;
4673 bool ambiguous = false;
4675 if (cpu_globals_initialized) {
4676 return;
4678 cpu_globals_initialized = true;
4680 if (!features) {
4681 return;
4684 for (featurestr = strtok(features, ",");
4685 featurestr;
4686 featurestr = strtok(NULL, ",")) {
4687 const char *name;
4688 const char *val = NULL;
4689 char *eq = NULL;
4690 char num[32];
4691 GlobalProperty *prop;
4693 /* Compatibility syntax: */
4694 if (featurestr[0] == '+') {
4695 plus_features = g_list_append(plus_features,
4696 g_strdup(featurestr + 1));
4697 continue;
4698 } else if (featurestr[0] == '-') {
4699 minus_features = g_list_append(minus_features,
4700 g_strdup(featurestr + 1));
4701 continue;
4704 eq = strchr(featurestr, '=');
4705 if (eq) {
4706 *eq++ = 0;
4707 val = eq;
4708 } else {
4709 val = "on";
4712 feat2prop(featurestr);
4713 name = featurestr;
4715 if (g_list_find_custom(plus_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;
4721 if (g_list_find_custom(minus_features, name, compare_string)) {
4722 warn_report("Ambiguous CPU model string. "
4723 "Don't mix both \"-%s\" and \"%s=%s\"",
4724 name, name, val);
4725 ambiguous = true;
4728 /* Special case: */
4729 if (!strcmp(name, "tsc-freq")) {
4730 int ret;
4731 uint64_t tsc_freq;
4733 ret = qemu_strtosz_metric(val, NULL, &tsc_freq);
4734 if (ret < 0 || tsc_freq > INT64_MAX) {
4735 error_setg(errp, "bad numerical value %s", val);
4736 return;
4738 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
4739 val = num;
4740 name = "tsc-frequency";
4743 prop = g_new0(typeof(*prop), 1);
4744 prop->driver = typename;
4745 prop->property = g_strdup(name);
4746 prop->value = g_strdup(val);
4747 qdev_prop_register_global(prop);
4750 if (ambiguous) {
4751 warn_report("Compatibility of ambiguous CPU model "
4752 "strings won't be kept on future QEMU versions");
4756 static void x86_cpu_filter_features(X86CPU *cpu, bool verbose);
4758 /* Build a list with the name of all features on a feature word array */
4759 static void x86_cpu_list_feature_names(FeatureWordArray features,
4760 strList **list)
4762 strList **tail = list;
4763 FeatureWord w;
4765 for (w = 0; w < FEATURE_WORDS; w++) {
4766 uint64_t filtered = features[w];
4767 int i;
4768 for (i = 0; i < 64; i++) {
4769 if (filtered & (1ULL << i)) {
4770 QAPI_LIST_APPEND(tail, g_strdup(x86_cpu_feature_name(w, i)));
4776 static void x86_cpu_get_unavailable_features(Object *obj, Visitor *v,
4777 const char *name, void *opaque,
4778 Error **errp)
4780 X86CPU *xc = X86_CPU(obj);
4781 strList *result = NULL;
4783 x86_cpu_list_feature_names(xc->filtered_features, &result);
4784 visit_type_strList(v, "unavailable-features", &result, errp);
4787 /* Check for missing features that may prevent the CPU class from
4788 * running using the current machine and accelerator.
4790 static void x86_cpu_class_check_missing_features(X86CPUClass *xcc,
4791 strList **list)
4793 strList **tail = list;
4794 X86CPU *xc;
4795 Error *err = NULL;
4797 if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
4798 QAPI_LIST_APPEND(tail, g_strdup("kvm"));
4799 return;
4802 xc = X86_CPU(object_new_with_class(OBJECT_CLASS(xcc)));
4804 x86_cpu_expand_features(xc, &err);
4805 if (err) {
4806 /* Errors at x86_cpu_expand_features should never happen,
4807 * but in case it does, just report the model as not
4808 * runnable at all using the "type" property.
4810 QAPI_LIST_APPEND(tail, g_strdup("type"));
4811 error_free(err);
4814 x86_cpu_filter_features(xc, false);
4816 x86_cpu_list_feature_names(xc->filtered_features, tail);
4818 object_unref(OBJECT(xc));
4821 /* Print all cpuid feature names in featureset
4823 static void listflags(GList *features)
4825 size_t len = 0;
4826 GList *tmp;
4828 for (tmp = features; tmp; tmp = tmp->next) {
4829 const char *name = tmp->data;
4830 if ((len + strlen(name) + 1) >= 75) {
4831 qemu_printf("\n");
4832 len = 0;
4834 qemu_printf("%s%s", len == 0 ? " " : " ", name);
4835 len += strlen(name) + 1;
4837 qemu_printf("\n");
4840 /* Sort alphabetically by type name, respecting X86CPUClass::ordering. */
4841 static gint x86_cpu_list_compare(gconstpointer a, gconstpointer b)
4843 ObjectClass *class_a = (ObjectClass *)a;
4844 ObjectClass *class_b = (ObjectClass *)b;
4845 X86CPUClass *cc_a = X86_CPU_CLASS(class_a);
4846 X86CPUClass *cc_b = X86_CPU_CLASS(class_b);
4847 int ret;
4849 if (cc_a->ordering != cc_b->ordering) {
4850 ret = cc_a->ordering - cc_b->ordering;
4851 } else {
4852 g_autofree char *name_a = x86_cpu_class_get_model_name(cc_a);
4853 g_autofree char *name_b = x86_cpu_class_get_model_name(cc_b);
4854 ret = strcmp(name_a, name_b);
4856 return ret;
4859 static GSList *get_sorted_cpu_model_list(void)
4861 GSList *list = object_class_get_list(TYPE_X86_CPU, false);
4862 list = g_slist_sort(list, x86_cpu_list_compare);
4863 return list;
4866 static char *x86_cpu_class_get_model_id(X86CPUClass *xc)
4868 Object *obj = object_new_with_class(OBJECT_CLASS(xc));
4869 char *r = object_property_get_str(obj, "model-id", &error_abort);
4870 object_unref(obj);
4871 return r;
4874 static char *x86_cpu_class_get_alias_of(X86CPUClass *cc)
4876 X86CPUVersion version;
4878 if (!cc->model || !cc->model->is_alias) {
4879 return NULL;
4881 version = x86_cpu_model_resolve_version(cc->model);
4882 if (version <= 0) {
4883 return NULL;
4885 return x86_cpu_versioned_model_name(cc->model->cpudef, version);
4888 static void x86_cpu_list_entry(gpointer data, gpointer user_data)
4890 ObjectClass *oc = data;
4891 X86CPUClass *cc = X86_CPU_CLASS(oc);
4892 g_autofree char *name = x86_cpu_class_get_model_name(cc);
4893 g_autofree char *desc = g_strdup(cc->model_description);
4894 g_autofree char *alias_of = x86_cpu_class_get_alias_of(cc);
4895 g_autofree char *model_id = x86_cpu_class_get_model_id(cc);
4897 if (!desc && alias_of) {
4898 if (cc->model && cc->model->version == CPU_VERSION_AUTO) {
4899 desc = g_strdup("(alias configured by machine type)");
4900 } else {
4901 desc = g_strdup_printf("(alias of %s)", alias_of);
4904 if (!desc && cc->model && cc->model->note) {
4905 desc = g_strdup_printf("%s [%s]", model_id, cc->model->note);
4907 if (!desc) {
4908 desc = g_strdup_printf("%s", model_id);
4911 qemu_printf("x86 %-20s %-58s\n", name, desc);
4914 /* list available CPU models and flags */
4915 void x86_cpu_list(void)
4917 int i, j;
4918 GSList *list;
4919 GList *names = NULL;
4921 qemu_printf("Available CPUs:\n");
4922 list = get_sorted_cpu_model_list();
4923 g_slist_foreach(list, x86_cpu_list_entry, NULL);
4924 g_slist_free(list);
4926 names = NULL;
4927 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
4928 FeatureWordInfo *fw = &feature_word_info[i];
4929 for (j = 0; j < 64; j++) {
4930 if (fw->feat_names[j]) {
4931 names = g_list_append(names, (gpointer)fw->feat_names[j]);
4936 names = g_list_sort(names, (GCompareFunc)strcmp);
4938 qemu_printf("\nRecognized CPUID flags:\n");
4939 listflags(names);
4940 qemu_printf("\n");
4941 g_list_free(names);
4944 static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
4946 ObjectClass *oc = data;
4947 X86CPUClass *cc = X86_CPU_CLASS(oc);
4948 CpuDefinitionInfoList **cpu_list = user_data;
4949 CpuDefinitionInfo *info;
4951 info = g_malloc0(sizeof(*info));
4952 info->name = x86_cpu_class_get_model_name(cc);
4953 x86_cpu_class_check_missing_features(cc, &info->unavailable_features);
4954 info->has_unavailable_features = true;
4955 info->q_typename = g_strdup(object_class_get_name(oc));
4956 info->migration_safe = cc->migration_safe;
4957 info->has_migration_safe = true;
4958 info->q_static = cc->static_model;
4959 if (cc->model && cc->model->cpudef->deprecation_note) {
4960 info->deprecated = true;
4961 } else {
4962 info->deprecated = false;
4965 * Old machine types won't report aliases, so that alias translation
4966 * doesn't break compatibility with previous QEMU versions.
4968 if (default_cpu_version != CPU_VERSION_LEGACY) {
4969 info->alias_of = x86_cpu_class_get_alias_of(cc);
4970 info->has_alias_of = !!info->alias_of;
4973 QAPI_LIST_PREPEND(*cpu_list, info);
4976 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
4978 CpuDefinitionInfoList *cpu_list = NULL;
4979 GSList *list = get_sorted_cpu_model_list();
4980 g_slist_foreach(list, x86_cpu_definition_entry, &cpu_list);
4981 g_slist_free(list);
4982 return cpu_list;
4985 static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
4986 bool migratable_only)
4988 FeatureWordInfo *wi = &feature_word_info[w];
4989 uint64_t r = 0;
4991 if (kvm_enabled()) {
4992 switch (wi->type) {
4993 case CPUID_FEATURE_WORD:
4994 r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid.eax,
4995 wi->cpuid.ecx,
4996 wi->cpuid.reg);
4997 break;
4998 case MSR_FEATURE_WORD:
4999 r = kvm_arch_get_supported_msr_feature(kvm_state,
5000 wi->msr.index);
5001 break;
5003 } else if (hvf_enabled()) {
5004 if (wi->type != CPUID_FEATURE_WORD) {
5005 return 0;
5007 r = hvf_get_supported_cpuid(wi->cpuid.eax,
5008 wi->cpuid.ecx,
5009 wi->cpuid.reg);
5010 } else if (tcg_enabled()) {
5011 r = wi->tcg_features;
5012 } else {
5013 return ~0;
5015 #ifndef TARGET_X86_64
5016 if (w == FEAT_8000_0001_EDX) {
5017 r &= ~CPUID_EXT2_LM;
5019 #endif
5020 if (migratable_only) {
5021 r &= x86_cpu_get_migratable_flags(w);
5023 return r;
5026 void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
5028 PropValue *pv;
5029 for (pv = props; pv->prop; pv++) {
5030 if (!pv->value) {
5031 continue;
5033 object_property_parse(OBJECT(cpu), pv->prop, pv->value,
5034 &error_abort);
5038 /* Apply properties for the CPU model version specified in model */
5039 static void x86_cpu_apply_version_props(X86CPU *cpu, X86CPUModel *model)
5041 const X86CPUVersionDefinition *vdef;
5042 X86CPUVersion version = x86_cpu_model_resolve_version(model);
5044 if (version == CPU_VERSION_LEGACY) {
5045 return;
5048 for (vdef = x86_cpu_def_get_versions(model->cpudef); vdef->version; vdef++) {
5049 PropValue *p;
5051 for (p = vdef->props; p && p->prop; p++) {
5052 object_property_parse(OBJECT(cpu), p->prop, p->value,
5053 &error_abort);
5056 if (vdef->version == version) {
5057 break;
5062 * If we reached the end of the list, version number was invalid
5064 assert(vdef->version == version);
5067 /* Load data from X86CPUDefinition into a X86CPU object
5069 static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model)
5071 const X86CPUDefinition *def = model->cpudef;
5072 CPUX86State *env = &cpu->env;
5073 FeatureWord w;
5075 /*NOTE: any property set by this function should be returned by
5076 * x86_cpu_static_props(), so static expansion of
5077 * query-cpu-model-expansion is always complete.
5080 /* CPU models only set _minimum_ values for level/xlevel: */
5081 object_property_set_uint(OBJECT(cpu), "min-level", def->level,
5082 &error_abort);
5083 object_property_set_uint(OBJECT(cpu), "min-xlevel", def->xlevel,
5084 &error_abort);
5086 object_property_set_int(OBJECT(cpu), "family", def->family, &error_abort);
5087 object_property_set_int(OBJECT(cpu), "model", def->model, &error_abort);
5088 object_property_set_int(OBJECT(cpu), "stepping", def->stepping,
5089 &error_abort);
5090 object_property_set_str(OBJECT(cpu), "model-id", def->model_id,
5091 &error_abort);
5092 for (w = 0; w < FEATURE_WORDS; w++) {
5093 env->features[w] = def->features[w];
5096 /* legacy-cache defaults to 'off' if CPU model provides cache info */
5097 cpu->legacy_cache = !def->cache_info;
5099 env->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
5101 /* sysenter isn't supported in compatibility mode on AMD,
5102 * syscall isn't supported in compatibility mode on Intel.
5103 * Normally we advertise the actual CPU vendor, but you can
5104 * override this using the 'vendor' property if you want to use
5105 * KVM's sysenter/syscall emulation in compatibility mode and
5106 * when doing cross vendor migration
5110 * vendor property is set here but then overloaded with the
5111 * host cpu vendor for KVM and HVF.
5113 object_property_set_str(OBJECT(cpu), "vendor", def->vendor, &error_abort);
5115 x86_cpu_apply_version_props(cpu, model);
5118 * Properties in versioned CPU model are not user specified features.
5119 * We can simply clear env->user_features here since it will be filled later
5120 * in x86_cpu_expand_features() based on plus_features and minus_features.
5122 memset(&env->user_features, 0, sizeof(env->user_features));
5125 static gchar *x86_gdb_arch_name(CPUState *cs)
5127 #ifdef TARGET_X86_64
5128 return g_strdup("i386:x86-64");
5129 #else
5130 return g_strdup("i386");
5131 #endif
5134 static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
5136 X86CPUModel *model = data;
5137 X86CPUClass *xcc = X86_CPU_CLASS(oc);
5138 CPUClass *cc = CPU_CLASS(oc);
5140 xcc->model = model;
5141 xcc->migration_safe = true;
5142 cc->deprecation_note = model->cpudef->deprecation_note;
5145 static void x86_register_cpu_model_type(const char *name, X86CPUModel *model)
5147 g_autofree char *typename = x86_cpu_type_name(name);
5148 TypeInfo ti = {
5149 .name = typename,
5150 .parent = TYPE_X86_CPU,
5151 .class_init = x86_cpu_cpudef_class_init,
5152 .class_data = model,
5155 type_register(&ti);
5158 static void x86_register_cpudef_types(const X86CPUDefinition *def)
5160 X86CPUModel *m;
5161 const X86CPUVersionDefinition *vdef;
5163 /* AMD aliases are handled at runtime based on CPUID vendor, so
5164 * they shouldn't be set on the CPU model table.
5166 assert(!(def->features[FEAT_8000_0001_EDX] & CPUID_EXT2_AMD_ALIASES));
5167 /* catch mistakes instead of silently truncating model_id when too long */
5168 assert(def->model_id && strlen(def->model_id) <= 48);
5170 /* Unversioned model: */
5171 m = g_new0(X86CPUModel, 1);
5172 m->cpudef = def;
5173 m->version = CPU_VERSION_AUTO;
5174 m->is_alias = true;
5175 x86_register_cpu_model_type(def->name, m);
5177 /* Versioned models: */
5179 for (vdef = x86_cpu_def_get_versions(def); vdef->version; vdef++) {
5180 X86CPUModel *m = g_new0(X86CPUModel, 1);
5181 g_autofree char *name =
5182 x86_cpu_versioned_model_name(def, vdef->version);
5183 m->cpudef = def;
5184 m->version = vdef->version;
5185 m->note = vdef->note;
5186 x86_register_cpu_model_type(name, m);
5188 if (vdef->alias) {
5189 X86CPUModel *am = g_new0(X86CPUModel, 1);
5190 am->cpudef = def;
5191 am->version = vdef->version;
5192 am->is_alias = true;
5193 x86_register_cpu_model_type(vdef->alias, am);
5199 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
5200 uint32_t *eax, uint32_t *ebx,
5201 uint32_t *ecx, uint32_t *edx)
5203 X86CPU *cpu = env_archcpu(env);
5204 CPUState *cs = env_cpu(env);
5205 uint32_t die_offset;
5206 uint32_t limit;
5207 uint32_t signature[3];
5208 X86CPUTopoInfo topo_info;
5210 topo_info.dies_per_pkg = env->nr_dies;
5211 topo_info.cores_per_die = cs->nr_cores;
5212 topo_info.threads_per_core = cs->nr_threads;
5214 /* Calculate & apply limits for different index ranges */
5215 if (index >= 0xC0000000) {
5216 limit = env->cpuid_xlevel2;
5217 } else if (index >= 0x80000000) {
5218 limit = env->cpuid_xlevel;
5219 } else if (index >= 0x40000000) {
5220 limit = 0x40000001;
5221 } else {
5222 limit = env->cpuid_level;
5225 if (index > limit) {
5226 /* Intel documentation states that invalid EAX input will
5227 * return the same information as EAX=cpuid_level
5228 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
5230 index = env->cpuid_level;
5233 switch(index) {
5234 case 0:
5235 *eax = env->cpuid_level;
5236 *ebx = env->cpuid_vendor1;
5237 *edx = env->cpuid_vendor2;
5238 *ecx = env->cpuid_vendor3;
5239 break;
5240 case 1:
5241 *eax = env->cpuid_version;
5242 *ebx = (cpu->apic_id << 24) |
5243 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
5244 *ecx = env->features[FEAT_1_ECX];
5245 if ((*ecx & CPUID_EXT_XSAVE) && (env->cr[4] & CR4_OSXSAVE_MASK)) {
5246 *ecx |= CPUID_EXT_OSXSAVE;
5248 *edx = env->features[FEAT_1_EDX];
5249 if (cs->nr_cores * cs->nr_threads > 1) {
5250 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
5251 *edx |= CPUID_HT;
5253 if (!cpu->enable_pmu) {
5254 *ecx &= ~CPUID_EXT_PDCM;
5256 break;
5257 case 2:
5258 /* cache info: needed for Pentium Pro compatibility */
5259 if (cpu->cache_info_passthrough) {
5260 host_cpuid(index, 0, eax, ebx, ecx, edx);
5261 break;
5263 *eax = 1; /* Number of CPUID[EAX=2] calls required */
5264 *ebx = 0;
5265 if (!cpu->enable_l3_cache) {
5266 *ecx = 0;
5267 } else {
5268 *ecx = cpuid2_cache_descriptor(env->cache_info_cpuid2.l3_cache);
5270 *edx = (cpuid2_cache_descriptor(env->cache_info_cpuid2.l1d_cache) << 16) |
5271 (cpuid2_cache_descriptor(env->cache_info_cpuid2.l1i_cache) << 8) |
5272 (cpuid2_cache_descriptor(env->cache_info_cpuid2.l2_cache));
5273 break;
5274 case 4:
5275 /* cache info: needed for Core compatibility */
5276 if (cpu->cache_info_passthrough) {
5277 host_cpuid(index, count, eax, ebx, ecx, edx);
5278 /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
5279 *eax &= ~0xFC000000;
5280 if ((*eax & 31) && cs->nr_cores > 1) {
5281 *eax |= (cs->nr_cores - 1) << 26;
5283 } else {
5284 *eax = 0;
5285 switch (count) {
5286 case 0: /* L1 dcache info */
5287 encode_cache_cpuid4(env->cache_info_cpuid4.l1d_cache,
5288 1, cs->nr_cores,
5289 eax, ebx, ecx, edx);
5290 break;
5291 case 1: /* L1 icache info */
5292 encode_cache_cpuid4(env->cache_info_cpuid4.l1i_cache,
5293 1, cs->nr_cores,
5294 eax, ebx, ecx, edx);
5295 break;
5296 case 2: /* L2 cache info */
5297 encode_cache_cpuid4(env->cache_info_cpuid4.l2_cache,
5298 cs->nr_threads, cs->nr_cores,
5299 eax, ebx, ecx, edx);
5300 break;
5301 case 3: /* L3 cache info */
5302 die_offset = apicid_die_offset(&topo_info);
5303 if (cpu->enable_l3_cache) {
5304 encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache,
5305 (1 << die_offset), cs->nr_cores,
5306 eax, ebx, ecx, edx);
5307 break;
5309 /* fall through */
5310 default: /* end of info */
5311 *eax = *ebx = *ecx = *edx = 0;
5312 break;
5315 break;
5316 case 5:
5317 /* MONITOR/MWAIT Leaf */
5318 *eax = cpu->mwait.eax; /* Smallest monitor-line size in bytes */
5319 *ebx = cpu->mwait.ebx; /* Largest monitor-line size in bytes */
5320 *ecx = cpu->mwait.ecx; /* flags */
5321 *edx = cpu->mwait.edx; /* mwait substates */
5322 break;
5323 case 6:
5324 /* Thermal and Power Leaf */
5325 *eax = env->features[FEAT_6_EAX];
5326 *ebx = 0;
5327 *ecx = 0;
5328 *edx = 0;
5329 break;
5330 case 7:
5331 /* Structured Extended Feature Flags Enumeration Leaf */
5332 if (count == 0) {
5333 /* Maximum ECX value for sub-leaves */
5334 *eax = env->cpuid_level_func7;
5335 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
5336 *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */
5337 if ((*ecx & CPUID_7_0_ECX_PKU) && env->cr[4] & CR4_PKE_MASK) {
5338 *ecx |= CPUID_7_0_ECX_OSPKE;
5340 *edx = env->features[FEAT_7_0_EDX]; /* Feature flags */
5341 } else if (count == 1) {
5342 *eax = env->features[FEAT_7_1_EAX];
5343 *ebx = 0;
5344 *ecx = 0;
5345 *edx = 0;
5346 } else {
5347 *eax = 0;
5348 *ebx = 0;
5349 *ecx = 0;
5350 *edx = 0;
5352 break;
5353 case 9:
5354 /* Direct Cache Access Information Leaf */
5355 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
5356 *ebx = 0;
5357 *ecx = 0;
5358 *edx = 0;
5359 break;
5360 case 0xA:
5361 /* Architectural Performance Monitoring Leaf */
5362 if (kvm_enabled() && cpu->enable_pmu) {
5363 KVMState *s = cs->kvm_state;
5365 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
5366 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
5367 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
5368 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
5369 } else if (hvf_enabled() && cpu->enable_pmu) {
5370 *eax = hvf_get_supported_cpuid(0xA, count, R_EAX);
5371 *ebx = hvf_get_supported_cpuid(0xA, count, R_EBX);
5372 *ecx = hvf_get_supported_cpuid(0xA, count, R_ECX);
5373 *edx = hvf_get_supported_cpuid(0xA, count, R_EDX);
5374 } else {
5375 *eax = 0;
5376 *ebx = 0;
5377 *ecx = 0;
5378 *edx = 0;
5380 break;
5381 case 0xB:
5382 /* Extended Topology Enumeration Leaf */
5383 if (!cpu->enable_cpuid_0xb) {
5384 *eax = *ebx = *ecx = *edx = 0;
5385 break;
5388 *ecx = count & 0xff;
5389 *edx = cpu->apic_id;
5391 switch (count) {
5392 case 0:
5393 *eax = apicid_core_offset(&topo_info);
5394 *ebx = cs->nr_threads;
5395 *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
5396 break;
5397 case 1:
5398 *eax = apicid_pkg_offset(&topo_info);
5399 *ebx = cs->nr_cores * cs->nr_threads;
5400 *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
5401 break;
5402 default:
5403 *eax = 0;
5404 *ebx = 0;
5405 *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
5408 assert(!(*eax & ~0x1f));
5409 *ebx &= 0xffff; /* The count doesn't need to be reliable. */
5410 break;
5411 case 0x1F:
5412 /* V2 Extended Topology Enumeration Leaf */
5413 if (env->nr_dies < 2) {
5414 *eax = *ebx = *ecx = *edx = 0;
5415 break;
5418 *ecx = count & 0xff;
5419 *edx = cpu->apic_id;
5420 switch (count) {
5421 case 0:
5422 *eax = apicid_core_offset(&topo_info);
5423 *ebx = cs->nr_threads;
5424 *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
5425 break;
5426 case 1:
5427 *eax = apicid_die_offset(&topo_info);
5428 *ebx = cs->nr_cores * cs->nr_threads;
5429 *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
5430 break;
5431 case 2:
5432 *eax = apicid_pkg_offset(&topo_info);
5433 *ebx = env->nr_dies * cs->nr_cores * cs->nr_threads;
5434 *ecx |= CPUID_TOPOLOGY_LEVEL_DIE;
5435 break;
5436 default:
5437 *eax = 0;
5438 *ebx = 0;
5439 *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
5441 assert(!(*eax & ~0x1f));
5442 *ebx &= 0xffff; /* The count doesn't need to be reliable. */
5443 break;
5444 case 0xD: {
5445 /* Processor Extended State */
5446 *eax = 0;
5447 *ebx = 0;
5448 *ecx = 0;
5449 *edx = 0;
5450 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
5451 break;
5454 if (count == 0) {
5455 *ecx = xsave_area_size(x86_cpu_xsave_components(cpu));
5456 *eax = env->features[FEAT_XSAVE_COMP_LO];
5457 *edx = env->features[FEAT_XSAVE_COMP_HI];
5459 * The initial value of xcr0 and ebx == 0, On host without kvm
5460 * commit 412a3c41(e.g., CentOS 6), the ebx's value always == 0
5461 * even through guest update xcr0, this will crash some legacy guest
5462 * (e.g., CentOS 6), So set ebx == ecx to workaroud it.
5464 *ebx = kvm_enabled() ? *ecx : xsave_area_size(env->xcr0);
5465 } else if (count == 1) {
5466 *eax = env->features[FEAT_XSAVE];
5467 } else if (count < ARRAY_SIZE(x86_ext_save_areas)) {
5468 if ((x86_cpu_xsave_components(cpu) >> count) & 1) {
5469 const ExtSaveArea *esa = &x86_ext_save_areas[count];
5470 *eax = esa->size;
5471 *ebx = esa->offset;
5474 break;
5476 case 0x14: {
5477 /* Intel Processor Trace Enumeration */
5478 *eax = 0;
5479 *ebx = 0;
5480 *ecx = 0;
5481 *edx = 0;
5482 if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) ||
5483 !kvm_enabled()) {
5484 break;
5487 if (count == 0) {
5488 *eax = INTEL_PT_MAX_SUBLEAF;
5489 *ebx = INTEL_PT_MINIMAL_EBX;
5490 *ecx = INTEL_PT_MINIMAL_ECX;
5491 if (env->features[FEAT_14_0_ECX] & CPUID_14_0_ECX_LIP) {
5492 *ecx |= CPUID_14_0_ECX_LIP;
5494 } else if (count == 1) {
5495 *eax = INTEL_PT_MTC_BITMAP | INTEL_PT_ADDR_RANGES_NUM;
5496 *ebx = INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP;
5498 break;
5500 case 0x40000000:
5502 * CPUID code in kvm_arch_init_vcpu() ignores stuff
5503 * set here, but we restrict to TCG none the less.
5505 if (tcg_enabled() && cpu->expose_tcg) {
5506 memcpy(signature, "TCGTCGTCGTCG", 12);
5507 *eax = 0x40000001;
5508 *ebx = signature[0];
5509 *ecx = signature[1];
5510 *edx = signature[2];
5511 } else {
5512 *eax = 0;
5513 *ebx = 0;
5514 *ecx = 0;
5515 *edx = 0;
5517 break;
5518 case 0x40000001:
5519 *eax = 0;
5520 *ebx = 0;
5521 *ecx = 0;
5522 *edx = 0;
5523 break;
5524 case 0x80000000:
5525 *eax = env->cpuid_xlevel;
5526 *ebx = env->cpuid_vendor1;
5527 *edx = env->cpuid_vendor2;
5528 *ecx = env->cpuid_vendor3;
5529 break;
5530 case 0x80000001:
5531 *eax = env->cpuid_version;
5532 *ebx = 0;
5533 *ecx = env->features[FEAT_8000_0001_ECX];
5534 *edx = env->features[FEAT_8000_0001_EDX];
5536 /* The Linux kernel checks for the CMPLegacy bit and
5537 * discards multiple thread information if it is set.
5538 * So don't set it here for Intel to make Linux guests happy.
5540 if (cs->nr_cores * cs->nr_threads > 1) {
5541 if (env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1 ||
5542 env->cpuid_vendor2 != CPUID_VENDOR_INTEL_2 ||
5543 env->cpuid_vendor3 != CPUID_VENDOR_INTEL_3) {
5544 *ecx |= 1 << 1; /* CmpLegacy bit */
5547 break;
5548 case 0x80000002:
5549 case 0x80000003:
5550 case 0x80000004:
5551 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
5552 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
5553 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
5554 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
5555 break;
5556 case 0x80000005:
5557 /* cache info (L1 cache) */
5558 if (cpu->cache_info_passthrough) {
5559 host_cpuid(index, 0, eax, ebx, ecx, edx);
5560 break;
5562 *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) |
5563 (L1_ITLB_2M_ASSOC << 8) | (L1_ITLB_2M_ENTRIES);
5564 *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) |
5565 (L1_ITLB_4K_ASSOC << 8) | (L1_ITLB_4K_ENTRIES);
5566 *ecx = encode_cache_cpuid80000005(env->cache_info_amd.l1d_cache);
5567 *edx = encode_cache_cpuid80000005(env->cache_info_amd.l1i_cache);
5568 break;
5569 case 0x80000006:
5570 /* cache info (L2 cache) */
5571 if (cpu->cache_info_passthrough) {
5572 host_cpuid(index, 0, eax, ebx, ecx, edx);
5573 break;
5575 *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) |
5576 (L2_DTLB_2M_ENTRIES << 16) |
5577 (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) |
5578 (L2_ITLB_2M_ENTRIES);
5579 *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) |
5580 (L2_DTLB_4K_ENTRIES << 16) |
5581 (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) |
5582 (L2_ITLB_4K_ENTRIES);
5583 encode_cache_cpuid80000006(env->cache_info_amd.l2_cache,
5584 cpu->enable_l3_cache ?
5585 env->cache_info_amd.l3_cache : NULL,
5586 ecx, edx);
5587 break;
5588 case 0x80000007:
5589 *eax = 0;
5590 *ebx = 0;
5591 *ecx = 0;
5592 *edx = env->features[FEAT_8000_0007_EDX];
5593 break;
5594 case 0x80000008:
5595 /* virtual & phys address size in low 2 bytes. */
5596 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
5597 /* 64 bit processor */
5598 *eax = cpu->phys_bits; /* configurable physical bits */
5599 if (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_LA57) {
5600 *eax |= 0x00003900; /* 57 bits virtual */
5601 } else {
5602 *eax |= 0x00003000; /* 48 bits virtual */
5604 } else {
5605 *eax = cpu->phys_bits;
5607 *ebx = env->features[FEAT_8000_0008_EBX];
5608 if (cs->nr_cores * cs->nr_threads > 1) {
5610 * Bits 15:12 is "The number of bits in the initial
5611 * Core::X86::Apic::ApicId[ApicId] value that indicate
5612 * thread ID within a package".
5613 * Bits 7:0 is "The number of threads in the package is NC+1"
5615 *ecx = (apicid_pkg_offset(&topo_info) << 12) |
5616 ((cs->nr_cores * cs->nr_threads) - 1);
5617 } else {
5618 *ecx = 0;
5620 *edx = 0;
5621 break;
5622 case 0x8000000A:
5623 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
5624 *eax = 0x00000001; /* SVM Revision */
5625 *ebx = 0x00000010; /* nr of ASIDs */
5626 *ecx = 0;
5627 *edx = env->features[FEAT_SVM]; /* optional features */
5628 } else {
5629 *eax = 0;
5630 *ebx = 0;
5631 *ecx = 0;
5632 *edx = 0;
5634 break;
5635 case 0x8000001D:
5636 *eax = 0;
5637 if (cpu->cache_info_passthrough) {
5638 host_cpuid(index, count, eax, ebx, ecx, edx);
5639 break;
5641 switch (count) {
5642 case 0: /* L1 dcache info */
5643 encode_cache_cpuid8000001d(env->cache_info_amd.l1d_cache,
5644 &topo_info, eax, ebx, ecx, edx);
5645 break;
5646 case 1: /* L1 icache info */
5647 encode_cache_cpuid8000001d(env->cache_info_amd.l1i_cache,
5648 &topo_info, eax, ebx, ecx, edx);
5649 break;
5650 case 2: /* L2 cache info */
5651 encode_cache_cpuid8000001d(env->cache_info_amd.l2_cache,
5652 &topo_info, eax, ebx, ecx, edx);
5653 break;
5654 case 3: /* L3 cache info */
5655 encode_cache_cpuid8000001d(env->cache_info_amd.l3_cache,
5656 &topo_info, eax, ebx, ecx, edx);
5657 break;
5658 default: /* end of info */
5659 *eax = *ebx = *ecx = *edx = 0;
5660 break;
5662 break;
5663 case 0x8000001E:
5664 if (cpu->core_id <= 255) {
5665 encode_topo_cpuid8000001e(cpu, &topo_info, eax, ebx, ecx, edx);
5666 } else {
5667 *eax = 0;
5668 *ebx = 0;
5669 *ecx = 0;
5670 *edx = 0;
5672 break;
5673 case 0xC0000000:
5674 *eax = env->cpuid_xlevel2;
5675 *ebx = 0;
5676 *ecx = 0;
5677 *edx = 0;
5678 break;
5679 case 0xC0000001:
5680 /* Support for VIA CPU's CPUID instruction */
5681 *eax = env->cpuid_version;
5682 *ebx = 0;
5683 *ecx = 0;
5684 *edx = env->features[FEAT_C000_0001_EDX];
5685 break;
5686 case 0xC0000002:
5687 case 0xC0000003:
5688 case 0xC0000004:
5689 /* Reserved for the future, and now filled with zero */
5690 *eax = 0;
5691 *ebx = 0;
5692 *ecx = 0;
5693 *edx = 0;
5694 break;
5695 case 0x8000001F:
5696 *eax = sev_enabled() ? 0x2 : 0;
5697 *eax |= sev_es_enabled() ? 0x8 : 0;
5698 *ebx = sev_get_cbit_position();
5699 *ebx |= sev_get_reduced_phys_bits() << 6;
5700 *ecx = 0;
5701 *edx = 0;
5702 break;
5703 default:
5704 /* reserved values: zero */
5705 *eax = 0;
5706 *ebx = 0;
5707 *ecx = 0;
5708 *edx = 0;
5709 break;
5713 static void x86_cpu_reset(DeviceState *dev)
5715 CPUState *s = CPU(dev);
5716 X86CPU *cpu = X86_CPU(s);
5717 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
5718 CPUX86State *env = &cpu->env;
5719 target_ulong cr4;
5720 uint64_t xcr0;
5721 int i;
5723 xcc->parent_reset(dev);
5725 memset(env, 0, offsetof(CPUX86State, end_reset_fields));
5727 env->old_exception = -1;
5729 /* init to reset state */
5731 env->hflags2 |= HF2_GIF_MASK;
5732 env->hflags &= ~HF_GUEST_MASK;
5734 cpu_x86_update_cr0(env, 0x60000010);
5735 env->a20_mask = ~0x0;
5736 env->smbase = 0x30000;
5737 env->msr_smi_count = 0;
5739 env->idt.limit = 0xffff;
5740 env->gdt.limit = 0xffff;
5741 env->ldt.limit = 0xffff;
5742 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
5743 env->tr.limit = 0xffff;
5744 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
5746 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
5747 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
5748 DESC_R_MASK | DESC_A_MASK);
5749 cpu_x86_load_seg_cache(env, R_DS, 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_ES, 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_SS, 0, 0, 0xffff,
5756 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
5757 DESC_A_MASK);
5758 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
5759 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
5760 DESC_A_MASK);
5761 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
5762 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
5763 DESC_A_MASK);
5765 env->eip = 0xfff0;
5766 env->regs[R_EDX] = env->cpuid_version;
5768 env->eflags = 0x2;
5770 /* FPU init */
5771 for (i = 0; i < 8; i++) {
5772 env->fptags[i] = 1;
5774 cpu_set_fpuc(env, 0x37f);
5776 env->mxcsr = 0x1f80;
5777 /* All units are in INIT state. */
5778 env->xstate_bv = 0;
5780 env->pat = 0x0007040600070406ULL;
5781 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
5782 if (env->features[FEAT_1_ECX] & CPUID_EXT_MONITOR) {
5783 env->msr_ia32_misc_enable |= MSR_IA32_MISC_ENABLE_MWAIT;
5786 memset(env->dr, 0, sizeof(env->dr));
5787 env->dr[6] = DR6_FIXED_1;
5788 env->dr[7] = DR7_FIXED_1;
5789 cpu_breakpoint_remove_all(s, BP_CPU);
5790 cpu_watchpoint_remove_all(s, BP_CPU);
5792 cr4 = 0;
5793 xcr0 = XSTATE_FP_MASK;
5795 #ifdef CONFIG_USER_ONLY
5796 /* Enable all the features for user-mode. */
5797 if (env->features[FEAT_1_EDX] & CPUID_SSE) {
5798 xcr0 |= XSTATE_SSE_MASK;
5800 for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
5801 const ExtSaveArea *esa = &x86_ext_save_areas[i];
5802 if (env->features[esa->feature] & esa->bits) {
5803 xcr0 |= 1ull << i;
5807 if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) {
5808 cr4 |= CR4_OSFXSR_MASK | CR4_OSXSAVE_MASK;
5810 if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_FSGSBASE) {
5811 cr4 |= CR4_FSGSBASE_MASK;
5813 #endif
5815 env->xcr0 = xcr0;
5816 cpu_x86_update_cr4(env, cr4);
5819 * SDM 11.11.5 requires:
5820 * - IA32_MTRR_DEF_TYPE MSR.E = 0
5821 * - IA32_MTRR_PHYSMASKn.V = 0
5822 * All other bits are undefined. For simplification, zero it all.
5824 env->mtrr_deftype = 0;
5825 memset(env->mtrr_var, 0, sizeof(env->mtrr_var));
5826 memset(env->mtrr_fixed, 0, sizeof(env->mtrr_fixed));
5828 env->interrupt_injected = -1;
5829 env->exception_nr = -1;
5830 env->exception_pending = 0;
5831 env->exception_injected = 0;
5832 env->exception_has_payload = false;
5833 env->exception_payload = 0;
5834 env->nmi_injected = false;
5835 #if !defined(CONFIG_USER_ONLY)
5836 /* We hard-wire the BSP to the first CPU. */
5837 apic_designate_bsp(cpu->apic_state, s->cpu_index == 0);
5839 s->halted = !cpu_is_bsp(cpu);
5841 if (kvm_enabled()) {
5842 kvm_arch_reset_vcpu(cpu);
5844 #endif
5847 static void mce_init(X86CPU *cpu)
5849 CPUX86State *cenv = &cpu->env;
5850 unsigned int bank;
5852 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
5853 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
5854 (CPUID_MCE | CPUID_MCA)) {
5855 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF |
5856 (cpu->enable_lmce ? MCG_LMCE_P : 0);
5857 cenv->mcg_ctl = ~(uint64_t)0;
5858 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
5859 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
5864 static void x86_cpu_adjust_level(X86CPU *cpu, uint32_t *min, uint32_t value)
5866 if (*min < value) {
5867 *min = value;
5871 /* Increase cpuid_min_{level,xlevel,xlevel2} automatically, if appropriate */
5872 static void x86_cpu_adjust_feat_level(X86CPU *cpu, FeatureWord w)
5874 CPUX86State *env = &cpu->env;
5875 FeatureWordInfo *fi = &feature_word_info[w];
5876 uint32_t eax = fi->cpuid.eax;
5877 uint32_t region = eax & 0xF0000000;
5879 assert(feature_word_info[w].type == CPUID_FEATURE_WORD);
5880 if (!env->features[w]) {
5881 return;
5884 switch (region) {
5885 case 0x00000000:
5886 x86_cpu_adjust_level(cpu, &env->cpuid_min_level, eax);
5887 break;
5888 case 0x80000000:
5889 x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, eax);
5890 break;
5891 case 0xC0000000:
5892 x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel2, eax);
5893 break;
5896 if (eax == 7) {
5897 x86_cpu_adjust_level(cpu, &env->cpuid_min_level_func7,
5898 fi->cpuid.ecx);
5902 /* Calculate XSAVE components based on the configured CPU feature flags */
5903 static void x86_cpu_enable_xsave_components(X86CPU *cpu)
5905 CPUX86State *env = &cpu->env;
5906 int i;
5907 uint64_t mask;
5909 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
5910 env->features[FEAT_XSAVE_COMP_LO] = 0;
5911 env->features[FEAT_XSAVE_COMP_HI] = 0;
5912 return;
5915 mask = 0;
5916 for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
5917 const ExtSaveArea *esa = &x86_ext_save_areas[i];
5918 if (env->features[esa->feature] & esa->bits) {
5919 mask |= (1ULL << i);
5923 env->features[FEAT_XSAVE_COMP_LO] = mask;
5924 env->features[FEAT_XSAVE_COMP_HI] = mask >> 32;
5927 /***** Steps involved on loading and filtering CPUID data
5929 * When initializing and realizing a CPU object, the steps
5930 * involved in setting up CPUID data are:
5932 * 1) Loading CPU model definition (X86CPUDefinition). This is
5933 * implemented by x86_cpu_load_model() and should be completely
5934 * transparent, as it is done automatically by instance_init.
5935 * No code should need to look at X86CPUDefinition structs
5936 * outside instance_init.
5938 * 2) CPU expansion. This is done by realize before CPUID
5939 * filtering, and will make sure host/accelerator data is
5940 * loaded for CPU models that depend on host capabilities
5941 * (e.g. "host"). Done by x86_cpu_expand_features().
5943 * 3) CPUID filtering. This initializes extra data related to
5944 * CPUID, and checks if the host supports all capabilities
5945 * required by the CPU. Runnability of a CPU model is
5946 * determined at this step. Done by x86_cpu_filter_features().
5948 * Some operations don't require all steps to be performed.
5949 * More precisely:
5951 * - CPU instance creation (instance_init) will run only CPU
5952 * model loading. CPU expansion can't run at instance_init-time
5953 * because host/accelerator data may be not available yet.
5954 * - CPU realization will perform both CPU model expansion and CPUID
5955 * filtering, and return an error in case one of them fails.
5956 * - query-cpu-definitions needs to run all 3 steps. It needs
5957 * to run CPUID filtering, as the 'unavailable-features'
5958 * field is set based on the filtering results.
5959 * - The query-cpu-model-expansion QMP command only needs to run
5960 * CPU model loading and CPU expansion. It should not filter
5961 * any CPUID data based on host capabilities.
5964 /* Expand CPU configuration data, based on configured features
5965 * and host/accelerator capabilities when appropriate.
5967 void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
5969 CPUX86State *env = &cpu->env;
5970 FeatureWord w;
5971 int i;
5972 GList *l;
5974 for (l = plus_features; l; l = l->next) {
5975 const char *prop = l->data;
5976 if (!object_property_set_bool(OBJECT(cpu), prop, true, errp)) {
5977 return;
5981 for (l = minus_features; l; l = l->next) {
5982 const char *prop = l->data;
5983 if (!object_property_set_bool(OBJECT(cpu), prop, false, errp)) {
5984 return;
5988 /*TODO: Now cpu->max_features doesn't overwrite features
5989 * set using QOM properties, and we can convert
5990 * plus_features & minus_features to global properties
5991 * inside x86_cpu_parse_featurestr() too.
5993 if (cpu->max_features) {
5994 for (w = 0; w < FEATURE_WORDS; w++) {
5995 /* Override only features that weren't set explicitly
5996 * by the user.
5998 env->features[w] |=
5999 x86_cpu_get_supported_feature_word(w, cpu->migratable) &
6000 ~env->user_features[w] &
6001 ~feature_word_info[w].no_autoenable_flags;
6005 for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
6006 FeatureDep *d = &feature_dependencies[i];
6007 if (!(env->features[d->from.index] & d->from.mask)) {
6008 uint64_t unavailable_features = env->features[d->to.index] & d->to.mask;
6010 /* Not an error unless the dependent feature was added explicitly. */
6011 mark_unavailable_features(cpu, d->to.index,
6012 unavailable_features & env->user_features[d->to.index],
6013 "This feature depends on other features that were not requested");
6015 env->features[d->to.index] &= ~unavailable_features;
6019 if (!kvm_enabled() || !cpu->expose_kvm) {
6020 env->features[FEAT_KVM] = 0;
6023 x86_cpu_enable_xsave_components(cpu);
6025 /* CPUID[EAX=7,ECX=0].EBX always increased level automatically: */
6026 x86_cpu_adjust_feat_level(cpu, FEAT_7_0_EBX);
6027 if (cpu->full_cpuid_auto_level) {
6028 x86_cpu_adjust_feat_level(cpu, FEAT_1_EDX);
6029 x86_cpu_adjust_feat_level(cpu, FEAT_1_ECX);
6030 x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX);
6031 x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX);
6032 x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EAX);
6033 x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX);
6034 x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX);
6035 x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX);
6036 x86_cpu_adjust_feat_level(cpu, FEAT_8000_0008_EBX);
6037 x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX);
6038 x86_cpu_adjust_feat_level(cpu, FEAT_SVM);
6039 x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);
6041 /* Intel Processor Trace requires CPUID[0x14] */
6042 if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT)) {
6043 if (cpu->intel_pt_auto_level) {
6044 x86_cpu_adjust_level(cpu, &cpu->env.cpuid_min_level, 0x14);
6045 } else if (cpu->env.cpuid_min_level < 0x14) {
6046 mark_unavailable_features(cpu, FEAT_7_0_EBX,
6047 CPUID_7_0_EBX_INTEL_PT,
6048 "Intel PT need CPUID leaf 0x14, please set by \"-cpu ...,intel-pt=on,min-level=0x14\"");
6052 /* CPU topology with multi-dies support requires CPUID[0x1F] */
6053 if (env->nr_dies > 1) {
6054 x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x1F);
6057 /* SVM requires CPUID[0x8000000A] */
6058 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
6059 x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);
6062 /* SEV requires CPUID[0x8000001F] */
6063 if (sev_enabled()) {
6064 x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000001F);
6068 /* Set cpuid_*level* based on cpuid_min_*level, if not explicitly set */
6069 if (env->cpuid_level_func7 == UINT32_MAX) {
6070 env->cpuid_level_func7 = env->cpuid_min_level_func7;
6072 if (env->cpuid_level == UINT32_MAX) {
6073 env->cpuid_level = env->cpuid_min_level;
6075 if (env->cpuid_xlevel == UINT32_MAX) {
6076 env->cpuid_xlevel = env->cpuid_min_xlevel;
6078 if (env->cpuid_xlevel2 == UINT32_MAX) {
6079 env->cpuid_xlevel2 = env->cpuid_min_xlevel2;
6084 * Finishes initialization of CPUID data, filters CPU feature
6085 * words based on host availability of each feature.
6087 * Returns: 0 if all flags are supported by the host, non-zero otherwise.
6089 static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
6091 CPUX86State *env = &cpu->env;
6092 FeatureWord w;
6093 const char *prefix = NULL;
6095 if (verbose) {
6096 prefix = accel_uses_host_cpuid()
6097 ? "host doesn't support requested feature"
6098 : "TCG doesn't support requested feature";
6101 for (w = 0; w < FEATURE_WORDS; w++) {
6102 uint64_t host_feat =
6103 x86_cpu_get_supported_feature_word(w, false);
6104 uint64_t requested_features = env->features[w];
6105 uint64_t unavailable_features = requested_features & ~host_feat;
6106 mark_unavailable_features(cpu, w, unavailable_features, prefix);
6109 if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) &&
6110 kvm_enabled()) {
6111 KVMState *s = CPU(cpu)->kvm_state;
6112 uint32_t eax_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_EAX);
6113 uint32_t ebx_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_EBX);
6114 uint32_t ecx_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_ECX);
6115 uint32_t eax_1 = kvm_arch_get_supported_cpuid(s, 0x14, 1, R_EAX);
6116 uint32_t ebx_1 = kvm_arch_get_supported_cpuid(s, 0x14, 1, R_EBX);
6118 if (!eax_0 ||
6119 ((ebx_0 & INTEL_PT_MINIMAL_EBX) != INTEL_PT_MINIMAL_EBX) ||
6120 ((ecx_0 & INTEL_PT_MINIMAL_ECX) != INTEL_PT_MINIMAL_ECX) ||
6121 ((eax_1 & INTEL_PT_MTC_BITMAP) != INTEL_PT_MTC_BITMAP) ||
6122 ((eax_1 & INTEL_PT_ADDR_RANGES_NUM_MASK) <
6123 INTEL_PT_ADDR_RANGES_NUM) ||
6124 ((ebx_1 & (INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP)) !=
6125 (INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP)) ||
6126 ((ecx_0 & CPUID_14_0_ECX_LIP) !=
6127 (env->features[FEAT_14_0_ECX] & CPUID_14_0_ECX_LIP))) {
6129 * Processor Trace capabilities aren't configurable, so if the
6130 * host can't emulate the capabilities we report on
6131 * cpu_x86_cpuid(), intel-pt can't be enabled on the current host.
6133 mark_unavailable_features(cpu, FEAT_7_0_EBX, CPUID_7_0_EBX_INTEL_PT, prefix);
6138 static void x86_cpu_hyperv_realize(X86CPU *cpu)
6140 size_t len;
6142 /* Hyper-V vendor id */
6143 if (!cpu->hyperv_vendor) {
6144 memcpy(cpu->hyperv_vendor_id, "Microsoft Hv", 12);
6145 } else {
6146 len = strlen(cpu->hyperv_vendor);
6148 if (len > 12) {
6149 warn_report("hv-vendor-id truncated to 12 characters");
6150 len = 12;
6152 memset(cpu->hyperv_vendor_id, 0, 12);
6153 memcpy(cpu->hyperv_vendor_id, cpu->hyperv_vendor, len);
6156 /* 'Hv#1' interface identification*/
6157 cpu->hyperv_interface_id[0] = 0x31237648;
6158 cpu->hyperv_interface_id[1] = 0;
6159 cpu->hyperv_interface_id[2] = 0;
6160 cpu->hyperv_interface_id[3] = 0;
6162 /* Hypervisor system identity */
6163 cpu->hyperv_version_id[0] = 0x00001bbc;
6164 cpu->hyperv_version_id[1] = 0x00060001;
6166 /* Hypervisor implementation limits */
6167 cpu->hyperv_limits[0] = 64;
6168 cpu->hyperv_limits[1] = 0;
6169 cpu->hyperv_limits[2] = 0;
6172 static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
6174 CPUState *cs = CPU(dev);
6175 X86CPU *cpu = X86_CPU(dev);
6176 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
6177 CPUX86State *env = &cpu->env;
6178 Error *local_err = NULL;
6179 static bool ht_warned;
6181 /* Process Hyper-V enlightenments */
6182 x86_cpu_hyperv_realize(cpu);
6184 cpu_exec_realizefn(cs, &local_err);
6185 if (local_err != NULL) {
6186 error_propagate(errp, local_err);
6187 return;
6190 if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
6191 g_autofree char *name = x86_cpu_class_get_model_name(xcc);
6192 error_setg(&local_err, "CPU model '%s' requires KVM or HVF", name);
6193 goto out;
6196 if (cpu->ucode_rev == 0) {
6197 /* The default is the same as KVM's. */
6198 if (IS_AMD_CPU(env)) {
6199 cpu->ucode_rev = 0x01000065;
6200 } else {
6201 cpu->ucode_rev = 0x100000000ULL;
6205 /* mwait extended info: needed for Core compatibility */
6206 /* We always wake on interrupt even if host does not have the capability */
6207 cpu->mwait.ecx |= CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
6209 if (cpu->apic_id == UNASSIGNED_APIC_ID) {
6210 error_setg(errp, "apic-id property was not initialized properly");
6211 return;
6214 x86_cpu_expand_features(cpu, &local_err);
6215 if (local_err) {
6216 goto out;
6219 x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid);
6221 if (cpu->enforce_cpuid && x86_cpu_have_filtered_features(cpu)) {
6222 error_setg(&local_err,
6223 accel_uses_host_cpuid() ?
6224 "Host doesn't support requested features" :
6225 "TCG doesn't support requested features");
6226 goto out;
6229 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
6230 * CPUID[1].EDX.
6232 if (IS_AMD_CPU(env)) {
6233 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
6234 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
6235 & CPUID_EXT2_AMD_ALIASES);
6238 /* For 64bit systems think about the number of physical bits to present.
6239 * ideally this should be the same as the host; anything other than matching
6240 * the host can cause incorrect guest behaviour.
6241 * QEMU used to pick the magic value of 40 bits that corresponds to
6242 * consumer AMD devices but nothing else.
6244 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
6245 if (cpu->phys_bits &&
6246 (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
6247 cpu->phys_bits < 32)) {
6248 error_setg(errp, "phys-bits should be between 32 and %u "
6249 " (but is %u)",
6250 TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bits);
6251 return;
6254 * 0 means it was not explicitly set by the user (or by machine
6255 * compat_props or by the host code in host-cpu.c).
6256 * In this case, the default is the value used by TCG (40).
6258 if (cpu->phys_bits == 0) {
6259 cpu->phys_bits = TCG_PHYS_ADDR_BITS;
6261 } else {
6262 /* For 32 bit systems don't use the user set value, but keep
6263 * phys_bits consistent with what we tell the guest.
6265 if (cpu->phys_bits != 0) {
6266 error_setg(errp, "phys-bits is not user-configurable in 32 bit");
6267 return;
6270 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
6271 cpu->phys_bits = 36;
6272 } else {
6273 cpu->phys_bits = 32;
6277 /* Cache information initialization */
6278 if (!cpu->legacy_cache) {
6279 if (!xcc->model || !xcc->model->cpudef->cache_info) {
6280 g_autofree char *name = x86_cpu_class_get_model_name(xcc);
6281 error_setg(errp,
6282 "CPU model '%s' doesn't support legacy-cache=off", name);
6283 return;
6285 env->cache_info_cpuid2 = env->cache_info_cpuid4 = env->cache_info_amd =
6286 *xcc->model->cpudef->cache_info;
6287 } else {
6288 /* Build legacy cache information */
6289 env->cache_info_cpuid2.l1d_cache = &legacy_l1d_cache;
6290 env->cache_info_cpuid2.l1i_cache = &legacy_l1i_cache;
6291 env->cache_info_cpuid2.l2_cache = &legacy_l2_cache_cpuid2;
6292 env->cache_info_cpuid2.l3_cache = &legacy_l3_cache;
6294 env->cache_info_cpuid4.l1d_cache = &legacy_l1d_cache;
6295 env->cache_info_cpuid4.l1i_cache = &legacy_l1i_cache;
6296 env->cache_info_cpuid4.l2_cache = &legacy_l2_cache;
6297 env->cache_info_cpuid4.l3_cache = &legacy_l3_cache;
6299 env->cache_info_amd.l1d_cache = &legacy_l1d_cache_amd;
6300 env->cache_info_amd.l1i_cache = &legacy_l1i_cache_amd;
6301 env->cache_info_amd.l2_cache = &legacy_l2_cache_amd;
6302 env->cache_info_amd.l3_cache = &legacy_l3_cache;
6305 #ifndef CONFIG_USER_ONLY
6306 MachineState *ms = MACHINE(qdev_get_machine());
6307 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
6309 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || ms->smp.cpus > 1) {
6310 x86_cpu_apic_create(cpu, &local_err);
6311 if (local_err != NULL) {
6312 goto out;
6315 #endif
6317 mce_init(cpu);
6319 qemu_init_vcpu(cs);
6322 * Most Intel and certain AMD CPUs support hyperthreading. Even though QEMU
6323 * fixes this issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX
6324 * based on inputs (sockets,cores,threads), it is still better to give
6325 * users a warning.
6327 * NOTE: the following code has to follow qemu_init_vcpu(). Otherwise
6328 * cs->nr_threads hasn't be populated yet and the checking is incorrect.
6330 if (IS_AMD_CPU(env) &&
6331 !(env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT) &&
6332 cs->nr_threads > 1 && !ht_warned) {
6333 warn_report("This family of AMD CPU doesn't support "
6334 "hyperthreading(%d)",
6335 cs->nr_threads);
6336 error_printf("Please configure -smp options properly"
6337 " or try enabling topoext feature.\n");
6338 ht_warned = true;
6341 #ifndef CONFIG_USER_ONLY
6342 x86_cpu_apic_realize(cpu, &local_err);
6343 if (local_err != NULL) {
6344 goto out;
6346 #endif /* !CONFIG_USER_ONLY */
6347 cpu_reset(cs);
6349 xcc->parent_realize(dev, &local_err);
6351 out:
6352 if (local_err != NULL) {
6353 error_propagate(errp, local_err);
6354 return;
6358 static void x86_cpu_unrealizefn(DeviceState *dev)
6360 X86CPU *cpu = X86_CPU(dev);
6361 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
6363 #ifndef CONFIG_USER_ONLY
6364 cpu_remove_sync(CPU(dev));
6365 qemu_unregister_reset(x86_cpu_machine_reset_cb, dev);
6366 #endif
6368 if (cpu->apic_state) {
6369 object_unparent(OBJECT(cpu->apic_state));
6370 cpu->apic_state = NULL;
6373 xcc->parent_unrealize(dev);
6376 typedef struct BitProperty {
6377 FeatureWord w;
6378 uint64_t mask;
6379 } BitProperty;
6381 static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
6382 void *opaque, Error **errp)
6384 X86CPU *cpu = X86_CPU(obj);
6385 BitProperty *fp = opaque;
6386 uint64_t f = cpu->env.features[fp->w];
6387 bool value = (f & fp->mask) == fp->mask;
6388 visit_type_bool(v, name, &value, errp);
6391 static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
6392 void *opaque, Error **errp)
6394 DeviceState *dev = DEVICE(obj);
6395 X86CPU *cpu = X86_CPU(obj);
6396 BitProperty *fp = opaque;
6397 bool value;
6399 if (dev->realized) {
6400 qdev_prop_set_after_realize(dev, name, errp);
6401 return;
6404 if (!visit_type_bool(v, name, &value, errp)) {
6405 return;
6408 if (value) {
6409 cpu->env.features[fp->w] |= fp->mask;
6410 } else {
6411 cpu->env.features[fp->w] &= ~fp->mask;
6413 cpu->env.user_features[fp->w] |= fp->mask;
6416 /* Register a boolean property to get/set a single bit in a uint32_t field.
6418 * The same property name can be registered multiple times to make it affect
6419 * multiple bits in the same FeatureWord. In that case, the getter will return
6420 * true only if all bits are set.
6422 static void x86_cpu_register_bit_prop(X86CPUClass *xcc,
6423 const char *prop_name,
6424 FeatureWord w,
6425 int bitnr)
6427 ObjectClass *oc = OBJECT_CLASS(xcc);
6428 BitProperty *fp;
6429 ObjectProperty *op;
6430 uint64_t mask = (1ULL << bitnr);
6432 op = object_class_property_find(oc, prop_name);
6433 if (op) {
6434 fp = op->opaque;
6435 assert(fp->w == w);
6436 fp->mask |= mask;
6437 } else {
6438 fp = g_new0(BitProperty, 1);
6439 fp->w = w;
6440 fp->mask = mask;
6441 object_class_property_add(oc, prop_name, "bool",
6442 x86_cpu_get_bit_prop,
6443 x86_cpu_set_bit_prop,
6444 NULL, fp);
6448 static void x86_cpu_register_feature_bit_props(X86CPUClass *xcc,
6449 FeatureWord w,
6450 int bitnr)
6452 FeatureWordInfo *fi = &feature_word_info[w];
6453 const char *name = fi->feat_names[bitnr];
6455 if (!name) {
6456 return;
6459 /* Property names should use "-" instead of "_".
6460 * Old names containing underscores are registered as aliases
6461 * using object_property_add_alias()
6463 assert(!strchr(name, '_'));
6464 /* aliases don't use "|" delimiters anymore, they are registered
6465 * manually using object_property_add_alias() */
6466 assert(!strchr(name, '|'));
6467 x86_cpu_register_bit_prop(xcc, name, w, bitnr);
6470 static void x86_cpu_initfn(Object *obj)
6472 X86CPU *cpu = X86_CPU(obj);
6473 X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
6474 CPUX86State *env = &cpu->env;
6476 env->nr_dies = 1;
6477 cpu_set_cpustate_pointers(cpu);
6479 object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
6480 x86_cpu_get_feature_words,
6481 NULL, NULL, (void *)env->features);
6482 object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
6483 x86_cpu_get_feature_words,
6484 NULL, NULL, (void *)cpu->filtered_features);
6486 object_property_add_alias(obj, "sse3", obj, "pni");
6487 object_property_add_alias(obj, "pclmuldq", obj, "pclmulqdq");
6488 object_property_add_alias(obj, "sse4-1", obj, "sse4.1");
6489 object_property_add_alias(obj, "sse4-2", obj, "sse4.2");
6490 object_property_add_alias(obj, "xd", obj, "nx");
6491 object_property_add_alias(obj, "ffxsr", obj, "fxsr-opt");
6492 object_property_add_alias(obj, "i64", obj, "lm");
6494 object_property_add_alias(obj, "ds_cpl", obj, "ds-cpl");
6495 object_property_add_alias(obj, "tsc_adjust", obj, "tsc-adjust");
6496 object_property_add_alias(obj, "fxsr_opt", obj, "fxsr-opt");
6497 object_property_add_alias(obj, "lahf_lm", obj, "lahf-lm");
6498 object_property_add_alias(obj, "cmp_legacy", obj, "cmp-legacy");
6499 object_property_add_alias(obj, "nodeid_msr", obj, "nodeid-msr");
6500 object_property_add_alias(obj, "perfctr_core", obj, "perfctr-core");
6501 object_property_add_alias(obj, "perfctr_nb", obj, "perfctr-nb");
6502 object_property_add_alias(obj, "kvm_nopiodelay", obj, "kvm-nopiodelay");
6503 object_property_add_alias(obj, "kvm_mmu", obj, "kvm-mmu");
6504 object_property_add_alias(obj, "kvm_asyncpf", obj, "kvm-asyncpf");
6505 object_property_add_alias(obj, "kvm_asyncpf_int", obj, "kvm-asyncpf-int");
6506 object_property_add_alias(obj, "kvm_steal_time", obj, "kvm-steal-time");
6507 object_property_add_alias(obj, "kvm_pv_eoi", obj, "kvm-pv-eoi");
6508 object_property_add_alias(obj, "kvm_pv_unhalt", obj, "kvm-pv-unhalt");
6509 object_property_add_alias(obj, "kvm_poll_control", obj, "kvm-poll-control");
6510 object_property_add_alias(obj, "svm_lock", obj, "svm-lock");
6511 object_property_add_alias(obj, "nrip_save", obj, "nrip-save");
6512 object_property_add_alias(obj, "tsc_scale", obj, "tsc-scale");
6513 object_property_add_alias(obj, "vmcb_clean", obj, "vmcb-clean");
6514 object_property_add_alias(obj, "pause_filter", obj, "pause-filter");
6515 object_property_add_alias(obj, "sse4_1", obj, "sse4.1");
6516 object_property_add_alias(obj, "sse4_2", obj, "sse4.2");
6518 if (xcc->model) {
6519 x86_cpu_load_model(cpu, xcc->model);
6522 /* if required, do accelerator-specific cpu initializations */
6523 accel_cpu_instance_init(CPU(obj));
6526 static int64_t x86_cpu_get_arch_id(CPUState *cs)
6528 X86CPU *cpu = X86_CPU(cs);
6530 return cpu->apic_id;
6533 #if !defined(CONFIG_USER_ONLY)
6534 static bool x86_cpu_get_paging_enabled(const CPUState *cs)
6536 X86CPU *cpu = X86_CPU(cs);
6538 return cpu->env.cr[0] & CR0_PG_MASK;
6540 #endif /* !CONFIG_USER_ONLY */
6542 static void x86_cpu_set_pc(CPUState *cs, vaddr value)
6544 X86CPU *cpu = X86_CPU(cs);
6546 cpu->env.eip = value;
6549 int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request)
6551 X86CPU *cpu = X86_CPU(cs);
6552 CPUX86State *env = &cpu->env;
6554 #if !defined(CONFIG_USER_ONLY)
6555 if (interrupt_request & CPU_INTERRUPT_POLL) {
6556 return CPU_INTERRUPT_POLL;
6558 #endif
6559 if (interrupt_request & CPU_INTERRUPT_SIPI) {
6560 return CPU_INTERRUPT_SIPI;
6563 if (env->hflags2 & HF2_GIF_MASK) {
6564 if ((interrupt_request & CPU_INTERRUPT_SMI) &&
6565 !(env->hflags & HF_SMM_MASK)) {
6566 return CPU_INTERRUPT_SMI;
6567 } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
6568 !(env->hflags2 & HF2_NMI_MASK)) {
6569 return CPU_INTERRUPT_NMI;
6570 } else if (interrupt_request & CPU_INTERRUPT_MCE) {
6571 return CPU_INTERRUPT_MCE;
6572 } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
6573 (((env->hflags2 & HF2_VINTR_MASK) &&
6574 (env->hflags2 & HF2_HIF_MASK)) ||
6575 (!(env->hflags2 & HF2_VINTR_MASK) &&
6576 (env->eflags & IF_MASK &&
6577 !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
6578 return CPU_INTERRUPT_HARD;
6579 #if !defined(CONFIG_USER_ONLY)
6580 } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
6581 (env->eflags & IF_MASK) &&
6582 !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
6583 return CPU_INTERRUPT_VIRQ;
6584 #endif
6588 return 0;
6591 static bool x86_cpu_has_work(CPUState *cs)
6593 return x86_cpu_pending_interrupt(cs, cs->interrupt_request) != 0;
6596 static void x86_disas_set_info(CPUState *cs, disassemble_info *info)
6598 X86CPU *cpu = X86_CPU(cs);
6599 CPUX86State *env = &cpu->env;
6601 info->mach = (env->hflags & HF_CS64_MASK ? bfd_mach_x86_64
6602 : env->hflags & HF_CS32_MASK ? bfd_mach_i386_i386
6603 : bfd_mach_i386_i8086);
6604 info->print_insn = print_insn_i386;
6606 info->cap_arch = CS_ARCH_X86;
6607 info->cap_mode = (env->hflags & HF_CS64_MASK ? CS_MODE_64
6608 : env->hflags & HF_CS32_MASK ? CS_MODE_32
6609 : CS_MODE_16);
6610 info->cap_insn_unit = 1;
6611 info->cap_insn_split = 8;
6614 void x86_update_hflags(CPUX86State *env)
6616 uint32_t hflags;
6617 #define HFLAG_COPY_MASK \
6618 ~( HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
6619 HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
6620 HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
6621 HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)
6623 hflags = env->hflags & HFLAG_COPY_MASK;
6624 hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
6625 hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
6626 hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
6627 (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
6628 hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
6630 if (env->cr[4] & CR4_OSFXSR_MASK) {
6631 hflags |= HF_OSFXSR_MASK;
6634 if (env->efer & MSR_EFER_LMA) {
6635 hflags |= HF_LMA_MASK;
6638 if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
6639 hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
6640 } else {
6641 hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
6642 (DESC_B_SHIFT - HF_CS32_SHIFT);
6643 hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
6644 (DESC_B_SHIFT - HF_SS32_SHIFT);
6645 if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK) ||
6646 !(hflags & HF_CS32_MASK)) {
6647 hflags |= HF_ADDSEG_MASK;
6648 } else {
6649 hflags |= ((env->segs[R_DS].base | env->segs[R_ES].base |
6650 env->segs[R_SS].base) != 0) << HF_ADDSEG_SHIFT;
6653 env->hflags = hflags;
6656 static Property x86_cpu_properties[] = {
6657 #ifdef CONFIG_USER_ONLY
6658 /* apic_id = 0 by default for *-user, see commit 9886e834 */
6659 DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, 0),
6660 DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, 0),
6661 DEFINE_PROP_INT32("core-id", X86CPU, core_id, 0),
6662 DEFINE_PROP_INT32("die-id", X86CPU, die_id, 0),
6663 DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, 0),
6664 #else
6665 DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, UNASSIGNED_APIC_ID),
6666 DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, -1),
6667 DEFINE_PROP_INT32("core-id", X86CPU, core_id, -1),
6668 DEFINE_PROP_INT32("die-id", X86CPU, die_id, -1),
6669 DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, -1),
6670 #endif
6671 DEFINE_PROP_INT32("node-id", X86CPU, node_id, CPU_UNSET_NUMA_NODE_ID),
6672 DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
6674 DEFINE_PROP_UINT32("hv-spinlocks", X86CPU, hyperv_spinlock_attempts,
6675 HYPERV_SPINLOCK_NEVER_NOTIFY),
6676 DEFINE_PROP_BIT64("hv-relaxed", X86CPU, hyperv_features,
6677 HYPERV_FEAT_RELAXED, 0),
6678 DEFINE_PROP_BIT64("hv-vapic", X86CPU, hyperv_features,
6679 HYPERV_FEAT_VAPIC, 0),
6680 DEFINE_PROP_BIT64("hv-time", X86CPU, hyperv_features,
6681 HYPERV_FEAT_TIME, 0),
6682 DEFINE_PROP_BIT64("hv-crash", X86CPU, hyperv_features,
6683 HYPERV_FEAT_CRASH, 0),
6684 DEFINE_PROP_BIT64("hv-reset", X86CPU, hyperv_features,
6685 HYPERV_FEAT_RESET, 0),
6686 DEFINE_PROP_BIT64("hv-vpindex", X86CPU, hyperv_features,
6687 HYPERV_FEAT_VPINDEX, 0),
6688 DEFINE_PROP_BIT64("hv-runtime", X86CPU, hyperv_features,
6689 HYPERV_FEAT_RUNTIME, 0),
6690 DEFINE_PROP_BIT64("hv-synic", X86CPU, hyperv_features,
6691 HYPERV_FEAT_SYNIC, 0),
6692 DEFINE_PROP_BIT64("hv-stimer", X86CPU, hyperv_features,
6693 HYPERV_FEAT_STIMER, 0),
6694 DEFINE_PROP_BIT64("hv-frequencies", X86CPU, hyperv_features,
6695 HYPERV_FEAT_FREQUENCIES, 0),
6696 DEFINE_PROP_BIT64("hv-reenlightenment", X86CPU, hyperv_features,
6697 HYPERV_FEAT_REENLIGHTENMENT, 0),
6698 DEFINE_PROP_BIT64("hv-tlbflush", X86CPU, hyperv_features,
6699 HYPERV_FEAT_TLBFLUSH, 0),
6700 DEFINE_PROP_BIT64("hv-evmcs", X86CPU, hyperv_features,
6701 HYPERV_FEAT_EVMCS, 0),
6702 DEFINE_PROP_BIT64("hv-ipi", X86CPU, hyperv_features,
6703 HYPERV_FEAT_IPI, 0),
6704 DEFINE_PROP_BIT64("hv-stimer-direct", X86CPU, hyperv_features,
6705 HYPERV_FEAT_STIMER_DIRECT, 0),
6706 DEFINE_PROP_ON_OFF_AUTO("hv-no-nonarch-coresharing", X86CPU,
6707 hyperv_no_nonarch_cs, ON_OFF_AUTO_OFF),
6708 DEFINE_PROP_BOOL("hv-passthrough", X86CPU, hyperv_passthrough, false),
6710 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
6711 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
6712 DEFINE_PROP_BOOL("x-force-features", X86CPU, force_features, false),
6713 DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
6714 DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0),
6715 DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false),
6716 DEFINE_PROP_UINT8("host-phys-bits-limit", X86CPU, host_phys_bits_limit, 0),
6717 DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true),
6718 DEFINE_PROP_UINT32("level-func7", X86CPU, env.cpuid_level_func7,
6719 UINT32_MAX),
6720 DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, UINT32_MAX),
6721 DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, UINT32_MAX),
6722 DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, UINT32_MAX),
6723 DEFINE_PROP_UINT32("min-level", X86CPU, env.cpuid_min_level, 0),
6724 DEFINE_PROP_UINT32("min-xlevel", X86CPU, env.cpuid_min_xlevel, 0),
6725 DEFINE_PROP_UINT32("min-xlevel2", X86CPU, env.cpuid_min_xlevel2, 0),
6726 DEFINE_PROP_UINT64("ucode-rev", X86CPU, ucode_rev, 0),
6727 DEFINE_PROP_BOOL("full-cpuid-auto-level", X86CPU, full_cpuid_auto_level, true),
6728 DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor),
6729 DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
6730 DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false),
6731 DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true),
6732 DEFINE_PROP_BOOL("kvm-no-smi-migration", X86CPU, kvm_no_smi_migration,
6733 false),
6734 DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
6735 DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
6736 DEFINE_PROP_BOOL("x-migrate-smi-count", X86CPU, migrate_smi_count,
6737 true),
6739 * lecacy_cache defaults to true unless the CPU model provides its
6740 * own cache information (see x86_cpu_load_def()).
6742 DEFINE_PROP_BOOL("legacy-cache", X86CPU, legacy_cache, true),
6745 * From "Requirements for Implementing the Microsoft
6746 * Hypervisor Interface":
6747 * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs
6749 * "Starting with Windows Server 2012 and Windows 8, if
6750 * CPUID.40000005.EAX contains a value of -1, Windows assumes that
6751 * the hypervisor imposes no specific limit to the number of VPs.
6752 * In this case, Windows Server 2012 guest VMs may use more than
6753 * 64 VPs, up to the maximum supported number of processors applicable
6754 * to the specific Windows version being used."
6756 DEFINE_PROP_INT32("x-hv-max-vps", X86CPU, hv_max_vps, -1),
6757 DEFINE_PROP_BOOL("x-hv-synic-kvm-only", X86CPU, hyperv_synic_kvm_only,
6758 false),
6759 DEFINE_PROP_BOOL("x-intel-pt-auto-level", X86CPU, intel_pt_auto_level,
6760 true),
6761 DEFINE_PROP_END_OF_LIST()
6764 #ifndef CONFIG_USER_ONLY
6765 #include "hw/core/sysemu-cpu-ops.h"
6767 static const struct SysemuCPUOps i386_sysemu_ops = {
6768 .get_memory_mapping = x86_cpu_get_memory_mapping,
6769 .get_paging_enabled = x86_cpu_get_paging_enabled,
6770 .get_phys_page_attrs_debug = x86_cpu_get_phys_page_attrs_debug,
6771 .asidx_from_attrs = x86_asidx_from_attrs,
6772 .get_crash_info = x86_cpu_get_crash_info,
6773 .write_elf32_note = x86_cpu_write_elf32_note,
6774 .write_elf64_note = x86_cpu_write_elf64_note,
6775 .write_elf32_qemunote = x86_cpu_write_elf32_qemunote,
6776 .write_elf64_qemunote = x86_cpu_write_elf64_qemunote,
6777 .legacy_vmsd = &vmstate_x86_cpu,
6779 #endif
6781 static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
6783 X86CPUClass *xcc = X86_CPU_CLASS(oc);
6784 CPUClass *cc = CPU_CLASS(oc);
6785 DeviceClass *dc = DEVICE_CLASS(oc);
6786 FeatureWord w;
6788 device_class_set_parent_realize(dc, x86_cpu_realizefn,
6789 &xcc->parent_realize);
6790 device_class_set_parent_unrealize(dc, x86_cpu_unrealizefn,
6791 &xcc->parent_unrealize);
6792 device_class_set_props(dc, x86_cpu_properties);
6794 device_class_set_parent_reset(dc, x86_cpu_reset, &xcc->parent_reset);
6795 cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
6797 cc->class_by_name = x86_cpu_class_by_name;
6798 cc->parse_features = x86_cpu_parse_featurestr;
6799 cc->has_work = x86_cpu_has_work;
6800 cc->dump_state = x86_cpu_dump_state;
6801 cc->set_pc = x86_cpu_set_pc;
6802 cc->gdb_read_register = x86_cpu_gdb_read_register;
6803 cc->gdb_write_register = x86_cpu_gdb_write_register;
6804 cc->get_arch_id = x86_cpu_get_arch_id;
6806 #ifndef CONFIG_USER_ONLY
6807 cc->sysemu_ops = &i386_sysemu_ops;
6808 #endif /* !CONFIG_USER_ONLY */
6810 cc->gdb_arch_name = x86_gdb_arch_name;
6811 #ifdef TARGET_X86_64
6812 cc->gdb_core_xml_file = "i386-64bit.xml";
6813 cc->gdb_num_core_regs = 66;
6814 #else
6815 cc->gdb_core_xml_file = "i386-32bit.xml";
6816 cc->gdb_num_core_regs = 50;
6817 #endif
6818 cc->disas_set_info = x86_disas_set_info;
6820 dc->user_creatable = true;
6822 object_class_property_add(oc, "family", "int",
6823 x86_cpuid_version_get_family,
6824 x86_cpuid_version_set_family, NULL, NULL);
6825 object_class_property_add(oc, "model", "int",
6826 x86_cpuid_version_get_model,
6827 x86_cpuid_version_set_model, NULL, NULL);
6828 object_class_property_add(oc, "stepping", "int",
6829 x86_cpuid_version_get_stepping,
6830 x86_cpuid_version_set_stepping, NULL, NULL);
6831 object_class_property_add_str(oc, "vendor",
6832 x86_cpuid_get_vendor,
6833 x86_cpuid_set_vendor);
6834 object_class_property_add_str(oc, "model-id",
6835 x86_cpuid_get_model_id,
6836 x86_cpuid_set_model_id);
6837 object_class_property_add(oc, "tsc-frequency", "int",
6838 x86_cpuid_get_tsc_freq,
6839 x86_cpuid_set_tsc_freq, NULL, NULL);
6841 * The "unavailable-features" property has the same semantics as
6842 * CpuDefinitionInfo.unavailable-features on the "query-cpu-definitions"
6843 * QMP command: they list the features that would have prevented the
6844 * CPU from running if the "enforce" flag was set.
6846 object_class_property_add(oc, "unavailable-features", "strList",
6847 x86_cpu_get_unavailable_features,
6848 NULL, NULL, NULL);
6850 #if !defined(CONFIG_USER_ONLY)
6851 object_class_property_add(oc, "crash-information", "GuestPanicInformation",
6852 x86_cpu_get_crash_info_qom, NULL, NULL, NULL);
6853 #endif
6855 for (w = 0; w < FEATURE_WORDS; w++) {
6856 int bitnr;
6857 for (bitnr = 0; bitnr < 64; bitnr++) {
6858 x86_cpu_register_feature_bit_props(xcc, w, bitnr);
6863 static const TypeInfo x86_cpu_type_info = {
6864 .name = TYPE_X86_CPU,
6865 .parent = TYPE_CPU,
6866 .instance_size = sizeof(X86CPU),
6867 .instance_init = x86_cpu_initfn,
6868 .abstract = true,
6869 .class_size = sizeof(X86CPUClass),
6870 .class_init = x86_cpu_common_class_init,
6874 /* "base" CPU model, used by query-cpu-model-expansion */
6875 static void x86_cpu_base_class_init(ObjectClass *oc, void *data)
6877 X86CPUClass *xcc = X86_CPU_CLASS(oc);
6879 xcc->static_model = true;
6880 xcc->migration_safe = true;
6881 xcc->model_description = "base CPU model type with no features enabled";
6882 xcc->ordering = 8;
6885 static const TypeInfo x86_base_cpu_type_info = {
6886 .name = X86_CPU_TYPE_NAME("base"),
6887 .parent = TYPE_X86_CPU,
6888 .class_init = x86_cpu_base_class_init,
6891 static void x86_cpu_register_types(void)
6893 int i;
6895 type_register_static(&x86_cpu_type_info);
6896 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
6897 x86_register_cpudef_types(&builtin_x86_defs[i]);
6899 type_register_static(&max_x86_cpu_type_info);
6900 type_register_static(&x86_base_cpu_type_info);
6903 type_init(x86_cpu_register_types)