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