Update version for 2.11.2 release
[qemu.git] / target / i386 / cpu.c
1 /*
2 * i386 CPUID helper functions
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 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 #include "qemu/osdep.h"
20 #include "qemu/cutils.h"
21
22 #include "cpu.h"
23 #include "exec/exec-all.h"
24 #include "sysemu/kvm.h"
25 #include "sysemu/cpus.h"
26 #include "kvm_i386.h"
27
28 #include "qemu/error-report.h"
29 #include "qemu/option.h"
30 #include "qemu/config-file.h"
31 #include "qapi/qmp/qerror.h"
32 #include "qapi/qmp/types.h"
33
34 #include "qapi-types.h"
35 #include "qapi-visit.h"
36 #include "qapi/visitor.h"
37 #include "qom/qom-qobject.h"
38 #include "sysemu/arch_init.h"
39
40 #if defined(CONFIG_KVM)
41 #include <linux/kvm_para.h>
42 #endif
43
44 #include "sysemu/sysemu.h"
45 #include "hw/qdev-properties.h"
46 #include "hw/i386/topology.h"
47 #ifndef CONFIG_USER_ONLY
48 #include "exec/address-spaces.h"
49 #include "hw/hw.h"
50 #include "hw/xen/xen.h"
51 #include "hw/i386/apic_internal.h"
52 #endif
53
54 #include "disas/capstone.h"
55
56
57 /* Cache topology CPUID constants: */
58
59 /* CPUID Leaf 2 Descriptors */
60
61 #define CPUID_2_L1D_32KB_8WAY_64B 0x2c
62 #define CPUID_2_L1I_32KB_8WAY_64B 0x30
63 #define CPUID_2_L2_2MB_8WAY_64B 0x7d
64 #define CPUID_2_L3_16MB_16WAY_64B 0x4d
65
66
67 /* CPUID Leaf 4 constants: */
68
69 /* EAX: */
70 #define CPUID_4_TYPE_DCACHE 1
71 #define CPUID_4_TYPE_ICACHE 2
72 #define CPUID_4_TYPE_UNIFIED 3
73
74 #define CPUID_4_LEVEL(l) ((l) << 5)
75
76 #define CPUID_4_SELF_INIT_LEVEL (1 << 8)
77 #define CPUID_4_FULLY_ASSOC (1 << 9)
78
79 /* EDX: */
80 #define CPUID_4_NO_INVD_SHARING (1 << 0)
81 #define CPUID_4_INCLUSIVE (1 << 1)
82 #define CPUID_4_COMPLEX_IDX (1 << 2)
83
84 #define ASSOC_FULL 0xFF
85
86 /* AMD associativity encoding used on CPUID Leaf 0x80000006: */
87 #define AMD_ENC_ASSOC(a) (a <= 1 ? a : \
88 a == 2 ? 0x2 : \
89 a == 4 ? 0x4 : \
90 a == 8 ? 0x6 : \
91 a == 16 ? 0x8 : \
92 a == 32 ? 0xA : \
93 a == 48 ? 0xB : \
94 a == 64 ? 0xC : \
95 a == 96 ? 0xD : \
96 a == 128 ? 0xE : \
97 a == ASSOC_FULL ? 0xF : \
98 0 /* invalid value */)
99
100
101 /* Definitions of the hardcoded cache entries we expose: */
102
103 /* L1 data cache: */
104 #define L1D_LINE_SIZE 64
105 #define L1D_ASSOCIATIVITY 8
106 #define L1D_SETS 64
107 #define L1D_PARTITIONS 1
108 /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
109 #define L1D_DESCRIPTOR CPUID_2_L1D_32KB_8WAY_64B
110 /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
111 #define L1D_LINES_PER_TAG 1
112 #define L1D_SIZE_KB_AMD 64
113 #define L1D_ASSOCIATIVITY_AMD 2
114
115 /* L1 instruction cache: */
116 #define L1I_LINE_SIZE 64
117 #define L1I_ASSOCIATIVITY 8
118 #define L1I_SETS 64
119 #define L1I_PARTITIONS 1
120 /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
121 #define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
122 /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
123 #define L1I_LINES_PER_TAG 1
124 #define L1I_SIZE_KB_AMD 64
125 #define L1I_ASSOCIATIVITY_AMD 2
126
127 /* Level 2 unified cache: */
128 #define L2_LINE_SIZE 64
129 #define L2_ASSOCIATIVITY 16
130 #define L2_SETS 4096
131 #define L2_PARTITIONS 1
132 /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
133 /*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
134 #define L2_DESCRIPTOR CPUID_2_L2_2MB_8WAY_64B
135 /*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
136 #define L2_LINES_PER_TAG 1
137 #define L2_SIZE_KB_AMD 512
138
139 /* Level 3 unified cache: */
140 #define L3_SIZE_KB 0 /* disabled */
141 #define L3_ASSOCIATIVITY 0 /* disabled */
142 #define L3_LINES_PER_TAG 0 /* disabled */
143 #define L3_LINE_SIZE 0 /* disabled */
144 #define L3_N_LINE_SIZE 64
145 #define L3_N_ASSOCIATIVITY 16
146 #define L3_N_SETS 16384
147 #define L3_N_PARTITIONS 1
148 #define L3_N_DESCRIPTOR CPUID_2_L3_16MB_16WAY_64B
149 #define L3_N_LINES_PER_TAG 1
150 #define L3_N_SIZE_KB_AMD 16384
151
152 /* TLB definitions: */
153
154 #define L1_DTLB_2M_ASSOC 1
155 #define L1_DTLB_2M_ENTRIES 255
156 #define L1_DTLB_4K_ASSOC 1
157 #define L1_DTLB_4K_ENTRIES 255
158
159 #define L1_ITLB_2M_ASSOC 1
160 #define L1_ITLB_2M_ENTRIES 255
161 #define L1_ITLB_4K_ASSOC 1
162 #define L1_ITLB_4K_ENTRIES 255
163
164 #define L2_DTLB_2M_ASSOC 0 /* disabled */
165 #define L2_DTLB_2M_ENTRIES 0 /* disabled */
166 #define L2_DTLB_4K_ASSOC 4
167 #define L2_DTLB_4K_ENTRIES 512
168
169 #define L2_ITLB_2M_ASSOC 0 /* disabled */
170 #define L2_ITLB_2M_ENTRIES 0 /* disabled */
171 #define L2_ITLB_4K_ASSOC 4
172 #define L2_ITLB_4K_ENTRIES 512
173
174
175
176 static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
177 uint32_t vendor2, uint32_t vendor3)
178 {
179 int i;
180 for (i = 0; i < 4; i++) {
181 dst[i] = vendor1 >> (8 * i);
182 dst[i + 4] = vendor2 >> (8 * i);
183 dst[i + 8] = vendor3 >> (8 * i);
184 }
185 dst[CPUID_VENDOR_SZ] = '\0';
186 }
187
188 #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
189 #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
190 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
191 #define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
192 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
193 CPUID_PSE36 | CPUID_FXSR)
194 #define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
195 #define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
196 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
197 CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
198 CPUID_PAE | CPUID_SEP | CPUID_APIC)
199
200 #define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
201 CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
202 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
203 CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
204 CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS | CPUID_DE)
205 /* partly implemented:
206 CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64) */
207 /* missing:
208 CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
209 #define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
210 CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
211 CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
212 CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */ \
213 CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
214 /* missing:
215 CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
216 CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
217 CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
218 CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_AVX,
219 CPUID_EXT_F16C, CPUID_EXT_RDRAND */
220
221 #ifdef TARGET_X86_64
222 #define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM)
223 #else
224 #define TCG_EXT2_X86_64_FEATURES 0
225 #endif
226
227 #define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
228 CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
229 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_PDPE1GB | \
230 TCG_EXT2_X86_64_FEATURES)
231 #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
232 CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
233 #define TCG_EXT4_FEATURES 0
234 #define TCG_SVM_FEATURES 0
235 #define TCG_KVM_FEATURES 0
236 #define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
237 CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
238 CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT | \
239 CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE | \
240 CPUID_7_0_EBX_ERMS)
241 /* missing:
242 CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
243 CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
244 CPUID_7_0_EBX_RDSEED */
245 #define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE | \
246 CPUID_7_0_ECX_LA57)
247 #define TCG_7_0_EDX_FEATURES 0
248 #define TCG_APM_FEATURES 0
249 #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
250 #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1)
251 /* missing:
252 CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
253
254 typedef struct FeatureWordInfo {
255 /* feature flags names are taken from "Intel Processor Identification and
256 * the CPUID Instruction" and AMD's "CPUID Specification".
257 * In cases of disagreement between feature naming conventions,
258 * aliases may be added.
259 */
260 const char *feat_names[32];
261 uint32_t cpuid_eax; /* Input EAX for CPUID */
262 bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
263 uint32_t cpuid_ecx; /* Input ECX value for CPUID */
264 int cpuid_reg; /* output register (R_* constant) */
265 uint32_t tcg_features; /* Feature flags supported by TCG */
266 uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
267 uint32_t migratable_flags; /* Feature flags known to be migratable */
268 } FeatureWordInfo;
269
270 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
271 [FEAT_1_EDX] = {
272 .feat_names = {
273 "fpu", "vme", "de", "pse",
274 "tsc", "msr", "pae", "mce",
275 "cx8", "apic", NULL, "sep",
276 "mtrr", "pge", "mca", "cmov",
277 "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
278 NULL, "ds" /* Intel dts */, "acpi", "mmx",
279 "fxsr", "sse", "sse2", "ss",
280 "ht" /* Intel htt */, "tm", "ia64", "pbe",
281 },
282 .cpuid_eax = 1, .cpuid_reg = R_EDX,
283 .tcg_features = TCG_FEATURES,
284 },
285 [FEAT_1_ECX] = {
286 .feat_names = {
287 "pni" /* Intel,AMD sse3 */, "pclmulqdq", "dtes64", "monitor",
288 "ds-cpl", "vmx", "smx", "est",
289 "tm2", "ssse3", "cid", NULL,
290 "fma", "cx16", "xtpr", "pdcm",
291 NULL, "pcid", "dca", "sse4.1",
292 "sse4.2", "x2apic", "movbe", "popcnt",
293 "tsc-deadline", "aes", "xsave", "osxsave",
294 "avx", "f16c", "rdrand", "hypervisor",
295 },
296 .cpuid_eax = 1, .cpuid_reg = R_ECX,
297 .tcg_features = TCG_EXT_FEATURES,
298 },
299 /* Feature names that are already defined on feature_name[] but
300 * are set on CPUID[8000_0001].EDX on AMD CPUs don't have their
301 * names on feat_names below. They are copied automatically
302 * to features[FEAT_8000_0001_EDX] if and only if CPU vendor is AMD.
303 */
304 [FEAT_8000_0001_EDX] = {
305 .feat_names = {
306 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
307 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
308 NULL /* cx8 */, NULL /* apic */, NULL, "syscall",
309 NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
310 NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
311 "nx", NULL, "mmxext", NULL /* mmx */,
312 NULL /* fxsr */, "fxsr-opt", "pdpe1gb", "rdtscp",
313 NULL, "lm", "3dnowext", "3dnow",
314 },
315 .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX,
316 .tcg_features = TCG_EXT2_FEATURES,
317 },
318 [FEAT_8000_0001_ECX] = {
319 .feat_names = {
320 "lahf-lm", "cmp-legacy", "svm", "extapic",
321 "cr8legacy", "abm", "sse4a", "misalignsse",
322 "3dnowprefetch", "osvw", "ibs", "xop",
323 "skinit", "wdt", NULL, "lwp",
324 "fma4", "tce", NULL, "nodeid-msr",
325 NULL, "tbm", "topoext", "perfctr-core",
326 "perfctr-nb", NULL, NULL, NULL,
327 NULL, NULL, NULL, NULL,
328 },
329 .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
330 .tcg_features = TCG_EXT3_FEATURES,
331 },
332 [FEAT_C000_0001_EDX] = {
333 .feat_names = {
334 NULL, NULL, "xstore", "xstore-en",
335 NULL, NULL, "xcrypt", "xcrypt-en",
336 "ace2", "ace2-en", "phe", "phe-en",
337 "pmm", "pmm-en", NULL, NULL,
338 NULL, NULL, NULL, NULL,
339 NULL, NULL, NULL, NULL,
340 NULL, NULL, NULL, NULL,
341 NULL, NULL, NULL, NULL,
342 },
343 .cpuid_eax = 0xC0000001, .cpuid_reg = R_EDX,
344 .tcg_features = TCG_EXT4_FEATURES,
345 },
346 [FEAT_KVM] = {
347 .feat_names = {
348 "kvmclock", "kvm-nopiodelay", "kvm-mmu", "kvmclock",
349 "kvm-asyncpf", "kvm-steal-time", "kvm-pv-eoi", "kvm-pv-unhalt",
350 NULL, "kvm-pv-tlb-flush", NULL, NULL,
351 NULL, NULL, NULL, NULL,
352 NULL, NULL, NULL, NULL,
353 NULL, NULL, NULL, NULL,
354 "kvmclock-stable-bit", NULL, NULL, NULL,
355 NULL, NULL, NULL, NULL,
356 },
357 .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
358 .tcg_features = TCG_KVM_FEATURES,
359 },
360 [FEAT_HYPERV_EAX] = {
361 .feat_names = {
362 NULL /* hv_msr_vp_runtime_access */, NULL /* hv_msr_time_refcount_access */,
363 NULL /* hv_msr_synic_access */, NULL /* hv_msr_stimer_access */,
364 NULL /* hv_msr_apic_access */, NULL /* hv_msr_hypercall_access */,
365 NULL /* hv_vpindex_access */, NULL /* hv_msr_reset_access */,
366 NULL /* hv_msr_stats_access */, NULL /* hv_reftsc_access */,
367 NULL /* hv_msr_idle_access */, NULL /* hv_msr_frequency_access */,
368 NULL, NULL, NULL, NULL,
369 NULL, NULL, NULL, NULL,
370 NULL, NULL, NULL, NULL,
371 NULL, NULL, NULL, NULL,
372 NULL, NULL, NULL, NULL,
373 },
374 .cpuid_eax = 0x40000003, .cpuid_reg = R_EAX,
375 },
376 [FEAT_HYPERV_EBX] = {
377 .feat_names = {
378 NULL /* hv_create_partitions */, NULL /* hv_access_partition_id */,
379 NULL /* hv_access_memory_pool */, NULL /* hv_adjust_message_buffers */,
380 NULL /* hv_post_messages */, NULL /* hv_signal_events */,
381 NULL /* hv_create_port */, NULL /* hv_connect_port */,
382 NULL /* hv_access_stats */, NULL, NULL, NULL /* hv_debugging */,
383 NULL /* hv_cpu_power_management */, NULL /* hv_configure_profiler */,
384 NULL, NULL,
385 NULL, NULL, NULL, NULL,
386 NULL, NULL, NULL, NULL,
387 NULL, NULL, NULL, NULL,
388 NULL, NULL, NULL, NULL,
389 },
390 .cpuid_eax = 0x40000003, .cpuid_reg = R_EBX,
391 },
392 [FEAT_HYPERV_EDX] = {
393 .feat_names = {
394 NULL /* hv_mwait */, NULL /* hv_guest_debugging */,
395 NULL /* hv_perf_monitor */, NULL /* hv_cpu_dynamic_part */,
396 NULL /* hv_hypercall_params_xmm */, NULL /* hv_guest_idle_state */,
397 NULL, NULL,
398 NULL, NULL, NULL /* hv_guest_crash_msr */, NULL,
399 NULL, NULL, NULL, NULL,
400 NULL, NULL, NULL, NULL,
401 NULL, NULL, NULL, NULL,
402 NULL, NULL, NULL, NULL,
403 NULL, NULL, NULL, NULL,
404 },
405 .cpuid_eax = 0x40000003, .cpuid_reg = R_EDX,
406 },
407 [FEAT_SVM] = {
408 .feat_names = {
409 "npt", "lbrv", "svm-lock", "nrip-save",
410 "tsc-scale", "vmcb-clean", "flushbyasid", "decodeassists",
411 NULL, NULL, "pause-filter", NULL,
412 "pfthreshold", NULL, NULL, NULL,
413 NULL, NULL, NULL, NULL,
414 NULL, NULL, NULL, NULL,
415 NULL, NULL, NULL, NULL,
416 NULL, NULL, NULL, NULL,
417 },
418 .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
419 .tcg_features = TCG_SVM_FEATURES,
420 },
421 [FEAT_7_0_EBX] = {
422 .feat_names = {
423 "fsgsbase", "tsc-adjust", NULL, "bmi1",
424 "hle", "avx2", NULL, "smep",
425 "bmi2", "erms", "invpcid", "rtm",
426 NULL, NULL, "mpx", NULL,
427 "avx512f", "avx512dq", "rdseed", "adx",
428 "smap", "avx512ifma", "pcommit", "clflushopt",
429 "clwb", NULL, "avx512pf", "avx512er",
430 "avx512cd", "sha-ni", "avx512bw", "avx512vl",
431 },
432 .cpuid_eax = 7,
433 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
434 .cpuid_reg = R_EBX,
435 .tcg_features = TCG_7_0_EBX_FEATURES,
436 },
437 [FEAT_7_0_ECX] = {
438 .feat_names = {
439 NULL, "avx512vbmi", "umip", "pku",
440 "ospke", NULL, NULL, NULL,
441 NULL, NULL, NULL, NULL,
442 NULL, NULL, "avx512-vpopcntdq", NULL,
443 "la57", NULL, NULL, NULL,
444 NULL, NULL, "rdpid", NULL,
445 NULL, NULL, NULL, NULL,
446 NULL, NULL, NULL, NULL,
447 },
448 .cpuid_eax = 7,
449 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
450 .cpuid_reg = R_ECX,
451 .tcg_features = TCG_7_0_ECX_FEATURES,
452 },
453 [FEAT_7_0_EDX] = {
454 .feat_names = {
455 NULL, NULL, "avx512-4vnniw", "avx512-4fmaps",
456 NULL, NULL, NULL, NULL,
457 NULL, NULL, NULL, NULL,
458 NULL, NULL, NULL, NULL,
459 NULL, NULL, NULL, NULL,
460 NULL, NULL, NULL, NULL,
461 NULL, NULL, "spec-ctrl", NULL,
462 NULL, NULL, NULL, NULL,
463 },
464 .cpuid_eax = 7,
465 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
466 .cpuid_reg = R_EDX,
467 .tcg_features = TCG_7_0_EDX_FEATURES,
468 },
469 [FEAT_8000_0007_EDX] = {
470 .feat_names = {
471 NULL, NULL, NULL, NULL,
472 NULL, NULL, NULL, NULL,
473 "invtsc", NULL, NULL, NULL,
474 NULL, NULL, NULL, NULL,
475 NULL, NULL, NULL, NULL,
476 NULL, NULL, NULL, NULL,
477 NULL, NULL, NULL, NULL,
478 NULL, NULL, NULL, NULL,
479 },
480 .cpuid_eax = 0x80000007,
481 .cpuid_reg = R_EDX,
482 .tcg_features = TCG_APM_FEATURES,
483 .unmigratable_flags = CPUID_APM_INVTSC,
484 },
485 [FEAT_8000_0008_EBX] = {
486 .feat_names = {
487 NULL, NULL, NULL, NULL,
488 NULL, NULL, NULL, NULL,
489 NULL, NULL, NULL, NULL,
490 "ibpb", NULL, NULL, NULL,
491 NULL, NULL, NULL, NULL,
492 NULL, NULL, NULL, NULL,
493 NULL, NULL, NULL, NULL,
494 NULL, NULL, NULL, NULL,
495 },
496 .cpuid_eax = 0x80000008,
497 .cpuid_reg = R_EBX,
498 .tcg_features = 0,
499 .unmigratable_flags = 0,
500 },
501 [FEAT_XSAVE] = {
502 .feat_names = {
503 "xsaveopt", "xsavec", "xgetbv1", "xsaves",
504 NULL, NULL, NULL, NULL,
505 NULL, NULL, NULL, NULL,
506 NULL, NULL, NULL, NULL,
507 NULL, NULL, NULL, NULL,
508 NULL, NULL, NULL, NULL,
509 NULL, NULL, NULL, NULL,
510 NULL, NULL, NULL, NULL,
511 },
512 .cpuid_eax = 0xd,
513 .cpuid_needs_ecx = true, .cpuid_ecx = 1,
514 .cpuid_reg = R_EAX,
515 .tcg_features = TCG_XSAVE_FEATURES,
516 },
517 [FEAT_6_EAX] = {
518 .feat_names = {
519 NULL, NULL, "arat", NULL,
520 NULL, NULL, NULL, NULL,
521 NULL, NULL, NULL, NULL,
522 NULL, NULL, NULL, NULL,
523 NULL, NULL, NULL, NULL,
524 NULL, NULL, NULL, NULL,
525 NULL, NULL, NULL, NULL,
526 NULL, NULL, NULL, NULL,
527 },
528 .cpuid_eax = 6, .cpuid_reg = R_EAX,
529 .tcg_features = TCG_6_EAX_FEATURES,
530 },
531 [FEAT_XSAVE_COMP_LO] = {
532 .cpuid_eax = 0xD,
533 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
534 .cpuid_reg = R_EAX,
535 .tcg_features = ~0U,
536 .migratable_flags = XSTATE_FP_MASK | XSTATE_SSE_MASK |
537 XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK |
538 XSTATE_OPMASK_MASK | XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_MASK |
539 XSTATE_PKRU_MASK,
540 },
541 [FEAT_XSAVE_COMP_HI] = {
542 .cpuid_eax = 0xD,
543 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
544 .cpuid_reg = R_EDX,
545 .tcg_features = ~0U,
546 },
547 };
548
549 typedef struct X86RegisterInfo32 {
550 /* Name of register */
551 const char *name;
552 /* QAPI enum value register */
553 X86CPURegister32 qapi_enum;
554 } X86RegisterInfo32;
555
556 #define REGISTER(reg) \
557 [R_##reg] = { .name = #reg, .qapi_enum = X86_CPU_REGISTER32_##reg }
558 static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
559 REGISTER(EAX),
560 REGISTER(ECX),
561 REGISTER(EDX),
562 REGISTER(EBX),
563 REGISTER(ESP),
564 REGISTER(EBP),
565 REGISTER(ESI),
566 REGISTER(EDI),
567 };
568 #undef REGISTER
569
570 typedef struct ExtSaveArea {
571 uint32_t feature, bits;
572 uint32_t offset, size;
573 } ExtSaveArea;
574
575 static const ExtSaveArea x86_ext_save_areas[] = {
576 [XSTATE_FP_BIT] = {
577 /* x87 FP state component is always enabled if XSAVE is supported */
578 .feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
579 /* x87 state is in the legacy region of the XSAVE area */
580 .offset = 0,
581 .size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
582 },
583 [XSTATE_SSE_BIT] = {
584 /* SSE state component is always enabled if XSAVE is supported */
585 .feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
586 /* SSE state is in the legacy region of the XSAVE area */
587 .offset = 0,
588 .size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
589 },
590 [XSTATE_YMM_BIT] =
591 { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
592 .offset = offsetof(X86XSaveArea, avx_state),
593 .size = sizeof(XSaveAVX) },
594 [XSTATE_BNDREGS_BIT] =
595 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
596 .offset = offsetof(X86XSaveArea, bndreg_state),
597 .size = sizeof(XSaveBNDREG) },
598 [XSTATE_BNDCSR_BIT] =
599 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
600 .offset = offsetof(X86XSaveArea, bndcsr_state),
601 .size = sizeof(XSaveBNDCSR) },
602 [XSTATE_OPMASK_BIT] =
603 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
604 .offset = offsetof(X86XSaveArea, opmask_state),
605 .size = sizeof(XSaveOpmask) },
606 [XSTATE_ZMM_Hi256_BIT] =
607 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
608 .offset = offsetof(X86XSaveArea, zmm_hi256_state),
609 .size = sizeof(XSaveZMM_Hi256) },
610 [XSTATE_Hi16_ZMM_BIT] =
611 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
612 .offset = offsetof(X86XSaveArea, hi16_zmm_state),
613 .size = sizeof(XSaveHi16_ZMM) },
614 [XSTATE_PKRU_BIT] =
615 { .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU,
616 .offset = offsetof(X86XSaveArea, pkru_state),
617 .size = sizeof(XSavePKRU) },
618 };
619
620 static uint32_t xsave_area_size(uint64_t mask)
621 {
622 int i;
623 uint64_t ret = 0;
624
625 for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
626 const ExtSaveArea *esa = &x86_ext_save_areas[i];
627 if ((mask >> i) & 1) {
628 ret = MAX(ret, esa->offset + esa->size);
629 }
630 }
631 return ret;
632 }
633
634 static inline uint64_t x86_cpu_xsave_components(X86CPU *cpu)
635 {
636 return ((uint64_t)cpu->env.features[FEAT_XSAVE_COMP_HI]) << 32 |
637 cpu->env.features[FEAT_XSAVE_COMP_LO];
638 }
639
640 const char *get_register_name_32(unsigned int reg)
641 {
642 if (reg >= CPU_NB_REGS32) {
643 return NULL;
644 }
645 return x86_reg_info_32[reg].name;
646 }
647
648 /*
649 * Returns the set of feature flags that are supported and migratable by
650 * QEMU, for a given FeatureWord.
651 */
652 static uint32_t x86_cpu_get_migratable_flags(FeatureWord w)
653 {
654 FeatureWordInfo *wi = &feature_word_info[w];
655 uint32_t r = 0;
656 int i;
657
658 for (i = 0; i < 32; i++) {
659 uint32_t f = 1U << i;
660
661 /* If the feature name is known, it is implicitly considered migratable,
662 * unless it is explicitly set in unmigratable_flags */
663 if ((wi->migratable_flags & f) ||
664 (wi->feat_names[i] && !(wi->unmigratable_flags & f))) {
665 r |= f;
666 }
667 }
668 return r;
669 }
670
671 void host_cpuid(uint32_t function, uint32_t count,
672 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
673 {
674 uint32_t vec[4];
675
676 #ifdef __x86_64__
677 asm volatile("cpuid"
678 : "=a"(vec[0]), "=b"(vec[1]),
679 "=c"(vec[2]), "=d"(vec[3])
680 : "0"(function), "c"(count) : "cc");
681 #elif defined(__i386__)
682 asm volatile("pusha \n\t"
683 "cpuid \n\t"
684 "mov %%eax, 0(%2) \n\t"
685 "mov %%ebx, 4(%2) \n\t"
686 "mov %%ecx, 8(%2) \n\t"
687 "mov %%edx, 12(%2) \n\t"
688 "popa"
689 : : "a"(function), "c"(count), "S"(vec)
690 : "memory", "cc");
691 #else
692 abort();
693 #endif
694
695 if (eax)
696 *eax = vec[0];
697 if (ebx)
698 *ebx = vec[1];
699 if (ecx)
700 *ecx = vec[2];
701 if (edx)
702 *edx = vec[3];
703 }
704
705 void host_vendor_fms(char *vendor, int *family, int *model, int *stepping)
706 {
707 uint32_t eax, ebx, ecx, edx;
708
709 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
710 x86_cpu_vendor_words2str(vendor, ebx, edx, ecx);
711
712 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
713 if (family) {
714 *family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
715 }
716 if (model) {
717 *model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
718 }
719 if (stepping) {
720 *stepping = eax & 0x0F;
721 }
722 }
723
724 /* CPU class name definitions: */
725
726 /* Return type name for a given CPU model name
727 * Caller is responsible for freeing the returned string.
728 */
729 static char *x86_cpu_type_name(const char *model_name)
730 {
731 return g_strdup_printf(X86_CPU_TYPE_NAME("%s"), model_name);
732 }
733
734 static ObjectClass *x86_cpu_class_by_name(const char *cpu_model)
735 {
736 ObjectClass *oc;
737 char *typename;
738
739 if (cpu_model == NULL) {
740 return NULL;
741 }
742
743 typename = x86_cpu_type_name(cpu_model);
744 oc = object_class_by_name(typename);
745 g_free(typename);
746 return oc;
747 }
748
749 static char *x86_cpu_class_get_model_name(X86CPUClass *cc)
750 {
751 const char *class_name = object_class_get_name(OBJECT_CLASS(cc));
752 assert(g_str_has_suffix(class_name, X86_CPU_TYPE_SUFFIX));
753 return g_strndup(class_name,
754 strlen(class_name) - strlen(X86_CPU_TYPE_SUFFIX));
755 }
756
757 struct X86CPUDefinition {
758 const char *name;
759 uint32_t level;
760 uint32_t xlevel;
761 /* vendor is zero-terminated, 12 character ASCII string */
762 char vendor[CPUID_VENDOR_SZ + 1];
763 int family;
764 int model;
765 int stepping;
766 FeatureWordArray features;
767 const char *model_id;
768 };
769
770 static X86CPUDefinition builtin_x86_defs[] = {
771 {
772 .name = "qemu64",
773 .level = 0xd,
774 .vendor = CPUID_VENDOR_AMD,
775 .family = 6,
776 .model = 6,
777 .stepping = 3,
778 .features[FEAT_1_EDX] =
779 PPRO_FEATURES |
780 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
781 CPUID_PSE36,
782 .features[FEAT_1_ECX] =
783 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
784 .features[FEAT_8000_0001_EDX] =
785 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
786 .features[FEAT_8000_0001_ECX] =
787 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM,
788 .xlevel = 0x8000000A,
789 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
790 },
791 {
792 .name = "phenom",
793 .level = 5,
794 .vendor = CPUID_VENDOR_AMD,
795 .family = 16,
796 .model = 2,
797 .stepping = 3,
798 /* Missing: CPUID_HT */
799 .features[FEAT_1_EDX] =
800 PPRO_FEATURES |
801 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
802 CPUID_PSE36 | CPUID_VME,
803 .features[FEAT_1_ECX] =
804 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
805 CPUID_EXT_POPCNT,
806 .features[FEAT_8000_0001_EDX] =
807 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
808 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
809 CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
810 /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
811 CPUID_EXT3_CR8LEG,
812 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
813 CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
814 .features[FEAT_8000_0001_ECX] =
815 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
816 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
817 /* Missing: CPUID_SVM_LBRV */
818 .features[FEAT_SVM] =
819 CPUID_SVM_NPT,
820 .xlevel = 0x8000001A,
821 .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
822 },
823 {
824 .name = "core2duo",
825 .level = 10,
826 .vendor = CPUID_VENDOR_INTEL,
827 .family = 6,
828 .model = 15,
829 .stepping = 11,
830 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
831 .features[FEAT_1_EDX] =
832 PPRO_FEATURES |
833 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
834 CPUID_PSE36 | CPUID_VME | CPUID_ACPI | CPUID_SS,
835 /* Missing: CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_EST,
836 * CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_VMX */
837 .features[FEAT_1_ECX] =
838 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
839 CPUID_EXT_CX16,
840 .features[FEAT_8000_0001_EDX] =
841 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
842 .features[FEAT_8000_0001_ECX] =
843 CPUID_EXT3_LAHF_LM,
844 .xlevel = 0x80000008,
845 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
846 },
847 {
848 .name = "kvm64",
849 .level = 0xd,
850 .vendor = CPUID_VENDOR_INTEL,
851 .family = 15,
852 .model = 6,
853 .stepping = 1,
854 /* Missing: CPUID_HT */
855 .features[FEAT_1_EDX] =
856 PPRO_FEATURES | CPUID_VME |
857 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
858 CPUID_PSE36,
859 /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
860 .features[FEAT_1_ECX] =
861 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
862 /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
863 .features[FEAT_8000_0001_EDX] =
864 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
865 /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
866 CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
867 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
868 CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
869 .features[FEAT_8000_0001_ECX] =
870 0,
871 .xlevel = 0x80000008,
872 .model_id = "Common KVM processor"
873 },
874 {
875 .name = "qemu32",
876 .level = 4,
877 .vendor = CPUID_VENDOR_INTEL,
878 .family = 6,
879 .model = 6,
880 .stepping = 3,
881 .features[FEAT_1_EDX] =
882 PPRO_FEATURES,
883 .features[FEAT_1_ECX] =
884 CPUID_EXT_SSE3,
885 .xlevel = 0x80000004,
886 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
887 },
888 {
889 .name = "kvm32",
890 .level = 5,
891 .vendor = CPUID_VENDOR_INTEL,
892 .family = 15,
893 .model = 6,
894 .stepping = 1,
895 .features[FEAT_1_EDX] =
896 PPRO_FEATURES | CPUID_VME |
897 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
898 .features[FEAT_1_ECX] =
899 CPUID_EXT_SSE3,
900 .features[FEAT_8000_0001_ECX] =
901 0,
902 .xlevel = 0x80000008,
903 .model_id = "Common 32-bit KVM processor"
904 },
905 {
906 .name = "coreduo",
907 .level = 10,
908 .vendor = CPUID_VENDOR_INTEL,
909 .family = 6,
910 .model = 14,
911 .stepping = 8,
912 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
913 .features[FEAT_1_EDX] =
914 PPRO_FEATURES | CPUID_VME |
915 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_ACPI |
916 CPUID_SS,
917 /* Missing: CPUID_EXT_EST, CPUID_EXT_TM2 , CPUID_EXT_XTPR,
918 * CPUID_EXT_PDCM, CPUID_EXT_VMX */
919 .features[FEAT_1_ECX] =
920 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
921 .features[FEAT_8000_0001_EDX] =
922 CPUID_EXT2_NX,
923 .xlevel = 0x80000008,
924 .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
925 },
926 {
927 .name = "486",
928 .level = 1,
929 .vendor = CPUID_VENDOR_INTEL,
930 .family = 4,
931 .model = 8,
932 .stepping = 0,
933 .features[FEAT_1_EDX] =
934 I486_FEATURES,
935 .xlevel = 0,
936 .model_id = "",
937 },
938 {
939 .name = "pentium",
940 .level = 1,
941 .vendor = CPUID_VENDOR_INTEL,
942 .family = 5,
943 .model = 4,
944 .stepping = 3,
945 .features[FEAT_1_EDX] =
946 PENTIUM_FEATURES,
947 .xlevel = 0,
948 .model_id = "",
949 },
950 {
951 .name = "pentium2",
952 .level = 2,
953 .vendor = CPUID_VENDOR_INTEL,
954 .family = 6,
955 .model = 5,
956 .stepping = 2,
957 .features[FEAT_1_EDX] =
958 PENTIUM2_FEATURES,
959 .xlevel = 0,
960 .model_id = "",
961 },
962 {
963 .name = "pentium3",
964 .level = 3,
965 .vendor = CPUID_VENDOR_INTEL,
966 .family = 6,
967 .model = 7,
968 .stepping = 3,
969 .features[FEAT_1_EDX] =
970 PENTIUM3_FEATURES,
971 .xlevel = 0,
972 .model_id = "",
973 },
974 {
975 .name = "athlon",
976 .level = 2,
977 .vendor = CPUID_VENDOR_AMD,
978 .family = 6,
979 .model = 2,
980 .stepping = 3,
981 .features[FEAT_1_EDX] =
982 PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
983 CPUID_MCA,
984 .features[FEAT_8000_0001_EDX] =
985 CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
986 .xlevel = 0x80000008,
987 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
988 },
989 {
990 .name = "n270",
991 .level = 10,
992 .vendor = CPUID_VENDOR_INTEL,
993 .family = 6,
994 .model = 28,
995 .stepping = 2,
996 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
997 .features[FEAT_1_EDX] =
998 PPRO_FEATURES |
999 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME |
1000 CPUID_ACPI | CPUID_SS,
1001 /* Some CPUs got no CPUID_SEP */
1002 /* Missing: CPUID_EXT_DSCPL, CPUID_EXT_EST, CPUID_EXT_TM2,
1003 * CPUID_EXT_XTPR */
1004 .features[FEAT_1_ECX] =
1005 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
1006 CPUID_EXT_MOVBE,
1007 .features[FEAT_8000_0001_EDX] =
1008 CPUID_EXT2_NX,
1009 .features[FEAT_8000_0001_ECX] =
1010 CPUID_EXT3_LAHF_LM,
1011 .xlevel = 0x80000008,
1012 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
1013 },
1014 {
1015 .name = "Conroe",
1016 .level = 10,
1017 .vendor = CPUID_VENDOR_INTEL,
1018 .family = 6,
1019 .model = 15,
1020 .stepping = 3,
1021 .features[FEAT_1_EDX] =
1022 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1023 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1024 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1025 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1026 CPUID_DE | CPUID_FP87,
1027 .features[FEAT_1_ECX] =
1028 CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
1029 .features[FEAT_8000_0001_EDX] =
1030 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
1031 .features[FEAT_8000_0001_ECX] =
1032 CPUID_EXT3_LAHF_LM,
1033 .xlevel = 0x80000008,
1034 .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
1035 },
1036 {
1037 .name = "Penryn",
1038 .level = 10,
1039 .vendor = CPUID_VENDOR_INTEL,
1040 .family = 6,
1041 .model = 23,
1042 .stepping = 3,
1043 .features[FEAT_1_EDX] =
1044 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1045 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1046 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1047 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1048 CPUID_DE | CPUID_FP87,
1049 .features[FEAT_1_ECX] =
1050 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1051 CPUID_EXT_SSE3,
1052 .features[FEAT_8000_0001_EDX] =
1053 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
1054 .features[FEAT_8000_0001_ECX] =
1055 CPUID_EXT3_LAHF_LM,
1056 .xlevel = 0x80000008,
1057 .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
1058 },
1059 {
1060 .name = "Nehalem",
1061 .level = 11,
1062 .vendor = CPUID_VENDOR_INTEL,
1063 .family = 6,
1064 .model = 26,
1065 .stepping = 3,
1066 .features[FEAT_1_EDX] =
1067 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1068 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1069 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1070 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1071 CPUID_DE | CPUID_FP87,
1072 .features[FEAT_1_ECX] =
1073 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1074 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
1075 .features[FEAT_8000_0001_EDX] =
1076 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1077 .features[FEAT_8000_0001_ECX] =
1078 CPUID_EXT3_LAHF_LM,
1079 .xlevel = 0x80000008,
1080 .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
1081 },
1082 {
1083 .name = "Nehalem-IBRS",
1084 .level = 11,
1085 .vendor = CPUID_VENDOR_INTEL,
1086 .family = 6,
1087 .model = 26,
1088 .stepping = 3,
1089 .features[FEAT_1_EDX] =
1090 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1091 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1092 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1093 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1094 CPUID_DE | CPUID_FP87,
1095 .features[FEAT_1_ECX] =
1096 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1097 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
1098 .features[FEAT_7_0_EDX] =
1099 CPUID_7_0_EDX_SPEC_CTRL,
1100 .features[FEAT_8000_0001_EDX] =
1101 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1102 .features[FEAT_8000_0001_ECX] =
1103 CPUID_EXT3_LAHF_LM,
1104 .xlevel = 0x80000008,
1105 .model_id = "Intel Core i7 9xx (Nehalem Core i7, IBRS update)",
1106 },
1107 {
1108 .name = "Westmere",
1109 .level = 11,
1110 .vendor = CPUID_VENDOR_INTEL,
1111 .family = 6,
1112 .model = 44,
1113 .stepping = 1,
1114 .features[FEAT_1_EDX] =
1115 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1116 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1117 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1118 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1119 CPUID_DE | CPUID_FP87,
1120 .features[FEAT_1_ECX] =
1121 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1122 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1123 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1124 .features[FEAT_8000_0001_EDX] =
1125 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1126 .features[FEAT_8000_0001_ECX] =
1127 CPUID_EXT3_LAHF_LM,
1128 .features[FEAT_6_EAX] =
1129 CPUID_6_EAX_ARAT,
1130 .xlevel = 0x80000008,
1131 .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
1132 },
1133 {
1134 .name = "Westmere-IBRS",
1135 .level = 11,
1136 .vendor = CPUID_VENDOR_INTEL,
1137 .family = 6,
1138 .model = 44,
1139 .stepping = 1,
1140 .features[FEAT_1_EDX] =
1141 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1142 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1143 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1144 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1145 CPUID_DE | CPUID_FP87,
1146 .features[FEAT_1_ECX] =
1147 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1148 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1149 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1150 .features[FEAT_8000_0001_EDX] =
1151 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1152 .features[FEAT_8000_0001_ECX] =
1153 CPUID_EXT3_LAHF_LM,
1154 .features[FEAT_7_0_EDX] =
1155 CPUID_7_0_EDX_SPEC_CTRL,
1156 .features[FEAT_6_EAX] =
1157 CPUID_6_EAX_ARAT,
1158 .xlevel = 0x80000008,
1159 .model_id = "Westmere E56xx/L56xx/X56xx (IBRS update)",
1160 },
1161 {
1162 .name = "SandyBridge",
1163 .level = 0xd,
1164 .vendor = CPUID_VENDOR_INTEL,
1165 .family = 6,
1166 .model = 42,
1167 .stepping = 1,
1168 .features[FEAT_1_EDX] =
1169 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1170 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1171 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1172 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1173 CPUID_DE | CPUID_FP87,
1174 .features[FEAT_1_ECX] =
1175 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1176 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1177 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1178 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1179 CPUID_EXT_SSE3,
1180 .features[FEAT_8000_0001_EDX] =
1181 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1182 CPUID_EXT2_SYSCALL,
1183 .features[FEAT_8000_0001_ECX] =
1184 CPUID_EXT3_LAHF_LM,
1185 .features[FEAT_XSAVE] =
1186 CPUID_XSAVE_XSAVEOPT,
1187 .features[FEAT_6_EAX] =
1188 CPUID_6_EAX_ARAT,
1189 .xlevel = 0x80000008,
1190 .model_id = "Intel Xeon E312xx (Sandy Bridge)",
1191 },
1192 {
1193 .name = "SandyBridge-IBRS",
1194 .level = 0xd,
1195 .vendor = CPUID_VENDOR_INTEL,
1196 .family = 6,
1197 .model = 42,
1198 .stepping = 1,
1199 .features[FEAT_1_EDX] =
1200 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1201 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1202 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1203 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1204 CPUID_DE | CPUID_FP87,
1205 .features[FEAT_1_ECX] =
1206 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1207 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1208 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1209 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1210 CPUID_EXT_SSE3,
1211 .features[FEAT_8000_0001_EDX] =
1212 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1213 CPUID_EXT2_SYSCALL,
1214 .features[FEAT_8000_0001_ECX] =
1215 CPUID_EXT3_LAHF_LM,
1216 .features[FEAT_7_0_EDX] =
1217 CPUID_7_0_EDX_SPEC_CTRL,
1218 .features[FEAT_XSAVE] =
1219 CPUID_XSAVE_XSAVEOPT,
1220 .features[FEAT_6_EAX] =
1221 CPUID_6_EAX_ARAT,
1222 .xlevel = 0x80000008,
1223 .model_id = "Intel Xeon E312xx (Sandy Bridge, IBRS update)",
1224 },
1225 {
1226 .name = "IvyBridge",
1227 .level = 0xd,
1228 .vendor = CPUID_VENDOR_INTEL,
1229 .family = 6,
1230 .model = 58,
1231 .stepping = 9,
1232 .features[FEAT_1_EDX] =
1233 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1234 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1235 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1236 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1237 CPUID_DE | CPUID_FP87,
1238 .features[FEAT_1_ECX] =
1239 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1240 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1241 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1242 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1243 CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1244 .features[FEAT_7_0_EBX] =
1245 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
1246 CPUID_7_0_EBX_ERMS,
1247 .features[FEAT_8000_0001_EDX] =
1248 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1249 CPUID_EXT2_SYSCALL,
1250 .features[FEAT_8000_0001_ECX] =
1251 CPUID_EXT3_LAHF_LM,
1252 .features[FEAT_XSAVE] =
1253 CPUID_XSAVE_XSAVEOPT,
1254 .features[FEAT_6_EAX] =
1255 CPUID_6_EAX_ARAT,
1256 .xlevel = 0x80000008,
1257 .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
1258 },
1259 {
1260 .name = "IvyBridge-IBRS",
1261 .level = 0xd,
1262 .vendor = CPUID_VENDOR_INTEL,
1263 .family = 6,
1264 .model = 58,
1265 .stepping = 9,
1266 .features[FEAT_1_EDX] =
1267 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1268 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1269 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1270 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1271 CPUID_DE | CPUID_FP87,
1272 .features[FEAT_1_ECX] =
1273 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1274 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1275 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1276 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1277 CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1278 .features[FEAT_7_0_EBX] =
1279 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
1280 CPUID_7_0_EBX_ERMS,
1281 .features[FEAT_8000_0001_EDX] =
1282 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1283 CPUID_EXT2_SYSCALL,
1284 .features[FEAT_8000_0001_ECX] =
1285 CPUID_EXT3_LAHF_LM,
1286 .features[FEAT_7_0_EDX] =
1287 CPUID_7_0_EDX_SPEC_CTRL,
1288 .features[FEAT_XSAVE] =
1289 CPUID_XSAVE_XSAVEOPT,
1290 .features[FEAT_6_EAX] =
1291 CPUID_6_EAX_ARAT,
1292 .xlevel = 0x80000008,
1293 .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge, IBRS)",
1294 },
1295 {
1296 .name = "Haswell-noTSX",
1297 .level = 0xd,
1298 .vendor = CPUID_VENDOR_INTEL,
1299 .family = 6,
1300 .model = 60,
1301 .stepping = 1,
1302 .features[FEAT_1_EDX] =
1303 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1304 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1305 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1306 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1307 CPUID_DE | CPUID_FP87,
1308 .features[FEAT_1_ECX] =
1309 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1310 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1311 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1312 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1313 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1314 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1315 .features[FEAT_8000_0001_EDX] =
1316 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1317 CPUID_EXT2_SYSCALL,
1318 .features[FEAT_8000_0001_ECX] =
1319 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
1320 .features[FEAT_7_0_EBX] =
1321 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1322 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1323 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
1324 .features[FEAT_XSAVE] =
1325 CPUID_XSAVE_XSAVEOPT,
1326 .features[FEAT_6_EAX] =
1327 CPUID_6_EAX_ARAT,
1328 .xlevel = 0x80000008,
1329 .model_id = "Intel Core Processor (Haswell, no TSX)",
1330 },
1331 {
1332 .name = "Haswell-noTSX-IBRS",
1333 .level = 0xd,
1334 .vendor = CPUID_VENDOR_INTEL,
1335 .family = 6,
1336 .model = 60,
1337 .stepping = 1,
1338 .features[FEAT_1_EDX] =
1339 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1340 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1341 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1342 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1343 CPUID_DE | CPUID_FP87,
1344 .features[FEAT_1_ECX] =
1345 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1346 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1347 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1348 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1349 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1350 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1351 .features[FEAT_8000_0001_EDX] =
1352 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1353 CPUID_EXT2_SYSCALL,
1354 .features[FEAT_8000_0001_ECX] =
1355 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
1356 .features[FEAT_7_0_EDX] =
1357 CPUID_7_0_EDX_SPEC_CTRL,
1358 .features[FEAT_7_0_EBX] =
1359 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1360 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1361 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
1362 .features[FEAT_XSAVE] =
1363 CPUID_XSAVE_XSAVEOPT,
1364 .features[FEAT_6_EAX] =
1365 CPUID_6_EAX_ARAT,
1366 .xlevel = 0x80000008,
1367 .model_id = "Intel Core Processor (Haswell, no TSX, IBRS)",
1368 },
1369 {
1370 .name = "Haswell",
1371 .level = 0xd,
1372 .vendor = CPUID_VENDOR_INTEL,
1373 .family = 6,
1374 .model = 60,
1375 .stepping = 4,
1376 .features[FEAT_1_EDX] =
1377 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1378 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1379 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1380 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1381 CPUID_DE | CPUID_FP87,
1382 .features[FEAT_1_ECX] =
1383 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1384 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1385 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1386 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1387 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1388 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1389 .features[FEAT_8000_0001_EDX] =
1390 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1391 CPUID_EXT2_SYSCALL,
1392 .features[FEAT_8000_0001_ECX] =
1393 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
1394 .features[FEAT_7_0_EBX] =
1395 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1396 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1397 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1398 CPUID_7_0_EBX_RTM,
1399 .features[FEAT_XSAVE] =
1400 CPUID_XSAVE_XSAVEOPT,
1401 .features[FEAT_6_EAX] =
1402 CPUID_6_EAX_ARAT,
1403 .xlevel = 0x80000008,
1404 .model_id = "Intel Core Processor (Haswell)",
1405 },
1406 {
1407 .name = "Haswell-IBRS",
1408 .level = 0xd,
1409 .vendor = CPUID_VENDOR_INTEL,
1410 .family = 6,
1411 .model = 60,
1412 .stepping = 4,
1413 .features[FEAT_1_EDX] =
1414 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1415 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1416 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1417 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1418 CPUID_DE | CPUID_FP87,
1419 .features[FEAT_1_ECX] =
1420 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1421 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1422 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1423 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1424 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1425 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1426 .features[FEAT_8000_0001_EDX] =
1427 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1428 CPUID_EXT2_SYSCALL,
1429 .features[FEAT_8000_0001_ECX] =
1430 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
1431 .features[FEAT_7_0_EDX] =
1432 CPUID_7_0_EDX_SPEC_CTRL,
1433 .features[FEAT_7_0_EBX] =
1434 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1435 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1436 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1437 CPUID_7_0_EBX_RTM,
1438 .features[FEAT_XSAVE] =
1439 CPUID_XSAVE_XSAVEOPT,
1440 .features[FEAT_6_EAX] =
1441 CPUID_6_EAX_ARAT,
1442 .xlevel = 0x80000008,
1443 .model_id = "Intel Core Processor (Haswell, IBRS)",
1444 },
1445 {
1446 .name = "Broadwell-noTSX",
1447 .level = 0xd,
1448 .vendor = CPUID_VENDOR_INTEL,
1449 .family = 6,
1450 .model = 61,
1451 .stepping = 2,
1452 .features[FEAT_1_EDX] =
1453 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1454 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1455 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1456 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1457 CPUID_DE | CPUID_FP87,
1458 .features[FEAT_1_ECX] =
1459 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1460 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1461 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1462 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1463 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1464 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1465 .features[FEAT_8000_0001_EDX] =
1466 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1467 CPUID_EXT2_SYSCALL,
1468 .features[FEAT_8000_0001_ECX] =
1469 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
1470 .features[FEAT_7_0_EBX] =
1471 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1472 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1473 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1474 CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1475 CPUID_7_0_EBX_SMAP,
1476 .features[FEAT_XSAVE] =
1477 CPUID_XSAVE_XSAVEOPT,
1478 .features[FEAT_6_EAX] =
1479 CPUID_6_EAX_ARAT,
1480 .xlevel = 0x80000008,
1481 .model_id = "Intel Core Processor (Broadwell, no TSX)",
1482 },
1483 {
1484 .name = "Broadwell-noTSX-IBRS",
1485 .level = 0xd,
1486 .vendor = CPUID_VENDOR_INTEL,
1487 .family = 6,
1488 .model = 61,
1489 .stepping = 2,
1490 .features[FEAT_1_EDX] =
1491 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1492 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1493 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1494 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1495 CPUID_DE | CPUID_FP87,
1496 .features[FEAT_1_ECX] =
1497 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1498 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1499 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1500 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1501 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1502 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1503 .features[FEAT_8000_0001_EDX] =
1504 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1505 CPUID_EXT2_SYSCALL,
1506 .features[FEAT_8000_0001_ECX] =
1507 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
1508 .features[FEAT_7_0_EDX] =
1509 CPUID_7_0_EDX_SPEC_CTRL,
1510 .features[FEAT_7_0_EBX] =
1511 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1512 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1513 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1514 CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1515 CPUID_7_0_EBX_SMAP,
1516 .features[FEAT_XSAVE] =
1517 CPUID_XSAVE_XSAVEOPT,
1518 .features[FEAT_6_EAX] =
1519 CPUID_6_EAX_ARAT,
1520 .xlevel = 0x80000008,
1521 .model_id = "Intel Core Processor (Broadwell, no TSX, IBRS)",
1522 },
1523 {
1524 .name = "Broadwell",
1525 .level = 0xd,
1526 .vendor = CPUID_VENDOR_INTEL,
1527 .family = 6,
1528 .model = 61,
1529 .stepping = 2,
1530 .features[FEAT_1_EDX] =
1531 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1532 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1533 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1534 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1535 CPUID_DE | CPUID_FP87,
1536 .features[FEAT_1_ECX] =
1537 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1538 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1539 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1540 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1541 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1542 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1543 .features[FEAT_8000_0001_EDX] =
1544 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1545 CPUID_EXT2_SYSCALL,
1546 .features[FEAT_8000_0001_ECX] =
1547 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
1548 .features[FEAT_7_0_EBX] =
1549 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1550 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1551 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1552 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1553 CPUID_7_0_EBX_SMAP,
1554 .features[FEAT_XSAVE] =
1555 CPUID_XSAVE_XSAVEOPT,
1556 .features[FEAT_6_EAX] =
1557 CPUID_6_EAX_ARAT,
1558 .xlevel = 0x80000008,
1559 .model_id = "Intel Core Processor (Broadwell)",
1560 },
1561 {
1562 .name = "Broadwell-IBRS",
1563 .level = 0xd,
1564 .vendor = CPUID_VENDOR_INTEL,
1565 .family = 6,
1566 .model = 61,
1567 .stepping = 2,
1568 .features[FEAT_1_EDX] =
1569 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1570 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1571 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1572 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1573 CPUID_DE | CPUID_FP87,
1574 .features[FEAT_1_ECX] =
1575 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1576 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1577 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1578 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1579 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1580 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1581 .features[FEAT_8000_0001_EDX] =
1582 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1583 CPUID_EXT2_SYSCALL,
1584 .features[FEAT_8000_0001_ECX] =
1585 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
1586 .features[FEAT_7_0_EDX] =
1587 CPUID_7_0_EDX_SPEC_CTRL,
1588 .features[FEAT_7_0_EBX] =
1589 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1590 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1591 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1592 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1593 CPUID_7_0_EBX_SMAP,
1594 .features[FEAT_XSAVE] =
1595 CPUID_XSAVE_XSAVEOPT,
1596 .features[FEAT_6_EAX] =
1597 CPUID_6_EAX_ARAT,
1598 .xlevel = 0x80000008,
1599 .model_id = "Intel Core Processor (Broadwell, IBRS)",
1600 },
1601 {
1602 .name = "Skylake-Client",
1603 .level = 0xd,
1604 .vendor = CPUID_VENDOR_INTEL,
1605 .family = 6,
1606 .model = 94,
1607 .stepping = 3,
1608 .features[FEAT_1_EDX] =
1609 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1610 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1611 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1612 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1613 CPUID_DE | CPUID_FP87,
1614 .features[FEAT_1_ECX] =
1615 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1616 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1617 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1618 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1619 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1620 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1621 .features[FEAT_8000_0001_EDX] =
1622 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1623 CPUID_EXT2_SYSCALL,
1624 .features[FEAT_8000_0001_ECX] =
1625 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
1626 .features[FEAT_7_0_EBX] =
1627 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1628 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1629 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1630 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1631 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
1632 /* Missing: XSAVES (not supported by some Linux versions,
1633 * including v4.1 to v4.12).
1634 * KVM doesn't yet expose any XSAVES state save component,
1635 * and the only one defined in Skylake (processor tracing)
1636 * probably will block migration anyway.
1637 */
1638 .features[FEAT_XSAVE] =
1639 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
1640 CPUID_XSAVE_XGETBV1,
1641 .features[FEAT_6_EAX] =
1642 CPUID_6_EAX_ARAT,
1643 .xlevel = 0x80000008,
1644 .model_id = "Intel Core Processor (Skylake)",
1645 },
1646 {
1647 .name = "Skylake-Client-IBRS",
1648 .level = 0xd,
1649 .vendor = CPUID_VENDOR_INTEL,
1650 .family = 6,
1651 .model = 94,
1652 .stepping = 3,
1653 .features[FEAT_1_EDX] =
1654 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1655 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1656 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1657 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1658 CPUID_DE | CPUID_FP87,
1659 .features[FEAT_1_ECX] =
1660 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1661 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1662 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1663 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1664 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1665 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1666 .features[FEAT_8000_0001_EDX] =
1667 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1668 CPUID_EXT2_SYSCALL,
1669 .features[FEAT_8000_0001_ECX] =
1670 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
1671 .features[FEAT_7_0_EDX] =
1672 CPUID_7_0_EDX_SPEC_CTRL,
1673 .features[FEAT_7_0_EBX] =
1674 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1675 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1676 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1677 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1678 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
1679 /* Missing: XSAVES (not supported by some Linux versions,
1680 * including v4.1 to v4.12).
1681 * KVM doesn't yet expose any XSAVES state save component,
1682 * and the only one defined in Skylake (processor tracing)
1683 * probably will block migration anyway.
1684 */
1685 .features[FEAT_XSAVE] =
1686 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
1687 CPUID_XSAVE_XGETBV1,
1688 .features[FEAT_6_EAX] =
1689 CPUID_6_EAX_ARAT,
1690 .xlevel = 0x80000008,
1691 .model_id = "Intel Core Processor (Skylake, IBRS)",
1692 },
1693 {
1694 .name = "Skylake-Server",
1695 .level = 0xd,
1696 .vendor = CPUID_VENDOR_INTEL,
1697 .family = 6,
1698 .model = 85,
1699 .stepping = 4,
1700 .features[FEAT_1_EDX] =
1701 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1702 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1703 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1704 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1705 CPUID_DE | CPUID_FP87,
1706 .features[FEAT_1_ECX] =
1707 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1708 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1709 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1710 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1711 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1712 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1713 .features[FEAT_8000_0001_EDX] =
1714 CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
1715 CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
1716 .features[FEAT_8000_0001_ECX] =
1717 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
1718 .features[FEAT_7_0_EBX] =
1719 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1720 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1721 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1722 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1723 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
1724 CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
1725 CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
1726 CPUID_7_0_EBX_AVX512VL,
1727 /* Missing: XSAVES (not supported by some Linux versions,
1728 * including v4.1 to v4.12).
1729 * KVM doesn't yet expose any XSAVES state save component,
1730 * and the only one defined in Skylake (processor tracing)
1731 * probably will block migration anyway.
1732 */
1733 .features[FEAT_XSAVE] =
1734 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
1735 CPUID_XSAVE_XGETBV1,
1736 .features[FEAT_6_EAX] =
1737 CPUID_6_EAX_ARAT,
1738 .xlevel = 0x80000008,
1739 .model_id = "Intel Xeon Processor (Skylake)",
1740 },
1741 {
1742 .name = "Skylake-Server-IBRS",
1743 .level = 0xd,
1744 .vendor = CPUID_VENDOR_INTEL,
1745 .family = 6,
1746 .model = 85,
1747 .stepping = 4,
1748 .features[FEAT_1_EDX] =
1749 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1750 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1751 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1752 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1753 CPUID_DE | CPUID_FP87,
1754 .features[FEAT_1_ECX] =
1755 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1756 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1757 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1758 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1759 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1760 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1761 .features[FEAT_8000_0001_EDX] =
1762 CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
1763 CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
1764 .features[FEAT_8000_0001_ECX] =
1765 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
1766 .features[FEAT_7_0_EDX] =
1767 CPUID_7_0_EDX_SPEC_CTRL,
1768 .features[FEAT_7_0_EBX] =
1769 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1770 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1771 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1772 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1773 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
1774 CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
1775 CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
1776 CPUID_7_0_EBX_AVX512VL,
1777 /* Missing: XSAVES (not supported by some Linux versions,
1778 * including v4.1 to v4.12).
1779 * KVM doesn't yet expose any XSAVES state save component,
1780 * and the only one defined in Skylake (processor tracing)
1781 * probably will block migration anyway.
1782 */
1783 .features[FEAT_XSAVE] =
1784 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
1785 CPUID_XSAVE_XGETBV1,
1786 .features[FEAT_6_EAX] =
1787 CPUID_6_EAX_ARAT,
1788 .xlevel = 0x80000008,
1789 .model_id = "Intel Xeon Processor (Skylake, IBRS)",
1790 },
1791 {
1792 .name = "Opteron_G1",
1793 .level = 5,
1794 .vendor = CPUID_VENDOR_AMD,
1795 .family = 15,
1796 .model = 6,
1797 .stepping = 1,
1798 .features[FEAT_1_EDX] =
1799 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1800 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1801 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1802 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1803 CPUID_DE | CPUID_FP87,
1804 .features[FEAT_1_ECX] =
1805 CPUID_EXT_SSE3,
1806 .features[FEAT_8000_0001_EDX] =
1807 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
1808 .xlevel = 0x80000008,
1809 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
1810 },
1811 {
1812 .name = "Opteron_G2",
1813 .level = 5,
1814 .vendor = CPUID_VENDOR_AMD,
1815 .family = 15,
1816 .model = 6,
1817 .stepping = 1,
1818 .features[FEAT_1_EDX] =
1819 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1820 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1821 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1822 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1823 CPUID_DE | CPUID_FP87,
1824 .features[FEAT_1_ECX] =
1825 CPUID_EXT_CX16 | CPUID_EXT_SSE3,
1826 /* Missing: CPUID_EXT2_RDTSCP */
1827 .features[FEAT_8000_0001_EDX] =
1828 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
1829 .features[FEAT_8000_0001_ECX] =
1830 CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
1831 .xlevel = 0x80000008,
1832 .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
1833 },
1834 {
1835 .name = "Opteron_G3",
1836 .level = 5,
1837 .vendor = CPUID_VENDOR_AMD,
1838 .family = 16,
1839 .model = 2,
1840 .stepping = 3,
1841 .features[FEAT_1_EDX] =
1842 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1843 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1844 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1845 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1846 CPUID_DE | CPUID_FP87,
1847 .features[FEAT_1_ECX] =
1848 CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
1849 CPUID_EXT_SSE3,
1850 /* Missing: CPUID_EXT2_RDTSCP */
1851 .features[FEAT_8000_0001_EDX] =
1852 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
1853 .features[FEAT_8000_0001_ECX] =
1854 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
1855 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
1856 .xlevel = 0x80000008,
1857 .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
1858 },
1859 {
1860 .name = "Opteron_G4",
1861 .level = 0xd,
1862 .vendor = CPUID_VENDOR_AMD,
1863 .family = 21,
1864 .model = 1,
1865 .stepping = 2,
1866 .features[FEAT_1_EDX] =
1867 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1868 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1869 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1870 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1871 CPUID_DE | CPUID_FP87,
1872 .features[FEAT_1_ECX] =
1873 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1874 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1875 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1876 CPUID_EXT_SSE3,
1877 /* Missing: CPUID_EXT2_RDTSCP */
1878 .features[FEAT_8000_0001_EDX] =
1879 CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_NX |
1880 CPUID_EXT2_SYSCALL,
1881 .features[FEAT_8000_0001_ECX] =
1882 CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1883 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1884 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1885 CPUID_EXT3_LAHF_LM,
1886 /* no xsaveopt! */
1887 .xlevel = 0x8000001A,
1888 .model_id = "AMD Opteron 62xx class CPU",
1889 },
1890 {
1891 .name = "Opteron_G5",
1892 .level = 0xd,
1893 .vendor = CPUID_VENDOR_AMD,
1894 .family = 21,
1895 .model = 2,
1896 .stepping = 0,
1897 .features[FEAT_1_EDX] =
1898 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1899 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1900 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1901 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1902 CPUID_DE | CPUID_FP87,
1903 .features[FEAT_1_ECX] =
1904 CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
1905 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1906 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
1907 CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1908 /* Missing: CPUID_EXT2_RDTSCP */
1909 .features[FEAT_8000_0001_EDX] =
1910 CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_NX |
1911 CPUID_EXT2_SYSCALL,
1912 .features[FEAT_8000_0001_ECX] =
1913 CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1914 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1915 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1916 CPUID_EXT3_LAHF_LM,
1917 /* no xsaveopt! */
1918 .xlevel = 0x8000001A,
1919 .model_id = "AMD Opteron 63xx class CPU",
1920 },
1921 {
1922 .name = "EPYC",
1923 .level = 0xd,
1924 .vendor = CPUID_VENDOR_AMD,
1925 .family = 23,
1926 .model = 1,
1927 .stepping = 2,
1928 .features[FEAT_1_EDX] =
1929 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
1930 CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
1931 CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
1932 CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
1933 CPUID_VME | CPUID_FP87,
1934 .features[FEAT_1_ECX] =
1935 CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
1936 CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT |
1937 CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1938 CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
1939 CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1940 .features[FEAT_8000_0001_EDX] =
1941 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
1942 CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
1943 CPUID_EXT2_SYSCALL,
1944 .features[FEAT_8000_0001_ECX] =
1945 CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
1946 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
1947 CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
1948 .features[FEAT_7_0_EBX] =
1949 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
1950 CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
1951 CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
1952 CPUID_7_0_EBX_SHA_NI,
1953 /* Missing: XSAVES (not supported by some Linux versions,
1954 * including v4.1 to v4.12).
1955 * KVM doesn't yet expose any XSAVES state save component.
1956 */
1957 .features[FEAT_XSAVE] =
1958 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
1959 CPUID_XSAVE_XGETBV1,
1960 .features[FEAT_6_EAX] =
1961 CPUID_6_EAX_ARAT,
1962 .xlevel = 0x8000000A,
1963 .model_id = "AMD EPYC Processor",
1964 },
1965 {
1966 .name = "EPYC-IBPB",
1967 .level = 0xd,
1968 .vendor = CPUID_VENDOR_AMD,
1969 .family = 23,
1970 .model = 1,
1971 .stepping = 2,
1972 .features[FEAT_1_EDX] =
1973 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
1974 CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
1975 CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
1976 CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
1977 CPUID_VME | CPUID_FP87,
1978 .features[FEAT_1_ECX] =
1979 CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
1980 CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT |
1981 CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1982 CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
1983 CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1984 .features[FEAT_8000_0001_EDX] =
1985 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
1986 CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
1987 CPUID_EXT2_SYSCALL,
1988 .features[FEAT_8000_0001_ECX] =
1989 CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
1990 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
1991 CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
1992 .features[FEAT_8000_0008_EBX] =
1993 CPUID_8000_0008_EBX_IBPB,
1994 .features[FEAT_7_0_EBX] =
1995 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
1996 CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
1997 CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
1998 CPUID_7_0_EBX_SHA_NI,
1999 /* Missing: XSAVES (not supported by some Linux versions,
2000 * including v4.1 to v4.12).
2001 * KVM doesn't yet expose any XSAVES state save component.
2002 */
2003 .features[FEAT_XSAVE] =
2004 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2005 CPUID_XSAVE_XGETBV1,
2006 .features[FEAT_6_EAX] =
2007 CPUID_6_EAX_ARAT,
2008 .xlevel = 0x8000000A,
2009 .model_id = "AMD EPYC Processor (with IBPB)",
2010 },
2011 };
2012
2013 typedef struct PropValue {
2014 const char *prop, *value;
2015 } PropValue;
2016
2017 /* KVM-specific features that are automatically added/removed
2018 * from all CPU models when KVM is enabled.
2019 */
2020 static PropValue kvm_default_props[] = {
2021 { "kvmclock", "on" },
2022 { "kvm-nopiodelay", "on" },
2023 { "kvm-asyncpf", "on" },
2024 { "kvm-steal-time", "on" },
2025 { "kvm-pv-eoi", "on" },
2026 { "kvmclock-stable-bit", "on" },
2027 { "x2apic", "on" },
2028 { "acpi", "off" },
2029 { "monitor", "off" },
2030 { "svm", "off" },
2031 { NULL, NULL },
2032 };
2033
2034 /* TCG-specific defaults that override all CPU models when using TCG
2035 */
2036 static PropValue tcg_default_props[] = {
2037 { "vme", "off" },
2038 { NULL, NULL },
2039 };
2040
2041
2042 void x86_cpu_change_kvm_default(const char *prop, const char *value)
2043 {
2044 PropValue *pv;
2045 for (pv = kvm_default_props; pv->prop; pv++) {
2046 if (!strcmp(pv->prop, prop)) {
2047 pv->value = value;
2048 break;
2049 }
2050 }
2051
2052 /* It is valid to call this function only for properties that
2053 * are already present in the kvm_default_props table.
2054 */
2055 assert(pv->prop);
2056 }
2057
2058 static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
2059 bool migratable_only);
2060
2061 static bool lmce_supported(void)
2062 {
2063 uint64_t mce_cap = 0;
2064
2065 #ifdef CONFIG_KVM
2066 if (kvm_ioctl(kvm_state, KVM_X86_GET_MCE_CAP_SUPPORTED, &mce_cap) < 0) {
2067 return false;
2068 }
2069 #endif
2070
2071 return !!(mce_cap & MCG_LMCE_P);
2072 }
2073
2074 #define CPUID_MODEL_ID_SZ 48
2075
2076 /**
2077 * cpu_x86_fill_model_id:
2078 * Get CPUID model ID string from host CPU.
2079 *
2080 * @str should have at least CPUID_MODEL_ID_SZ bytes
2081 *
2082 * The function does NOT add a null terminator to the string
2083 * automatically.
2084 */
2085 static int cpu_x86_fill_model_id(char *str)
2086 {
2087 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
2088 int i;
2089
2090 for (i = 0; i < 3; i++) {
2091 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
2092 memcpy(str + i * 16 + 0, &eax, 4);
2093 memcpy(str + i * 16 + 4, &ebx, 4);
2094 memcpy(str + i * 16 + 8, &ecx, 4);
2095 memcpy(str + i * 16 + 12, &edx, 4);
2096 }
2097 return 0;
2098 }
2099
2100 static Property max_x86_cpu_properties[] = {
2101 DEFINE_PROP_BOOL("migratable", X86CPU, migratable, true),
2102 DEFINE_PROP_BOOL("host-cache-info", X86CPU, cache_info_passthrough, false),
2103 DEFINE_PROP_END_OF_LIST()
2104 };
2105
2106 static void max_x86_cpu_class_init(ObjectClass *oc, void *data)
2107 {
2108 DeviceClass *dc = DEVICE_CLASS(oc);
2109 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2110
2111 xcc->ordering = 9;
2112
2113 xcc->model_description =
2114 "Enables all features supported by the accelerator in the current host";
2115
2116 dc->props = max_x86_cpu_properties;
2117 }
2118
2119 static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp);
2120
2121 static void max_x86_cpu_initfn(Object *obj)
2122 {
2123 X86CPU *cpu = X86_CPU(obj);
2124 CPUX86State *env = &cpu->env;
2125 KVMState *s = kvm_state;
2126
2127 /* We can't fill the features array here because we don't know yet if
2128 * "migratable" is true or false.
2129 */
2130 cpu->max_features = true;
2131
2132 if (kvm_enabled()) {
2133 char vendor[CPUID_VENDOR_SZ + 1] = { 0 };
2134 char model_id[CPUID_MODEL_ID_SZ + 1] = { 0 };
2135 int family, model, stepping;
2136
2137 host_vendor_fms(vendor, &family, &model, &stepping);
2138
2139 cpu_x86_fill_model_id(model_id);
2140
2141 object_property_set_str(OBJECT(cpu), vendor, "vendor", &error_abort);
2142 object_property_set_int(OBJECT(cpu), family, "family", &error_abort);
2143 object_property_set_int(OBJECT(cpu), model, "model", &error_abort);
2144 object_property_set_int(OBJECT(cpu), stepping, "stepping",
2145 &error_abort);
2146 object_property_set_str(OBJECT(cpu), model_id, "model-id",
2147 &error_abort);
2148
2149 env->cpuid_min_level =
2150 kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
2151 env->cpuid_min_xlevel =
2152 kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
2153 env->cpuid_min_xlevel2 =
2154 kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
2155
2156 if (lmce_supported()) {
2157 object_property_set_bool(OBJECT(cpu), true, "lmce", &error_abort);
2158 }
2159 } else {
2160 object_property_set_str(OBJECT(cpu), CPUID_VENDOR_AMD,
2161 "vendor", &error_abort);
2162 object_property_set_int(OBJECT(cpu), 6, "family", &error_abort);
2163 object_property_set_int(OBJECT(cpu), 6, "model", &error_abort);
2164 object_property_set_int(OBJECT(cpu), 3, "stepping", &error_abort);
2165 object_property_set_str(OBJECT(cpu),
2166 "QEMU TCG CPU version " QEMU_HW_VERSION,
2167 "model-id", &error_abort);
2168 }
2169
2170 object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
2171 }
2172
2173 static const TypeInfo max_x86_cpu_type_info = {
2174 .name = X86_CPU_TYPE_NAME("max"),
2175 .parent = TYPE_X86_CPU,
2176 .instance_init = max_x86_cpu_initfn,
2177 .class_init = max_x86_cpu_class_init,
2178 };
2179
2180 #ifdef CONFIG_KVM
2181
2182 static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
2183 {
2184 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2185
2186 xcc->kvm_required = true;
2187 xcc->ordering = 8;
2188
2189 xcc->model_description =
2190 "KVM processor with all supported host features "
2191 "(only available in KVM mode)";
2192 }
2193
2194 static const TypeInfo host_x86_cpu_type_info = {
2195 .name = X86_CPU_TYPE_NAME("host"),
2196 .parent = X86_CPU_TYPE_NAME("max"),
2197 .class_init = host_x86_cpu_class_init,
2198 };
2199
2200 #endif
2201
2202 static void report_unavailable_features(FeatureWord w, uint32_t mask)
2203 {
2204 FeatureWordInfo *f = &feature_word_info[w];
2205 int i;
2206
2207 for (i = 0; i < 32; ++i) {
2208 if ((1UL << i) & mask) {
2209 const char *reg = get_register_name_32(f->cpuid_reg);
2210 assert(reg);
2211 warn_report("%s doesn't support requested feature: "
2212 "CPUID.%02XH:%s%s%s [bit %d]",
2213 kvm_enabled() ? "host" : "TCG",
2214 f->cpuid_eax, reg,
2215 f->feat_names[i] ? "." : "",
2216 f->feat_names[i] ? f->feat_names[i] : "", i);
2217 }
2218 }
2219 }
2220
2221 static void x86_cpuid_version_get_family(Object *obj, Visitor *v,
2222 const char *name, void *opaque,
2223 Error **errp)
2224 {
2225 X86CPU *cpu = X86_CPU(obj);
2226 CPUX86State *env = &cpu->env;
2227 int64_t value;
2228
2229 value = (env->cpuid_version >> 8) & 0xf;
2230 if (value == 0xf) {
2231 value += (env->cpuid_version >> 20) & 0xff;
2232 }
2233 visit_type_int(v, name, &value, errp);
2234 }
2235
2236 static void x86_cpuid_version_set_family(Object *obj, Visitor *v,
2237 const char *name, void *opaque,
2238 Error **errp)
2239 {
2240 X86CPU *cpu = X86_CPU(obj);
2241 CPUX86State *env = &cpu->env;
2242 const int64_t min = 0;
2243 const int64_t max = 0xff + 0xf;
2244 Error *local_err = NULL;
2245 int64_t value;
2246
2247 visit_type_int(v, name, &value, &local_err);
2248 if (local_err) {
2249 error_propagate(errp, local_err);
2250 return;
2251 }
2252 if (value < min || value > max) {
2253 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
2254 name ? name : "null", value, min, max);
2255 return;
2256 }
2257
2258 env->cpuid_version &= ~0xff00f00;
2259 if (value > 0x0f) {
2260 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
2261 } else {
2262 env->cpuid_version |= value << 8;
2263 }
2264 }
2265
2266 static void x86_cpuid_version_get_model(Object *obj, Visitor *v,
2267 const char *name, void *opaque,
2268 Error **errp)
2269 {
2270 X86CPU *cpu = X86_CPU(obj);
2271 CPUX86State *env = &cpu->env;
2272 int64_t value;
2273
2274 value = (env->cpuid_version >> 4) & 0xf;
2275 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
2276 visit_type_int(v, name, &value, errp);
2277 }
2278
2279 static void x86_cpuid_version_set_model(Object *obj, Visitor *v,
2280 const char *name, void *opaque,
2281 Error **errp)
2282 {
2283 X86CPU *cpu = X86_CPU(obj);
2284 CPUX86State *env = &cpu->env;
2285 const int64_t min = 0;
2286 const int64_t max = 0xff;
2287 Error *local_err = NULL;
2288 int64_t value;
2289
2290 visit_type_int(v, name, &value, &local_err);
2291 if (local_err) {
2292 error_propagate(errp, local_err);
2293 return;
2294 }
2295 if (value < min || value > max) {
2296 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
2297 name ? name : "null", value, min, max);
2298 return;
2299 }
2300
2301 env->cpuid_version &= ~0xf00f0;
2302 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
2303 }
2304
2305 static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
2306 const char *name, void *opaque,
2307 Error **errp)
2308 {
2309 X86CPU *cpu = X86_CPU(obj);
2310 CPUX86State *env = &cpu->env;
2311 int64_t value;
2312
2313 value = env->cpuid_version & 0xf;
2314 visit_type_int(v, name, &value, errp);
2315 }
2316
2317 static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
2318 const char *name, void *opaque,
2319 Error **errp)
2320 {
2321 X86CPU *cpu = X86_CPU(obj);
2322 CPUX86State *env = &cpu->env;
2323 const int64_t min = 0;
2324 const int64_t max = 0xf;
2325 Error *local_err = NULL;
2326 int64_t value;
2327
2328 visit_type_int(v, name, &value, &local_err);
2329 if (local_err) {
2330 error_propagate(errp, local_err);
2331 return;
2332 }
2333 if (value < min || value > max) {
2334 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
2335 name ? name : "null", value, min, max);
2336 return;
2337 }
2338
2339 env->cpuid_version &= ~0xf;
2340 env->cpuid_version |= value & 0xf;
2341 }
2342
2343 static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
2344 {
2345 X86CPU *cpu = X86_CPU(obj);
2346 CPUX86State *env = &cpu->env;
2347 char *value;
2348
2349 value = g_malloc(CPUID_VENDOR_SZ + 1);
2350 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
2351 env->cpuid_vendor3);
2352 return value;
2353 }
2354
2355 static void x86_cpuid_set_vendor(Object *obj, const char *value,
2356 Error **errp)
2357 {
2358 X86CPU *cpu = X86_CPU(obj);
2359 CPUX86State *env = &cpu->env;
2360 int i;
2361
2362 if (strlen(value) != CPUID_VENDOR_SZ) {
2363 error_setg(errp, QERR_PROPERTY_VALUE_BAD, "", "vendor", value);
2364 return;
2365 }
2366
2367 env->cpuid_vendor1 = 0;
2368 env->cpuid_vendor2 = 0;
2369 env->cpuid_vendor3 = 0;
2370 for (i = 0; i < 4; i++) {
2371 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
2372 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
2373 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
2374 }
2375 }
2376
2377 static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
2378 {
2379 X86CPU *cpu = X86_CPU(obj);
2380 CPUX86State *env = &cpu->env;
2381 char *value;
2382 int i;
2383
2384 value = g_malloc(48 + 1);
2385 for (i = 0; i < 48; i++) {
2386 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
2387 }
2388 value[48] = '\0';
2389 return value;
2390 }
2391
2392 static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
2393 Error **errp)
2394 {
2395 X86CPU *cpu = X86_CPU(obj);
2396 CPUX86State *env = &cpu->env;
2397 int c, len, i;
2398
2399 if (model_id == NULL) {
2400 model_id = "";
2401 }
2402 len = strlen(model_id);
2403 memset(env->cpuid_model, 0, 48);
2404 for (i = 0; i < 48; i++) {
2405 if (i >= len) {
2406 c = '\0';
2407 } else {
2408 c = (uint8_t)model_id[i];
2409 }
2410 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
2411 }
2412 }
2413
2414 static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, const char *name,
2415 void *opaque, Error **errp)
2416 {
2417 X86CPU *cpu = X86_CPU(obj);
2418 int64_t value;
2419
2420 value = cpu->env.tsc_khz * 1000;
2421 visit_type_int(v, name, &value, errp);
2422 }
2423
2424 static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
2425 void *opaque, Error **errp)
2426 {
2427 X86CPU *cpu = X86_CPU(obj);
2428 const int64_t min = 0;
2429 const int64_t max = INT64_MAX;
2430 Error *local_err = NULL;
2431 int64_t value;
2432
2433 visit_type_int(v, name, &value, &local_err);
2434 if (local_err) {
2435 error_propagate(errp, local_err);
2436 return;
2437 }
2438 if (value < min || value > max) {
2439 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
2440 name ? name : "null", value, min, max);
2441 return;
2442 }
2443
2444 cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
2445 }
2446
2447 /* Generic getter for "feature-words" and "filtered-features" properties */
2448 static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
2449 const char *name, void *opaque,
2450 Error **errp)
2451 {
2452 uint32_t *array = (uint32_t *)opaque;
2453 FeatureWord w;
2454 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
2455 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
2456 X86CPUFeatureWordInfoList *list = NULL;
2457
2458 for (w = 0; w < FEATURE_WORDS; w++) {
2459 FeatureWordInfo *wi = &feature_word_info[w];
2460 X86CPUFeatureWordInfo *qwi = &word_infos[w];
2461 qwi->cpuid_input_eax = wi->cpuid_eax;
2462 qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
2463 qwi->cpuid_input_ecx = wi->cpuid_ecx;
2464 qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
2465 qwi->features = array[w];
2466
2467 /* List will be in reverse order, but order shouldn't matter */
2468 list_entries[w].next = list;
2469 list_entries[w].value = &word_infos[w];
2470 list = &list_entries[w];
2471 }
2472
2473 visit_type_X86CPUFeatureWordInfoList(v, "feature-words", &list, errp);
2474 }
2475
2476 static void x86_get_hv_spinlocks(Object *obj, Visitor *v, const char *name,
2477 void *opaque, Error **errp)
2478 {
2479 X86CPU *cpu = X86_CPU(obj);
2480 int64_t value = cpu->hyperv_spinlock_attempts;
2481
2482 visit_type_int(v, name, &value, errp);
2483 }
2484
2485 static void x86_set_hv_spinlocks(Object *obj, Visitor *v, const char *name,
2486 void *opaque, Error **errp)
2487 {
2488 const int64_t min = 0xFFF;
2489 const int64_t max = UINT_MAX;
2490 X86CPU *cpu = X86_CPU(obj);
2491 Error *err = NULL;
2492 int64_t value;
2493
2494 visit_type_int(v, name, &value, &err);
2495 if (err) {
2496 error_propagate(errp, err);
2497 return;
2498 }
2499
2500 if (value < min || value > max) {
2501 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
2502 " (minimum: %" PRId64 ", maximum: %" PRId64 ")",
2503 object_get_typename(obj), name ? name : "null",
2504 value, min, max);
2505 return;
2506 }
2507 cpu->hyperv_spinlock_attempts = value;
2508 }
2509
2510 static const PropertyInfo qdev_prop_spinlocks = {
2511 .name = "int",
2512 .get = x86_get_hv_spinlocks,
2513 .set = x86_set_hv_spinlocks,
2514 };
2515
2516 /* Convert all '_' in a feature string option name to '-', to make feature
2517 * name conform to QOM property naming rule, which uses '-' instead of '_'.
2518 */
2519 static inline void feat2prop(char *s)
2520 {
2521 while ((s = strchr(s, '_'))) {
2522 *s = '-';
2523 }
2524 }
2525
2526 /* Return the feature property name for a feature flag bit */
2527 static const char *x86_cpu_feature_name(FeatureWord w, int bitnr)
2528 {
2529 /* XSAVE components are automatically enabled by other features,
2530 * so return the original feature name instead
2531 */
2532 if (w == FEAT_XSAVE_COMP_LO || w == FEAT_XSAVE_COMP_HI) {
2533 int comp = (w == FEAT_XSAVE_COMP_HI) ? bitnr + 32 : bitnr;
2534
2535 if (comp < ARRAY_SIZE(x86_ext_save_areas) &&
2536 x86_ext_save_areas[comp].bits) {
2537 w = x86_ext_save_areas[comp].feature;
2538 bitnr = ctz32(x86_ext_save_areas[comp].bits);
2539 }
2540 }
2541
2542 assert(bitnr < 32);
2543 assert(w < FEATURE_WORDS);
2544 return feature_word_info[w].feat_names[bitnr];
2545 }
2546
2547 /* Compatibily hack to maintain legacy +-feat semantic,
2548 * where +-feat overwrites any feature set by
2549 * feat=on|feat even if the later is parsed after +-feat
2550 * (i.e. "-x2apic,x2apic=on" will result in x2apic disabled)
2551 */
2552 static GList *plus_features, *minus_features;
2553
2554 static gint compare_string(gconstpointer a, gconstpointer b)
2555 {
2556 return g_strcmp0(a, b);
2557 }
2558
2559 /* Parse "+feature,-feature,feature=foo" CPU feature string
2560 */
2561 static void x86_cpu_parse_featurestr(const char *typename, char *features,
2562 Error **errp)
2563 {
2564 char *featurestr; /* Single 'key=value" string being parsed */
2565 static bool cpu_globals_initialized;
2566 bool ambiguous = false;
2567
2568 if (cpu_globals_initialized) {
2569 return;
2570 }
2571 cpu_globals_initialized = true;
2572
2573 if (!features) {
2574 return;
2575 }
2576
2577 for (featurestr = strtok(features, ",");
2578 featurestr;
2579 featurestr = strtok(NULL, ",")) {
2580 const char *name;
2581 const char *val = NULL;
2582 char *eq = NULL;
2583 char num[32];
2584 GlobalProperty *prop;
2585
2586 /* Compatibility syntax: */
2587 if (featurestr[0] == '+') {
2588 plus_features = g_list_append(plus_features,
2589 g_strdup(featurestr + 1));
2590 continue;
2591 } else if (featurestr[0] == '-') {
2592 minus_features = g_list_append(minus_features,
2593 g_strdup(featurestr + 1));
2594 continue;
2595 }
2596
2597 eq = strchr(featurestr, '=');
2598 if (eq) {
2599 *eq++ = 0;
2600 val = eq;
2601 } else {
2602 val = "on";
2603 }
2604
2605 feat2prop(featurestr);
2606 name = featurestr;
2607
2608 if (g_list_find_custom(plus_features, name, compare_string)) {
2609 warn_report("Ambiguous CPU model string. "
2610 "Don't mix both \"+%s\" and \"%s=%s\"",
2611 name, name, val);
2612 ambiguous = true;
2613 }
2614 if (g_list_find_custom(minus_features, name, compare_string)) {
2615 warn_report("Ambiguous CPU model string. "
2616 "Don't mix both \"-%s\" and \"%s=%s\"",
2617 name, name, val);
2618 ambiguous = true;
2619 }
2620
2621 /* Special case: */
2622 if (!strcmp(name, "tsc-freq")) {
2623 int ret;
2624 uint64_t tsc_freq;
2625
2626 ret = qemu_strtosz_metric(val, NULL, &tsc_freq);
2627 if (ret < 0 || tsc_freq > INT64_MAX) {
2628 error_setg(errp, "bad numerical value %s", val);
2629 return;
2630 }
2631 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
2632 val = num;
2633 name = "tsc-frequency";
2634 }
2635
2636 prop = g_new0(typeof(*prop), 1);
2637 prop->driver = typename;
2638 prop->property = g_strdup(name);
2639 prop->value = g_strdup(val);
2640 prop->errp = &error_fatal;
2641 qdev_prop_register_global(prop);
2642 }
2643
2644 if (ambiguous) {
2645 warn_report("Compatibility of ambiguous CPU model "
2646 "strings won't be kept on future QEMU versions");
2647 }
2648 }
2649
2650 static void x86_cpu_expand_features(X86CPU *cpu, Error **errp);
2651 static int x86_cpu_filter_features(X86CPU *cpu);
2652
2653 /* Check for missing features that may prevent the CPU class from
2654 * running using the current machine and accelerator.
2655 */
2656 static void x86_cpu_class_check_missing_features(X86CPUClass *xcc,
2657 strList **missing_feats)
2658 {
2659 X86CPU *xc;
2660 FeatureWord w;
2661 Error *err = NULL;
2662 strList **next = missing_feats;
2663
2664 if (xcc->kvm_required && !kvm_enabled()) {
2665 strList *new = g_new0(strList, 1);
2666 new->value = g_strdup("kvm");;
2667 *missing_feats = new;
2668 return;
2669 }
2670
2671 xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc))));
2672
2673 x86_cpu_expand_features(xc, &err);
2674 if (err) {
2675 /* Errors at x86_cpu_expand_features should never happen,
2676 * but in case it does, just report the model as not
2677 * runnable at all using the "type" property.
2678 */
2679 strList *new = g_new0(strList, 1);
2680 new->value = g_strdup("type");
2681 *next = new;
2682 next = &new->next;
2683 }
2684
2685 x86_cpu_filter_features(xc);
2686
2687 for (w = 0; w < FEATURE_WORDS; w++) {
2688 uint32_t filtered = xc->filtered_features[w];
2689 int i;
2690 for (i = 0; i < 32; i++) {
2691 if (filtered & (1UL << i)) {
2692 strList *new = g_new0(strList, 1);
2693 new->value = g_strdup(x86_cpu_feature_name(w, i));
2694 *next = new;
2695 next = &new->next;
2696 }
2697 }
2698 }
2699
2700 object_unref(OBJECT(xc));
2701 }
2702
2703 /* Print all cpuid feature names in featureset
2704 */
2705 static void listflags(FILE *f, fprintf_function print, const char **featureset)
2706 {
2707 int bit;
2708 bool first = true;
2709
2710 for (bit = 0; bit < 32; bit++) {
2711 if (featureset[bit]) {
2712 print(f, "%s%s", first ? "" : " ", featureset[bit]);
2713 first = false;
2714 }
2715 }
2716 }
2717
2718 /* Sort alphabetically by type name, respecting X86CPUClass::ordering. */
2719 static gint x86_cpu_list_compare(gconstpointer a, gconstpointer b)
2720 {
2721 ObjectClass *class_a = (ObjectClass *)a;
2722 ObjectClass *class_b = (ObjectClass *)b;
2723 X86CPUClass *cc_a = X86_CPU_CLASS(class_a);
2724 X86CPUClass *cc_b = X86_CPU_CLASS(class_b);
2725 const char *name_a, *name_b;
2726
2727 if (cc_a->ordering != cc_b->ordering) {
2728 return cc_a->ordering - cc_b->ordering;
2729 } else {
2730 name_a = object_class_get_name(class_a);
2731 name_b = object_class_get_name(class_b);
2732 return strcmp(name_a, name_b);
2733 }
2734 }
2735
2736 static GSList *get_sorted_cpu_model_list(void)
2737 {
2738 GSList *list = object_class_get_list(TYPE_X86_CPU, false);
2739 list = g_slist_sort(list, x86_cpu_list_compare);
2740 return list;
2741 }
2742
2743 static void x86_cpu_list_entry(gpointer data, gpointer user_data)
2744 {
2745 ObjectClass *oc = data;
2746 X86CPUClass *cc = X86_CPU_CLASS(oc);
2747 CPUListState *s = user_data;
2748 char *name = x86_cpu_class_get_model_name(cc);
2749 const char *desc = cc->model_description;
2750 if (!desc && cc->cpu_def) {
2751 desc = cc->cpu_def->model_id;
2752 }
2753
2754 (*s->cpu_fprintf)(s->file, "x86 %16s %-48s\n",
2755 name, desc);
2756 g_free(name);
2757 }
2758
2759 /* list available CPU models and flags */
2760 void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
2761 {
2762 int i;
2763 CPUListState s = {
2764 .file = f,
2765 .cpu_fprintf = cpu_fprintf,
2766 };
2767 GSList *list;
2768
2769 (*cpu_fprintf)(f, "Available CPUs:\n");
2770 list = get_sorted_cpu_model_list();
2771 g_slist_foreach(list, x86_cpu_list_entry, &s);
2772 g_slist_free(list);
2773
2774 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
2775 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
2776 FeatureWordInfo *fw = &feature_word_info[i];
2777
2778 (*cpu_fprintf)(f, " ");
2779 listflags(f, cpu_fprintf, fw->feat_names);
2780 (*cpu_fprintf)(f, "\n");
2781 }
2782 }
2783
2784 static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
2785 {
2786 ObjectClass *oc = data;
2787 X86CPUClass *cc = X86_CPU_CLASS(oc);
2788 CpuDefinitionInfoList **cpu_list = user_data;
2789 CpuDefinitionInfoList *entry;
2790 CpuDefinitionInfo *info;
2791
2792 info = g_malloc0(sizeof(*info));
2793 info->name = x86_cpu_class_get_model_name(cc);
2794 x86_cpu_class_check_missing_features(cc, &info->unavailable_features);
2795 info->has_unavailable_features = true;
2796 info->q_typename = g_strdup(object_class_get_name(oc));
2797 info->migration_safe = cc->migration_safe;
2798 info->has_migration_safe = true;
2799 info->q_static = cc->static_model;
2800
2801 entry = g_malloc0(sizeof(*entry));
2802 entry->value = info;
2803 entry->next = *cpu_list;
2804 *cpu_list = entry;
2805 }
2806
2807 CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
2808 {
2809 CpuDefinitionInfoList *cpu_list = NULL;
2810 GSList *list = get_sorted_cpu_model_list();
2811 g_slist_foreach(list, x86_cpu_definition_entry, &cpu_list);
2812 g_slist_free(list);
2813 return cpu_list;
2814 }
2815
2816 static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
2817 bool migratable_only)
2818 {
2819 FeatureWordInfo *wi = &feature_word_info[w];
2820 uint32_t r;
2821
2822 if (kvm_enabled()) {
2823 r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid_eax,
2824 wi->cpuid_ecx,
2825 wi->cpuid_reg);
2826 } else if (tcg_enabled()) {
2827 r = wi->tcg_features;
2828 } else {
2829 return ~0;
2830 }
2831 if (migratable_only) {
2832 r &= x86_cpu_get_migratable_flags(w);
2833 }
2834 return r;
2835 }
2836
2837 static void x86_cpu_report_filtered_features(X86CPU *cpu)
2838 {
2839 FeatureWord w;
2840
2841 for (w = 0; w < FEATURE_WORDS; w++) {
2842 report_unavailable_features(w, cpu->filtered_features[w]);
2843 }
2844 }
2845
2846 static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
2847 {
2848 PropValue *pv;
2849 for (pv = props; pv->prop; pv++) {
2850 if (!pv->value) {
2851 continue;
2852 }
2853 object_property_parse(OBJECT(cpu), pv->value, pv->prop,
2854 &error_abort);
2855 }
2856 }
2857
2858 /* Load data from X86CPUDefinition into a X86CPU object
2859 */
2860 static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
2861 {
2862 CPUX86State *env = &cpu->env;
2863 const char *vendor;
2864 char host_vendor[CPUID_VENDOR_SZ + 1];
2865 FeatureWord w;
2866
2867 /*NOTE: any property set by this function should be returned by
2868 * x86_cpu_static_props(), so static expansion of
2869 * query-cpu-model-expansion is always complete.
2870 */
2871
2872 /* CPU models only set _minimum_ values for level/xlevel: */
2873 object_property_set_uint(OBJECT(cpu), def->level, "min-level", errp);
2874 object_property_set_uint(OBJECT(cpu), def->xlevel, "min-xlevel", errp);
2875
2876 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
2877 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
2878 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
2879 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
2880 for (w = 0; w < FEATURE_WORDS; w++) {
2881 env->features[w] = def->features[w];
2882 }
2883
2884 /* Special cases not set in the X86CPUDefinition structs: */
2885 if (kvm_enabled()) {
2886 if (!kvm_irqchip_in_kernel()) {
2887 x86_cpu_change_kvm_default("x2apic", "off");
2888 }
2889
2890 x86_cpu_apply_props(cpu, kvm_default_props);
2891 } else if (tcg_enabled()) {
2892 x86_cpu_apply_props(cpu, tcg_default_props);
2893 }
2894
2895 env->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
2896
2897 /* sysenter isn't supported in compatibility mode on AMD,
2898 * syscall isn't supported in compatibility mode on Intel.
2899 * Normally we advertise the actual CPU vendor, but you can
2900 * override this using the 'vendor' property if you want to use
2901 * KVM's sysenter/syscall emulation in compatibility mode and
2902 * when doing cross vendor migration
2903 */
2904 vendor = def->vendor;
2905 if (kvm_enabled()) {
2906 uint32_t ebx = 0, ecx = 0, edx = 0;
2907 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
2908 x86_cpu_vendor_words2str(host_vendor, ebx, edx, ecx);
2909 vendor = host_vendor;
2910 }
2911
2912 object_property_set_str(OBJECT(cpu), vendor, "vendor", errp);
2913
2914 }
2915
2916 /* Return a QDict containing keys for all properties that can be included
2917 * in static expansion of CPU models. All properties set by x86_cpu_load_def()
2918 * must be included in the dictionary.
2919 */
2920 static QDict *x86_cpu_static_props(void)
2921 {
2922 FeatureWord w;
2923 int i;
2924 static const char *props[] = {
2925 "min-level",
2926 "min-xlevel",
2927 "family",
2928 "model",
2929 "stepping",
2930 "model-id",
2931 "vendor",
2932 "lmce",
2933 NULL,
2934 };
2935 static QDict *d;
2936
2937 if (d) {
2938 return d;
2939 }
2940
2941 d = qdict_new();
2942 for (i = 0; props[i]; i++) {
2943 qdict_put_null(d, props[i]);
2944 }
2945
2946 for (w = 0; w < FEATURE_WORDS; w++) {
2947 FeatureWordInfo *fi = &feature_word_info[w];
2948 int bit;
2949 for (bit = 0; bit < 32; bit++) {
2950 if (!fi->feat_names[bit]) {
2951 continue;
2952 }
2953 qdict_put_null(d, fi->feat_names[bit]);
2954 }
2955 }
2956
2957 return d;
2958 }
2959
2960 /* Add an entry to @props dict, with the value for property. */
2961 static void x86_cpu_expand_prop(X86CPU *cpu, QDict *props, const char *prop)
2962 {
2963 QObject *value = object_property_get_qobject(OBJECT(cpu), prop,
2964 &error_abort);
2965
2966 qdict_put_obj(props, prop, value);
2967 }
2968
2969 /* Convert CPU model data from X86CPU object to a property dictionary
2970 * that can recreate exactly the same CPU model.
2971 */
2972 static void x86_cpu_to_dict(X86CPU *cpu, QDict *props)
2973 {
2974 QDict *sprops = x86_cpu_static_props();
2975 const QDictEntry *e;
2976
2977 for (e = qdict_first(sprops); e; e = qdict_next(sprops, e)) {
2978 const char *prop = qdict_entry_key(e);
2979 x86_cpu_expand_prop(cpu, props, prop);
2980 }
2981 }
2982
2983 /* Convert CPU model data from X86CPU object to a property dictionary
2984 * that can recreate exactly the same CPU model, including every
2985 * writeable QOM property.
2986 */
2987 static void x86_cpu_to_dict_full(X86CPU *cpu, QDict *props)
2988 {
2989 ObjectPropertyIterator iter;
2990 ObjectProperty *prop;
2991
2992 object_property_iter_init(&iter, OBJECT(cpu));
2993 while ((prop = object_property_iter_next(&iter))) {
2994 /* skip read-only or write-only properties */
2995 if (!prop->get || !prop->set) {
2996 continue;
2997 }
2998
2999 /* "hotplugged" is the only property that is configurable
3000 * on the command-line but will be set differently on CPUs
3001 * created using "-cpu ... -smp ..." and by CPUs created
3002 * on the fly by x86_cpu_from_model() for querying. Skip it.
3003 */
3004 if (!strcmp(prop->name, "hotplugged")) {
3005 continue;
3006 }
3007 x86_cpu_expand_prop(cpu, props, prop->name);
3008 }
3009 }
3010
3011 static void object_apply_props(Object *obj, QDict *props, Error **errp)
3012 {
3013 const QDictEntry *prop;
3014 Error *err = NULL;
3015
3016 for (prop = qdict_first(props); prop; prop = qdict_next(props, prop)) {
3017 object_property_set_qobject(obj, qdict_entry_value(prop),
3018 qdict_entry_key(prop), &err);
3019 if (err) {
3020 break;
3021 }
3022 }
3023
3024 error_propagate(errp, err);
3025 }
3026
3027 /* Create X86CPU object according to model+props specification */
3028 static X86CPU *x86_cpu_from_model(const char *model, QDict *props, Error **errp)
3029 {
3030 X86CPU *xc = NULL;
3031 X86CPUClass *xcc;
3032 Error *err = NULL;
3033
3034 xcc = X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model));
3035 if (xcc == NULL) {
3036 error_setg(&err, "CPU model '%s' not found", model);
3037 goto out;
3038 }
3039
3040 xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc))));
3041 if (props) {
3042 object_apply_props(OBJECT(xc), props, &err);
3043 if (err) {
3044 goto out;
3045 }
3046 }
3047
3048 x86_cpu_expand_features(xc, &err);
3049 if (err) {
3050 goto out;
3051 }
3052
3053 out:
3054 if (err) {
3055 error_propagate(errp, err);
3056 object_unref(OBJECT(xc));
3057 xc = NULL;
3058 }
3059 return xc;
3060 }
3061
3062 CpuModelExpansionInfo *
3063 arch_query_cpu_model_expansion(CpuModelExpansionType type,
3064 CpuModelInfo *model,
3065 Error **errp)
3066 {
3067 X86CPU *xc = NULL;
3068 Error *err = NULL;
3069 CpuModelExpansionInfo *ret = g_new0(CpuModelExpansionInfo, 1);
3070 QDict *props = NULL;
3071 const char *base_name;
3072
3073 xc = x86_cpu_from_model(model->name,
3074 model->has_props ?
3075 qobject_to_qdict(model->props) :
3076 NULL, &err);
3077 if (err) {
3078 goto out;
3079 }
3080
3081 props = qdict_new();
3082
3083 switch (type) {
3084 case CPU_MODEL_EXPANSION_TYPE_STATIC:
3085 /* Static expansion will be based on "base" only */
3086 base_name = "base";
3087 x86_cpu_to_dict(xc, props);
3088 break;
3089 case CPU_MODEL_EXPANSION_TYPE_FULL:
3090 /* As we don't return every single property, full expansion needs
3091 * to keep the original model name+props, and add extra
3092 * properties on top of that.
3093 */
3094 base_name = model->name;
3095 x86_cpu_to_dict_full(xc, props);
3096 break;
3097 default:
3098 error_setg(&err, "Unsupportted expansion type");
3099 goto out;
3100 }
3101
3102 if (!props) {
3103 props = qdict_new();
3104 }
3105 x86_cpu_to_dict(xc, props);
3106
3107 ret->model = g_new0(CpuModelInfo, 1);
3108 ret->model->name = g_strdup(base_name);
3109 ret->model->props = QOBJECT(props);
3110 ret->model->has_props = true;
3111
3112 out:
3113 object_unref(OBJECT(xc));
3114 if (err) {
3115 error_propagate(errp, err);
3116 qapi_free_CpuModelExpansionInfo(ret);
3117 ret = NULL;
3118 }
3119 return ret;
3120 }
3121
3122 static gchar *x86_gdb_arch_name(CPUState *cs)
3123 {
3124 #ifdef TARGET_X86_64
3125 return g_strdup("i386:x86-64");
3126 #else
3127 return g_strdup("i386");
3128 #endif
3129 }
3130
3131 static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
3132 {
3133 X86CPUDefinition *cpudef = data;
3134 X86CPUClass *xcc = X86_CPU_CLASS(oc);
3135
3136 xcc->cpu_def = cpudef;
3137 xcc->migration_safe = true;
3138 }
3139
3140 static void x86_register_cpudef_type(X86CPUDefinition *def)
3141 {
3142 char *typename = x86_cpu_type_name(def->name);
3143 TypeInfo ti = {
3144 .name = typename,
3145 .parent = TYPE_X86_CPU,
3146 .class_init = x86_cpu_cpudef_class_init,
3147 .class_data = def,
3148 };
3149
3150 /* AMD aliases are handled at runtime based on CPUID vendor, so
3151 * they shouldn't be set on the CPU model table.
3152 */
3153 assert(!(def->features[FEAT_8000_0001_EDX] & CPUID_EXT2_AMD_ALIASES));
3154 /* catch mistakes instead of silently truncating model_id when too long */
3155 assert(def->model_id && strlen(def->model_id) <= 48);
3156
3157
3158 type_register(&ti);
3159 g_free(typename);
3160 }
3161
3162 #if !defined(CONFIG_USER_ONLY)
3163
3164 void cpu_clear_apic_feature(CPUX86State *env)
3165 {
3166 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
3167 }
3168
3169 #endif /* !CONFIG_USER_ONLY */
3170
3171 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
3172 uint32_t *eax, uint32_t *ebx,
3173 uint32_t *ecx, uint32_t *edx)
3174 {
3175 X86CPU *cpu = x86_env_get_cpu(env);
3176 CPUState *cs = CPU(cpu);
3177 uint32_t pkg_offset;
3178 uint32_t limit;
3179 uint32_t signature[3];
3180
3181 /* Calculate & apply limits for different index ranges */
3182 if (index >= 0xC0000000) {
3183 limit = env->cpuid_xlevel2;
3184 } else if (index >= 0x80000000) {
3185 limit = env->cpuid_xlevel;
3186 } else if (index >= 0x40000000) {
3187 limit = 0x40000001;
3188 } else {
3189 limit = env->cpuid_level;
3190 }
3191
3192 if (index > limit) {
3193 /* Intel documentation states that invalid EAX input will
3194 * return the same information as EAX=cpuid_level
3195 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
3196 */
3197 index = env->cpuid_level;
3198 }
3199
3200 switch(index) {
3201 case 0:
3202 *eax = env->cpuid_level;
3203 *ebx = env->cpuid_vendor1;
3204 *edx = env->cpuid_vendor2;
3205 *ecx = env->cpuid_vendor3;
3206 break;
3207 case 1:
3208 *eax = env->cpuid_version;
3209 *ebx = (cpu->apic_id << 24) |
3210 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
3211 *ecx = env->features[FEAT_1_ECX];
3212 if ((*ecx & CPUID_EXT_XSAVE) && (env->cr[4] & CR4_OSXSAVE_MASK)) {
3213 *ecx |= CPUID_EXT_OSXSAVE;
3214 }
3215 *edx = env->features[FEAT_1_EDX];
3216 if (cs->nr_cores * cs->nr_threads > 1) {
3217 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
3218 *edx |= CPUID_HT;
3219 }
3220 break;
3221 case 2:
3222 /* cache info: needed for Pentium Pro compatibility */
3223 if (cpu->cache_info_passthrough) {
3224 host_cpuid(index, 0, eax, ebx, ecx, edx);
3225 break;
3226 }
3227 *eax = 1; /* Number of CPUID[EAX=2] calls required */
3228 *ebx = 0;
3229 if (!cpu->enable_l3_cache) {
3230 *ecx = 0;
3231 } else {
3232 *ecx = L3_N_DESCRIPTOR;
3233 }
3234 *edx = (L1D_DESCRIPTOR << 16) | \
3235 (L1I_DESCRIPTOR << 8) | \
3236 (L2_DESCRIPTOR);
3237 break;
3238 case 4:
3239 /* cache info: needed for Core compatibility */
3240 if (cpu->cache_info_passthrough) {
3241 host_cpuid(index, count, eax, ebx, ecx, edx);
3242 *eax &= ~0xFC000000;
3243 } else {
3244 *eax = 0;
3245 switch (count) {
3246 case 0: /* L1 dcache info */
3247 *eax |= CPUID_4_TYPE_DCACHE | \
3248 CPUID_4_LEVEL(1) | \
3249 CPUID_4_SELF_INIT_LEVEL;
3250 *ebx = (L1D_LINE_SIZE - 1) | \
3251 ((L1D_PARTITIONS - 1) << 12) | \
3252 ((L1D_ASSOCIATIVITY - 1) << 22);
3253 *ecx = L1D_SETS - 1;
3254 *edx = CPUID_4_NO_INVD_SHARING;
3255 break;
3256 case 1: /* L1 icache info */
3257 *eax |= CPUID_4_TYPE_ICACHE | \
3258 CPUID_4_LEVEL(1) | \
3259 CPUID_4_SELF_INIT_LEVEL;
3260 *ebx = (L1I_LINE_SIZE - 1) | \
3261 ((L1I_PARTITIONS - 1) << 12) | \
3262 ((L1I_ASSOCIATIVITY - 1) << 22);
3263 *ecx = L1I_SETS - 1;
3264 *edx = CPUID_4_NO_INVD_SHARING;
3265 break;
3266 case 2: /* L2 cache info */
3267 *eax |= CPUID_4_TYPE_UNIFIED | \
3268 CPUID_4_LEVEL(2) | \
3269 CPUID_4_SELF_INIT_LEVEL;
3270 if (cs->nr_threads > 1) {
3271 *eax |= (cs->nr_threads - 1) << 14;
3272 }
3273 *ebx = (L2_LINE_SIZE - 1) | \
3274 ((L2_PARTITIONS - 1) << 12) | \
3275 ((L2_ASSOCIATIVITY - 1) << 22);
3276 *ecx = L2_SETS - 1;
3277 *edx = CPUID_4_NO_INVD_SHARING;
3278 break;
3279 case 3: /* L3 cache info */
3280 if (!cpu->enable_l3_cache) {
3281 *eax = 0;
3282 *ebx = 0;
3283 *ecx = 0;
3284 *edx = 0;
3285 break;
3286 }
3287 *eax |= CPUID_4_TYPE_UNIFIED | \
3288 CPUID_4_LEVEL(3) | \
3289 CPUID_4_SELF_INIT_LEVEL;
3290 pkg_offset = apicid_pkg_offset(cs->nr_cores, cs->nr_threads);
3291 *eax |= ((1 << pkg_offset) - 1) << 14;
3292 *ebx = (L3_N_LINE_SIZE - 1) | \
3293 ((L3_N_PARTITIONS - 1) << 12) | \
3294 ((L3_N_ASSOCIATIVITY - 1) << 22);
3295 *ecx = L3_N_SETS - 1;
3296 *edx = CPUID_4_INCLUSIVE | CPUID_4_COMPLEX_IDX;
3297 break;
3298 default: /* end of info */
3299 *eax = 0;
3300 *ebx = 0;
3301 *ecx = 0;
3302 *edx = 0;
3303 break;
3304 }
3305 }
3306
3307 /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
3308 if ((*eax & 31) && cs->nr_cores > 1) {
3309 *eax |= (cs->nr_cores - 1) << 26;
3310 }
3311 break;
3312 case 5:
3313 /* mwait info: needed for Core compatibility */
3314 *eax = 0; /* Smallest monitor-line size in bytes */
3315 *ebx = 0; /* Largest monitor-line size in bytes */
3316 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
3317 *edx = 0;
3318 break;
3319 case 6:
3320 /* Thermal and Power Leaf */
3321 *eax = env->features[FEAT_6_EAX];
3322 *ebx = 0;
3323 *ecx = 0;
3324 *edx = 0;
3325 break;
3326 case 7:
3327 /* Structured Extended Feature Flags Enumeration Leaf */
3328 if (count == 0) {
3329 *eax = 0; /* Maximum ECX value for sub-leaves */
3330 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
3331 *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */
3332 if ((*ecx & CPUID_7_0_ECX_PKU) && env->cr[4] & CR4_PKE_MASK) {
3333 *ecx |= CPUID_7_0_ECX_OSPKE;
3334 }
3335 *edx = env->features[FEAT_7_0_EDX]; /* Feature flags */
3336 } else {
3337 *eax = 0;
3338 *ebx = 0;
3339 *ecx = 0;
3340 *edx = 0;
3341 }
3342 break;
3343 case 9:
3344 /* Direct Cache Access Information Leaf */
3345 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
3346 *ebx = 0;
3347 *ecx = 0;
3348 *edx = 0;
3349 break;
3350 case 0xA:
3351 /* Architectural Performance Monitoring Leaf */
3352 if (kvm_enabled() && cpu->enable_pmu) {
3353 KVMState *s = cs->kvm_state;
3354
3355 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
3356 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
3357 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
3358 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
3359 } else {
3360 *eax = 0;
3361 *ebx = 0;
3362 *ecx = 0;
3363 *edx = 0;
3364 }
3365 break;
3366 case 0xB:
3367 /* Extended Topology Enumeration Leaf */
3368 if (!cpu->enable_cpuid_0xb) {
3369 *eax = *ebx = *ecx = *edx = 0;
3370 break;
3371 }
3372
3373 *ecx = count & 0xff;
3374 *edx = cpu->apic_id;
3375
3376 switch (count) {
3377 case 0:
3378 *eax = apicid_core_offset(cs->nr_cores, cs->nr_threads);
3379 *ebx = cs->nr_threads;
3380 *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
3381 break;
3382 case 1:
3383 *eax = apicid_pkg_offset(cs->nr_cores, cs->nr_threads);
3384 *ebx = cs->nr_cores * cs->nr_threads;
3385 *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
3386 break;
3387 default:
3388 *eax = 0;
3389 *ebx = 0;
3390 *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
3391 }
3392
3393 assert(!(*eax & ~0x1f));
3394 *ebx &= 0xffff; /* The count doesn't need to be reliable. */
3395 break;
3396 case 0xD: {
3397 /* Processor Extended State */
3398 *eax = 0;
3399 *ebx = 0;
3400 *ecx = 0;
3401 *edx = 0;
3402 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
3403 break;
3404 }
3405
3406 if (count == 0) {
3407 *ecx = xsave_area_size(x86_cpu_xsave_components(cpu));
3408 *eax = env->features[FEAT_XSAVE_COMP_LO];
3409 *edx = env->features[FEAT_XSAVE_COMP_HI];
3410 *ebx = *ecx;
3411 } else if (count == 1) {
3412 *eax = env->features[FEAT_XSAVE];
3413 } else if (count < ARRAY_SIZE(x86_ext_save_areas)) {
3414 if ((x86_cpu_xsave_components(cpu) >> count) & 1) {
3415 const ExtSaveArea *esa = &x86_ext_save_areas[count];
3416 *eax = esa->size;
3417 *ebx = esa->offset;
3418 }
3419 }
3420 break;
3421 }
3422 case 0x40000000:
3423 /*
3424 * CPUID code in kvm_arch_init_vcpu() ignores stuff
3425 * set here, but we restrict to TCG none the less.
3426 */
3427 if (tcg_enabled() && cpu->expose_tcg) {
3428 memcpy(signature, "TCGTCGTCGTCG", 12);
3429 *eax = 0x40000001;
3430 *ebx = signature[0];
3431 *ecx = signature[1];
3432 *edx = signature[2];
3433 } else {
3434 *eax = 0;
3435 *ebx = 0;
3436 *ecx = 0;