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