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