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