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