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