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