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