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