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