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