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