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