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