]> git.proxmox.com Git - mirror_qemu.git/blame - target-i386/cpu.c
target-i386: Remove assert(kvm_enabled()) from host_x86_cpu_initfn()
[mirror_qemu.git] / target-i386 / cpu.c
CommitLineData
c6dc6f63
AP
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 */
1ef26b1f 19#include "qemu/osdep.h"
f348b6d1 20#include "qemu/cutils.h"
c6dc6f63
AP
21
22#include "cpu.h"
63c91552 23#include "exec/exec-all.h"
9c17d615 24#include "sysemu/kvm.h"
8932cfdf 25#include "sysemu/cpus.h"
50a2c6e5 26#include "kvm_i386.h"
c6dc6f63 27
d49b6836 28#include "qemu/error-report.h"
1de7afc9
PB
29#include "qemu/option.h"
30#include "qemu/config-file.h"
7b1b5d19 31#include "qapi/qmp/qerror.h"
c6dc6f63 32
8e8aba50
EH
33#include "qapi-types.h"
34#include "qapi-visit.h"
7b1b5d19 35#include "qapi/visitor.h"
9c17d615 36#include "sysemu/arch_init.h"
71ad61d3 37
b834b508 38#if defined(CONFIG_KVM)
ef8621b1 39#include <linux/kvm_para.h>
b834b508 40#endif
65dee380 41
9c17d615 42#include "sysemu/sysemu.h"
53a89e26 43#include "hw/qdev-properties.h"
5232d00a 44#include "hw/i386/topology.h"
bdeec802 45#ifndef CONFIG_USER_ONLY
2001d0cd 46#include "exec/address-spaces.h"
741da0d3 47#include "hw/hw.h"
0d09e41a 48#include "hw/xen/xen.h"
0d09e41a 49#include "hw/i386/apic_internal.h"
bdeec802
IM
50#endif
51
5e891bf8
EH
52
53/* Cache topology CPUID constants: */
54
55/* CPUID Leaf 2 Descriptors */
56
57#define CPUID_2_L1D_32KB_8WAY_64B 0x2c
58#define CPUID_2_L1I_32KB_8WAY_64B 0x30
59#define CPUID_2_L2_2MB_8WAY_64B 0x7d
60
61
62/* CPUID Leaf 4 constants: */
63
64/* EAX: */
65#define CPUID_4_TYPE_DCACHE 1
66#define CPUID_4_TYPE_ICACHE 2
67#define CPUID_4_TYPE_UNIFIED 3
68
69#define CPUID_4_LEVEL(l) ((l) << 5)
70
71#define CPUID_4_SELF_INIT_LEVEL (1 << 8)
72#define CPUID_4_FULLY_ASSOC (1 << 9)
73
74/* EDX: */
75#define CPUID_4_NO_INVD_SHARING (1 << 0)
76#define CPUID_4_INCLUSIVE (1 << 1)
77#define CPUID_4_COMPLEX_IDX (1 << 2)
78
79#define ASSOC_FULL 0xFF
80
81/* AMD associativity encoding used on CPUID Leaf 0x80000006: */
82#define AMD_ENC_ASSOC(a) (a <= 1 ? a : \
83 a == 2 ? 0x2 : \
84 a == 4 ? 0x4 : \
85 a == 8 ? 0x6 : \
86 a == 16 ? 0x8 : \
87 a == 32 ? 0xA : \
88 a == 48 ? 0xB : \
89 a == 64 ? 0xC : \
90 a == 96 ? 0xD : \
91 a == 128 ? 0xE : \
92 a == ASSOC_FULL ? 0xF : \
93 0 /* invalid value */)
94
95
96/* Definitions of the hardcoded cache entries we expose: */
97
98/* L1 data cache: */
99#define L1D_LINE_SIZE 64
100#define L1D_ASSOCIATIVITY 8
101#define L1D_SETS 64
102#define L1D_PARTITIONS 1
103/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
104#define L1D_DESCRIPTOR CPUID_2_L1D_32KB_8WAY_64B
105/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
106#define L1D_LINES_PER_TAG 1
107#define L1D_SIZE_KB_AMD 64
108#define L1D_ASSOCIATIVITY_AMD 2
109
110/* L1 instruction cache: */
111#define L1I_LINE_SIZE 64
112#define L1I_ASSOCIATIVITY 8
113#define L1I_SETS 64
114#define L1I_PARTITIONS 1
115/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
116#define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
117/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
118#define L1I_LINES_PER_TAG 1
119#define L1I_SIZE_KB_AMD 64
120#define L1I_ASSOCIATIVITY_AMD 2
121
122/* Level 2 unified cache: */
123#define L2_LINE_SIZE 64
124#define L2_ASSOCIATIVITY 16
125#define L2_SETS 4096
126#define L2_PARTITIONS 1
127/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
128/*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
129#define L2_DESCRIPTOR CPUID_2_L2_2MB_8WAY_64B
130/*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
131#define L2_LINES_PER_TAG 1
132#define L2_SIZE_KB_AMD 512
133
134/* No L3 cache: */
135#define L3_SIZE_KB 0 /* disabled */
136#define L3_ASSOCIATIVITY 0 /* disabled */
137#define L3_LINES_PER_TAG 0 /* disabled */
138#define L3_LINE_SIZE 0 /* disabled */
139
140/* TLB definitions: */
141
142#define L1_DTLB_2M_ASSOC 1
143#define L1_DTLB_2M_ENTRIES 255
144#define L1_DTLB_4K_ASSOC 1
145#define L1_DTLB_4K_ENTRIES 255
146
147#define L1_ITLB_2M_ASSOC 1
148#define L1_ITLB_2M_ENTRIES 255
149#define L1_ITLB_4K_ASSOC 1
150#define L1_ITLB_4K_ENTRIES 255
151
152#define L2_DTLB_2M_ASSOC 0 /* disabled */
153#define L2_DTLB_2M_ENTRIES 0 /* disabled */
154#define L2_DTLB_4K_ASSOC 4
155#define L2_DTLB_4K_ENTRIES 512
156
157#define L2_ITLB_2M_ASSOC 0 /* disabled */
158#define L2_ITLB_2M_ENTRIES 0 /* disabled */
159#define L2_ITLB_4K_ASSOC 4
160#define L2_ITLB_4K_ENTRIES 512
161
162
163
99b88a17
IM
164static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
165 uint32_t vendor2, uint32_t vendor3)
166{
167 int i;
168 for (i = 0; i < 4; i++) {
169 dst[i] = vendor1 >> (8 * i);
170 dst[i + 4] = vendor2 >> (8 * i);
171 dst[i + 8] = vendor3 >> (8 * i);
172 }
173 dst[CPUID_VENDOR_SZ] = '\0';
174}
175
c6dc6f63
AP
176/* feature flags taken from "Intel Processor Identification and the CPUID
177 * Instruction" and AMD's "CPUID Specification". In cases of disagreement
178 * between feature naming conventions, aliases may be added.
179 */
180static const char *feature_name[] = {
181 "fpu", "vme", "de", "pse",
182 "tsc", "msr", "pae", "mce",
183 "cx8", "apic", NULL, "sep",
184 "mtrr", "pge", "mca", "cmov",
185 "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
186 NULL, "ds" /* Intel dts */, "acpi", "mmx",
187 "fxsr", "sse", "sse2", "ss",
188 "ht" /* Intel htt */, "tm", "ia64", "pbe",
189};
190static const char *ext_feature_name[] = {
f370be3c 191 "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
e117f772 192 "ds_cpl", "vmx", "smx", "est",
c6dc6f63 193 "tm2", "ssse3", "cid", NULL,
e117f772 194 "fma", "cx16", "xtpr", "pdcm",
434acb81 195 NULL, "pcid", "dca", "sse4.1|sse4_1",
e117f772 196 "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
eaf3f097 197 "tsc-deadline", "aes", "xsave", "osxsave",
c8acc380 198 "avx", "f16c", "rdrand", "hypervisor",
c6dc6f63 199};
3b671a40
EH
200/* Feature names that are already defined on feature_name[] but are set on
201 * CPUID[8000_0001].EDX on AMD CPUs don't have their names on
202 * ext2_feature_name[]. They are copied automatically to cpuid_ext2_features
203 * if and only if CPU vendor is AMD.
204 */
c6dc6f63 205static const char *ext2_feature_name[] = {
3b671a40
EH
206 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
207 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
208 NULL /* cx8 */ /* AMD CMPXCHG8B */, NULL /* apic */, NULL, "syscall",
209 NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
210 NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
211 "nx|xd", NULL, "mmxext", NULL /* mmx */,
212 NULL /* fxsr */, "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
01f590d5 213 NULL, "lm|i64", "3dnowext", "3dnow",
c6dc6f63
AP
214};
215static const char *ext3_feature_name[] = {
216 "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
217 "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
e117f772 218 "3dnowprefetch", "osvw", "ibs", "xop",
c8acc380
AP
219 "skinit", "wdt", NULL, "lwp",
220 "fma4", "tce", NULL, "nodeid_msr",
221 NULL, "tbm", "topoext", "perfctr_core",
222 "perfctr_nb", NULL, NULL, NULL,
c6dc6f63
AP
223 NULL, NULL, NULL, NULL,
224};
225
89e49c8b
EH
226static const char *ext4_feature_name[] = {
227 NULL, NULL, "xstore", "xstore-en",
228 NULL, NULL, "xcrypt", "xcrypt-en",
229 "ace2", "ace2-en", "phe", "phe-en",
230 "pmm", "pmm-en", NULL, NULL,
231 NULL, NULL, NULL, NULL,
232 NULL, NULL, NULL, NULL,
233 NULL, NULL, NULL, NULL,
234 NULL, NULL, NULL, NULL,
235};
236
c6dc6f63 237static const char *kvm_feature_name[] = {
c3d39807 238 "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock",
f010bc64 239 "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", "kvm_pv_unhalt",
c3d39807
DS
240 NULL, NULL, NULL, NULL,
241 NULL, NULL, NULL, NULL,
242 NULL, NULL, NULL, NULL,
243 NULL, NULL, NULL, NULL,
8248c36a 244 "kvmclock-stable-bit", NULL, NULL, NULL,
c3d39807 245 NULL, NULL, NULL, NULL,
c6dc6f63
AP
246};
247
296acb64
JR
248static const char *svm_feature_name[] = {
249 "npt", "lbrv", "svm_lock", "nrip_save",
250 "tsc_scale", "vmcb_clean", "flushbyasid", "decodeassists",
251 NULL, NULL, "pause_filter", NULL,
252 "pfthreshold", NULL, NULL, NULL,
253 NULL, NULL, NULL, NULL,
254 NULL, NULL, NULL, NULL,
255 NULL, NULL, NULL, NULL,
256 NULL, NULL, NULL, NULL,
257};
258
a9321a4d 259static const char *cpuid_7_0_ebx_feature_name[] = {
7b458bfd 260 "fsgsbase", "tsc_adjust", NULL, "bmi1", "hle", "avx2", NULL, "smep",
5bd8ff07 261 "bmi2", "erms", "invpcid", "rtm", NULL, NULL, "mpx", NULL,
f7fda280
XG
262 "avx512f", NULL, "rdseed", "adx", "smap", NULL, "pcommit", "clflushopt",
263 "clwb", NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL,
a9321a4d
PA
264};
265
f74eefe0
HH
266static const char *cpuid_7_0_ecx_feature_name[] = {
267 NULL, NULL, NULL, "pku",
268 "ospke", NULL, NULL, NULL,
269 NULL, NULL, NULL, NULL,
270 NULL, NULL, NULL, NULL,
271 NULL, NULL, NULL, NULL,
272 NULL, NULL, NULL, NULL,
273 NULL, NULL, NULL, NULL,
274 NULL, NULL, NULL, NULL,
275};
276
303752a9
MT
277static const char *cpuid_apm_edx_feature_name[] = {
278 NULL, NULL, NULL, NULL,
279 NULL, NULL, NULL, NULL,
280 "invtsc", NULL, NULL, NULL,
281 NULL, NULL, NULL, NULL,
282 NULL, NULL, NULL, NULL,
283 NULL, NULL, NULL, NULL,
284 NULL, NULL, NULL, NULL,
285 NULL, NULL, NULL, NULL,
286};
287
0bb0b2d2
PB
288static const char *cpuid_xsave_feature_name[] = {
289 "xsaveopt", "xsavec", "xgetbv1", "xsaves",
290 NULL, NULL, NULL, NULL,
291 NULL, NULL, NULL, NULL,
292 NULL, NULL, NULL, NULL,
293 NULL, NULL, NULL, NULL,
294 NULL, NULL, NULL, NULL,
295 NULL, NULL, NULL, NULL,
296 NULL, NULL, NULL, NULL,
297};
298
28b8e4d0
JK
299static const char *cpuid_6_feature_name[] = {
300 NULL, NULL, "arat", NULL,
301 NULL, NULL, NULL, NULL,
302 NULL, NULL, NULL, NULL,
303 NULL, NULL, NULL, NULL,
304 NULL, NULL, NULL, NULL,
305 NULL, NULL, NULL, NULL,
306 NULL, NULL, NULL, NULL,
307 NULL, NULL, NULL, NULL,
308};
309
621626ce
EH
310#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
311#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
312 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
313#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
314 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
315 CPUID_PSE36 | CPUID_FXSR)
316#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
317#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
318 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
319 CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
320 CPUID_PAE | CPUID_SEP | CPUID_APIC)
321
322#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
323 CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
324 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
325 CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
b6c5a6f0 326 CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS | CPUID_DE)
621626ce
EH
327 /* partly implemented:
328 CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64) */
329 /* missing:
330 CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
331#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
332 CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
333 CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
19dc85db 334 CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */ \
621626ce
EH
335 CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
336 /* missing:
337 CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
338 CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
339 CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
19dc85db
RH
340 CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_AVX,
341 CPUID_EXT_F16C, CPUID_EXT_RDRAND */
621626ce
EH
342
343#ifdef TARGET_X86_64
344#define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM)
345#else
346#define TCG_EXT2_X86_64_FEATURES 0
347#endif
348
349#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
350 CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
351 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_PDPE1GB | \
352 TCG_EXT2_X86_64_FEATURES)
353#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
354 CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
355#define TCG_EXT4_FEATURES 0
356#define TCG_SVM_FEATURES 0
357#define TCG_KVM_FEATURES 0
358#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
0c47242b
XG
359 CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
360 CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT | \
07929f2a 361 CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE)
621626ce 362 /* missing:
07929f2a 363 CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
621626ce
EH
364 CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
365 CPUID_7_0_EBX_RDSEED */
0f70ed47 366#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE)
303752a9 367#define TCG_APM_FEATURES 0
28b8e4d0 368#define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
c9cfe8f9
RH
369#define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1)
370 /* missing:
371 CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
621626ce 372
5ef57876
EH
373typedef struct FeatureWordInfo {
374 const char **feat_names;
04d104b6
EH
375 uint32_t cpuid_eax; /* Input EAX for CPUID */
376 bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
377 uint32_t cpuid_ecx; /* Input ECX value for CPUID */
378 int cpuid_reg; /* output register (R_* constant) */
37ce3522 379 uint32_t tcg_features; /* Feature flags supported by TCG */
84f1b92f 380 uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
5ef57876
EH
381} FeatureWordInfo;
382
383static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
bffd67b0
EH
384 [FEAT_1_EDX] = {
385 .feat_names = feature_name,
386 .cpuid_eax = 1, .cpuid_reg = R_EDX,
37ce3522 387 .tcg_features = TCG_FEATURES,
bffd67b0
EH
388 },
389 [FEAT_1_ECX] = {
390 .feat_names = ext_feature_name,
391 .cpuid_eax = 1, .cpuid_reg = R_ECX,
37ce3522 392 .tcg_features = TCG_EXT_FEATURES,
bffd67b0
EH
393 },
394 [FEAT_8000_0001_EDX] = {
395 .feat_names = ext2_feature_name,
396 .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX,
37ce3522 397 .tcg_features = TCG_EXT2_FEATURES,
bffd67b0
EH
398 },
399 [FEAT_8000_0001_ECX] = {
400 .feat_names = ext3_feature_name,
401 .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
37ce3522 402 .tcg_features = TCG_EXT3_FEATURES,
bffd67b0 403 },
89e49c8b
EH
404 [FEAT_C000_0001_EDX] = {
405 .feat_names = ext4_feature_name,
406 .cpuid_eax = 0xC0000001, .cpuid_reg = R_EDX,
37ce3522 407 .tcg_features = TCG_EXT4_FEATURES,
89e49c8b 408 },
bffd67b0
EH
409 [FEAT_KVM] = {
410 .feat_names = kvm_feature_name,
411 .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
37ce3522 412 .tcg_features = TCG_KVM_FEATURES,
bffd67b0
EH
413 },
414 [FEAT_SVM] = {
415 .feat_names = svm_feature_name,
416 .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
37ce3522 417 .tcg_features = TCG_SVM_FEATURES,
bffd67b0
EH
418 },
419 [FEAT_7_0_EBX] = {
420 .feat_names = cpuid_7_0_ebx_feature_name,
04d104b6
EH
421 .cpuid_eax = 7,
422 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
423 .cpuid_reg = R_EBX,
37ce3522 424 .tcg_features = TCG_7_0_EBX_FEATURES,
bffd67b0 425 },
f74eefe0
HH
426 [FEAT_7_0_ECX] = {
427 .feat_names = cpuid_7_0_ecx_feature_name,
428 .cpuid_eax = 7,
429 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
430 .cpuid_reg = R_ECX,
431 .tcg_features = TCG_7_0_ECX_FEATURES,
432 },
303752a9
MT
433 [FEAT_8000_0007_EDX] = {
434 .feat_names = cpuid_apm_edx_feature_name,
435 .cpuid_eax = 0x80000007,
436 .cpuid_reg = R_EDX,
437 .tcg_features = TCG_APM_FEATURES,
438 .unmigratable_flags = CPUID_APM_INVTSC,
439 },
0bb0b2d2
PB
440 [FEAT_XSAVE] = {
441 .feat_names = cpuid_xsave_feature_name,
442 .cpuid_eax = 0xd,
443 .cpuid_needs_ecx = true, .cpuid_ecx = 1,
444 .cpuid_reg = R_EAX,
c9cfe8f9 445 .tcg_features = TCG_XSAVE_FEATURES,
0bb0b2d2 446 },
28b8e4d0
JK
447 [FEAT_6_EAX] = {
448 .feat_names = cpuid_6_feature_name,
449 .cpuid_eax = 6, .cpuid_reg = R_EAX,
450 .tcg_features = TCG_6_EAX_FEATURES,
451 },
5ef57876
EH
452};
453
8e8aba50
EH
454typedef struct X86RegisterInfo32 {
455 /* Name of register */
456 const char *name;
457 /* QAPI enum value register */
458 X86CPURegister32 qapi_enum;
459} X86RegisterInfo32;
460
461#define REGISTER(reg) \
5d371f41 462 [R_##reg] = { .name = #reg, .qapi_enum = X86_CPU_REGISTER32_##reg }
a443bc34 463static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
8e8aba50
EH
464 REGISTER(EAX),
465 REGISTER(ECX),
466 REGISTER(EDX),
467 REGISTER(EBX),
468 REGISTER(ESP),
469 REGISTER(EBP),
470 REGISTER(ESI),
471 REGISTER(EDI),
472};
473#undef REGISTER
474
f4f1110e 475const ExtSaveArea x86_ext_save_areas[] = {
cfc3b074
PB
476 [XSTATE_YMM_BIT] =
477 { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
ee1b09f6
EH
478 .offset = offsetof(X86XSaveArea, avx_state),
479 .size = sizeof(XSaveAVX) },
cfc3b074
PB
480 [XSTATE_BNDREGS_BIT] =
481 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
ee1b09f6
EH
482 .offset = offsetof(X86XSaveArea, bndreg_state),
483 .size = sizeof(XSaveBNDREG) },
cfc3b074
PB
484 [XSTATE_BNDCSR_BIT] =
485 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
ee1b09f6
EH
486 .offset = offsetof(X86XSaveArea, bndcsr_state),
487 .size = sizeof(XSaveBNDCSR) },
cfc3b074
PB
488 [XSTATE_OPMASK_BIT] =
489 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
ee1b09f6
EH
490 .offset = offsetof(X86XSaveArea, opmask_state),
491 .size = sizeof(XSaveOpmask) },
cfc3b074
PB
492 [XSTATE_ZMM_Hi256_BIT] =
493 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
ee1b09f6
EH
494 .offset = offsetof(X86XSaveArea, zmm_hi256_state),
495 .size = sizeof(XSaveZMM_Hi256) },
cfc3b074
PB
496 [XSTATE_Hi16_ZMM_BIT] =
497 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
ee1b09f6
EH
498 .offset = offsetof(X86XSaveArea, hi16_zmm_state),
499 .size = sizeof(XSaveHi16_ZMM) },
cfc3b074
PB
500 [XSTATE_PKRU_BIT] =
501 { .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU,
ee1b09f6
EH
502 .offset = offsetof(X86XSaveArea, pkru_state),
503 .size = sizeof(XSavePKRU) },
2560f19f 504};
8e8aba50 505
8b4beddc
EH
506const char *get_register_name_32(unsigned int reg)
507{
31ccdde2 508 if (reg >= CPU_NB_REGS32) {
8b4beddc
EH
509 return NULL;
510 }
8e8aba50 511 return x86_reg_info_32[reg].name;
8b4beddc
EH
512}
513
84f1b92f
EH
514/*
515 * Returns the set of feature flags that are supported and migratable by
516 * QEMU, for a given FeatureWord.
517 */
518static uint32_t x86_cpu_get_migratable_flags(FeatureWord w)
519{
520 FeatureWordInfo *wi = &feature_word_info[w];
521 uint32_t r = 0;
522 int i;
523
524 for (i = 0; i < 32; i++) {
525 uint32_t f = 1U << i;
526 /* If the feature name is unknown, it is not supported by QEMU yet */
527 if (!wi->feat_names[i]) {
528 continue;
529 }
530 /* Skip features known to QEMU, but explicitly marked as unmigratable */
531 if (wi->unmigratable_flags & f) {
532 continue;
533 }
534 r |= f;
535 }
536 return r;
537}
538
bb44e0d1
JK
539void host_cpuid(uint32_t function, uint32_t count,
540 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
bdde476a 541{
a1fd24af
AL
542 uint32_t vec[4];
543
544#ifdef __x86_64__
545 asm volatile("cpuid"
546 : "=a"(vec[0]), "=b"(vec[1]),
547 "=c"(vec[2]), "=d"(vec[3])
548 : "0"(function), "c"(count) : "cc");
c1f41226 549#elif defined(__i386__)
a1fd24af
AL
550 asm volatile("pusha \n\t"
551 "cpuid \n\t"
552 "mov %%eax, 0(%2) \n\t"
553 "mov %%ebx, 4(%2) \n\t"
554 "mov %%ecx, 8(%2) \n\t"
555 "mov %%edx, 12(%2) \n\t"
556 "popa"
557 : : "a"(function), "c"(count), "S"(vec)
558 : "memory", "cc");
c1f41226
EH
559#else
560 abort();
a1fd24af
AL
561#endif
562
bdde476a 563 if (eax)
a1fd24af 564 *eax = vec[0];
bdde476a 565 if (ebx)
a1fd24af 566 *ebx = vec[1];
bdde476a 567 if (ecx)
a1fd24af 568 *ecx = vec[2];
bdde476a 569 if (edx)
a1fd24af 570 *edx = vec[3];
bdde476a 571}
c6dc6f63
AP
572
573#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
574
575/* general substring compare of *[s1..e1) and *[s2..e2). sx is start of
576 * a substring. ex if !NULL points to the first char after a substring,
577 * otherwise the string is assumed to sized by a terminating nul.
578 * Return lexical ordering of *s1:*s2.
579 */
8f9d989c
CF
580static int sstrcmp(const char *s1, const char *e1,
581 const char *s2, const char *e2)
c6dc6f63
AP
582{
583 for (;;) {
584 if (!*s1 || !*s2 || *s1 != *s2)
585 return (*s1 - *s2);
586 ++s1, ++s2;
587 if (s1 == e1 && s2 == e2)
588 return (0);
589 else if (s1 == e1)
590 return (*s2);
591 else if (s2 == e2)
592 return (*s1);
593 }
594}
595
596/* compare *[s..e) to *altstr. *altstr may be a simple string or multiple
597 * '|' delimited (possibly empty) strings in which case search for a match
598 * within the alternatives proceeds left to right. Return 0 for success,
599 * non-zero otherwise.
600 */
601static int altcmp(const char *s, const char *e, const char *altstr)
602{
603 const char *p, *q;
604
605 for (q = p = altstr; ; ) {
606 while (*p && *p != '|')
607 ++p;
608 if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
609 return (0);
610 if (!*p)
611 return (1);
612 else
613 q = ++p;
614 }
615}
616
617/* search featureset for flag *[s..e), if found set corresponding bit in
e41e0fc6 618 * *pval and return true, otherwise return false
c6dc6f63 619 */
e41e0fc6
JK
620static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
621 const char **featureset)
c6dc6f63
AP
622{
623 uint32_t mask;
624 const char **ppc;
e41e0fc6 625 bool found = false;
c6dc6f63 626
e41e0fc6 627 for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
c6dc6f63
AP
628 if (*ppc && !altcmp(s, e, *ppc)) {
629 *pval |= mask;
e41e0fc6 630 found = true;
c6dc6f63 631 }
e41e0fc6
JK
632 }
633 return found;
c6dc6f63
AP
634}
635
5ef57876 636static void add_flagname_to_bitmaps(const char *flagname,
c00c94ab
EH
637 FeatureWordArray words,
638 Error **errp)
c6dc6f63 639{
5ef57876
EH
640 FeatureWord w;
641 for (w = 0; w < FEATURE_WORDS; w++) {
642 FeatureWordInfo *wi = &feature_word_info[w];
643 if (wi->feat_names &&
644 lookup_feature(&words[w], flagname, NULL, wi->feat_names)) {
645 break;
646 }
647 }
648 if (w == FEATURE_WORDS) {
c00c94ab 649 error_setg(errp, "CPU feature %s not found", flagname);
5ef57876 650 }
c6dc6f63
AP
651}
652
d940ee9b
EH
653/* CPU class name definitions: */
654
655#define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU
656#define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX)
657
658/* Return type name for a given CPU model name
659 * Caller is responsible for freeing the returned string.
660 */
661static char *x86_cpu_type_name(const char *model_name)
662{
663 return g_strdup_printf(X86_CPU_TYPE_NAME("%s"), model_name);
664}
665
500050d1
AF
666static ObjectClass *x86_cpu_class_by_name(const char *cpu_model)
667{
d940ee9b
EH
668 ObjectClass *oc;
669 char *typename;
670
500050d1
AF
671 if (cpu_model == NULL) {
672 return NULL;
673 }
674
d940ee9b
EH
675 typename = x86_cpu_type_name(cpu_model);
676 oc = object_class_by_name(typename);
677 g_free(typename);
678 return oc;
500050d1
AF
679}
680
d940ee9b 681struct X86CPUDefinition {
c6dc6f63
AP
682 const char *name;
683 uint32_t level;
90e4b0c3
EH
684 uint32_t xlevel;
685 uint32_t xlevel2;
99b88a17
IM
686 /* vendor is zero-terminated, 12 character ASCII string */
687 char vendor[CPUID_VENDOR_SZ + 1];
c6dc6f63
AP
688 int family;
689 int model;
690 int stepping;
0514ef2f 691 FeatureWordArray features;
c6dc6f63 692 char model_id[48];
d940ee9b 693};
c6dc6f63 694
9576de75 695static X86CPUDefinition builtin_x86_defs[] = {
c6dc6f63
AP
696 {
697 .name = "qemu64",
3046bb5d 698 .level = 0xd,
99b88a17 699 .vendor = CPUID_VENDOR_AMD,
c6dc6f63 700 .family = 6,
f8e6a11a 701 .model = 6,
c6dc6f63 702 .stepping = 3,
0514ef2f 703 .features[FEAT_1_EDX] =
27861ecc 704 PPRO_FEATURES |
c6dc6f63 705 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
c6dc6f63 706 CPUID_PSE36,
0514ef2f 707 .features[FEAT_1_ECX] =
6aa91e4a 708 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
0514ef2f 709 .features[FEAT_8000_0001_EDX] =
c6dc6f63 710 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
0514ef2f 711 .features[FEAT_8000_0001_ECX] =
71195672 712 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM,
c6dc6f63 713 .xlevel = 0x8000000A,
9cf2cc3d 714 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
c6dc6f63
AP
715 },
716 {
717 .name = "phenom",
718 .level = 5,
99b88a17 719 .vendor = CPUID_VENDOR_AMD,
c6dc6f63
AP
720 .family = 16,
721 .model = 2,
722 .stepping = 3,
b9fc20bc 723 /* Missing: CPUID_HT */
0514ef2f 724 .features[FEAT_1_EDX] =
27861ecc 725 PPRO_FEATURES |
c6dc6f63 726 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
b9fc20bc 727 CPUID_PSE36 | CPUID_VME,
0514ef2f 728 .features[FEAT_1_ECX] =
27861ecc 729 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
c6dc6f63 730 CPUID_EXT_POPCNT,
0514ef2f 731 .features[FEAT_8000_0001_EDX] =
c6dc6f63
AP
732 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
733 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
8560efed 734 CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
c6dc6f63
AP
735 /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
736 CPUID_EXT3_CR8LEG,
737 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
738 CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
0514ef2f 739 .features[FEAT_8000_0001_ECX] =
27861ecc 740 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
c6dc6f63 741 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
b9fc20bc 742 /* Missing: CPUID_SVM_LBRV */
0514ef2f 743 .features[FEAT_SVM] =
b9fc20bc 744 CPUID_SVM_NPT,
c6dc6f63
AP
745 .xlevel = 0x8000001A,
746 .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
747 },
748 {
749 .name = "core2duo",
750 .level = 10,
99b88a17 751 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
752 .family = 6,
753 .model = 15,
754 .stepping = 11,
b9fc20bc 755 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
0514ef2f 756 .features[FEAT_1_EDX] =
27861ecc 757 PPRO_FEATURES |
c6dc6f63 758 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
b9fc20bc
EH
759 CPUID_PSE36 | CPUID_VME | CPUID_ACPI | CPUID_SS,
760 /* Missing: CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_EST,
e93abc14 761 * CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_VMX */
0514ef2f 762 .features[FEAT_1_ECX] =
27861ecc 763 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
e93abc14 764 CPUID_EXT_CX16,
0514ef2f 765 .features[FEAT_8000_0001_EDX] =
27861ecc 766 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
0514ef2f 767 .features[FEAT_8000_0001_ECX] =
27861ecc 768 CPUID_EXT3_LAHF_LM,
c6dc6f63
AP
769 .xlevel = 0x80000008,
770 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
771 },
772 {
773 .name = "kvm64",
3046bb5d 774 .level = 0xd,
99b88a17 775 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
776 .family = 15,
777 .model = 6,
778 .stepping = 1,
b3a4f0b1 779 /* Missing: CPUID_HT */
0514ef2f 780 .features[FEAT_1_EDX] =
b3a4f0b1 781 PPRO_FEATURES | CPUID_VME |
c6dc6f63
AP
782 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
783 CPUID_PSE36,
784 /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
0514ef2f 785 .features[FEAT_1_ECX] =
27861ecc 786 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
c6dc6f63 787 /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
0514ef2f 788 .features[FEAT_8000_0001_EDX] =
c6dc6f63
AP
789 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
790 /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
791 CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
792 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
793 CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
0514ef2f 794 .features[FEAT_8000_0001_ECX] =
27861ecc 795 0,
c6dc6f63
AP
796 .xlevel = 0x80000008,
797 .model_id = "Common KVM processor"
798 },
c6dc6f63
AP
799 {
800 .name = "qemu32",
801 .level = 4,
99b88a17 802 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63 803 .family = 6,
f8e6a11a 804 .model = 6,
c6dc6f63 805 .stepping = 3,
0514ef2f 806 .features[FEAT_1_EDX] =
27861ecc 807 PPRO_FEATURES,
0514ef2f 808 .features[FEAT_1_ECX] =
6aa91e4a 809 CPUID_EXT_SSE3,
58012d66 810 .xlevel = 0x80000004,
9cf2cc3d 811 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
c6dc6f63 812 },
eafaf1e5
AP
813 {
814 .name = "kvm32",
815 .level = 5,
99b88a17 816 .vendor = CPUID_VENDOR_INTEL,
eafaf1e5
AP
817 .family = 15,
818 .model = 6,
819 .stepping = 1,
0514ef2f 820 .features[FEAT_1_EDX] =
b3a4f0b1 821 PPRO_FEATURES | CPUID_VME |
eafaf1e5 822 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
0514ef2f 823 .features[FEAT_1_ECX] =
27861ecc 824 CPUID_EXT_SSE3,
0514ef2f 825 .features[FEAT_8000_0001_ECX] =
27861ecc 826 0,
eafaf1e5
AP
827 .xlevel = 0x80000008,
828 .model_id = "Common 32-bit KVM processor"
829 },
c6dc6f63
AP
830 {
831 .name = "coreduo",
832 .level = 10,
99b88a17 833 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
834 .family = 6,
835 .model = 14,
836 .stepping = 8,
b9fc20bc 837 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
0514ef2f 838 .features[FEAT_1_EDX] =
27861ecc 839 PPRO_FEATURES | CPUID_VME |
b9fc20bc
EH
840 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_ACPI |
841 CPUID_SS,
842 /* Missing: CPUID_EXT_EST, CPUID_EXT_TM2 , CPUID_EXT_XTPR,
e93abc14 843 * CPUID_EXT_PDCM, CPUID_EXT_VMX */
0514ef2f 844 .features[FEAT_1_ECX] =
e93abc14 845 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
0514ef2f 846 .features[FEAT_8000_0001_EDX] =
27861ecc 847 CPUID_EXT2_NX,
c6dc6f63
AP
848 .xlevel = 0x80000008,
849 .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
850 },
851 {
852 .name = "486",
58012d66 853 .level = 1,
99b88a17 854 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63 855 .family = 4,
b2a856d9 856 .model = 8,
c6dc6f63 857 .stepping = 0,
0514ef2f 858 .features[FEAT_1_EDX] =
27861ecc 859 I486_FEATURES,
c6dc6f63
AP
860 .xlevel = 0,
861 },
862 {
863 .name = "pentium",
864 .level = 1,
99b88a17 865 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
866 .family = 5,
867 .model = 4,
868 .stepping = 3,
0514ef2f 869 .features[FEAT_1_EDX] =
27861ecc 870 PENTIUM_FEATURES,
c6dc6f63
AP
871 .xlevel = 0,
872 },
873 {
874 .name = "pentium2",
875 .level = 2,
99b88a17 876 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
877 .family = 6,
878 .model = 5,
879 .stepping = 2,
0514ef2f 880 .features[FEAT_1_EDX] =
27861ecc 881 PENTIUM2_FEATURES,
c6dc6f63
AP
882 .xlevel = 0,
883 },
884 {
885 .name = "pentium3",
3046bb5d 886 .level = 3,
99b88a17 887 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
888 .family = 6,
889 .model = 7,
890 .stepping = 3,
0514ef2f 891 .features[FEAT_1_EDX] =
27861ecc 892 PENTIUM3_FEATURES,
c6dc6f63
AP
893 .xlevel = 0,
894 },
895 {
896 .name = "athlon",
897 .level = 2,
99b88a17 898 .vendor = CPUID_VENDOR_AMD,
c6dc6f63
AP
899 .family = 6,
900 .model = 2,
901 .stepping = 3,
0514ef2f 902 .features[FEAT_1_EDX] =
27861ecc 903 PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
60032ac0 904 CPUID_MCA,
0514ef2f 905 .features[FEAT_8000_0001_EDX] =
60032ac0 906 CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
c6dc6f63 907 .xlevel = 0x80000008,
9cf2cc3d 908 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
c6dc6f63
AP
909 },
910 {
911 .name = "n270",
3046bb5d 912 .level = 10,
99b88a17 913 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
914 .family = 6,
915 .model = 28,
916 .stepping = 2,
b9fc20bc 917 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
0514ef2f 918 .features[FEAT_1_EDX] =
27861ecc 919 PPRO_FEATURES |
b9fc20bc
EH
920 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME |
921 CPUID_ACPI | CPUID_SS,
c6dc6f63 922 /* Some CPUs got no CPUID_SEP */
b9fc20bc
EH
923 /* Missing: CPUID_EXT_DSCPL, CPUID_EXT_EST, CPUID_EXT_TM2,
924 * CPUID_EXT_XTPR */
0514ef2f 925 .features[FEAT_1_ECX] =
27861ecc 926 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
4458c236 927 CPUID_EXT_MOVBE,
0514ef2f 928 .features[FEAT_8000_0001_EDX] =
60032ac0 929 CPUID_EXT2_NX,
0514ef2f 930 .features[FEAT_8000_0001_ECX] =
27861ecc 931 CPUID_EXT3_LAHF_LM,
3046bb5d 932 .xlevel = 0x80000008,
c6dc6f63
AP
933 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
934 },
3eca4642
EH
935 {
936 .name = "Conroe",
3046bb5d 937 .level = 10,
99b88a17 938 .vendor = CPUID_VENDOR_INTEL,
3eca4642 939 .family = 6,
ffce9ebb 940 .model = 15,
3eca4642 941 .stepping = 3,
0514ef2f 942 .features[FEAT_1_EDX] =
b3a4f0b1 943 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
b3fb3a20
EH
944 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
945 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
946 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
947 CPUID_DE | CPUID_FP87,
0514ef2f 948 .features[FEAT_1_ECX] =
27861ecc 949 CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
0514ef2f 950 .features[FEAT_8000_0001_EDX] =
27861ecc 951 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
0514ef2f 952 .features[FEAT_8000_0001_ECX] =
27861ecc 953 CPUID_EXT3_LAHF_LM,
3046bb5d 954 .xlevel = 0x80000008,
3eca4642
EH
955 .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
956 },
957 {
958 .name = "Penryn",
3046bb5d 959 .level = 10,
99b88a17 960 .vendor = CPUID_VENDOR_INTEL,
3eca4642 961 .family = 6,
ffce9ebb 962 .model = 23,
3eca4642 963 .stepping = 3,
0514ef2f 964 .features[FEAT_1_EDX] =
b3a4f0b1 965 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
b3fb3a20
EH
966 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
967 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
968 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
969 CPUID_DE | CPUID_FP87,
0514ef2f 970 .features[FEAT_1_ECX] =
27861ecc 971 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
b3fb3a20 972 CPUID_EXT_SSE3,
0514ef2f 973 .features[FEAT_8000_0001_EDX] =
27861ecc 974 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
0514ef2f 975 .features[FEAT_8000_0001_ECX] =
27861ecc 976 CPUID_EXT3_LAHF_LM,
3046bb5d 977 .xlevel = 0x80000008,
3eca4642
EH
978 .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
979 },
980 {
981 .name = "Nehalem",
3046bb5d 982 .level = 11,
99b88a17 983 .vendor = CPUID_VENDOR_INTEL,
3eca4642 984 .family = 6,
ffce9ebb 985 .model = 26,
3eca4642 986 .stepping = 3,
0514ef2f 987 .features[FEAT_1_EDX] =
b3a4f0b1 988 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
b3fb3a20
EH
989 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
990 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
991 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
992 CPUID_DE | CPUID_FP87,
0514ef2f 993 .features[FEAT_1_ECX] =
27861ecc 994 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
b3fb3a20 995 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
0514ef2f 996 .features[FEAT_8000_0001_EDX] =
27861ecc 997 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
0514ef2f 998 .features[FEAT_8000_0001_ECX] =
27861ecc 999 CPUID_EXT3_LAHF_LM,
3046bb5d 1000 .xlevel = 0x80000008,
3eca4642
EH
1001 .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
1002 },
1003 {
1004 .name = "Westmere",
1005 .level = 11,
99b88a17 1006 .vendor = CPUID_VENDOR_INTEL,
3eca4642
EH
1007 .family = 6,
1008 .model = 44,
1009 .stepping = 1,
0514ef2f 1010 .features[FEAT_1_EDX] =
b3a4f0b1 1011 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
b3fb3a20
EH
1012 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1013 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1014 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1015 CPUID_DE | CPUID_FP87,
0514ef2f 1016 .features[FEAT_1_ECX] =
27861ecc 1017 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
b3fb3a20
EH
1018 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1019 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
0514ef2f 1020 .features[FEAT_8000_0001_EDX] =
27861ecc 1021 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
0514ef2f 1022 .features[FEAT_8000_0001_ECX] =
27861ecc 1023 CPUID_EXT3_LAHF_LM,
28b8e4d0
JK
1024 .features[FEAT_6_EAX] =
1025 CPUID_6_EAX_ARAT,
3046bb5d 1026 .xlevel = 0x80000008,
3eca4642
EH
1027 .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
1028 },
1029 {
1030 .name = "SandyBridge",
1031 .level = 0xd,
99b88a17 1032 .vendor = CPUID_VENDOR_INTEL,
3eca4642
EH
1033 .family = 6,
1034 .model = 42,
1035 .stepping = 1,
0514ef2f 1036 .features[FEAT_1_EDX] =
b3a4f0b1 1037 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
b3fb3a20
EH
1038 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1039 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1040 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1041 CPUID_DE | CPUID_FP87,
0514ef2f 1042 .features[FEAT_1_ECX] =
27861ecc 1043 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
b3fb3a20
EH
1044 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1045 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1046 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1047 CPUID_EXT_SSE3,
0514ef2f 1048 .features[FEAT_8000_0001_EDX] =
27861ecc 1049 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
b3fb3a20 1050 CPUID_EXT2_SYSCALL,
0514ef2f 1051 .features[FEAT_8000_0001_ECX] =
27861ecc 1052 CPUID_EXT3_LAHF_LM,
0bb0b2d2
PB
1053 .features[FEAT_XSAVE] =
1054 CPUID_XSAVE_XSAVEOPT,
28b8e4d0
JK
1055 .features[FEAT_6_EAX] =
1056 CPUID_6_EAX_ARAT,
3046bb5d 1057 .xlevel = 0x80000008,
3eca4642
EH
1058 .model_id = "Intel Xeon E312xx (Sandy Bridge)",
1059 },
2f9ac42a
PB
1060 {
1061 .name = "IvyBridge",
1062 .level = 0xd,
1063 .vendor = CPUID_VENDOR_INTEL,
1064 .family = 6,
1065 .model = 58,
1066 .stepping = 9,
1067 .features[FEAT_1_EDX] =
1068 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1069 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1070 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1071 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1072 CPUID_DE | CPUID_FP87,
1073 .features[FEAT_1_ECX] =
1074 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1075 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1076 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1077 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1078 CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1079 .features[FEAT_7_0_EBX] =
1080 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
1081 CPUID_7_0_EBX_ERMS,
1082 .features[FEAT_8000_0001_EDX] =
1083 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1084 CPUID_EXT2_SYSCALL,
1085 .features[FEAT_8000_0001_ECX] =
1086 CPUID_EXT3_LAHF_LM,
1087 .features[FEAT_XSAVE] =
1088 CPUID_XSAVE_XSAVEOPT,
28b8e4d0
JK
1089 .features[FEAT_6_EAX] =
1090 CPUID_6_EAX_ARAT,
3046bb5d 1091 .xlevel = 0x80000008,
2f9ac42a
PB
1092 .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
1093 },
37507094 1094 {
a356850b
EH
1095 .name = "Haswell-noTSX",
1096 .level = 0xd,
1097 .vendor = CPUID_VENDOR_INTEL,
1098 .family = 6,
1099 .model = 60,
1100 .stepping = 1,
1101 .features[FEAT_1_EDX] =
1102 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1103 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1104 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1105 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1106 CPUID_DE | CPUID_FP87,
1107 .features[FEAT_1_ECX] =
1108 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1109 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1110 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1111 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1112 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1113 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1114 .features[FEAT_8000_0001_EDX] =
1115 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1116 CPUID_EXT2_SYSCALL,
1117 .features[FEAT_8000_0001_ECX] =
becb6667 1118 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
a356850b
EH
1119 .features[FEAT_7_0_EBX] =
1120 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1121 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1122 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
1123 .features[FEAT_XSAVE] =
1124 CPUID_XSAVE_XSAVEOPT,
28b8e4d0
JK
1125 .features[FEAT_6_EAX] =
1126 CPUID_6_EAX_ARAT,
3046bb5d 1127 .xlevel = 0x80000008,
a356850b
EH
1128 .model_id = "Intel Core Processor (Haswell, no TSX)",
1129 }, {
37507094
EH
1130 .name = "Haswell",
1131 .level = 0xd,
99b88a17 1132 .vendor = CPUID_VENDOR_INTEL,
37507094
EH
1133 .family = 6,
1134 .model = 60,
1135 .stepping = 1,
0514ef2f 1136 .features[FEAT_1_EDX] =
b3a4f0b1 1137 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
b3fb3a20
EH
1138 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1139 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1140 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1141 CPUID_DE | CPUID_FP87,
0514ef2f 1142 .features[FEAT_1_ECX] =
27861ecc 1143 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
b3fb3a20
EH
1144 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1145 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1146 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1147 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
78a611f1 1148 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
0514ef2f 1149 .features[FEAT_8000_0001_EDX] =
27861ecc 1150 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
b3fb3a20 1151 CPUID_EXT2_SYSCALL,
0514ef2f 1152 .features[FEAT_8000_0001_ECX] =
becb6667 1153 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
0514ef2f 1154 .features[FEAT_7_0_EBX] =
27861ecc 1155 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1ee91598
EH
1156 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1157 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1158 CPUID_7_0_EBX_RTM,
0bb0b2d2
PB
1159 .features[FEAT_XSAVE] =
1160 CPUID_XSAVE_XSAVEOPT,
28b8e4d0
JK
1161 .features[FEAT_6_EAX] =
1162 CPUID_6_EAX_ARAT,
3046bb5d 1163 .xlevel = 0x80000008,
37507094
EH
1164 .model_id = "Intel Core Processor (Haswell)",
1165 },
a356850b
EH
1166 {
1167 .name = "Broadwell-noTSX",
1168 .level = 0xd,
1169 .vendor = CPUID_VENDOR_INTEL,
1170 .family = 6,
1171 .model = 61,
1172 .stepping = 2,
1173 .features[FEAT_1_EDX] =
1174 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1175 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1176 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1177 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1178 CPUID_DE | CPUID_FP87,
1179 .features[FEAT_1_ECX] =
1180 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1181 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1182 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1183 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1184 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1185 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1186 .features[FEAT_8000_0001_EDX] =
1187 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1188 CPUID_EXT2_SYSCALL,
1189 .features[FEAT_8000_0001_ECX] =
becb6667 1190 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
a356850b
EH
1191 .features[FEAT_7_0_EBX] =
1192 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1193 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1194 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1195 CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1196 CPUID_7_0_EBX_SMAP,
1197 .features[FEAT_XSAVE] =
1198 CPUID_XSAVE_XSAVEOPT,
28b8e4d0
JK
1199 .features[FEAT_6_EAX] =
1200 CPUID_6_EAX_ARAT,
3046bb5d 1201 .xlevel = 0x80000008,
a356850b
EH
1202 .model_id = "Intel Core Processor (Broadwell, no TSX)",
1203 },
ece01354
EH
1204 {
1205 .name = "Broadwell",
1206 .level = 0xd,
1207 .vendor = CPUID_VENDOR_INTEL,
1208 .family = 6,
1209 .model = 61,
1210 .stepping = 2,
1211 .features[FEAT_1_EDX] =
b3a4f0b1 1212 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
ece01354
EH
1213 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1214 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1215 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1216 CPUID_DE | CPUID_FP87,
1217 .features[FEAT_1_ECX] =
1218 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1219 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1220 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1221 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1222 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
78a611f1 1223 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
ece01354
EH
1224 .features[FEAT_8000_0001_EDX] =
1225 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1226 CPUID_EXT2_SYSCALL,
1227 .features[FEAT_8000_0001_ECX] =
becb6667 1228 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
ece01354
EH
1229 .features[FEAT_7_0_EBX] =
1230 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1ee91598 1231 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
ece01354 1232 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1ee91598 1233 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
ece01354 1234 CPUID_7_0_EBX_SMAP,
0bb0b2d2
PB
1235 .features[FEAT_XSAVE] =
1236 CPUID_XSAVE_XSAVEOPT,
28b8e4d0
JK
1237 .features[FEAT_6_EAX] =
1238 CPUID_6_EAX_ARAT,
3046bb5d 1239 .xlevel = 0x80000008,
ece01354
EH
1240 .model_id = "Intel Core Processor (Broadwell)",
1241 },
f6f949e9
EH
1242 {
1243 .name = "Skylake-Client",
1244 .level = 0xd,
1245 .vendor = CPUID_VENDOR_INTEL,
1246 .family = 6,
1247 .model = 94,
1248 .stepping = 3,
1249 .features[FEAT_1_EDX] =
1250 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1251 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1252 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1253 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1254 CPUID_DE | CPUID_FP87,
1255 .features[FEAT_1_ECX] =
1256 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1257 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1258 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1259 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1260 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1261 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1262 .features[FEAT_8000_0001_EDX] =
1263 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1264 CPUID_EXT2_SYSCALL,
1265 .features[FEAT_8000_0001_ECX] =
1266 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
1267 .features[FEAT_7_0_EBX] =
1268 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1269 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1270 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1271 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1272 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
1273 /* Missing: XSAVES (not supported by some Linux versions,
1274 * including v4.1 to v4.6).
1275 * KVM doesn't yet expose any XSAVES state save component,
1276 * and the only one defined in Skylake (processor tracing)
1277 * probably will block migration anyway.
1278 */
1279 .features[FEAT_XSAVE] =
1280 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
1281 CPUID_XSAVE_XGETBV1,
1282 .features[FEAT_6_EAX] =
1283 CPUID_6_EAX_ARAT,
1284 .xlevel = 0x80000008,
1285 .model_id = "Intel Core Processor (Skylake)",
1286 },
3eca4642
EH
1287 {
1288 .name = "Opteron_G1",
1289 .level = 5,
99b88a17 1290 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
1291 .family = 15,
1292 .model = 6,
1293 .stepping = 1,
0514ef2f 1294 .features[FEAT_1_EDX] =
b3a4f0b1 1295 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
b3fb3a20
EH
1296 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1297 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1298 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1299 CPUID_DE | CPUID_FP87,
0514ef2f 1300 .features[FEAT_1_ECX] =
27861ecc 1301 CPUID_EXT_SSE3,
0514ef2f 1302 .features[FEAT_8000_0001_EDX] =
27861ecc 1303 CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
b3fb3a20
EH
1304 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1305 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1306 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1307 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1308 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
3eca4642
EH
1309 .xlevel = 0x80000008,
1310 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
1311 },
1312 {
1313 .name = "Opteron_G2",
1314 .level = 5,
99b88a17 1315 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
1316 .family = 15,
1317 .model = 6,
1318 .stepping = 1,
0514ef2f 1319 .features[FEAT_1_EDX] =
b3a4f0b1 1320 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
b3fb3a20
EH
1321 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1322 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1323 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1324 CPUID_DE | CPUID_FP87,
0514ef2f 1325 .features[FEAT_1_ECX] =
27861ecc 1326 CPUID_EXT_CX16 | CPUID_EXT_SSE3,
33b5e8c0 1327 /* Missing: CPUID_EXT2_RDTSCP */
0514ef2f 1328 .features[FEAT_8000_0001_EDX] =
33b5e8c0 1329 CPUID_EXT2_LM | CPUID_EXT2_FXSR |
b3fb3a20
EH
1330 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1331 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1332 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1333 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1334 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1335 CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 1336 .features[FEAT_8000_0001_ECX] =
27861ecc 1337 CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
3eca4642
EH
1338 .xlevel = 0x80000008,
1339 .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
1340 },
1341 {
1342 .name = "Opteron_G3",
1343 .level = 5,
99b88a17 1344 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
1345 .family = 15,
1346 .model = 6,
1347 .stepping = 1,
0514ef2f 1348 .features[FEAT_1_EDX] =
b3a4f0b1 1349 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
b3fb3a20
EH
1350 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1351 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1352 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1353 CPUID_DE | CPUID_FP87,
0514ef2f 1354 .features[FEAT_1_ECX] =
27861ecc 1355 CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
b3fb3a20 1356 CPUID_EXT_SSE3,
33b5e8c0 1357 /* Missing: CPUID_EXT2_RDTSCP */
0514ef2f 1358 .features[FEAT_8000_0001_EDX] =
33b5e8c0 1359 CPUID_EXT2_LM | CPUID_EXT2_FXSR |
b3fb3a20
EH
1360 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1361 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1362 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1363 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1364 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1365 CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 1366 .features[FEAT_8000_0001_ECX] =
27861ecc 1367 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
b3fb3a20 1368 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
3eca4642
EH
1369 .xlevel = 0x80000008,
1370 .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
1371 },
1372 {
1373 .name = "Opteron_G4",
1374 .level = 0xd,
99b88a17 1375 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
1376 .family = 21,
1377 .model = 1,
1378 .stepping = 2,
0514ef2f 1379 .features[FEAT_1_EDX] =
b3a4f0b1 1380 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
b3fb3a20
EH
1381 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1382 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1383 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1384 CPUID_DE | CPUID_FP87,
0514ef2f 1385 .features[FEAT_1_ECX] =
27861ecc 1386 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
b3fb3a20
EH
1387 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1388 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1389 CPUID_EXT_SSE3,
33b5e8c0 1390 /* Missing: CPUID_EXT2_RDTSCP */
0514ef2f 1391 .features[FEAT_8000_0001_EDX] =
33b5e8c0 1392 CPUID_EXT2_LM |
b3fb3a20
EH
1393 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1394 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1395 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1396 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1397 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1398 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 1399 .features[FEAT_8000_0001_ECX] =
27861ecc 1400 CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
b3fb3a20
EH
1401 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1402 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1403 CPUID_EXT3_LAHF_LM,
0bb0b2d2 1404 /* no xsaveopt! */
3eca4642
EH
1405 .xlevel = 0x8000001A,
1406 .model_id = "AMD Opteron 62xx class CPU",
1407 },
021941b9
AP
1408 {
1409 .name = "Opteron_G5",
1410 .level = 0xd,
99b88a17 1411 .vendor = CPUID_VENDOR_AMD,
021941b9
AP
1412 .family = 21,
1413 .model = 2,
1414 .stepping = 0,
0514ef2f 1415 .features[FEAT_1_EDX] =
b3a4f0b1 1416 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
b3fb3a20
EH
1417 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1418 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1419 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1420 CPUID_DE | CPUID_FP87,
0514ef2f 1421 .features[FEAT_1_ECX] =
27861ecc 1422 CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
b3fb3a20
EH
1423 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1424 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
1425 CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
33b5e8c0 1426 /* Missing: CPUID_EXT2_RDTSCP */
0514ef2f 1427 .features[FEAT_8000_0001_EDX] =
33b5e8c0 1428 CPUID_EXT2_LM |
b3fb3a20
EH
1429 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1430 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1431 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1432 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1433 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1434 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 1435 .features[FEAT_8000_0001_ECX] =
27861ecc 1436 CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
b3fb3a20
EH
1437 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1438 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1439 CPUID_EXT3_LAHF_LM,
0bb0b2d2 1440 /* no xsaveopt! */
021941b9
AP
1441 .xlevel = 0x8000001A,
1442 .model_id = "AMD Opteron 63xx class CPU",
1443 },
c6dc6f63
AP
1444};
1445
5114e842
EH
1446typedef struct PropValue {
1447 const char *prop, *value;
1448} PropValue;
1449
1450/* KVM-specific features that are automatically added/removed
1451 * from all CPU models when KVM is enabled.
1452 */
1453static PropValue kvm_default_props[] = {
1454 { "kvmclock", "on" },
1455 { "kvm-nopiodelay", "on" },
1456 { "kvm-asyncpf", "on" },
1457 { "kvm-steal-time", "on" },
1458 { "kvm-pv-eoi", "on" },
1459 { "kvmclock-stable-bit", "on" },
1460 { "x2apic", "on" },
1461 { "acpi", "off" },
1462 { "monitor", "off" },
1463 { "svm", "off" },
1464 { NULL, NULL },
1465};
1466
1467void x86_cpu_change_kvm_default(const char *prop, const char *value)
1468{
1469 PropValue *pv;
1470 for (pv = kvm_default_props; pv->prop; pv++) {
1471 if (!strcmp(pv->prop, prop)) {
1472 pv->value = value;
1473 break;
1474 }
1475 }
1476
1477 /* It is valid to call this function only for properties that
1478 * are already present in the kvm_default_props table.
1479 */
1480 assert(pv->prop);
1481}
1482
4d1b279b
EH
1483static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
1484 bool migratable_only);
1485
d940ee9b
EH
1486#ifdef CONFIG_KVM
1487
c6dc6f63
AP
1488static int cpu_x86_fill_model_id(char *str)
1489{
1490 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1491 int i;
1492
1493 for (i = 0; i < 3; i++) {
1494 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
1495 memcpy(str + i * 16 + 0, &eax, 4);
1496 memcpy(str + i * 16 + 4, &ebx, 4);
1497 memcpy(str + i * 16 + 8, &ecx, 4);
1498 memcpy(str + i * 16 + 12, &edx, 4);
1499 }
1500 return 0;
1501}
1502
d940ee9b
EH
1503static X86CPUDefinition host_cpudef;
1504
84f1b92f 1505static Property host_x86_cpu_properties[] = {
120eee7d 1506 DEFINE_PROP_BOOL("migratable", X86CPU, migratable, true),
e265e3e4 1507 DEFINE_PROP_BOOL("host-cache-info", X86CPU, cache_info_passthrough, false),
84f1b92f
EH
1508 DEFINE_PROP_END_OF_LIST()
1509};
1510
d940ee9b 1511/* class_init for the "host" CPU model
6e746f30 1512 *
d940ee9b 1513 * This function may be called before KVM is initialized.
6e746f30 1514 */
d940ee9b 1515static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
c6dc6f63 1516{
84f1b92f 1517 DeviceClass *dc = DEVICE_CLASS(oc);
d940ee9b 1518 X86CPUClass *xcc = X86_CPU_CLASS(oc);
c6dc6f63
AP
1519 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1520
d940ee9b 1521 xcc->kvm_required = true;
6e746f30 1522
c6dc6f63 1523 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
d940ee9b 1524 x86_cpu_vendor_words2str(host_cpudef.vendor, ebx, edx, ecx);
c6dc6f63
AP
1525
1526 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
d940ee9b
EH
1527 host_cpudef.family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1528 host_cpudef.model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1529 host_cpudef.stepping = eax & 0x0F;
c6dc6f63 1530
d940ee9b 1531 cpu_x86_fill_model_id(host_cpudef.model_id);
2a573259 1532
d940ee9b 1533 xcc->cpu_def = &host_cpudef;
d940ee9b
EH
1534
1535 /* level, xlevel, xlevel2, and the feature words are initialized on
1536 * instance_init, because they require KVM to be initialized.
1537 */
84f1b92f
EH
1538
1539 dc->props = host_x86_cpu_properties;
4c315c27
MA
1540 /* Reason: host_x86_cpu_initfn() dies when !kvm_enabled() */
1541 dc->cannot_destroy_with_object_finalize_yet = true;
d940ee9b
EH
1542}
1543
1544static void host_x86_cpu_initfn(Object *obj)
1545{
1546 X86CPU *cpu = X86_CPU(obj);
1547 CPUX86State *env = &cpu->env;
1548 KVMState *s = kvm_state;
d940ee9b 1549
4d1b279b
EH
1550 /* We can't fill the features array here because we don't know yet if
1551 * "migratable" is true or false.
1552 */
1553 cpu->host_features = true;
1554
e4356010
EH
1555 /* If KVM is disabled, cpu_x86_create() will already report an error */
1556 if (kvm_enabled()) {
1557 env->cpuid_level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
1558 env->cpuid_xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
1559 env->cpuid_xlevel2 = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
1560 }
2a573259 1561
d940ee9b 1562 object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
c6dc6f63
AP
1563}
1564
d940ee9b
EH
1565static const TypeInfo host_x86_cpu_type_info = {
1566 .name = X86_CPU_TYPE_NAME("host"),
1567 .parent = TYPE_X86_CPU,
1568 .instance_init = host_x86_cpu_initfn,
1569 .class_init = host_x86_cpu_class_init,
1570};
1571
1572#endif
1573
8459e396 1574static void report_unavailable_features(FeatureWord w, uint32_t mask)
c6dc6f63 1575{
8459e396 1576 FeatureWordInfo *f = &feature_word_info[w];
c6dc6f63
AP
1577 int i;
1578
857aee33 1579 for (i = 0; i < 32; ++i) {
72370dc1 1580 if ((1UL << i) & mask) {
bffd67b0 1581 const char *reg = get_register_name_32(f->cpuid_reg);
8b4beddc 1582 assert(reg);
fefb41bf 1583 fprintf(stderr, "warning: %s doesn't support requested feature: "
8b4beddc 1584 "CPUID.%02XH:%s%s%s [bit %d]\n",
fefb41bf 1585 kvm_enabled() ? "host" : "TCG",
bffd67b0
EH
1586 f->cpuid_eax, reg,
1587 f->feat_names[i] ? "." : "",
1588 f->feat_names[i] ? f->feat_names[i] : "", i);
c6dc6f63 1589 }
857aee33 1590 }
c6dc6f63
AP
1591}
1592
d7bce999
EB
1593static void x86_cpuid_version_get_family(Object *obj, Visitor *v,
1594 const char *name, void *opaque,
1595 Error **errp)
95b8519d
AF
1596{
1597 X86CPU *cpu = X86_CPU(obj);
1598 CPUX86State *env = &cpu->env;
1599 int64_t value;
1600
1601 value = (env->cpuid_version >> 8) & 0xf;
1602 if (value == 0xf) {
1603 value += (env->cpuid_version >> 20) & 0xff;
1604 }
51e72bc1 1605 visit_type_int(v, name, &value, errp);
95b8519d
AF
1606}
1607
d7bce999
EB
1608static void x86_cpuid_version_set_family(Object *obj, Visitor *v,
1609 const char *name, void *opaque,
1610 Error **errp)
ed5e1ec3 1611{
71ad61d3
AF
1612 X86CPU *cpu = X86_CPU(obj);
1613 CPUX86State *env = &cpu->env;
1614 const int64_t min = 0;
1615 const int64_t max = 0xff + 0xf;
65cd9064 1616 Error *local_err = NULL;
71ad61d3
AF
1617 int64_t value;
1618
51e72bc1 1619 visit_type_int(v, name, &value, &local_err);
65cd9064
MA
1620 if (local_err) {
1621 error_propagate(errp, local_err);
71ad61d3
AF
1622 return;
1623 }
1624 if (value < min || value > max) {
c6bd8c70
MA
1625 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1626 name ? name : "null", value, min, max);
71ad61d3
AF
1627 return;
1628 }
1629
ed5e1ec3 1630 env->cpuid_version &= ~0xff00f00;
71ad61d3
AF
1631 if (value > 0x0f) {
1632 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
ed5e1ec3 1633 } else {
71ad61d3 1634 env->cpuid_version |= value << 8;
ed5e1ec3
AF
1635 }
1636}
1637
d7bce999
EB
1638static void x86_cpuid_version_get_model(Object *obj, Visitor *v,
1639 const char *name, void *opaque,
1640 Error **errp)
67e30c83
AF
1641{
1642 X86CPU *cpu = X86_CPU(obj);
1643 CPUX86State *env = &cpu->env;
1644 int64_t value;
1645
1646 value = (env->cpuid_version >> 4) & 0xf;
1647 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
51e72bc1 1648 visit_type_int(v, name, &value, errp);
67e30c83
AF
1649}
1650
d7bce999
EB
1651static void x86_cpuid_version_set_model(Object *obj, Visitor *v,
1652 const char *name, void *opaque,
1653 Error **errp)
b0704cbd 1654{
c5291a4f
AF
1655 X86CPU *cpu = X86_CPU(obj);
1656 CPUX86State *env = &cpu->env;
1657 const int64_t min = 0;
1658 const int64_t max = 0xff;
65cd9064 1659 Error *local_err = NULL;
c5291a4f
AF
1660 int64_t value;
1661
51e72bc1 1662 visit_type_int(v, name, &value, &local_err);
65cd9064
MA
1663 if (local_err) {
1664 error_propagate(errp, local_err);
c5291a4f
AF
1665 return;
1666 }
1667 if (value < min || value > max) {
c6bd8c70
MA
1668 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1669 name ? name : "null", value, min, max);
c5291a4f
AF
1670 return;
1671 }
1672
b0704cbd 1673 env->cpuid_version &= ~0xf00f0;
c5291a4f 1674 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
b0704cbd
AF
1675}
1676
35112e41 1677static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
d7bce999 1678 const char *name, void *opaque,
35112e41
AF
1679 Error **errp)
1680{
1681 X86CPU *cpu = X86_CPU(obj);
1682 CPUX86State *env = &cpu->env;
1683 int64_t value;
1684
1685 value = env->cpuid_version & 0xf;
51e72bc1 1686 visit_type_int(v, name, &value, errp);
35112e41
AF
1687}
1688
036e2222 1689static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
d7bce999 1690 const char *name, void *opaque,
036e2222 1691 Error **errp)
38c3dc46 1692{
036e2222
AF
1693 X86CPU *cpu = X86_CPU(obj);
1694 CPUX86State *env = &cpu->env;
1695 const int64_t min = 0;
1696 const int64_t max = 0xf;
65cd9064 1697 Error *local_err = NULL;
036e2222
AF
1698 int64_t value;
1699
51e72bc1 1700 visit_type_int(v, name, &value, &local_err);
65cd9064
MA
1701 if (local_err) {
1702 error_propagate(errp, local_err);
036e2222
AF
1703 return;
1704 }
1705 if (value < min || value > max) {
c6bd8c70
MA
1706 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1707 name ? name : "null", value, min, max);
036e2222
AF
1708 return;
1709 }
1710
38c3dc46 1711 env->cpuid_version &= ~0xf;
036e2222 1712 env->cpuid_version |= value & 0xf;
38c3dc46
AF
1713}
1714
d480e1af
AF
1715static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1716{
1717 X86CPU *cpu = X86_CPU(obj);
1718 CPUX86State *env = &cpu->env;
1719 char *value;
d480e1af 1720
e42a92ae 1721 value = g_malloc(CPUID_VENDOR_SZ + 1);
99b88a17
IM
1722 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
1723 env->cpuid_vendor3);
d480e1af
AF
1724 return value;
1725}
1726
1727static void x86_cpuid_set_vendor(Object *obj, const char *value,
1728 Error **errp)
1729{
1730 X86CPU *cpu = X86_CPU(obj);
1731 CPUX86State *env = &cpu->env;
1732 int i;
1733
9df694ee 1734 if (strlen(value) != CPUID_VENDOR_SZ) {
c6bd8c70 1735 error_setg(errp, QERR_PROPERTY_VALUE_BAD, "", "vendor", value);
d480e1af
AF
1736 return;
1737 }
1738
1739 env->cpuid_vendor1 = 0;
1740 env->cpuid_vendor2 = 0;
1741 env->cpuid_vendor3 = 0;
1742 for (i = 0; i < 4; i++) {
1743 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1744 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1745 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1746 }
d480e1af
AF
1747}
1748
63e886eb
AF
1749static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1750{
1751 X86CPU *cpu = X86_CPU(obj);
1752 CPUX86State *env = &cpu->env;
1753 char *value;
1754 int i;
1755
1756 value = g_malloc(48 + 1);
1757 for (i = 0; i < 48; i++) {
1758 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1759 }
1760 value[48] = '\0';
1761 return value;
1762}
1763
938d4c25
AF
1764static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1765 Error **errp)
dcce6675 1766{
938d4c25
AF
1767 X86CPU *cpu = X86_CPU(obj);
1768 CPUX86State *env = &cpu->env;
dcce6675
AF
1769 int c, len, i;
1770
1771 if (model_id == NULL) {
1772 model_id = "";
1773 }
1774 len = strlen(model_id);
d0a6acf4 1775 memset(env->cpuid_model, 0, 48);
dcce6675
AF
1776 for (i = 0; i < 48; i++) {
1777 if (i >= len) {
1778 c = '\0';
1779 } else {
1780 c = (uint8_t)model_id[i];
1781 }
1782 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1783 }
1784}
1785
d7bce999
EB
1786static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, const char *name,
1787 void *opaque, Error **errp)
89e48965
AF
1788{
1789 X86CPU *cpu = X86_CPU(obj);
1790 int64_t value;
1791
1792 value = cpu->env.tsc_khz * 1000;
51e72bc1 1793 visit_type_int(v, name, &value, errp);
89e48965
AF
1794}
1795
d7bce999
EB
1796static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
1797 void *opaque, Error **errp)
89e48965
AF
1798{
1799 X86CPU *cpu = X86_CPU(obj);
1800 const int64_t min = 0;
2e84849a 1801 const int64_t max = INT64_MAX;
65cd9064 1802 Error *local_err = NULL;
89e48965
AF
1803 int64_t value;
1804
51e72bc1 1805 visit_type_int(v, name, &value, &local_err);
65cd9064
MA
1806 if (local_err) {
1807 error_propagate(errp, local_err);
89e48965
AF
1808 return;
1809 }
1810 if (value < min || value > max) {
c6bd8c70
MA
1811 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1812 name ? name : "null", value, min, max);
89e48965
AF
1813 return;
1814 }
1815
36f96c4b 1816 cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
89e48965
AF
1817}
1818
d7bce999
EB
1819static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, const char *name,
1820 void *opaque, Error **errp)
31050930
IM
1821{
1822 X86CPU *cpu = X86_CPU(obj);
7e72a45c 1823 int64_t value = cpu->apic_id;
31050930 1824
51e72bc1 1825 visit_type_int(v, name, &value, errp);
31050930
IM
1826}
1827
d7bce999
EB
1828static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, const char *name,
1829 void *opaque, Error **errp)
31050930
IM
1830{
1831 X86CPU *cpu = X86_CPU(obj);
8d6d4980 1832 DeviceState *dev = DEVICE(obj);
31050930
IM
1833 const int64_t min = 0;
1834 const int64_t max = UINT32_MAX;
1835 Error *error = NULL;
1836 int64_t value;
1837
8d6d4980
IM
1838 if (dev->realized) {
1839 error_setg(errp, "Attempt to set property '%s' on '%s' after "
1840 "it was realized", name, object_get_typename(obj));
1841 return;
1842 }
1843
51e72bc1 1844 visit_type_int(v, name, &value, &error);
31050930
IM
1845 if (error) {
1846 error_propagate(errp, error);
1847 return;
1848 }
1849 if (value < min || value > max) {
1850 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1851 " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
1852 object_get_typename(obj), name, value, min, max);
1853 return;
1854 }
1855
7e72a45c 1856 if ((value != cpu->apic_id) && cpu_exists(value)) {
31050930
IM
1857 error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
1858 return;
1859 }
7e72a45c 1860 cpu->apic_id = value;
31050930
IM
1861}
1862
7e5292b5 1863/* Generic getter for "feature-words" and "filtered-features" properties */
d7bce999
EB
1864static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
1865 const char *name, void *opaque,
1866 Error **errp)
8e8aba50 1867{
7e5292b5 1868 uint32_t *array = (uint32_t *)opaque;
8e8aba50
EH
1869 FeatureWord w;
1870 Error *err = NULL;
1871 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
1872 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
1873 X86CPUFeatureWordInfoList *list = NULL;
1874
1875 for (w = 0; w < FEATURE_WORDS; w++) {
1876 FeatureWordInfo *wi = &feature_word_info[w];
1877 X86CPUFeatureWordInfo *qwi = &word_infos[w];
1878 qwi->cpuid_input_eax = wi->cpuid_eax;
1879 qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
1880 qwi->cpuid_input_ecx = wi->cpuid_ecx;
1881 qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
7e5292b5 1882 qwi->features = array[w];
8e8aba50
EH
1883
1884 /* List will be in reverse order, but order shouldn't matter */
1885 list_entries[w].next = list;
1886 list_entries[w].value = &word_infos[w];
1887 list = &list_entries[w];
1888 }
1889
51e72bc1 1890 visit_type_X86CPUFeatureWordInfoList(v, "feature-words", &list, &err);
8e8aba50
EH
1891 error_propagate(errp, err);
1892}
1893
d7bce999
EB
1894static void x86_get_hv_spinlocks(Object *obj, Visitor *v, const char *name,
1895 void *opaque, Error **errp)
c8f0f88e
IM
1896{
1897 X86CPU *cpu = X86_CPU(obj);
1898 int64_t value = cpu->hyperv_spinlock_attempts;
1899
51e72bc1 1900 visit_type_int(v, name, &value, errp);
c8f0f88e
IM
1901}
1902
d7bce999
EB
1903static void x86_set_hv_spinlocks(Object *obj, Visitor *v, const char *name,
1904 void *opaque, Error **errp)
c8f0f88e
IM
1905{
1906 const int64_t min = 0xFFF;
1907 const int64_t max = UINT_MAX;
1908 X86CPU *cpu = X86_CPU(obj);
1909 Error *err = NULL;
1910 int64_t value;
1911
51e72bc1 1912 visit_type_int(v, name, &value, &err);
c8f0f88e
IM
1913 if (err) {
1914 error_propagate(errp, err);
1915 return;
1916 }
1917
1918 if (value < min || value > max) {
1919 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
5bb4c35d 1920 " (minimum: %" PRId64 ", maximum: %" PRId64 ")",
1921 object_get_typename(obj), name ? name : "null",
1922 value, min, max);
c8f0f88e
IM
1923 return;
1924 }
1925 cpu->hyperv_spinlock_attempts = value;
1926}
1927
1928static PropertyInfo qdev_prop_spinlocks = {
1929 .name = "int",
1930 .get = x86_get_hv_spinlocks,
1931 .set = x86_set_hv_spinlocks,
1932};
1933
72ac2e87
IM
1934/* Convert all '_' in a feature string option name to '-', to make feature
1935 * name conform to QOM property naming rule, which uses '-' instead of '_'.
1936 */
1937static inline void feat2prop(char *s)
1938{
1939 while ((s = strchr(s, '_'))) {
1940 *s = '-';
1941 }
1942}
1943
dc15c051
IM
1944/* Compatibily hack to maintain legacy +-feat semantic,
1945 * where +-feat overwrites any feature set by
1946 * feat=on|feat even if the later is parsed after +-feat
1947 * (i.e. "-x2apic,x2apic=on" will result in x2apic disabled)
1948 */
1949static FeatureWordArray plus_features = { 0 };
1950static FeatureWordArray minus_features = { 0 };
1951
8f961357
EH
1952/* Parse "+feature,-feature,feature=foo" CPU feature string
1953 */
94a444b2
AF
1954static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
1955 Error **errp)
8f961357 1956{
94a444b2 1957 X86CPU *cpu = X86_CPU(cs);
8f961357 1958 char *featurestr; /* Single 'key=value" string being parsed */
94a444b2 1959 Error *local_err = NULL;
8f961357 1960
8f961357 1961 featurestr = features ? strtok(features, ",") : NULL;
c6dc6f63
AP
1962
1963 while (featurestr) {
1964 char *val;
1965 if (featurestr[0] == '+') {
c00c94ab 1966 add_flagname_to_bitmaps(featurestr + 1, plus_features, &local_err);
c6dc6f63 1967 } else if (featurestr[0] == '-') {
c00c94ab 1968 add_flagname_to_bitmaps(featurestr + 1, minus_features, &local_err);
c6dc6f63
AP
1969 } else if ((val = strchr(featurestr, '='))) {
1970 *val = 0; val++;
72ac2e87 1971 feat2prop(featurestr);
c19b8521 1972 if (!strcmp(featurestr, "tsc-freq")) {
b862d1fe
JR
1973 int64_t tsc_freq;
1974 char *err;
a91987c2 1975 char num[32];
b862d1fe 1976
4677bb40
MAL
1977 tsc_freq = qemu_strtosz_suffix_unit(val, &err,
1978 QEMU_STRTOSZ_DEFSUFFIX_B, 1000);
45009a30 1979 if (tsc_freq < 0 || *err) {
6b1dd54b
PB
1980 error_setg(errp, "bad numerical value %s", val);
1981 return;
b862d1fe 1982 }
a91987c2 1983 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
94a444b2
AF
1984 object_property_parse(OBJECT(cpu), num, "tsc-frequency",
1985 &local_err);
c6dc6f63 1986 } else {
94a444b2 1987 object_property_parse(OBJECT(cpu), val, featurestr, &local_err);
c6dc6f63 1988 }
c6dc6f63 1989 } else {
258f5abe 1990 feat2prop(featurestr);
94a444b2 1991 object_property_parse(OBJECT(cpu), "on", featurestr, &local_err);
a91987c2 1992 }
94a444b2
AF
1993 if (local_err) {
1994 error_propagate(errp, local_err);
6b1dd54b 1995 return;
c6dc6f63
AP
1996 }
1997 featurestr = strtok(NULL, ",");
1998 }
c6dc6f63
AP
1999}
2000
8c3329e5 2001/* Print all cpuid feature names in featureset
c6dc6f63 2002 */
8c3329e5 2003static void listflags(FILE *f, fprintf_function print, const char **featureset)
0856579c 2004{
8c3329e5
EH
2005 int bit;
2006 bool first = true;
2007
2008 for (bit = 0; bit < 32; bit++) {
2009 if (featureset[bit]) {
2010 print(f, "%s%s", first ? "" : " ", featureset[bit]);
2011 first = false;
c6dc6f63 2012 }
8c3329e5 2013 }
c6dc6f63
AP
2014}
2015
e916cbf8
PM
2016/* generate CPU information. */
2017void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
c6dc6f63 2018{
9576de75 2019 X86CPUDefinition *def;
c6dc6f63 2020 char buf[256];
7fc9b714 2021 int i;
c6dc6f63 2022
7fc9b714
AF
2023 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
2024 def = &builtin_x86_defs[i];
c04321b3 2025 snprintf(buf, sizeof(buf), "%s", def->name);
6cdf8854 2026 (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
c6dc6f63 2027 }
21ad7789
JK
2028#ifdef CONFIG_KVM
2029 (*cpu_fprintf)(f, "x86 %16s %-48s\n", "host",
2030 "KVM processor with all supported host features "
2031 "(only available in KVM mode)");
2032#endif
2033
6cdf8854 2034 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
3af60be2
JK
2035 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
2036 FeatureWordInfo *fw = &feature_word_info[i];
2037
8c3329e5
EH
2038 (*cpu_fprintf)(f, " ");
2039 listflags(f, cpu_fprintf, fw->feat_names);
2040 (*cpu_fprintf)(f, "\n");
3af60be2 2041 }
c6dc6f63
AP
2042}
2043
76b64a7a 2044CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
e3966126
AL
2045{
2046 CpuDefinitionInfoList *cpu_list = NULL;
9576de75 2047 X86CPUDefinition *def;
7fc9b714 2048 int i;
e3966126 2049
7fc9b714 2050 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
e3966126
AL
2051 CpuDefinitionInfoList *entry;
2052 CpuDefinitionInfo *info;
2053
7fc9b714 2054 def = &builtin_x86_defs[i];
e3966126
AL
2055 info = g_malloc0(sizeof(*info));
2056 info->name = g_strdup(def->name);
2057
2058 entry = g_malloc0(sizeof(*entry));
2059 entry->value = info;
2060 entry->next = cpu_list;
2061 cpu_list = entry;
2062 }
2063
2064 return cpu_list;
2065}
2066
84f1b92f
EH
2067static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
2068 bool migratable_only)
27418adf
EH
2069{
2070 FeatureWordInfo *wi = &feature_word_info[w];
84f1b92f 2071 uint32_t r;
27418adf 2072
fefb41bf 2073 if (kvm_enabled()) {
84f1b92f
EH
2074 r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid_eax,
2075 wi->cpuid_ecx,
2076 wi->cpuid_reg);
fefb41bf 2077 } else if (tcg_enabled()) {
84f1b92f 2078 r = wi->tcg_features;
fefb41bf
EH
2079 } else {
2080 return ~0;
2081 }
84f1b92f
EH
2082 if (migratable_only) {
2083 r &= x86_cpu_get_migratable_flags(w);
2084 }
2085 return r;
27418adf
EH
2086}
2087
51f63aed
EH
2088/*
2089 * Filters CPU feature words based on host availability of each feature.
2090 *
51f63aed
EH
2091 * Returns: 0 if all flags are supported by the host, non-zero otherwise.
2092 */
27418adf 2093static int x86_cpu_filter_features(X86CPU *cpu)
bc74b7db
EH
2094{
2095 CPUX86State *env = &cpu->env;
bd87d2a2 2096 FeatureWord w;
51f63aed
EH
2097 int rv = 0;
2098
bd87d2a2 2099 for (w = 0; w < FEATURE_WORDS; w++) {
84f1b92f
EH
2100 uint32_t host_feat =
2101 x86_cpu_get_supported_feature_word(w, cpu->migratable);
034acf4a
EH
2102 uint32_t requested_features = env->features[w];
2103 env->features[w] &= host_feat;
2104 cpu->filtered_features[w] = requested_features & ~env->features[w];
51f63aed
EH
2105 if (cpu->filtered_features[w]) {
2106 if (cpu->check_cpuid || cpu->enforce_cpuid) {
8459e396 2107 report_unavailable_features(w, cpu->filtered_features[w]);
51f63aed
EH
2108 }
2109 rv = 1;
2110 }
bd87d2a2 2111 }
51f63aed
EH
2112
2113 return rv;
bc74b7db 2114}
bc74b7db 2115
5114e842
EH
2116static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
2117{
2118 PropValue *pv;
2119 for (pv = props; pv->prop; pv++) {
2120 if (!pv->value) {
2121 continue;
2122 }
2123 object_property_parse(OBJECT(cpu), pv->value, pv->prop,
2124 &error_abort);
2125 }
2126}
2127
d940ee9b 2128/* Load data from X86CPUDefinition
c080e30e 2129 */
d940ee9b 2130static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
c6dc6f63 2131{
61dcd775 2132 CPUX86State *env = &cpu->env;
74f54bc4
EH
2133 const char *vendor;
2134 char host_vendor[CPUID_VENDOR_SZ + 1];
e1c224b4 2135 FeatureWord w;
c6dc6f63 2136
2d64255b
AF
2137 object_property_set_int(OBJECT(cpu), def->level, "level", errp);
2138 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
2139 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
2140 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
2d64255b 2141 object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
01431f3c 2142 object_property_set_int(OBJECT(cpu), def->xlevel2, "xlevel2", errp);
2d64255b 2143 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
e1c224b4
EH
2144 for (w = 0; w < FEATURE_WORDS; w++) {
2145 env->features[w] = def->features[w];
2146 }
82beb536 2147
9576de75 2148 /* Special cases not set in the X86CPUDefinition structs: */
82beb536 2149 if (kvm_enabled()) {
492a4c94
LT
2150 if (!kvm_irqchip_in_kernel()) {
2151 x86_cpu_change_kvm_default("x2apic", "off");
2152 }
2153
5114e842 2154 x86_cpu_apply_props(cpu, kvm_default_props);
82beb536 2155 }
5fcca9ff 2156
82beb536 2157 env->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
7c08db30
EH
2158
2159 /* sysenter isn't supported in compatibility mode on AMD,
2160 * syscall isn't supported in compatibility mode on Intel.
2161 * Normally we advertise the actual CPU vendor, but you can
2162 * override this using the 'vendor' property if you want to use
2163 * KVM's sysenter/syscall emulation in compatibility mode and
2164 * when doing cross vendor migration
2165 */
74f54bc4 2166 vendor = def->vendor;
7c08db30
EH
2167 if (kvm_enabled()) {
2168 uint32_t ebx = 0, ecx = 0, edx = 0;
2169 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
2170 x86_cpu_vendor_words2str(host_vendor, ebx, edx, ecx);
2171 vendor = host_vendor;
2172 }
2173
2174 object_property_set_str(OBJECT(cpu), vendor, "vendor", errp);
2175
c6dc6f63
AP
2176}
2177
e1570d00 2178X86CPU *cpu_x86_create(const char *cpu_model, Error **errp)
5c3c6a68 2179{
2d64255b 2180 X86CPU *cpu = NULL;
d940ee9b 2181 X86CPUClass *xcc;
500050d1 2182 ObjectClass *oc;
2d64255b
AF
2183 gchar **model_pieces;
2184 char *name, *features;
5c3c6a68
AF
2185 Error *error = NULL;
2186
2d64255b
AF
2187 model_pieces = g_strsplit(cpu_model, ",", 2);
2188 if (!model_pieces[0]) {
2189 error_setg(&error, "Invalid/empty CPU model name");
2190 goto out;
2191 }
2192 name = model_pieces[0];
2193 features = model_pieces[1];
2194
500050d1
AF
2195 oc = x86_cpu_class_by_name(name);
2196 if (oc == NULL) {
2197 error_setg(&error, "Unable to find CPU definition: %s", name);
2198 goto out;
2199 }
d940ee9b
EH
2200 xcc = X86_CPU_CLASS(oc);
2201
2202 if (xcc->kvm_required && !kvm_enabled()) {
2203 error_setg(&error, "CPU model '%s' requires KVM", name);
285f025d
EH
2204 goto out;
2205 }
2206
d940ee9b
EH
2207 cpu = X86_CPU(object_new(object_class_get_name(oc)));
2208
94a444b2 2209 x86_cpu_parse_featurestr(CPU(cpu), features, &error);
2d64255b
AF
2210 if (error) {
2211 goto out;
5c3c6a68
AF
2212 }
2213
7f833247 2214out:
cd7b87ff
AF
2215 if (error != NULL) {
2216 error_propagate(errp, error);
500050d1
AF
2217 if (cpu) {
2218 object_unref(OBJECT(cpu));
2219 cpu = NULL;
2220 }
cd7b87ff 2221 }
7f833247
IM
2222 g_strfreev(model_pieces);
2223 return cpu;
2224}
2225
0856579c 2226X86CPU *cpu_x86_init(const char *cpu_model)
7f833247
IM
2227{
2228 Error *error = NULL;
2229 X86CPU *cpu;
2230
e1570d00 2231 cpu = cpu_x86_create(cpu_model, &error);
5c3c6a68 2232 if (error) {
0856579c 2233 goto out;
9c235e83 2234 }
7f833247 2235
7f833247 2236 object_property_set_bool(OBJECT(cpu), true, "realized", &error);
18b0e4e7 2237
0856579c
PM
2238out:
2239 if (error) {
2240 error_report_err(error);
2241 if (cpu != NULL) {
2242 object_unref(OBJECT(cpu));
2243 cpu = NULL;
2244 }
18b0e4e7 2245 }
0856579c 2246 return cpu;
5c3c6a68
AF
2247}
2248
d940ee9b
EH
2249static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
2250{
2251 X86CPUDefinition *cpudef = data;
2252 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2253
2254 xcc->cpu_def = cpudef;
2255}
2256
2257static void x86_register_cpudef_type(X86CPUDefinition *def)
2258{
2259 char *typename = x86_cpu_type_name(def->name);
2260 TypeInfo ti = {
2261 .name = typename,
2262 .parent = TYPE_X86_CPU,
2263 .class_init = x86_cpu_cpudef_class_init,
2264 .class_data = def,
2265 };
2266
2267 type_register(&ti);
2268 g_free(typename);
2269}
2270
c6dc6f63 2271#if !defined(CONFIG_USER_ONLY)
c6dc6f63 2272
0e26b7b8
BS
2273void cpu_clear_apic_feature(CPUX86State *env)
2274{
0514ef2f 2275 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
0e26b7b8
BS
2276}
2277
c6dc6f63
AP
2278#endif /* !CONFIG_USER_ONLY */
2279
c6dc6f63
AP
2280void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
2281 uint32_t *eax, uint32_t *ebx,
2282 uint32_t *ecx, uint32_t *edx)
2283{
a60f24b5
AF
2284 X86CPU *cpu = x86_env_get_cpu(env);
2285 CPUState *cs = CPU(cpu);
2286
c6dc6f63
AP
2287 /* test if maximum index reached */
2288 if (index & 0x80000000) {
b3baa152
BW
2289 if (index > env->cpuid_xlevel) {
2290 if (env->cpuid_xlevel2 > 0) {
2291 /* Handle the Centaur's CPUID instruction. */
2292 if (index > env->cpuid_xlevel2) {
2293 index = env->cpuid_xlevel2;
2294 } else if (index < 0xC0000000) {
2295 index = env->cpuid_xlevel;
2296 }
2297 } else {
57f26ae7
EH
2298 /* Intel documentation states that invalid EAX input will
2299 * return the same information as EAX=cpuid_level
2300 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
2301 */
2302 index = env->cpuid_level;
b3baa152
BW
2303 }
2304 }
c6dc6f63
AP
2305 } else {
2306 if (index > env->cpuid_level)
2307 index = env->cpuid_level;
2308 }
2309
2310 switch(index) {
2311 case 0:
2312 *eax = env->cpuid_level;
5eb2f7a4
EH
2313 *ebx = env->cpuid_vendor1;
2314 *edx = env->cpuid_vendor2;
2315 *ecx = env->cpuid_vendor3;
c6dc6f63
AP
2316 break;
2317 case 1:
2318 *eax = env->cpuid_version;
7e72a45c
EH
2319 *ebx = (cpu->apic_id << 24) |
2320 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
0514ef2f 2321 *ecx = env->features[FEAT_1_ECX];
19dc85db
RH
2322 if ((*ecx & CPUID_EXT_XSAVE) && (env->cr[4] & CR4_OSXSAVE_MASK)) {
2323 *ecx |= CPUID_EXT_OSXSAVE;
2324 }
0514ef2f 2325 *edx = env->features[FEAT_1_EDX];
ce3960eb
AF
2326 if (cs->nr_cores * cs->nr_threads > 1) {
2327 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
19dc85db 2328 *edx |= CPUID_HT;
c6dc6f63
AP
2329 }
2330 break;
2331 case 2:
2332 /* cache info: needed for Pentium Pro compatibility */
787aaf57
BC
2333 if (cpu->cache_info_passthrough) {
2334 host_cpuid(index, 0, eax, ebx, ecx, edx);
2335 break;
2336 }
5e891bf8 2337 *eax = 1; /* Number of CPUID[EAX=2] calls required */
c6dc6f63
AP
2338 *ebx = 0;
2339 *ecx = 0;
5e891bf8
EH
2340 *edx = (L1D_DESCRIPTOR << 16) | \
2341 (L1I_DESCRIPTOR << 8) | \
2342 (L2_DESCRIPTOR);
c6dc6f63
AP
2343 break;
2344 case 4:
2345 /* cache info: needed for Core compatibility */
787aaf57
BC
2346 if (cpu->cache_info_passthrough) {
2347 host_cpuid(index, count, eax, ebx, ecx, edx);
76c2975a 2348 *eax &= ~0xFC000000;
c6dc6f63 2349 } else {
2f7a21c4 2350 *eax = 0;
76c2975a 2351 switch (count) {
c6dc6f63 2352 case 0: /* L1 dcache info */
5e891bf8
EH
2353 *eax |= CPUID_4_TYPE_DCACHE | \
2354 CPUID_4_LEVEL(1) | \
2355 CPUID_4_SELF_INIT_LEVEL;
2356 *ebx = (L1D_LINE_SIZE - 1) | \
2357 ((L1D_PARTITIONS - 1) << 12) | \
2358 ((L1D_ASSOCIATIVITY - 1) << 22);
2359 *ecx = L1D_SETS - 1;
2360 *edx = CPUID_4_NO_INVD_SHARING;
c6dc6f63
AP
2361 break;
2362 case 1: /* L1 icache info */
5e891bf8
EH
2363 *eax |= CPUID_4_TYPE_ICACHE | \
2364 CPUID_4_LEVEL(1) | \
2365 CPUID_4_SELF_INIT_LEVEL;
2366 *ebx = (L1I_LINE_SIZE - 1) | \
2367 ((L1I_PARTITIONS - 1) << 12) | \
2368 ((L1I_ASSOCIATIVITY - 1) << 22);
2369 *ecx = L1I_SETS - 1;
2370 *edx = CPUID_4_NO_INVD_SHARING;
c6dc6f63
AP
2371 break;
2372 case 2: /* L2 cache info */
5e891bf8
EH
2373 *eax |= CPUID_4_TYPE_UNIFIED | \
2374 CPUID_4_LEVEL(2) | \
2375 CPUID_4_SELF_INIT_LEVEL;
ce3960eb
AF
2376 if (cs->nr_threads > 1) {
2377 *eax |= (cs->nr_threads - 1) << 14;
c6dc6f63 2378 }
5e891bf8
EH
2379 *ebx = (L2_LINE_SIZE - 1) | \
2380 ((L2_PARTITIONS - 1) << 12) | \
2381 ((L2_ASSOCIATIVITY - 1) << 22);
2382 *ecx = L2_SETS - 1;
2383 *edx = CPUID_4_NO_INVD_SHARING;
c6dc6f63
AP
2384 break;
2385 default: /* end of info */
2386 *eax = 0;
2387 *ebx = 0;
2388 *ecx = 0;
2389 *edx = 0;
2390 break;
76c2975a
PB
2391 }
2392 }
2393
2394 /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
2395 if ((*eax & 31) && cs->nr_cores > 1) {
2396 *eax |= (cs->nr_cores - 1) << 26;
c6dc6f63
AP
2397 }
2398 break;
2399 case 5:
2400 /* mwait info: needed for Core compatibility */
2401 *eax = 0; /* Smallest monitor-line size in bytes */
2402 *ebx = 0; /* Largest monitor-line size in bytes */
2403 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
2404 *edx = 0;
2405 break;
2406 case 6:
2407 /* Thermal and Power Leaf */
28b8e4d0 2408 *eax = env->features[FEAT_6_EAX];
c6dc6f63
AP
2409 *ebx = 0;
2410 *ecx = 0;
2411 *edx = 0;
2412 break;
f7911686 2413 case 7:
13526728
EH
2414 /* Structured Extended Feature Flags Enumeration Leaf */
2415 if (count == 0) {
2416 *eax = 0; /* Maximum ECX value for sub-leaves */
0514ef2f 2417 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
f74eefe0 2418 *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */
0f70ed47
PB
2419 if ((*ecx & CPUID_7_0_ECX_PKU) && env->cr[4] & CR4_PKE_MASK) {
2420 *ecx |= CPUID_7_0_ECX_OSPKE;
2421 }
13526728 2422 *edx = 0; /* Reserved */
f7911686
YW
2423 } else {
2424 *eax = 0;
2425 *ebx = 0;
2426 *ecx = 0;
2427 *edx = 0;
2428 }
2429 break;
c6dc6f63
AP
2430 case 9:
2431 /* Direct Cache Access Information Leaf */
2432 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2433 *ebx = 0;
2434 *ecx = 0;
2435 *edx = 0;
2436 break;
2437 case 0xA:
2438 /* Architectural Performance Monitoring Leaf */
9337e3b6 2439 if (kvm_enabled() && cpu->enable_pmu) {
a60f24b5 2440 KVMState *s = cs->kvm_state;
a0fa8208
GN
2441
2442 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
2443 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
2444 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
2445 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
2446 } else {
2447 *eax = 0;
2448 *ebx = 0;
2449 *ecx = 0;
2450 *edx = 0;
2451 }
c6dc6f63 2452 break;
5232d00a
RK
2453 case 0xB:
2454 /* Extended Topology Enumeration Leaf */
2455 if (!cpu->enable_cpuid_0xb) {
2456 *eax = *ebx = *ecx = *edx = 0;
2457 break;
2458 }
2459
2460 *ecx = count & 0xff;
2461 *edx = cpu->apic_id;
2462
2463 switch (count) {
2464 case 0:
2465 *eax = apicid_core_offset(smp_cores, smp_threads);
2466 *ebx = smp_threads;
2467 *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
2468 break;
2469 case 1:
2470 *eax = apicid_pkg_offset(smp_cores, smp_threads);
2471 *ebx = smp_cores * smp_threads;
2472 *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
2473 break;
2474 default:
2475 *eax = 0;
2476 *ebx = 0;
2477 *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
2478 }
2479
2480 assert(!(*eax & ~0x1f));
2481 *ebx &= 0xffff; /* The count doesn't need to be reliable. */
2482 break;
2560f19f
PB
2483 case 0xD: {
2484 KVMState *s = cs->kvm_state;
19dc85db 2485 uint64_t ena_mask;
2560f19f
PB
2486 int i;
2487
51e49430 2488 /* Processor Extended State */
2560f19f
PB
2489 *eax = 0;
2490 *ebx = 0;
2491 *ecx = 0;
2492 *edx = 0;
19dc85db 2493 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
51e49430
SY
2494 break;
2495 }
19dc85db
RH
2496 if (kvm_enabled()) {
2497 ena_mask = kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX);
2498 ena_mask <<= 32;
2499 ena_mask |= kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX);
2500 } else {
2501 ena_mask = -1;
2502 }
ba9bc59e 2503
2560f19f
PB
2504 if (count == 0) {
2505 *ecx = 0x240;
f4f1110e
RH
2506 for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
2507 const ExtSaveArea *esa = &x86_ext_save_areas[i];
19dc85db
RH
2508 if ((env->features[esa->feature] & esa->bits) == esa->bits
2509 && ((ena_mask >> i) & 1) != 0) {
2560f19f 2510 if (i < 32) {
19dc85db 2511 *eax |= 1u << i;
2560f19f 2512 } else {
19dc85db 2513 *edx |= 1u << (i - 32);
2560f19f
PB
2514 }
2515 *ecx = MAX(*ecx, esa->offset + esa->size);
2516 }
2517 }
cfc3b074 2518 *eax |= ena_mask & (XSTATE_FP_MASK | XSTATE_SSE_MASK);
2560f19f
PB
2519 *ebx = *ecx;
2520 } else if (count == 1) {
0bb0b2d2 2521 *eax = env->features[FEAT_XSAVE];
f4f1110e
RH
2522 } else if (count < ARRAY_SIZE(x86_ext_save_areas)) {
2523 const ExtSaveArea *esa = &x86_ext_save_areas[count];
19dc85db
RH
2524 if ((env->features[esa->feature] & esa->bits) == esa->bits
2525 && ((ena_mask >> count) & 1) != 0) {
33f373d7
LJ
2526 *eax = esa->size;
2527 *ebx = esa->offset;
2560f19f 2528 }
51e49430
SY
2529 }
2530 break;
2560f19f 2531 }
c6dc6f63
AP
2532 case 0x80000000:
2533 *eax = env->cpuid_xlevel;
2534 *ebx = env->cpuid_vendor1;
2535 *edx = env->cpuid_vendor2;
2536 *ecx = env->cpuid_vendor3;
2537 break;
2538 case 0x80000001:
2539 *eax = env->cpuid_version;
2540 *ebx = 0;
0514ef2f
EH
2541 *ecx = env->features[FEAT_8000_0001_ECX];
2542 *edx = env->features[FEAT_8000_0001_EDX];
c6dc6f63
AP
2543
2544 /* The Linux kernel checks for the CMPLegacy bit and
2545 * discards multiple thread information if it is set.
cb8d4c8f 2546 * So don't set it here for Intel to make Linux guests happy.
c6dc6f63 2547 */
ce3960eb 2548 if (cs->nr_cores * cs->nr_threads > 1) {
5eb2f7a4
EH
2549 if (env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1 ||
2550 env->cpuid_vendor2 != CPUID_VENDOR_INTEL_2 ||
2551 env->cpuid_vendor3 != CPUID_VENDOR_INTEL_3) {
c6dc6f63
AP
2552 *ecx |= 1 << 1; /* CmpLegacy bit */
2553 }
2554 }
c6dc6f63
AP
2555 break;
2556 case 0x80000002:
2557 case 0x80000003:
2558 case 0x80000004:
2559 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2560 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2561 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2562 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2563 break;
2564 case 0x80000005:
2565 /* cache info (L1 cache) */
787aaf57
BC
2566 if (cpu->cache_info_passthrough) {
2567 host_cpuid(index, 0, eax, ebx, ecx, edx);
2568 break;
2569 }
5e891bf8
EH
2570 *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \
2571 (L1_ITLB_2M_ASSOC << 8) | (L1_ITLB_2M_ENTRIES);
2572 *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
2573 (L1_ITLB_4K_ASSOC << 8) | (L1_ITLB_4K_ENTRIES);
2574 *ecx = (L1D_SIZE_KB_AMD << 24) | (L1D_ASSOCIATIVITY_AMD << 16) | \
2575 (L1D_LINES_PER_TAG << 8) | (L1D_LINE_SIZE);
2576 *edx = (L1I_SIZE_KB_AMD << 24) | (L1I_ASSOCIATIVITY_AMD << 16) | \
2577 (L1I_LINES_PER_TAG << 8) | (L1I_LINE_SIZE);
c6dc6f63
AP
2578 break;
2579 case 0x80000006:
2580 /* cache info (L2 cache) */
787aaf57
BC
2581 if (cpu->cache_info_passthrough) {
2582 host_cpuid(index, 0, eax, ebx, ecx, edx);
2583 break;
2584 }
5e891bf8
EH
2585 *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \
2586 (L2_DTLB_2M_ENTRIES << 16) | \
2587 (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \
2588 (L2_ITLB_2M_ENTRIES);
2589 *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) | \
2590 (L2_DTLB_4K_ENTRIES << 16) | \
2591 (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
2592 (L2_ITLB_4K_ENTRIES);
2593 *ecx = (L2_SIZE_KB_AMD << 16) | \
2594 (AMD_ENC_ASSOC(L2_ASSOCIATIVITY) << 12) | \
2595 (L2_LINES_PER_TAG << 8) | (L2_LINE_SIZE);
2596 *edx = ((L3_SIZE_KB/512) << 18) | \
2597 (AMD_ENC_ASSOC(L3_ASSOCIATIVITY) << 12) | \
2598 (L3_LINES_PER_TAG << 8) | (L3_LINE_SIZE);
c6dc6f63 2599 break;
303752a9
MT
2600 case 0x80000007:
2601 *eax = 0;
2602 *ebx = 0;
2603 *ecx = 0;
2604 *edx = env->features[FEAT_8000_0007_EDX];
2605 break;
c6dc6f63
AP
2606 case 0x80000008:
2607 /* virtual & phys address size in low 2 bytes. */
2608/* XXX: This value must match the one used in the MMU code. */
0514ef2f 2609 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
c6dc6f63
AP
2610 /* 64 bit processor */
2611/* XXX: The physical address space is limited to 42 bits in exec.c. */
dd13e088 2612 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
c6dc6f63 2613 } else {
0514ef2f 2614 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
c6dc6f63 2615 *eax = 0x00000024; /* 36 bits physical */
dd13e088 2616 } else {
c6dc6f63 2617 *eax = 0x00000020; /* 32 bits physical */
dd13e088 2618 }
c6dc6f63
AP
2619 }
2620 *ebx = 0;
2621 *ecx = 0;
2622 *edx = 0;
ce3960eb
AF
2623 if (cs->nr_cores * cs->nr_threads > 1) {
2624 *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
c6dc6f63
AP
2625 }
2626 break;
2627 case 0x8000000A:
0514ef2f 2628 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
9f3fb565
EH
2629 *eax = 0x00000001; /* SVM Revision */
2630 *ebx = 0x00000010; /* nr of ASIDs */
2631 *ecx = 0;
0514ef2f 2632 *edx = env->features[FEAT_SVM]; /* optional features */
9f3fb565
EH
2633 } else {
2634 *eax = 0;
2635 *ebx = 0;
2636 *ecx = 0;
2637 *edx = 0;
2638 }
c6dc6f63 2639 break;
b3baa152
BW
2640 case 0xC0000000:
2641 *eax = env->cpuid_xlevel2;
2642 *ebx = 0;
2643 *ecx = 0;
2644 *edx = 0;
2645 break;
2646 case 0xC0000001:
2647 /* Support for VIA CPU's CPUID instruction */
2648 *eax = env->cpuid_version;
2649 *ebx = 0;
2650 *ecx = 0;
0514ef2f 2651 *edx = env->features[FEAT_C000_0001_EDX];
b3baa152
BW
2652 break;
2653 case 0xC0000002:
2654 case 0xC0000003:
2655 case 0xC0000004:
2656 /* Reserved for the future, and now filled with zero */
2657 *eax = 0;
2658 *ebx = 0;
2659 *ecx = 0;
2660 *edx = 0;
2661 break;
c6dc6f63
AP
2662 default:
2663 /* reserved values: zero */
2664 *eax = 0;
2665 *ebx = 0;
2666 *ecx = 0;
2667 *edx = 0;
2668 break;
2669 }
2670}
5fd2087a
AF
2671
2672/* CPUClass::reset() */
2673static void x86_cpu_reset(CPUState *s)
2674{
2675 X86CPU *cpu = X86_CPU(s);
2676 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2677 CPUX86State *env = &cpu->env;
a114d25d
RH
2678 target_ulong cr4;
2679 uint64_t xcr0;
c1958aea
AF
2680 int i;
2681
5fd2087a
AF
2682 xcc->parent_reset(s);
2683
43175fa9 2684 memset(env, 0, offsetof(CPUX86State, cpuid_level));
c1958aea 2685
00c8cb0a 2686 tlb_flush(s, 1);
c1958aea
AF
2687
2688 env->old_exception = -1;
2689
2690 /* init to reset state */
2691
2692#ifdef CONFIG_SOFTMMU
2693 env->hflags |= HF_SOFTMMU_MASK;
2694#endif
2695 env->hflags2 |= HF2_GIF_MASK;
2696
2697 cpu_x86_update_cr0(env, 0x60000010);
2698 env->a20_mask = ~0x0;
2699 env->smbase = 0x30000;
2700
2701 env->idt.limit = 0xffff;
2702 env->gdt.limit = 0xffff;
2703 env->ldt.limit = 0xffff;
2704 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2705 env->tr.limit = 0xffff;
2706 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2707
2708 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2709 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2710 DESC_R_MASK | DESC_A_MASK);
2711 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2712 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2713 DESC_A_MASK);
2714 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
2715 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2716 DESC_A_MASK);
2717 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
2718 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2719 DESC_A_MASK);
2720 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
2721 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2722 DESC_A_MASK);
2723 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
2724 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2725 DESC_A_MASK);
2726
2727 env->eip = 0xfff0;
2728 env->regs[R_EDX] = env->cpuid_version;
2729
2730 env->eflags = 0x2;
2731
2732 /* FPU init */
2733 for (i = 0; i < 8; i++) {
2734 env->fptags[i] = 1;
2735 }
5bde1407 2736 cpu_set_fpuc(env, 0x37f);
c1958aea
AF
2737
2738 env->mxcsr = 0x1f80;
a114d25d
RH
2739 /* All units are in INIT state. */
2740 env->xstate_bv = 0;
c1958aea
AF
2741
2742 env->pat = 0x0007040600070406ULL;
2743 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2744
2745 memset(env->dr, 0, sizeof(env->dr));
2746 env->dr[6] = DR6_FIXED_1;
2747 env->dr[7] = DR7_FIXED_1;
b3310ab3 2748 cpu_breakpoint_remove_all(s, BP_CPU);
75a34036 2749 cpu_watchpoint_remove_all(s, BP_CPU);
dd673288 2750
a114d25d 2751 cr4 = 0;
cfc3b074 2752 xcr0 = XSTATE_FP_MASK;
a114d25d
RH
2753
2754#ifdef CONFIG_USER_ONLY
2755 /* Enable all the features for user-mode. */
2756 if (env->features[FEAT_1_EDX] & CPUID_SSE) {
cfc3b074 2757 xcr0 |= XSTATE_SSE_MASK;
a114d25d 2758 }
0f70ed47
PB
2759 for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
2760 const ExtSaveArea *esa = &x86_ext_save_areas[i];
2761 if ((env->features[esa->feature] & esa->bits) == esa->bits) {
2762 xcr0 |= 1ull << i;
2763 }
a114d25d 2764 }
0f70ed47 2765
a114d25d
RH
2766 if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) {
2767 cr4 |= CR4_OSFXSR_MASK | CR4_OSXSAVE_MASK;
2768 }
07929f2a
RH
2769 if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_FSGSBASE) {
2770 cr4 |= CR4_FSGSBASE_MASK;
2771 }
a114d25d
RH
2772#endif
2773
2774 env->xcr0 = xcr0;
2775 cpu_x86_update_cr4(env, cr4);
0522604b 2776
9db2efd9
AW
2777 /*
2778 * SDM 11.11.5 requires:
2779 * - IA32_MTRR_DEF_TYPE MSR.E = 0
2780 * - IA32_MTRR_PHYSMASKn.V = 0
2781 * All other bits are undefined. For simplification, zero it all.
2782 */
2783 env->mtrr_deftype = 0;
2784 memset(env->mtrr_var, 0, sizeof(env->mtrr_var));
2785 memset(env->mtrr_fixed, 0, sizeof(env->mtrr_fixed));
2786
dd673288
IM
2787#if !defined(CONFIG_USER_ONLY)
2788 /* We hard-wire the BSP to the first CPU. */
9cb11fd7 2789 apic_designate_bsp(cpu->apic_state, s->cpu_index == 0);
dd673288 2790
259186a7 2791 s->halted = !cpu_is_bsp(cpu);
50a2c6e5
PB
2792
2793 if (kvm_enabled()) {
2794 kvm_arch_reset_vcpu(cpu);
2795 }
dd673288 2796#endif
5fd2087a
AF
2797}
2798
dd673288
IM
2799#ifndef CONFIG_USER_ONLY
2800bool cpu_is_bsp(X86CPU *cpu)
2801{
02e51483 2802 return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
dd673288 2803}
65dee380
IM
2804
2805/* TODO: remove me, when reset over QOM tree is implemented */
2806static void x86_cpu_machine_reset_cb(void *opaque)
2807{
2808 X86CPU *cpu = opaque;
2809 cpu_reset(CPU(cpu));
2810}
dd673288
IM
2811#endif
2812
de024815
AF
2813static void mce_init(X86CPU *cpu)
2814{
2815 CPUX86State *cenv = &cpu->env;
2816 unsigned int bank;
2817
2818 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
0514ef2f 2819 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
de024815
AF
2820 (CPUID_MCE | CPUID_MCA)) {
2821 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2822 cenv->mcg_ctl = ~(uint64_t)0;
2823 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2824 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2825 }
2826 }
2827}
2828
bdeec802 2829#ifndef CONFIG_USER_ONLY
d3c64d6a 2830static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
bdeec802 2831{
449994eb 2832 APICCommonState *apic;
bdeec802
IM
2833 const char *apic_type = "apic";
2834
15eafc2e 2835 if (kvm_apic_in_kernel()) {
bdeec802
IM
2836 apic_type = "kvm-apic";
2837 } else if (xen_enabled()) {
2838 apic_type = "xen-apic";
2839 }
2840
46232aaa 2841 cpu->apic_state = DEVICE(object_new(apic_type));
bdeec802
IM
2842
2843 object_property_add_child(OBJECT(cpu), "apic",
02e51483 2844 OBJECT(cpu->apic_state), NULL);
7e72a45c 2845 qdev_prop_set_uint8(cpu->apic_state, "id", cpu->apic_id);
bdeec802 2846 /* TODO: convert to link<> */
02e51483 2847 apic = APIC_COMMON(cpu->apic_state);
60671e58 2848 apic->cpu = cpu;
8d42d2d3 2849 apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE;
d3c64d6a
IM
2850}
2851
2852static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2853{
8d42d2d3
CF
2854 APICCommonState *apic;
2855 static bool apic_mmio_map_once;
2856
02e51483 2857 if (cpu->apic_state == NULL) {
d3c64d6a
IM
2858 return;
2859 }
6e8e2651
MA
2860 object_property_set_bool(OBJECT(cpu->apic_state), true, "realized",
2861 errp);
8d42d2d3
CF
2862
2863 /* Map APIC MMIO area */
2864 apic = APIC_COMMON(cpu->apic_state);
2865 if (!apic_mmio_map_once) {
2866 memory_region_add_subregion_overlap(get_system_memory(),
2867 apic->apicbase &
2868 MSR_IA32_APICBASE_BASE,
2869 &apic->io_memory,
2870 0x1000);
2871 apic_mmio_map_once = true;
2872 }
bdeec802 2873}
f809c605
PB
2874
2875static void x86_cpu_machine_done(Notifier *n, void *unused)
2876{
2877 X86CPU *cpu = container_of(n, X86CPU, machine_done);
2878 MemoryRegion *smram =
2879 (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
2880
2881 if (smram) {
2882 cpu->smram = g_new(MemoryRegion, 1);
2883 memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
2884 smram, 0, 1ull << 32);
2885 memory_region_set_enabled(cpu->smram, false);
2886 memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->smram, 1);
2887 }
2888}
d3c64d6a
IM
2889#else
2890static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2891{
2892}
bdeec802
IM
2893#endif
2894
e48638fd
WH
2895
2896#define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \
2897 (env)->cpuid_vendor2 == CPUID_VENDOR_INTEL_2 && \
2898 (env)->cpuid_vendor3 == CPUID_VENDOR_INTEL_3)
2899#define IS_AMD_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && \
2900 (env)->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && \
2901 (env)->cpuid_vendor3 == CPUID_VENDOR_AMD_3)
2b6f294c 2902static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
7a059953 2903{
14a10fc3 2904 CPUState *cs = CPU(dev);
2b6f294c
AF
2905 X86CPU *cpu = X86_CPU(dev);
2906 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
b34d12d1 2907 CPUX86State *env = &cpu->env;
2b6f294c 2908 Error *local_err = NULL;
e48638fd 2909 static bool ht_warned;
dc15c051 2910 FeatureWord w;
b34d12d1 2911
9886e834
EH
2912 if (cpu->apic_id < 0) {
2913 error_setg(errp, "apic-id property was not initialized properly");
2914 return;
2915 }
2916
dc15c051
IM
2917 /*TODO: cpu->host_features incorrectly overwrites features
2918 * set using "feat=on|off". Once we fix this, we can convert
2919 * plus_features & minus_features to global properties
2920 * inside x86_cpu_parse_featurestr() too.
2921 */
2922 if (cpu->host_features) {
2923 for (w = 0; w < FEATURE_WORDS; w++) {
2924 env->features[w] =
2925 x86_cpu_get_supported_feature_word(w, cpu->migratable);
2926 }
2927 }
2928
2929 for (w = 0; w < FEATURE_WORDS; w++) {
2930 cpu->env.features[w] |= plus_features[w];
2931 cpu->env.features[w] &= ~minus_features[w];
2932 }
2933
0514ef2f 2934 if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
b34d12d1
IM
2935 env->cpuid_level = 7;
2936 }
7a059953 2937
9997cf7b
EH
2938 if (x86_cpu_filter_features(cpu) && cpu->enforce_cpuid) {
2939 error_setg(&local_err,
2940 kvm_enabled() ?
2941 "Host doesn't support requested features" :
2942 "TCG doesn't support requested features");
2943 goto out;
2944 }
2945
9b15cd9e
IM
2946 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
2947 * CPUID[1].EDX.
2948 */
e48638fd 2949 if (IS_AMD_CPU(env)) {
0514ef2f
EH
2950 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
2951 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
9b15cd9e
IM
2952 & CPUID_EXT2_AMD_ALIASES);
2953 }
2954
fefb41bf 2955
42ecabaa
EH
2956 cpu_exec_init(cs, &error_abort);
2957
57f2453a
EH
2958 if (tcg_enabled()) {
2959 tcg_x86_init();
2960 }
2961
65dee380
IM
2962#ifndef CONFIG_USER_ONLY
2963 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
bdeec802 2964
0514ef2f 2965 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
d3c64d6a 2966 x86_cpu_apic_create(cpu, &local_err);
2b6f294c 2967 if (local_err != NULL) {
4dc1f449 2968 goto out;
bdeec802
IM
2969 }
2970 }
65dee380
IM
2971#endif
2972
7a059953 2973 mce_init(cpu);
2001d0cd
PB
2974
2975#ifndef CONFIG_USER_ONLY
2976 if (tcg_enabled()) {
56943e8c
PM
2977 AddressSpace *newas = g_new(AddressSpace, 1);
2978
f809c605 2979 cpu->cpu_as_mem = g_new(MemoryRegion, 1);
2001d0cd 2980 cpu->cpu_as_root = g_new(MemoryRegion, 1);
f809c605
PB
2981
2982 /* Outer container... */
2983 memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
2001d0cd 2984 memory_region_set_enabled(cpu->cpu_as_root, true);
f809c605
PB
2985
2986 /* ... with two regions inside: normal system memory with low
2987 * priority, and...
2988 */
2989 memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
2990 get_system_memory(), 0, ~0ull);
2991 memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
2992 memory_region_set_enabled(cpu->cpu_as_mem, true);
56943e8c 2993 address_space_init(newas, cpu->cpu_as_root, "CPU");
12ebc9a7 2994 cs->num_ases = 1;
56943e8c 2995 cpu_address_space_init(cs, newas, 0);
f809c605
PB
2996
2997 /* ... SMRAM with higher priority, linked from /machine/smram. */
2998 cpu->machine_done.notify = x86_cpu_machine_done;
2999 qemu_add_machine_init_done_notifier(&cpu->machine_done);
2001d0cd
PB
3000 }
3001#endif
3002
14a10fc3 3003 qemu_init_vcpu(cs);
d3c64d6a 3004
e48638fd
WH
3005 /* Only Intel CPUs support hyperthreading. Even though QEMU fixes this
3006 * issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX
3007 * based on inputs (sockets,cores,threads), it is still better to gives
3008 * users a warning.
3009 *
3010 * NOTE: the following code has to follow qemu_init_vcpu(). Otherwise
3011 * cs->nr_threads hasn't be populated yet and the checking is incorrect.
3012 */
3013 if (!IS_INTEL_CPU(env) && cs->nr_threads > 1 && !ht_warned) {
3014 error_report("AMD CPU doesn't support hyperthreading. Please configure"
3015 " -smp options properly.");
3016 ht_warned = true;
3017 }
3018
d3c64d6a
IM
3019 x86_cpu_apic_realize(cpu, &local_err);
3020 if (local_err != NULL) {
3021 goto out;
3022 }
14a10fc3 3023 cpu_reset(cs);
2b6f294c 3024
4dc1f449 3025 xcc->parent_realize(dev, &local_err);
2001d0cd 3026
4dc1f449
IM
3027out:
3028 if (local_err != NULL) {
3029 error_propagate(errp, local_err);
3030 return;
3031 }
7a059953
AF
3032}
3033
38e5c119
EH
3034typedef struct BitProperty {
3035 uint32_t *ptr;
3036 uint32_t mask;
3037} BitProperty;
3038
d7bce999
EB
3039static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
3040 void *opaque, Error **errp)
38e5c119
EH
3041{
3042 BitProperty *fp = opaque;
3043 bool value = (*fp->ptr & fp->mask) == fp->mask;
51e72bc1 3044 visit_type_bool(v, name, &value, errp);
38e5c119
EH
3045}
3046
d7bce999
EB
3047static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
3048 void *opaque, Error **errp)
38e5c119
EH
3049{
3050 DeviceState *dev = DEVICE(obj);
3051 BitProperty *fp = opaque;
3052 Error *local_err = NULL;
3053 bool value;
3054
3055 if (dev->realized) {
3056 qdev_prop_set_after_realize(dev, name, errp);
3057 return;
3058 }
3059
51e72bc1 3060 visit_type_bool(v, name, &value, &local_err);
38e5c119
EH
3061 if (local_err) {
3062 error_propagate(errp, local_err);
3063 return;
3064 }
3065
3066 if (value) {
3067 *fp->ptr |= fp->mask;
3068 } else {
3069 *fp->ptr &= ~fp->mask;
3070 }
3071}
3072
3073static void x86_cpu_release_bit_prop(Object *obj, const char *name,
3074 void *opaque)
3075{
3076 BitProperty *prop = opaque;
3077 g_free(prop);
3078}
3079
3080/* Register a boolean property to get/set a single bit in a uint32_t field.
3081 *
3082 * The same property name can be registered multiple times to make it affect
3083 * multiple bits in the same FeatureWord. In that case, the getter will return
3084 * true only if all bits are set.
3085 */
3086static void x86_cpu_register_bit_prop(X86CPU *cpu,
3087 const char *prop_name,
3088 uint32_t *field,
3089 int bitnr)
3090{
3091 BitProperty *fp;
3092 ObjectProperty *op;
3093 uint32_t mask = (1UL << bitnr);
3094
3095 op = object_property_find(OBJECT(cpu), prop_name, NULL);
3096 if (op) {
3097 fp = op->opaque;
3098 assert(fp->ptr == field);
3099 fp->mask |= mask;
3100 } else {
3101 fp = g_new0(BitProperty, 1);
3102 fp->ptr = field;
3103 fp->mask = mask;
3104 object_property_add(OBJECT(cpu), prop_name, "bool",
3105 x86_cpu_get_bit_prop,
3106 x86_cpu_set_bit_prop,
3107 x86_cpu_release_bit_prop, fp, &error_abort);
3108 }
3109}
3110
3111static void x86_cpu_register_feature_bit_props(X86CPU *cpu,
3112 FeatureWord w,
3113 int bitnr)
3114{
3115 Object *obj = OBJECT(cpu);
3116 int i;
3117 char **names;
3118 FeatureWordInfo *fi = &feature_word_info[w];
3119
3120 if (!fi->feat_names) {
3121 return;
3122 }
3123 if (!fi->feat_names[bitnr]) {
3124 return;
3125 }
3126
3127 names = g_strsplit(fi->feat_names[bitnr], "|", 0);
3128
3129 feat2prop(names[0]);
3130 x86_cpu_register_bit_prop(cpu, names[0], &cpu->env.features[w], bitnr);
3131
3132 for (i = 1; names[i]; i++) {
3133 feat2prop(names[i]);
d461a44c 3134 object_property_add_alias(obj, names[i], obj, names[0],
38e5c119
EH
3135 &error_abort);
3136 }
3137
3138 g_strfreev(names);
3139}
3140
de024815
AF
3141static void x86_cpu_initfn(Object *obj)
3142{
55e5c285 3143 CPUState *cs = CPU(obj);
de024815 3144 X86CPU *cpu = X86_CPU(obj);
d940ee9b 3145 X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
de024815 3146 CPUX86State *env = &cpu->env;
38e5c119 3147 FeatureWord w;
de024815 3148
c05efcb1 3149 cs->env_ptr = env;
71ad61d3
AF
3150
3151 object_property_add(obj, "family", "int",
95b8519d 3152 x86_cpuid_version_get_family,
71ad61d3 3153 x86_cpuid_version_set_family, NULL, NULL, NULL);
c5291a4f 3154 object_property_add(obj, "model", "int",
67e30c83 3155 x86_cpuid_version_get_model,
c5291a4f 3156 x86_cpuid_version_set_model, NULL, NULL, NULL);
036e2222 3157 object_property_add(obj, "stepping", "int",
35112e41 3158 x86_cpuid_version_get_stepping,
036e2222 3159 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
d480e1af
AF
3160 object_property_add_str(obj, "vendor",
3161 x86_cpuid_get_vendor,
3162 x86_cpuid_set_vendor, NULL);
938d4c25 3163 object_property_add_str(obj, "model-id",
63e886eb 3164 x86_cpuid_get_model_id,
938d4c25 3165 x86_cpuid_set_model_id, NULL);
89e48965
AF
3166 object_property_add(obj, "tsc-frequency", "int",
3167 x86_cpuid_get_tsc_freq,
3168 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
31050930
IM
3169 object_property_add(obj, "apic-id", "int",
3170 x86_cpuid_get_apic_id,
3171 x86_cpuid_set_apic_id, NULL, NULL, NULL);
8e8aba50
EH
3172 object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
3173 x86_cpu_get_feature_words,
7e5292b5
EH
3174 NULL, NULL, (void *)env->features, NULL);
3175 object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
3176 x86_cpu_get_feature_words,
3177 NULL, NULL, (void *)cpu->filtered_features, NULL);
71ad61d3 3178
92067bf4 3179 cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
d65e9815 3180
9886e834
EH
3181#ifndef CONFIG_USER_ONLY
3182 /* Any code creating new X86CPU objects have to set apic-id explicitly */
3183 cpu->apic_id = -1;
3184#endif
3185
38e5c119
EH
3186 for (w = 0; w < FEATURE_WORDS; w++) {
3187 int bitnr;
3188
3189 for (bitnr = 0; bitnr < 32; bitnr++) {
3190 x86_cpu_register_feature_bit_props(cpu, w, bitnr);
3191 }
3192 }
3193
d940ee9b 3194 x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
de024815
AF
3195}
3196
997395d3
IM
3197static int64_t x86_cpu_get_arch_id(CPUState *cs)
3198{
3199 X86CPU *cpu = X86_CPU(cs);
997395d3 3200
7e72a45c 3201 return cpu->apic_id;
997395d3
IM
3202}
3203
444d5590
AF
3204static bool x86_cpu_get_paging_enabled(const CPUState *cs)
3205{
3206 X86CPU *cpu = X86_CPU(cs);
3207
3208 return cpu->env.cr[0] & CR0_PG_MASK;
3209}
3210
f45748f1
AF
3211static void x86_cpu_set_pc(CPUState *cs, vaddr value)
3212{
3213 X86CPU *cpu = X86_CPU(cs);
3214
3215 cpu->env.eip = value;
3216}
3217
bdf7ae5b
AF
3218static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
3219{
3220 X86CPU *cpu = X86_CPU(cs);
3221
3222 cpu->env.eip = tb->pc - tb->cs_base;
3223}
3224
8c2e1b00
AF
3225static bool x86_cpu_has_work(CPUState *cs)
3226{
3227 X86CPU *cpu = X86_CPU(cs);
3228 CPUX86State *env = &cpu->env;
3229
6220e900
PD
3230 return ((cs->interrupt_request & (CPU_INTERRUPT_HARD |
3231 CPU_INTERRUPT_POLL)) &&
8c2e1b00
AF
3232 (env->eflags & IF_MASK)) ||
3233 (cs->interrupt_request & (CPU_INTERRUPT_NMI |
3234 CPU_INTERRUPT_INIT |
3235 CPU_INTERRUPT_SIPI |
a9bad65d
PB
3236 CPU_INTERRUPT_MCE)) ||
3237 ((cs->interrupt_request & CPU_INTERRUPT_SMI) &&
3238 !(env->hflags & HF_SMM_MASK));
8c2e1b00
AF
3239}
3240
9337e3b6
EH
3241static Property x86_cpu_properties[] = {
3242 DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
c8f0f88e 3243 { .name = "hv-spinlocks", .info = &qdev_prop_spinlocks },
89314504 3244 DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false),
0f46685d 3245 DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false),
48a5f3bc 3246 DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false),
f2a53c9e 3247 DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false),
744b8a94 3248 DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false),
8c145d7c 3249 DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false),
46eb8f98 3250 DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
866eea9a 3251 DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
ff99aa64 3252 DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
15e41345 3253 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
912ffc47 3254 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
f522d2ac 3255 DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
b9472b76
EH
3256 DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, 0),
3257 DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, 0),
01431f3c 3258 DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0),
1c4a55db 3259 DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
5232d00a 3260 DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
9337e3b6
EH
3261 DEFINE_PROP_END_OF_LIST()
3262};
3263
5fd2087a
AF
3264static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
3265{
3266 X86CPUClass *xcc = X86_CPU_CLASS(oc);
3267 CPUClass *cc = CPU_CLASS(oc);
2b6f294c
AF
3268 DeviceClass *dc = DEVICE_CLASS(oc);
3269
3270 xcc->parent_realize = dc->realize;
3271 dc->realize = x86_cpu_realizefn;
9337e3b6 3272 dc->props = x86_cpu_properties;
5fd2087a
AF
3273
3274 xcc->parent_reset = cc->reset;
3275 cc->reset = x86_cpu_reset;
91b1df8c 3276 cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
f56e3a14 3277
500050d1 3278 cc->class_by_name = x86_cpu_class_by_name;
94a444b2 3279 cc->parse_features = x86_cpu_parse_featurestr;
8c2e1b00 3280 cc->has_work = x86_cpu_has_work;
97a8ea5a 3281 cc->do_interrupt = x86_cpu_do_interrupt;
42f53fea 3282 cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
878096ee 3283 cc->dump_state = x86_cpu_dump_state;
f45748f1 3284 cc->set_pc = x86_cpu_set_pc;
bdf7ae5b 3285 cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
5b50e790
AF
3286 cc->gdb_read_register = x86_cpu_gdb_read_register;
3287 cc->gdb_write_register = x86_cpu_gdb_write_register;
444d5590
AF
3288 cc->get_arch_id = x86_cpu_get_arch_id;
3289 cc->get_paging_enabled = x86_cpu_get_paging_enabled;
7510454e
AF
3290#ifdef CONFIG_USER_ONLY
3291 cc->handle_mmu_fault = x86_cpu_handle_mmu_fault;
3292#else
a23bbfda 3293 cc->get_memory_mapping = x86_cpu_get_memory_mapping;
00b941e5 3294 cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
c72bf468
JF
3295 cc->write_elf64_note = x86_cpu_write_elf64_note;
3296 cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
3297 cc->write_elf32_note = x86_cpu_write_elf32_note;
3298 cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
00b941e5 3299 cc->vmsd = &vmstate_x86_cpu;
c72bf468 3300#endif
a0e372f0 3301 cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
86025ee4
PM
3302#ifndef CONFIG_USER_ONLY
3303 cc->debug_excp_handler = breakpoint_handler;
3304#endif
374e0cd4
RH
3305 cc->cpu_exec_enter = x86_cpu_exec_enter;
3306 cc->cpu_exec_exit = x86_cpu_exec_exit;
4c315c27
MA
3307
3308 /*
3309 * Reason: x86_cpu_initfn() calls cpu_exec_init(), which saves the
3310 * object in cpus -> dangling pointer after final object_unref().
3311 */
3312 dc->cannot_destroy_with_object_finalize_yet = true;
5fd2087a
AF
3313}
3314
3315static const TypeInfo x86_cpu_type_info = {
3316 .name = TYPE_X86_CPU,
3317 .parent = TYPE_CPU,
3318 .instance_size = sizeof(X86CPU),
de024815 3319 .instance_init = x86_cpu_initfn,
d940ee9b 3320 .abstract = true,
5fd2087a
AF
3321 .class_size = sizeof(X86CPUClass),
3322 .class_init = x86_cpu_common_class_init,
3323};
3324
3325static void x86_cpu_register_types(void)
3326{
d940ee9b
EH
3327 int i;
3328
5fd2087a 3329 type_register_static(&x86_cpu_type_info);
d940ee9b
EH
3330 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
3331 x86_register_cpudef_type(&builtin_x86_defs[i]);
3332 }
3333#ifdef CONFIG_KVM
3334 type_register_static(&host_x86_cpu_type_info);
3335#endif
5fd2087a
AF
3336}
3337
3338type_init(x86_cpu_register_types)