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