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