]> git.proxmox.com Git - mirror_qemu.git/blame - target-i386/cpu.c
target-i386: Prepare CPUClass::class_by_name for X86CPU
[mirror_qemu.git] / target-i386 / cpu.c
CommitLineData
c6dc6f63
AP
1/*
2 * i386 CPUID helper functions
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19#include <stdlib.h>
20#include <stdio.h>
21#include <string.h>
22#include <inttypes.h>
23
24#include "cpu.h"
9c17d615 25#include "sysemu/kvm.h"
8932cfdf
EH
26#include "sysemu/cpus.h"
27#include "topology.h"
c6dc6f63 28
1de7afc9
PB
29#include "qemu/option.h"
30#include "qemu/config-file.h"
7b1b5d19 31#include "qapi/qmp/qerror.h"
c6dc6f63 32
8e8aba50
EH
33#include "qapi-types.h"
34#include "qapi-visit.h"
7b1b5d19 35#include "qapi/visitor.h"
9c17d615 36#include "sysemu/arch_init.h"
71ad61d3 37
65dee380 38#include "hw/hw.h"
b834b508 39#if defined(CONFIG_KVM)
ef8621b1 40#include <linux/kvm_para.h>
b834b508 41#endif
65dee380 42
9c17d615 43#include "sysemu/sysemu.h"
53a89e26 44#include "hw/qdev-properties.h"
62fc403f 45#include "hw/cpu/icc_bus.h"
bdeec802 46#ifndef CONFIG_USER_ONLY
0d09e41a 47#include "hw/xen/xen.h"
0d09e41a 48#include "hw/i386/apic_internal.h"
bdeec802
IM
49#endif
50
5e891bf8
EH
51
52/* Cache topology CPUID constants: */
53
54/* CPUID Leaf 2 Descriptors */
55
56#define CPUID_2_L1D_32KB_8WAY_64B 0x2c
57#define CPUID_2_L1I_32KB_8WAY_64B 0x30
58#define CPUID_2_L2_2MB_8WAY_64B 0x7d
59
60
61/* CPUID Leaf 4 constants: */
62
63/* EAX: */
64#define CPUID_4_TYPE_DCACHE 1
65#define CPUID_4_TYPE_ICACHE 2
66#define CPUID_4_TYPE_UNIFIED 3
67
68#define CPUID_4_LEVEL(l) ((l) << 5)
69
70#define CPUID_4_SELF_INIT_LEVEL (1 << 8)
71#define CPUID_4_FULLY_ASSOC (1 << 9)
72
73/* EDX: */
74#define CPUID_4_NO_INVD_SHARING (1 << 0)
75#define CPUID_4_INCLUSIVE (1 << 1)
76#define CPUID_4_COMPLEX_IDX (1 << 2)
77
78#define ASSOC_FULL 0xFF
79
80/* AMD associativity encoding used on CPUID Leaf 0x80000006: */
81#define AMD_ENC_ASSOC(a) (a <= 1 ? a : \
82 a == 2 ? 0x2 : \
83 a == 4 ? 0x4 : \
84 a == 8 ? 0x6 : \
85 a == 16 ? 0x8 : \
86 a == 32 ? 0xA : \
87 a == 48 ? 0xB : \
88 a == 64 ? 0xC : \
89 a == 96 ? 0xD : \
90 a == 128 ? 0xE : \
91 a == ASSOC_FULL ? 0xF : \
92 0 /* invalid value */)
93
94
95/* Definitions of the hardcoded cache entries we expose: */
96
97/* L1 data cache: */
98#define L1D_LINE_SIZE 64
99#define L1D_ASSOCIATIVITY 8
100#define L1D_SETS 64
101#define L1D_PARTITIONS 1
102/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
103#define L1D_DESCRIPTOR CPUID_2_L1D_32KB_8WAY_64B
104/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
105#define L1D_LINES_PER_TAG 1
106#define L1D_SIZE_KB_AMD 64
107#define L1D_ASSOCIATIVITY_AMD 2
108
109/* L1 instruction cache: */
110#define L1I_LINE_SIZE 64
111#define L1I_ASSOCIATIVITY 8
112#define L1I_SETS 64
113#define L1I_PARTITIONS 1
114/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
115#define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
116/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
117#define L1I_LINES_PER_TAG 1
118#define L1I_SIZE_KB_AMD 64
119#define L1I_ASSOCIATIVITY_AMD 2
120
121/* Level 2 unified cache: */
122#define L2_LINE_SIZE 64
123#define L2_ASSOCIATIVITY 16
124#define L2_SETS 4096
125#define L2_PARTITIONS 1
126/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
127/*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
128#define L2_DESCRIPTOR CPUID_2_L2_2MB_8WAY_64B
129/*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
130#define L2_LINES_PER_TAG 1
131#define L2_SIZE_KB_AMD 512
132
133/* No L3 cache: */
134#define L3_SIZE_KB 0 /* disabled */
135#define L3_ASSOCIATIVITY 0 /* disabled */
136#define L3_LINES_PER_TAG 0 /* disabled */
137#define L3_LINE_SIZE 0 /* disabled */
138
139/* TLB definitions: */
140
141#define L1_DTLB_2M_ASSOC 1
142#define L1_DTLB_2M_ENTRIES 255
143#define L1_DTLB_4K_ASSOC 1
144#define L1_DTLB_4K_ENTRIES 255
145
146#define L1_ITLB_2M_ASSOC 1
147#define L1_ITLB_2M_ENTRIES 255
148#define L1_ITLB_4K_ASSOC 1
149#define L1_ITLB_4K_ENTRIES 255
150
151#define L2_DTLB_2M_ASSOC 0 /* disabled */
152#define L2_DTLB_2M_ENTRIES 0 /* disabled */
153#define L2_DTLB_4K_ASSOC 4
154#define L2_DTLB_4K_ENTRIES 512
155
156#define L2_ITLB_2M_ASSOC 0 /* disabled */
157#define L2_ITLB_2M_ENTRIES 0 /* disabled */
158#define L2_ITLB_4K_ASSOC 4
159#define L2_ITLB_4K_ENTRIES 512
160
161
162
99b88a17
IM
163static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
164 uint32_t vendor2, uint32_t vendor3)
165{
166 int i;
167 for (i = 0; i < 4; i++) {
168 dst[i] = vendor1 >> (8 * i);
169 dst[i + 4] = vendor2 >> (8 * i);
170 dst[i + 8] = vendor3 >> (8 * i);
171 }
172 dst[CPUID_VENDOR_SZ] = '\0';
173}
174
c6dc6f63
AP
175/* feature flags taken from "Intel Processor Identification and the CPUID
176 * Instruction" and AMD's "CPUID Specification". In cases of disagreement
177 * between feature naming conventions, aliases may be added.
178 */
179static const char *feature_name[] = {
180 "fpu", "vme", "de", "pse",
181 "tsc", "msr", "pae", "mce",
182 "cx8", "apic", NULL, "sep",
183 "mtrr", "pge", "mca", "cmov",
184 "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
185 NULL, "ds" /* Intel dts */, "acpi", "mmx",
186 "fxsr", "sse", "sse2", "ss",
187 "ht" /* Intel htt */, "tm", "ia64", "pbe",
188};
189static const char *ext_feature_name[] = {
f370be3c 190 "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
e117f772 191 "ds_cpl", "vmx", "smx", "est",
c6dc6f63 192 "tm2", "ssse3", "cid", NULL,
e117f772 193 "fma", "cx16", "xtpr", "pdcm",
434acb81 194 NULL, "pcid", "dca", "sse4.1|sse4_1",
e117f772 195 "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
eaf3f097 196 "tsc-deadline", "aes", "xsave", "osxsave",
c8acc380 197 "avx", "f16c", "rdrand", "hypervisor",
c6dc6f63 198};
3b671a40
EH
199/* Feature names that are already defined on feature_name[] but are set on
200 * CPUID[8000_0001].EDX on AMD CPUs don't have their names on
201 * ext2_feature_name[]. They are copied automatically to cpuid_ext2_features
202 * if and only if CPU vendor is AMD.
203 */
c6dc6f63 204static const char *ext2_feature_name[] = {
3b671a40
EH
205 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
206 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
207 NULL /* cx8 */ /* AMD CMPXCHG8B */, NULL /* apic */, NULL, "syscall",
208 NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
209 NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
210 "nx|xd", NULL, "mmxext", NULL /* mmx */,
211 NULL /* fxsr */, "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
01f590d5 212 NULL, "lm|i64", "3dnowext", "3dnow",
c6dc6f63
AP
213};
214static const char *ext3_feature_name[] = {
215 "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
216 "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
e117f772 217 "3dnowprefetch", "osvw", "ibs", "xop",
c8acc380
AP
218 "skinit", "wdt", NULL, "lwp",
219 "fma4", "tce", NULL, "nodeid_msr",
220 NULL, "tbm", "topoext", "perfctr_core",
221 "perfctr_nb", NULL, NULL, NULL,
c6dc6f63
AP
222 NULL, NULL, NULL, NULL,
223};
224
89e49c8b
EH
225static const char *ext4_feature_name[] = {
226 NULL, NULL, "xstore", "xstore-en",
227 NULL, NULL, "xcrypt", "xcrypt-en",
228 "ace2", "ace2-en", "phe", "phe-en",
229 "pmm", "pmm-en", NULL, NULL,
230 NULL, NULL, NULL, NULL,
231 NULL, NULL, NULL, NULL,
232 NULL, NULL, NULL, NULL,
233 NULL, NULL, NULL, NULL,
234};
235
c6dc6f63 236static const char *kvm_feature_name[] = {
c3d39807 237 "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock",
f010bc64 238 "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", "kvm_pv_unhalt",
c3d39807
DS
239 NULL, NULL, NULL, NULL,
240 NULL, NULL, NULL, NULL,
241 NULL, NULL, NULL, NULL,
242 NULL, NULL, NULL, NULL,
243 NULL, NULL, NULL, NULL,
244 NULL, NULL, NULL, NULL,
c6dc6f63
AP
245};
246
296acb64
JR
247static const char *svm_feature_name[] = {
248 "npt", "lbrv", "svm_lock", "nrip_save",
249 "tsc_scale", "vmcb_clean", "flushbyasid", "decodeassists",
250 NULL, NULL, "pause_filter", NULL,
251 "pfthreshold", NULL, NULL, NULL,
252 NULL, NULL, NULL, NULL,
253 NULL, NULL, NULL, NULL,
254 NULL, NULL, NULL, NULL,
255 NULL, NULL, NULL, NULL,
256};
257
a9321a4d 258static const char *cpuid_7_0_ebx_feature_name[] = {
811a8ae0
EH
259 "fsgsbase", NULL, NULL, "bmi1", "hle", "avx2", NULL, "smep",
260 "bmi2", "erms", "invpcid", "rtm", NULL, NULL, NULL, NULL,
c8acc380 261 NULL, NULL, "rdseed", "adx", "smap", NULL, NULL, NULL,
a9321a4d
PA
262 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
263};
264
5ef57876
EH
265typedef struct FeatureWordInfo {
266 const char **feat_names;
04d104b6
EH
267 uint32_t cpuid_eax; /* Input EAX for CPUID */
268 bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
269 uint32_t cpuid_ecx; /* Input ECX value for CPUID */
270 int cpuid_reg; /* output register (R_* constant) */
5ef57876
EH
271} FeatureWordInfo;
272
273static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
bffd67b0
EH
274 [FEAT_1_EDX] = {
275 .feat_names = feature_name,
276 .cpuid_eax = 1, .cpuid_reg = R_EDX,
277 },
278 [FEAT_1_ECX] = {
279 .feat_names = ext_feature_name,
280 .cpuid_eax = 1, .cpuid_reg = R_ECX,
281 },
282 [FEAT_8000_0001_EDX] = {
283 .feat_names = ext2_feature_name,
284 .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX,
285 },
286 [FEAT_8000_0001_ECX] = {
287 .feat_names = ext3_feature_name,
288 .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
289 },
89e49c8b
EH
290 [FEAT_C000_0001_EDX] = {
291 .feat_names = ext4_feature_name,
292 .cpuid_eax = 0xC0000001, .cpuid_reg = R_EDX,
293 },
bffd67b0
EH
294 [FEAT_KVM] = {
295 .feat_names = kvm_feature_name,
296 .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
297 },
298 [FEAT_SVM] = {
299 .feat_names = svm_feature_name,
300 .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
301 },
302 [FEAT_7_0_EBX] = {
303 .feat_names = cpuid_7_0_ebx_feature_name,
04d104b6
EH
304 .cpuid_eax = 7,
305 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
306 .cpuid_reg = R_EBX,
bffd67b0 307 },
5ef57876
EH
308};
309
8e8aba50
EH
310typedef struct X86RegisterInfo32 {
311 /* Name of register */
312 const char *name;
313 /* QAPI enum value register */
314 X86CPURegister32 qapi_enum;
315} X86RegisterInfo32;
316
317#define REGISTER(reg) \
5d371f41 318 [R_##reg] = { .name = #reg, .qapi_enum = X86_CPU_REGISTER32_##reg }
8e8aba50
EH
319X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
320 REGISTER(EAX),
321 REGISTER(ECX),
322 REGISTER(EDX),
323 REGISTER(EBX),
324 REGISTER(ESP),
325 REGISTER(EBP),
326 REGISTER(ESI),
327 REGISTER(EDI),
328};
329#undef REGISTER
330
2560f19f
PB
331typedef struct ExtSaveArea {
332 uint32_t feature, bits;
333 uint32_t offset, size;
334} ExtSaveArea;
335
336static const ExtSaveArea ext_save_areas[] = {
337 [2] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
33f373d7 338 .offset = 0x240, .size = 0x100 },
79e9ebeb
LJ
339 [3] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
340 .offset = 0x3c0, .size = 0x40 },
341 [4] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
b0f15a5d 342 .offset = 0x400, .size = 0x40 },
2560f19f 343};
8e8aba50 344
8b4beddc
EH
345const char *get_register_name_32(unsigned int reg)
346{
31ccdde2 347 if (reg >= CPU_NB_REGS32) {
8b4beddc
EH
348 return NULL;
349 }
8e8aba50 350 return x86_reg_info_32[reg].name;
8b4beddc
EH
351}
352
c6dc6f63
AP
353/* collects per-function cpuid data
354 */
355typedef struct model_features_t {
356 uint32_t *guest_feat;
357 uint32_t *host_feat;
bffd67b0 358 FeatureWord feat_word;
8b4beddc 359} model_features_t;
c6dc6f63 360
5fcca9ff
EH
361/* KVM-specific features that are automatically added to all CPU models
362 * when KVM is enabled.
363 */
364static uint32_t kvm_default_features[FEATURE_WORDS] = {
365 [FEAT_KVM] = (1 << KVM_FEATURE_CLOCKSOURCE) |
dc59944b 366 (1 << KVM_FEATURE_NOP_IO_DELAY) |
dc59944b
MT
367 (1 << KVM_FEATURE_CLOCKSOURCE2) |
368 (1 << KVM_FEATURE_ASYNC_PF) |
369 (1 << KVM_FEATURE_STEAL_TIME) |
29694758 370 (1 << KVM_FEATURE_PV_EOI) |
5fcca9ff 371 (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT),
ef02ef5f 372 [FEAT_1_ECX] = CPUID_EXT_X2APIC,
5fcca9ff 373};
dc59944b 374
8fb4f821 375void x86_cpu_compat_disable_kvm_features(FeatureWord w, uint32_t features)
dc59944b 376{
8fb4f821 377 kvm_default_features[w] &= ~features;
dc59944b
MT
378}
379
bb44e0d1
JK
380void host_cpuid(uint32_t function, uint32_t count,
381 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
bdde476a 382{
a1fd24af
AL
383 uint32_t vec[4];
384
385#ifdef __x86_64__
386 asm volatile("cpuid"
387 : "=a"(vec[0]), "=b"(vec[1]),
388 "=c"(vec[2]), "=d"(vec[3])
389 : "0"(function), "c"(count) : "cc");
c1f41226 390#elif defined(__i386__)
a1fd24af
AL
391 asm volatile("pusha \n\t"
392 "cpuid \n\t"
393 "mov %%eax, 0(%2) \n\t"
394 "mov %%ebx, 4(%2) \n\t"
395 "mov %%ecx, 8(%2) \n\t"
396 "mov %%edx, 12(%2) \n\t"
397 "popa"
398 : : "a"(function), "c"(count), "S"(vec)
399 : "memory", "cc");
c1f41226
EH
400#else
401 abort();
a1fd24af
AL
402#endif
403
bdde476a 404 if (eax)
a1fd24af 405 *eax = vec[0];
bdde476a 406 if (ebx)
a1fd24af 407 *ebx = vec[1];
bdde476a 408 if (ecx)
a1fd24af 409 *ecx = vec[2];
bdde476a 410 if (edx)
a1fd24af 411 *edx = vec[3];
bdde476a 412}
c6dc6f63
AP
413
414#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
415
416/* general substring compare of *[s1..e1) and *[s2..e2). sx is start of
417 * a substring. ex if !NULL points to the first char after a substring,
418 * otherwise the string is assumed to sized by a terminating nul.
419 * Return lexical ordering of *s1:*s2.
420 */
421static int sstrcmp(const char *s1, const char *e1, const char *s2,
422 const char *e2)
423{
424 for (;;) {
425 if (!*s1 || !*s2 || *s1 != *s2)
426 return (*s1 - *s2);
427 ++s1, ++s2;
428 if (s1 == e1 && s2 == e2)
429 return (0);
430 else if (s1 == e1)
431 return (*s2);
432 else if (s2 == e2)
433 return (*s1);
434 }
435}
436
437/* compare *[s..e) to *altstr. *altstr may be a simple string or multiple
438 * '|' delimited (possibly empty) strings in which case search for a match
439 * within the alternatives proceeds left to right. Return 0 for success,
440 * non-zero otherwise.
441 */
442static int altcmp(const char *s, const char *e, const char *altstr)
443{
444 const char *p, *q;
445
446 for (q = p = altstr; ; ) {
447 while (*p && *p != '|')
448 ++p;
449 if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
450 return (0);
451 if (!*p)
452 return (1);
453 else
454 q = ++p;
455 }
456}
457
458/* search featureset for flag *[s..e), if found set corresponding bit in
e41e0fc6 459 * *pval and return true, otherwise return false
c6dc6f63 460 */
e41e0fc6
JK
461static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
462 const char **featureset)
c6dc6f63
AP
463{
464 uint32_t mask;
465 const char **ppc;
e41e0fc6 466 bool found = false;
c6dc6f63 467
e41e0fc6 468 for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
c6dc6f63
AP
469 if (*ppc && !altcmp(s, e, *ppc)) {
470 *pval |= mask;
e41e0fc6 471 found = true;
c6dc6f63 472 }
e41e0fc6
JK
473 }
474 return found;
c6dc6f63
AP
475}
476
5ef57876
EH
477static void add_flagname_to_bitmaps(const char *flagname,
478 FeatureWordArray words)
c6dc6f63 479{
5ef57876
EH
480 FeatureWord w;
481 for (w = 0; w < FEATURE_WORDS; w++) {
482 FeatureWordInfo *wi = &feature_word_info[w];
483 if (wi->feat_names &&
484 lookup_feature(&words[w], flagname, NULL, wi->feat_names)) {
485 break;
486 }
487 }
488 if (w == FEATURE_WORDS) {
489 fprintf(stderr, "CPU feature %s not found\n", flagname);
490 }
c6dc6f63
AP
491}
492
500050d1
AF
493static ObjectClass *x86_cpu_class_by_name(const char *cpu_model)
494{
495 if (cpu_model == NULL) {
496 return NULL;
497 }
498
499 return object_class_by_name(TYPE_X86_CPU);
500}
501
9576de75 502typedef struct X86CPUDefinition {
c6dc6f63
AP
503 const char *name;
504 uint32_t level;
90e4b0c3
EH
505 uint32_t xlevel;
506 uint32_t xlevel2;
99b88a17
IM
507 /* vendor is zero-terminated, 12 character ASCII string */
508 char vendor[CPUID_VENDOR_SZ + 1];
c6dc6f63
AP
509 int family;
510 int model;
511 int stepping;
0514ef2f 512 FeatureWordArray features;
c6dc6f63 513 char model_id[48];
787aaf57 514 bool cache_info_passthrough;
9576de75 515} X86CPUDefinition;
c6dc6f63
AP
516
517#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
518#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
519 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
520#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
521 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
522 CPUID_PSE36 | CPUID_FXSR)
523#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
524#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
525 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
526 CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
527 CPUID_PAE | CPUID_SEP | CPUID_APIC)
528
551a2dec
AP
529#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
530 CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
531 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
532 CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
533 CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
8560efed
AJ
534 /* partly implemented:
535 CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
536 CPUID_PSE36 (needed for Solaris) */
537 /* missing:
538 CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
e71827bc
AJ
539#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
540 CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
541 CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
d640045a 542 CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
8560efed 543 /* missing:
e71827bc
AJ
544 CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
545 CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
546 CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
d640045a
AJ
547 CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_XSAVE,
548 CPUID_EXT_OSXSAVE, CPUID_EXT_AVX, CPUID_EXT_F16C,
83f7dc28 549 CPUID_EXT_RDRAND */
60032ac0 550#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
551a2dec
AP
551 CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
552 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
8560efed
AJ
553 /* missing:
554 CPUID_EXT2_PDPE1GB */
551a2dec
AP
555#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
556 CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
296acb64 557#define TCG_SVM_FEATURES 0
7073fbad 558#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP \
cd7f97ca 559 CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX)
111994ee 560 /* missing:
7073fbad
RH
561 CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
562 CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
cd7f97ca 563 CPUID_7_0_EBX_RDSEED */
551a2dec 564
7fc9b714 565/* built-in CPU model definitions
c6dc6f63 566 */
9576de75 567static X86CPUDefinition builtin_x86_defs[] = {
c6dc6f63
AP
568 {
569 .name = "qemu64",
570 .level = 4,
99b88a17 571 .vendor = CPUID_VENDOR_AMD,
c6dc6f63 572 .family = 6,
f8e6a11a 573 .model = 6,
c6dc6f63 574 .stepping = 3,
0514ef2f 575 .features[FEAT_1_EDX] =
27861ecc 576 PPRO_FEATURES |
c6dc6f63 577 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
c6dc6f63 578 CPUID_PSE36,
0514ef2f 579 .features[FEAT_1_ECX] =
27861ecc 580 CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
0514ef2f 581 .features[FEAT_8000_0001_EDX] =
27861ecc 582 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
c6dc6f63 583 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
0514ef2f 584 .features[FEAT_8000_0001_ECX] =
27861ecc 585 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
c6dc6f63
AP
586 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
587 .xlevel = 0x8000000A,
c6dc6f63
AP
588 },
589 {
590 .name = "phenom",
591 .level = 5,
99b88a17 592 .vendor = CPUID_VENDOR_AMD,
c6dc6f63
AP
593 .family = 16,
594 .model = 2,
595 .stepping = 3,
0514ef2f 596 .features[FEAT_1_EDX] =
27861ecc 597 PPRO_FEATURES |
c6dc6f63 598 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
8560efed 599 CPUID_PSE36 | CPUID_VME | CPUID_HT,
0514ef2f 600 .features[FEAT_1_ECX] =
27861ecc 601 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
c6dc6f63 602 CPUID_EXT_POPCNT,
0514ef2f 603 .features[FEAT_8000_0001_EDX] =
27861ecc 604 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
c6dc6f63
AP
605 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
606 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
8560efed 607 CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
c6dc6f63
AP
608 /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
609 CPUID_EXT3_CR8LEG,
610 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
611 CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
0514ef2f 612 .features[FEAT_8000_0001_ECX] =
27861ecc 613 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
c6dc6f63 614 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
0514ef2f 615 .features[FEAT_SVM] =
27861ecc 616 CPUID_SVM_NPT | CPUID_SVM_LBRV,
c6dc6f63
AP
617 .xlevel = 0x8000001A,
618 .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
619 },
620 {
621 .name = "core2duo",
622 .level = 10,
99b88a17 623 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
624 .family = 6,
625 .model = 15,
626 .stepping = 11,
0514ef2f 627 .features[FEAT_1_EDX] =
27861ecc 628 PPRO_FEATURES |
c6dc6f63 629 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
8560efed
AJ
630 CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
631 CPUID_HT | CPUID_TM | CPUID_PBE,
0514ef2f 632 .features[FEAT_1_ECX] =
27861ecc 633 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
8560efed
AJ
634 CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
635 CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
0514ef2f 636 .features[FEAT_8000_0001_EDX] =
27861ecc 637 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
0514ef2f 638 .features[FEAT_8000_0001_ECX] =
27861ecc 639 CPUID_EXT3_LAHF_LM,
c6dc6f63
AP
640 .xlevel = 0x80000008,
641 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
642 },
643 {
644 .name = "kvm64",
645 .level = 5,
99b88a17 646 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
647 .family = 15,
648 .model = 6,
649 .stepping = 1,
650 /* Missing: CPUID_VME, CPUID_HT */
0514ef2f 651 .features[FEAT_1_EDX] =
27861ecc 652 PPRO_FEATURES |
c6dc6f63
AP
653 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
654 CPUID_PSE36,
655 /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
0514ef2f 656 .features[FEAT_1_ECX] =
27861ecc 657 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
c6dc6f63 658 /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
0514ef2f 659 .features[FEAT_8000_0001_EDX] =
27861ecc 660 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
c6dc6f63
AP
661 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
662 /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
663 CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
664 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
665 CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
0514ef2f 666 .features[FEAT_8000_0001_ECX] =
27861ecc 667 0,
c6dc6f63
AP
668 .xlevel = 0x80000008,
669 .model_id = "Common KVM processor"
670 },
c6dc6f63
AP
671 {
672 .name = "qemu32",
673 .level = 4,
99b88a17 674 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63 675 .family = 6,
f8e6a11a 676 .model = 6,
c6dc6f63 677 .stepping = 3,
0514ef2f 678 .features[FEAT_1_EDX] =
27861ecc 679 PPRO_FEATURES,
0514ef2f 680 .features[FEAT_1_ECX] =
27861ecc 681 CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
58012d66 682 .xlevel = 0x80000004,
c6dc6f63 683 },
eafaf1e5
AP
684 {
685 .name = "kvm32",
686 .level = 5,
99b88a17 687 .vendor = CPUID_VENDOR_INTEL,
eafaf1e5
AP
688 .family = 15,
689 .model = 6,
690 .stepping = 1,
0514ef2f 691 .features[FEAT_1_EDX] =
27861ecc 692 PPRO_FEATURES |
eafaf1e5 693 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
0514ef2f 694 .features[FEAT_1_ECX] =
27861ecc 695 CPUID_EXT_SSE3,
0514ef2f 696 .features[FEAT_8000_0001_EDX] =
27861ecc 697 PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES,
0514ef2f 698 .features[FEAT_8000_0001_ECX] =
27861ecc 699 0,
eafaf1e5
AP
700 .xlevel = 0x80000008,
701 .model_id = "Common 32-bit KVM processor"
702 },
c6dc6f63
AP
703 {
704 .name = "coreduo",
705 .level = 10,
99b88a17 706 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
707 .family = 6,
708 .model = 14,
709 .stepping = 8,
0514ef2f 710 .features[FEAT_1_EDX] =
27861ecc 711 PPRO_FEATURES | CPUID_VME |
8560efed
AJ
712 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
713 CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
0514ef2f 714 .features[FEAT_1_ECX] =
27861ecc 715 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
8560efed 716 CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
0514ef2f 717 .features[FEAT_8000_0001_EDX] =
27861ecc 718 CPUID_EXT2_NX,
c6dc6f63
AP
719 .xlevel = 0x80000008,
720 .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
721 },
722 {
723 .name = "486",
58012d66 724 .level = 1,
99b88a17 725 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63 726 .family = 4,
b2a856d9 727 .model = 8,
c6dc6f63 728 .stepping = 0,
0514ef2f 729 .features[FEAT_1_EDX] =
27861ecc 730 I486_FEATURES,
c6dc6f63
AP
731 .xlevel = 0,
732 },
733 {
734 .name = "pentium",
735 .level = 1,
99b88a17 736 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
737 .family = 5,
738 .model = 4,
739 .stepping = 3,
0514ef2f 740 .features[FEAT_1_EDX] =
27861ecc 741 PENTIUM_FEATURES,
c6dc6f63
AP
742 .xlevel = 0,
743 },
744 {
745 .name = "pentium2",
746 .level = 2,
99b88a17 747 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
748 .family = 6,
749 .model = 5,
750 .stepping = 2,
0514ef2f 751 .features[FEAT_1_EDX] =
27861ecc 752 PENTIUM2_FEATURES,
c6dc6f63
AP
753 .xlevel = 0,
754 },
755 {
756 .name = "pentium3",
757 .level = 2,
99b88a17 758 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
759 .family = 6,
760 .model = 7,
761 .stepping = 3,
0514ef2f 762 .features[FEAT_1_EDX] =
27861ecc 763 PENTIUM3_FEATURES,
c6dc6f63
AP
764 .xlevel = 0,
765 },
766 {
767 .name = "athlon",
768 .level = 2,
99b88a17 769 .vendor = CPUID_VENDOR_AMD,
c6dc6f63
AP
770 .family = 6,
771 .model = 2,
772 .stepping = 3,
0514ef2f 773 .features[FEAT_1_EDX] =
27861ecc 774 PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
60032ac0 775 CPUID_MCA,
0514ef2f 776 .features[FEAT_8000_0001_EDX] =
27861ecc 777 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
60032ac0 778 CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
c6dc6f63 779 .xlevel = 0x80000008,
c6dc6f63
AP
780 },
781 {
782 .name = "n270",
783 /* original is on level 10 */
784 .level = 5,
99b88a17 785 .vendor = CPUID_VENDOR_INTEL,
c6dc6f63
AP
786 .family = 6,
787 .model = 28,
788 .stepping = 2,
0514ef2f 789 .features[FEAT_1_EDX] =
27861ecc 790 PPRO_FEATURES |
8560efed
AJ
791 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
792 CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
c6dc6f63 793 /* Some CPUs got no CPUID_SEP */
0514ef2f 794 .features[FEAT_1_ECX] =
27861ecc 795 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
4458c236
BP
796 CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR |
797 CPUID_EXT_MOVBE,
0514ef2f 798 .features[FEAT_8000_0001_EDX] =
27861ecc 799 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
60032ac0 800 CPUID_EXT2_NX,
0514ef2f 801 .features[FEAT_8000_0001_ECX] =
27861ecc 802 CPUID_EXT3_LAHF_LM,
c6dc6f63
AP
803 .xlevel = 0x8000000A,
804 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
805 },
3eca4642
EH
806 {
807 .name = "Conroe",
6b11322e 808 .level = 4,
99b88a17 809 .vendor = CPUID_VENDOR_INTEL,
3eca4642 810 .family = 6,
ffce9ebb 811 .model = 15,
3eca4642 812 .stepping = 3,
0514ef2f 813 .features[FEAT_1_EDX] =
27861ecc 814 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
815 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
816 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
817 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
818 CPUID_DE | CPUID_FP87,
0514ef2f 819 .features[FEAT_1_ECX] =
27861ecc 820 CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
0514ef2f 821 .features[FEAT_8000_0001_EDX] =
27861ecc 822 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
0514ef2f 823 .features[FEAT_8000_0001_ECX] =
27861ecc 824 CPUID_EXT3_LAHF_LM,
3eca4642
EH
825 .xlevel = 0x8000000A,
826 .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
827 },
828 {
829 .name = "Penryn",
6b11322e 830 .level = 4,
99b88a17 831 .vendor = CPUID_VENDOR_INTEL,
3eca4642 832 .family = 6,
ffce9ebb 833 .model = 23,
3eca4642 834 .stepping = 3,
0514ef2f 835 .features[FEAT_1_EDX] =
27861ecc 836 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
837 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
838 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
839 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
840 CPUID_DE | CPUID_FP87,
0514ef2f 841 .features[FEAT_1_ECX] =
27861ecc 842 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
3eca4642 843 CPUID_EXT_SSE3,
0514ef2f 844 .features[FEAT_8000_0001_EDX] =
27861ecc 845 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
0514ef2f 846 .features[FEAT_8000_0001_ECX] =
27861ecc 847 CPUID_EXT3_LAHF_LM,
3eca4642
EH
848 .xlevel = 0x8000000A,
849 .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
850 },
851 {
852 .name = "Nehalem",
6b11322e 853 .level = 4,
99b88a17 854 .vendor = CPUID_VENDOR_INTEL,
3eca4642 855 .family = 6,
ffce9ebb 856 .model = 26,
3eca4642 857 .stepping = 3,
0514ef2f 858 .features[FEAT_1_EDX] =
27861ecc 859 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
860 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
861 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
862 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
863 CPUID_DE | CPUID_FP87,
0514ef2f 864 .features[FEAT_1_ECX] =
27861ecc 865 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
3eca4642 866 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
0514ef2f 867 .features[FEAT_8000_0001_EDX] =
27861ecc 868 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
0514ef2f 869 .features[FEAT_8000_0001_ECX] =
27861ecc 870 CPUID_EXT3_LAHF_LM,
3eca4642
EH
871 .xlevel = 0x8000000A,
872 .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
873 },
874 {
875 .name = "Westmere",
876 .level = 11,
99b88a17 877 .vendor = CPUID_VENDOR_INTEL,
3eca4642
EH
878 .family = 6,
879 .model = 44,
880 .stepping = 1,
0514ef2f 881 .features[FEAT_1_EDX] =
27861ecc 882 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
883 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
884 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
885 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
886 CPUID_DE | CPUID_FP87,
0514ef2f 887 .features[FEAT_1_ECX] =
27861ecc 888 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
3eca4642 889 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
41cb383f 890 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
0514ef2f 891 .features[FEAT_8000_0001_EDX] =
27861ecc 892 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
0514ef2f 893 .features[FEAT_8000_0001_ECX] =
27861ecc 894 CPUID_EXT3_LAHF_LM,
3eca4642
EH
895 .xlevel = 0x8000000A,
896 .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
897 },
898 {
899 .name = "SandyBridge",
900 .level = 0xd,
99b88a17 901 .vendor = CPUID_VENDOR_INTEL,
3eca4642
EH
902 .family = 6,
903 .model = 42,
904 .stepping = 1,
0514ef2f 905 .features[FEAT_1_EDX] =
27861ecc 906 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
907 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
908 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
909 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
910 CPUID_DE | CPUID_FP87,
0514ef2f 911 .features[FEAT_1_ECX] =
27861ecc 912 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
3eca4642
EH
913 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
914 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
915 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
916 CPUID_EXT_SSE3,
0514ef2f 917 .features[FEAT_8000_0001_EDX] =
27861ecc 918 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
3eca4642 919 CPUID_EXT2_SYSCALL,
0514ef2f 920 .features[FEAT_8000_0001_ECX] =
27861ecc 921 CPUID_EXT3_LAHF_LM,
3eca4642
EH
922 .xlevel = 0x8000000A,
923 .model_id = "Intel Xeon E312xx (Sandy Bridge)",
924 },
37507094
EH
925 {
926 .name = "Haswell",
927 .level = 0xd,
99b88a17 928 .vendor = CPUID_VENDOR_INTEL,
37507094
EH
929 .family = 6,
930 .model = 60,
931 .stepping = 1,
0514ef2f 932 .features[FEAT_1_EDX] =
27861ecc 933 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
37507094 934 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
80ae4160 935 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
37507094
EH
936 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
937 CPUID_DE | CPUID_FP87,
0514ef2f 938 .features[FEAT_1_ECX] =
27861ecc 939 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
37507094
EH
940 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
941 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
942 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
943 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
944 CPUID_EXT_PCID,
0514ef2f 945 .features[FEAT_8000_0001_EDX] =
27861ecc 946 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
80ae4160 947 CPUID_EXT2_SYSCALL,
0514ef2f 948 .features[FEAT_8000_0001_ECX] =
27861ecc 949 CPUID_EXT3_LAHF_LM,
0514ef2f 950 .features[FEAT_7_0_EBX] =
27861ecc 951 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
37507094
EH
952 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
953 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
954 CPUID_7_0_EBX_RTM,
955 .xlevel = 0x8000000A,
956 .model_id = "Intel Core Processor (Haswell)",
957 },
3eca4642
EH
958 {
959 .name = "Opteron_G1",
960 .level = 5,
99b88a17 961 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
962 .family = 15,
963 .model = 6,
964 .stepping = 1,
0514ef2f 965 .features[FEAT_1_EDX] =
27861ecc 966 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
967 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
968 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
969 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
970 CPUID_DE | CPUID_FP87,
0514ef2f 971 .features[FEAT_1_ECX] =
27861ecc 972 CPUID_EXT_SSE3,
0514ef2f 973 .features[FEAT_8000_0001_EDX] =
27861ecc 974 CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
3eca4642
EH
975 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
976 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
977 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
978 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
979 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
980 .xlevel = 0x80000008,
981 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
982 },
983 {
984 .name = "Opteron_G2",
985 .level = 5,
99b88a17 986 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
987 .family = 15,
988 .model = 6,
989 .stepping = 1,
0514ef2f 990 .features[FEAT_1_EDX] =
27861ecc 991 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
992 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
993 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
994 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
995 CPUID_DE | CPUID_FP87,
0514ef2f 996 .features[FEAT_1_ECX] =
27861ecc 997 CPUID_EXT_CX16 | CPUID_EXT_SSE3,
0514ef2f 998 .features[FEAT_8000_0001_EDX] =
27861ecc 999 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
3eca4642
EH
1000 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1001 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1002 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1003 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1004 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1005 CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 1006 .features[FEAT_8000_0001_ECX] =
27861ecc 1007 CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
3eca4642
EH
1008 .xlevel = 0x80000008,
1009 .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
1010 },
1011 {
1012 .name = "Opteron_G3",
1013 .level = 5,
99b88a17 1014 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
1015 .family = 15,
1016 .model = 6,
1017 .stepping = 1,
0514ef2f 1018 .features[FEAT_1_EDX] =
27861ecc 1019 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
1020 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1021 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1022 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1023 CPUID_DE | CPUID_FP87,
0514ef2f 1024 .features[FEAT_1_ECX] =
27861ecc 1025 CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
3eca4642 1026 CPUID_EXT_SSE3,
0514ef2f 1027 .features[FEAT_8000_0001_EDX] =
27861ecc 1028 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
3eca4642
EH
1029 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1030 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1031 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1032 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1033 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1034 CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 1035 .features[FEAT_8000_0001_ECX] =
27861ecc 1036 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
3eca4642
EH
1037 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
1038 .xlevel = 0x80000008,
1039 .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
1040 },
1041 {
1042 .name = "Opteron_G4",
1043 .level = 0xd,
99b88a17 1044 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
1045 .family = 21,
1046 .model = 1,
1047 .stepping = 2,
0514ef2f 1048 .features[FEAT_1_EDX] =
27861ecc 1049 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
1050 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1051 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1052 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1053 CPUID_DE | CPUID_FP87,
0514ef2f 1054 .features[FEAT_1_ECX] =
27861ecc 1055 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
3eca4642
EH
1056 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1057 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1058 CPUID_EXT_SSE3,
0514ef2f 1059 .features[FEAT_8000_0001_EDX] =
27861ecc 1060 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
3eca4642
EH
1061 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1062 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1063 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1064 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1065 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1066 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 1067 .features[FEAT_8000_0001_ECX] =
27861ecc 1068 CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
3eca4642
EH
1069 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1070 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1071 CPUID_EXT3_LAHF_LM,
1072 .xlevel = 0x8000001A,
1073 .model_id = "AMD Opteron 62xx class CPU",
1074 },
021941b9
AP
1075 {
1076 .name = "Opteron_G5",
1077 .level = 0xd,
99b88a17 1078 .vendor = CPUID_VENDOR_AMD,
021941b9
AP
1079 .family = 21,
1080 .model = 2,
1081 .stepping = 0,
0514ef2f 1082 .features[FEAT_1_EDX] =
27861ecc 1083 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
021941b9
AP
1084 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1085 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1086 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1087 CPUID_DE | CPUID_FP87,
0514ef2f 1088 .features[FEAT_1_ECX] =
27861ecc 1089 CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
021941b9
AP
1090 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1091 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
1092 CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
0514ef2f 1093 .features[FEAT_8000_0001_EDX] =
27861ecc 1094 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
021941b9
AP
1095 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1096 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1097 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1098 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1099 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1100 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 1101 .features[FEAT_8000_0001_ECX] =
27861ecc 1102 CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
021941b9
AP
1103 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1104 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1105 CPUID_EXT3_LAHF_LM,
1106 .xlevel = 0x8000001A,
1107 .model_id = "AMD Opteron 63xx class CPU",
1108 },
c6dc6f63
AP
1109};
1110
0668af54
EH
1111/**
1112 * x86_cpu_compat_set_features:
1113 * @cpu_model: CPU model name to be changed. If NULL, all CPU models are changed
1114 * @w: Identifies the feature word to be changed.
1115 * @feat_add: Feature bits to be added to feature word
1116 * @feat_remove: Feature bits to be removed from feature word
1117 *
1118 * Change CPU model feature bits for compatibility.
1119 *
1120 * This function may be used by machine-type compatibility functions
1121 * to enable or disable feature bits on specific CPU models.
1122 */
1123void x86_cpu_compat_set_features(const char *cpu_model, FeatureWord w,
1124 uint32_t feat_add, uint32_t feat_remove)
1125{
9576de75 1126 X86CPUDefinition *def;
0668af54
EH
1127 int i;
1128 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1129 def = &builtin_x86_defs[i];
1130 if (!cpu_model || !strcmp(cpu_model, def->name)) {
1131 def->features[w] |= feat_add;
1132 def->features[w] &= ~feat_remove;
1133 }
1134 }
1135}
1136
c6dc6f63
AP
1137static int cpu_x86_fill_model_id(char *str)
1138{
1139 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1140 int i;
1141
1142 for (i = 0; i < 3; i++) {
1143 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
1144 memcpy(str + i * 16 + 0, &eax, 4);
1145 memcpy(str + i * 16 + 4, &ebx, 4);
1146 memcpy(str + i * 16 + 8, &ecx, 4);
1147 memcpy(str + i * 16 + 12, &edx, 4);
1148 }
1149 return 0;
1150}
1151
9576de75 1152/* Fill a X86CPUDefinition struct with information about the host CPU, and
6e746f30
EH
1153 * the CPU features supported by the host hardware + host kernel
1154 *
1155 * This function may be called only if KVM is enabled.
1156 */
9576de75 1157static void kvm_cpu_fill_host(X86CPUDefinition *x86_cpu_def)
c6dc6f63 1158{
12869995 1159 KVMState *s = kvm_state;
c6dc6f63 1160 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
74f54bc4 1161 FeatureWord w;
c6dc6f63 1162
6e746f30
EH
1163 assert(kvm_enabled());
1164
c6dc6f63 1165 x86_cpu_def->name = "host";
787aaf57 1166 x86_cpu_def->cache_info_passthrough = true;
c6dc6f63 1167 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
99b88a17 1168 x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
c6dc6f63
AP
1169
1170 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
1171 x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1172 x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1173 x86_cpu_def->stepping = eax & 0x0F;
c6dc6f63 1174
12869995 1175 x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
2a573259
EH
1176 x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
1177 x86_cpu_def->xlevel2 =
1178 kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
1179
1180 cpu_x86_fill_model_id(x86_cpu_def->model_id);
1181
2bc65d2b
EH
1182 for (w = 0; w < FEATURE_WORDS; w++) {
1183 FeatureWordInfo *wi = &feature_word_info[w];
1184 x86_cpu_def->features[w] =
1185 kvm_arch_get_supported_cpuid(s, wi->cpuid_eax, wi->cpuid_ecx,
1186 wi->cpuid_reg);
1187 }
c6dc6f63
AP
1188}
1189
bffd67b0 1190static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask)
c6dc6f63
AP
1191{
1192 int i;
1193
1194 for (i = 0; i < 32; ++i)
1195 if (1 << i & mask) {
bffd67b0 1196 const char *reg = get_register_name_32(f->cpuid_reg);
8b4beddc
EH
1197 assert(reg);
1198 fprintf(stderr, "warning: host doesn't support requested feature: "
1199 "CPUID.%02XH:%s%s%s [bit %d]\n",
bffd67b0
EH
1200 f->cpuid_eax, reg,
1201 f->feat_names[i] ? "." : "",
1202 f->feat_names[i] ? f->feat_names[i] : "", i);
c6dc6f63
AP
1203 break;
1204 }
1205 return 0;
1206}
1207
07ca5945
EH
1208/* Check if all requested cpu flags are making their way to the guest
1209 *
1210 * Returns 0 if all flags are supported by the host, non-zero otherwise.
6e746f30
EH
1211 *
1212 * This function may be called only if KVM is enabled.
c6dc6f63 1213 */
f0b9b111 1214static int kvm_check_features_against_host(KVMState *s, X86CPU *cpu)
c6dc6f63 1215{
5ec01c2e 1216 CPUX86State *env = &cpu->env;
f0b9b111
EH
1217 int rv = 0;
1218 FeatureWord w;
c6dc6f63 1219
6e746f30
EH
1220 assert(kvm_enabled());
1221
f0b9b111 1222 for (w = 0; w < FEATURE_WORDS; w++) {
bffd67b0 1223 FeatureWordInfo *wi = &feature_word_info[w];
f0b9b111
EH
1224 uint32_t guest_feat = env->features[w];
1225 uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax,
1226 wi->cpuid_ecx,
1227 wi->cpuid_reg);
1228 uint32_t mask;
bffd67b0 1229 for (mask = 1; mask; mask <<= 1) {
f0b9b111 1230 if (guest_feat & mask && !(host_feat & mask)) {
bffd67b0
EH
1231 unavailable_host_feature(wi, mask);
1232 rv = 1;
1233 }
1234 }
1235 }
c6dc6f63
AP
1236 return rv;
1237}
1238
95b8519d
AF
1239static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
1240 const char *name, Error **errp)
1241{
1242 X86CPU *cpu = X86_CPU(obj);
1243 CPUX86State *env = &cpu->env;
1244 int64_t value;
1245
1246 value = (env->cpuid_version >> 8) & 0xf;
1247 if (value == 0xf) {
1248 value += (env->cpuid_version >> 20) & 0xff;
1249 }
1250 visit_type_int(v, &value, name, errp);
1251}
1252
71ad61d3
AF
1253static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
1254 const char *name, Error **errp)
ed5e1ec3 1255{
71ad61d3
AF
1256 X86CPU *cpu = X86_CPU(obj);
1257 CPUX86State *env = &cpu->env;
1258 const int64_t min = 0;
1259 const int64_t max = 0xff + 0xf;
1260 int64_t value;
1261
1262 visit_type_int(v, &value, name, errp);
1263 if (error_is_set(errp)) {
1264 return;
1265 }
1266 if (value < min || value > max) {
1267 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1268 name ? name : "null", value, min, max);
1269 return;
1270 }
1271
ed5e1ec3 1272 env->cpuid_version &= ~0xff00f00;
71ad61d3
AF
1273 if (value > 0x0f) {
1274 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
ed5e1ec3 1275 } else {
71ad61d3 1276 env->cpuid_version |= value << 8;
ed5e1ec3
AF
1277 }
1278}
1279
67e30c83
AF
1280static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
1281 const char *name, Error **errp)
1282{
1283 X86CPU *cpu = X86_CPU(obj);
1284 CPUX86State *env = &cpu->env;
1285 int64_t value;
1286
1287 value = (env->cpuid_version >> 4) & 0xf;
1288 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
1289 visit_type_int(v, &value, name, errp);
1290}
1291
c5291a4f
AF
1292static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
1293 const char *name, Error **errp)
b0704cbd 1294{
c5291a4f
AF
1295 X86CPU *cpu = X86_CPU(obj);
1296 CPUX86State *env = &cpu->env;
1297 const int64_t min = 0;
1298 const int64_t max = 0xff;
1299 int64_t value;
1300
1301 visit_type_int(v, &value, name, errp);
1302 if (error_is_set(errp)) {
1303 return;
1304 }
1305 if (value < min || value > max) {
1306 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1307 name ? name : "null", value, min, max);
1308 return;
1309 }
1310
b0704cbd 1311 env->cpuid_version &= ~0xf00f0;
c5291a4f 1312 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
b0704cbd
AF
1313}
1314
35112e41
AF
1315static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
1316 void *opaque, const char *name,
1317 Error **errp)
1318{
1319 X86CPU *cpu = X86_CPU(obj);
1320 CPUX86State *env = &cpu->env;
1321 int64_t value;
1322
1323 value = env->cpuid_version & 0xf;
1324 visit_type_int(v, &value, name, errp);
1325}
1326
036e2222
AF
1327static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
1328 void *opaque, const char *name,
1329 Error **errp)
38c3dc46 1330{
036e2222
AF
1331 X86CPU *cpu = X86_CPU(obj);
1332 CPUX86State *env = &cpu->env;
1333 const int64_t min = 0;
1334 const int64_t max = 0xf;
1335 int64_t value;
1336
1337 visit_type_int(v, &value, name, errp);
1338 if (error_is_set(errp)) {
1339 return;
1340 }
1341 if (value < min || value > max) {
1342 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1343 name ? name : "null", value, min, max);
1344 return;
1345 }
1346
38c3dc46 1347 env->cpuid_version &= ~0xf;
036e2222 1348 env->cpuid_version |= value & 0xf;
38c3dc46
AF
1349}
1350
8e1898bf
AF
1351static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
1352 const char *name, Error **errp)
1353{
1354 X86CPU *cpu = X86_CPU(obj);
8e1898bf 1355
fa029887 1356 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
8e1898bf
AF
1357}
1358
1359static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
1360 const char *name, Error **errp)
1361{
1362 X86CPU *cpu = X86_CPU(obj);
8e1898bf 1363
fa029887 1364 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
8e1898bf
AF
1365}
1366
16b93aa8
AF
1367static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
1368 const char *name, Error **errp)
1369{
1370 X86CPU *cpu = X86_CPU(obj);
16b93aa8 1371
fa029887 1372 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
16b93aa8
AF
1373}
1374
1375static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
1376 const char *name, Error **errp)
1377{
1378 X86CPU *cpu = X86_CPU(obj);
16b93aa8 1379
fa029887 1380 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
16b93aa8
AF
1381}
1382
d480e1af
AF
1383static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1384{
1385 X86CPU *cpu = X86_CPU(obj);
1386 CPUX86State *env = &cpu->env;
1387 char *value;
d480e1af 1388
9df694ee 1389 value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
99b88a17
IM
1390 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
1391 env->cpuid_vendor3);
d480e1af
AF
1392 return value;
1393}
1394
1395static void x86_cpuid_set_vendor(Object *obj, const char *value,
1396 Error **errp)
1397{
1398 X86CPU *cpu = X86_CPU(obj);
1399 CPUX86State *env = &cpu->env;
1400 int i;
1401
9df694ee 1402 if (strlen(value) != CPUID_VENDOR_SZ) {
d480e1af
AF
1403 error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
1404 "vendor", value);
1405 return;
1406 }
1407
1408 env->cpuid_vendor1 = 0;
1409 env->cpuid_vendor2 = 0;
1410 env->cpuid_vendor3 = 0;
1411 for (i = 0; i < 4; i++) {
1412 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1413 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1414 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1415 }
d480e1af
AF
1416}
1417
63e886eb
AF
1418static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1419{
1420 X86CPU *cpu = X86_CPU(obj);
1421 CPUX86State *env = &cpu->env;
1422 char *value;
1423 int i;
1424
1425 value = g_malloc(48 + 1);
1426 for (i = 0; i < 48; i++) {
1427 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1428 }
1429 value[48] = '\0';
1430 return value;
1431}
1432
938d4c25
AF
1433static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1434 Error **errp)
dcce6675 1435{
938d4c25
AF
1436 X86CPU *cpu = X86_CPU(obj);
1437 CPUX86State *env = &cpu->env;
dcce6675
AF
1438 int c, len, i;
1439
1440 if (model_id == NULL) {
1441 model_id = "";
1442 }
1443 len = strlen(model_id);
d0a6acf4 1444 memset(env->cpuid_model, 0, 48);
dcce6675
AF
1445 for (i = 0; i < 48; i++) {
1446 if (i >= len) {
1447 c = '\0';
1448 } else {
1449 c = (uint8_t)model_id[i];
1450 }
1451 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1452 }
1453}
1454
89e48965
AF
1455static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
1456 const char *name, Error **errp)
1457{
1458 X86CPU *cpu = X86_CPU(obj);
1459 int64_t value;
1460
1461 value = cpu->env.tsc_khz * 1000;
1462 visit_type_int(v, &value, name, errp);
1463}
1464
1465static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
1466 const char *name, Error **errp)
1467{
1468 X86CPU *cpu = X86_CPU(obj);
1469 const int64_t min = 0;
2e84849a 1470 const int64_t max = INT64_MAX;
89e48965
AF
1471 int64_t value;
1472
1473 visit_type_int(v, &value, name, errp);
1474 if (error_is_set(errp)) {
1475 return;
1476 }
1477 if (value < min || value > max) {
1478 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1479 name ? name : "null", value, min, max);
1480 return;
1481 }
1482
1483 cpu->env.tsc_khz = value / 1000;
1484}
1485
31050930
IM
1486static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, void *opaque,
1487 const char *name, Error **errp)
1488{
1489 X86CPU *cpu = X86_CPU(obj);
1490 int64_t value = cpu->env.cpuid_apic_id;
1491
1492 visit_type_int(v, &value, name, errp);
1493}
1494
1495static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque,
1496 const char *name, Error **errp)
1497{
1498 X86CPU *cpu = X86_CPU(obj);
8d6d4980 1499 DeviceState *dev = DEVICE(obj);
31050930
IM
1500 const int64_t min = 0;
1501 const int64_t max = UINT32_MAX;
1502 Error *error = NULL;
1503 int64_t value;
1504
8d6d4980
IM
1505 if (dev->realized) {
1506 error_setg(errp, "Attempt to set property '%s' on '%s' after "
1507 "it was realized", name, object_get_typename(obj));
1508 return;
1509 }
1510
31050930
IM
1511 visit_type_int(v, &value, name, &error);
1512 if (error) {
1513 error_propagate(errp, error);
1514 return;
1515 }
1516 if (value < min || value > max) {
1517 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1518 " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
1519 object_get_typename(obj), name, value, min, max);
1520 return;
1521 }
1522
1523 if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
1524 error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
1525 return;
1526 }
1527 cpu->env.cpuid_apic_id = value;
1528}
1529
7e5292b5 1530/* Generic getter for "feature-words" and "filtered-features" properties */
8e8aba50
EH
1531static void x86_cpu_get_feature_words(Object *obj, Visitor *v, void *opaque,
1532 const char *name, Error **errp)
1533{
7e5292b5 1534 uint32_t *array = (uint32_t *)opaque;
8e8aba50
EH
1535 FeatureWord w;
1536 Error *err = NULL;
1537 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
1538 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
1539 X86CPUFeatureWordInfoList *list = NULL;
1540
1541 for (w = 0; w < FEATURE_WORDS; w++) {
1542 FeatureWordInfo *wi = &feature_word_info[w];
1543 X86CPUFeatureWordInfo *qwi = &word_infos[w];
1544 qwi->cpuid_input_eax = wi->cpuid_eax;
1545 qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
1546 qwi->cpuid_input_ecx = wi->cpuid_ecx;
1547 qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
7e5292b5 1548 qwi->features = array[w];
8e8aba50
EH
1549
1550 /* List will be in reverse order, but order shouldn't matter */
1551 list_entries[w].next = list;
1552 list_entries[w].value = &word_infos[w];
1553 list = &list_entries[w];
1554 }
1555
1556 visit_type_X86CPUFeatureWordInfoList(v, &list, "feature-words", &err);
1557 error_propagate(errp, err);
1558}
1559
c8f0f88e
IM
1560static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
1561 const char *name, Error **errp)
1562{
1563 X86CPU *cpu = X86_CPU(obj);
1564 int64_t value = cpu->hyperv_spinlock_attempts;
1565
1566 visit_type_int(v, &value, name, errp);
1567}
1568
1569static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
1570 const char *name, Error **errp)
1571{
1572 const int64_t min = 0xFFF;
1573 const int64_t max = UINT_MAX;
1574 X86CPU *cpu = X86_CPU(obj);
1575 Error *err = NULL;
1576 int64_t value;
1577
1578 visit_type_int(v, &value, name, &err);
1579 if (err) {
1580 error_propagate(errp, err);
1581 return;
1582 }
1583
1584 if (value < min || value > max) {
1585 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1586 " (minimum: %" PRId64 ", maximum: %" PRId64 ")",
1587 object_get_typename(obj), name ? name : "null",
1588 value, min, max);
1589 return;
1590 }
1591 cpu->hyperv_spinlock_attempts = value;
1592}
1593
1594static PropertyInfo qdev_prop_spinlocks = {
1595 .name = "int",
1596 .get = x86_get_hv_spinlocks,
1597 .set = x86_set_hv_spinlocks,
1598};
1599
9576de75 1600static int cpu_x86_find_by_name(X86CPU *cpu, X86CPUDefinition *x86_cpu_def,
c1399112 1601 const char *name)
c6dc6f63 1602{
9576de75 1603 X86CPUDefinition *def;
7fc9b714 1604 int i;
c6dc6f63 1605
4bfe910d
AF
1606 if (name == NULL) {
1607 return -1;
9f3fb565 1608 }
4bfe910d 1609 if (kvm_enabled() && strcmp(name, "host") == 0) {
6e746f30 1610 kvm_cpu_fill_host(x86_cpu_def);
00b81053 1611 object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
4bfe910d 1612 return 0;
c6dc6f63
AP
1613 }
1614
7fc9b714
AF
1615 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1616 def = &builtin_x86_defs[i];
4bfe910d
AF
1617 if (strcmp(name, def->name) == 0) {
1618 memcpy(x86_cpu_def, def, sizeof(*def));
1619 return 0;
1620 }
1621 }
1622
1623 return -1;
8f961357
EH
1624}
1625
72ac2e87
IM
1626/* Convert all '_' in a feature string option name to '-', to make feature
1627 * name conform to QOM property naming rule, which uses '-' instead of '_'.
1628 */
1629static inline void feat2prop(char *s)
1630{
1631 while ((s = strchr(s, '_'))) {
1632 *s = '-';
1633 }
1634}
1635
8f961357
EH
1636/* Parse "+feature,-feature,feature=foo" CPU feature string
1637 */
a91987c2 1638static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
8f961357 1639{
8f961357
EH
1640 char *featurestr; /* Single 'key=value" string being parsed */
1641 /* Features to be added */
077c68c3 1642 FeatureWordArray plus_features = { 0 };
8f961357 1643 /* Features to be removed */
5ef57876 1644 FeatureWordArray minus_features = { 0 };
8f961357 1645 uint32_t numvalue;
a91987c2 1646 CPUX86State *env = &cpu->env;
8f961357 1647
8f961357 1648 featurestr = features ? strtok(features, ",") : NULL;
c6dc6f63
AP
1649
1650 while (featurestr) {
1651 char *val;
1652 if (featurestr[0] == '+') {
5ef57876 1653 add_flagname_to_bitmaps(featurestr + 1, plus_features);
c6dc6f63 1654 } else if (featurestr[0] == '-') {
5ef57876 1655 add_flagname_to_bitmaps(featurestr + 1, minus_features);
c6dc6f63
AP
1656 } else if ((val = strchr(featurestr, '='))) {
1657 *val = 0; val++;
72ac2e87 1658 feat2prop(featurestr);
d024d209 1659 if (!strcmp(featurestr, "xlevel")) {
c6dc6f63 1660 char *err;
a91987c2
IM
1661 char num[32];
1662
c6dc6f63
AP
1663 numvalue = strtoul(val, &err, 0);
1664 if (!*val || *err) {
312fd5f2 1665 error_setg(errp, "bad numerical value %s", val);
a91987c2 1666 goto out;
c6dc6f63
AP
1667 }
1668 if (numvalue < 0x80000000) {
8ba8a698
IM
1669 fprintf(stderr, "xlevel value shall always be >= 0x80000000"
1670 ", fixup will be removed in future versions\n");
2f7a21c4 1671 numvalue += 0x80000000;
c6dc6f63 1672 }
a91987c2
IM
1673 snprintf(num, sizeof(num), "%" PRIu32, numvalue);
1674 object_property_parse(OBJECT(cpu), num, featurestr, errp);
72ac2e87 1675 } else if (!strcmp(featurestr, "tsc-freq")) {
b862d1fe
JR
1676 int64_t tsc_freq;
1677 char *err;
a91987c2 1678 char num[32];
b862d1fe
JR
1679
1680 tsc_freq = strtosz_suffix_unit(val, &err,
1681 STRTOSZ_DEFSUFFIX_B, 1000);
45009a30 1682 if (tsc_freq < 0 || *err) {
312fd5f2 1683 error_setg(errp, "bad numerical value %s", val);
a91987c2 1684 goto out;
b862d1fe 1685 }
a91987c2
IM
1686 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
1687 object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
72ac2e87 1688 } else if (!strcmp(featurestr, "hv-spinlocks")) {
28f52cc0 1689 char *err;
92067bf4 1690 const int min = 0xFFF;
c8f0f88e 1691 char num[32];
28f52cc0
VR
1692 numvalue = strtoul(val, &err, 0);
1693 if (!*val || *err) {
312fd5f2 1694 error_setg(errp, "bad numerical value %s", val);
a91987c2 1695 goto out;
28f52cc0 1696 }
92067bf4
IM
1697 if (numvalue < min) {
1698 fprintf(stderr, "hv-spinlocks value shall always be >= 0x%x"
1699 ", fixup will be removed in future versions\n",
1700 min);
1701 numvalue = min;
1702 }
c8f0f88e
IM
1703 snprintf(num, sizeof(num), "%" PRId32, numvalue);
1704 object_property_parse(OBJECT(cpu), num, featurestr, errp);
c6dc6f63 1705 } else {
d024d209 1706 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63 1707 }
c6dc6f63 1708 } else {
258f5abe
IM
1709 feat2prop(featurestr);
1710 object_property_parse(OBJECT(cpu), "on", featurestr, errp);
a91987c2
IM
1711 }
1712 if (error_is_set(errp)) {
1713 goto out;
c6dc6f63
AP
1714 }
1715 featurestr = strtok(NULL, ",");
1716 }
0514ef2f
EH
1717 env->features[FEAT_1_EDX] |= plus_features[FEAT_1_EDX];
1718 env->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX];
1719 env->features[FEAT_8000_0001_EDX] |= plus_features[FEAT_8000_0001_EDX];
1720 env->features[FEAT_8000_0001_ECX] |= plus_features[FEAT_8000_0001_ECX];
1721 env->features[FEAT_C000_0001_EDX] |= plus_features[FEAT_C000_0001_EDX];
1722 env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
1723 env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
1724 env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
1725 env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
1726 env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
1727 env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX];
1728 env->features[FEAT_8000_0001_ECX] &= ~minus_features[FEAT_8000_0001_ECX];
1729 env->features[FEAT_C000_0001_EDX] &= ~minus_features[FEAT_C000_0001_EDX];
1730 env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
1731 env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
1732 env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
c6dc6f63 1733
a91987c2
IM
1734out:
1735 return;
c6dc6f63
AP
1736}
1737
1738/* generate a composite string into buf of all cpuid names in featureset
1739 * selected by fbits. indicate truncation at bufsize in the event of overflow.
1740 * if flags, suppress names undefined in featureset.
1741 */
1742static void listflags(char *buf, int bufsize, uint32_t fbits,
1743 const char **featureset, uint32_t flags)
1744{
1745 const char **p = &featureset[31];
1746 char *q, *b, bit;
1747 int nc;
1748
1749 b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1750 *buf = '\0';
1751 for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1752 if (fbits & 1 << bit && (*p || !flags)) {
1753 if (*p)
1754 nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1755 else
1756 nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1757 if (bufsize <= nc) {
1758 if (b) {
1759 memcpy(b, "...", sizeof("..."));
1760 }
1761 return;
1762 }
1763 q += nc;
1764 bufsize -= nc;
1765 }
1766}
1767
e916cbf8
PM
1768/* generate CPU information. */
1769void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
c6dc6f63 1770{
9576de75 1771 X86CPUDefinition *def;
c6dc6f63 1772 char buf[256];
7fc9b714 1773 int i;
c6dc6f63 1774
7fc9b714
AF
1775 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1776 def = &builtin_x86_defs[i];
c04321b3 1777 snprintf(buf, sizeof(buf), "%s", def->name);
6cdf8854 1778 (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
c6dc6f63 1779 }
21ad7789
JK
1780#ifdef CONFIG_KVM
1781 (*cpu_fprintf)(f, "x86 %16s %-48s\n", "host",
1782 "KVM processor with all supported host features "
1783 "(only available in KVM mode)");
1784#endif
1785
6cdf8854 1786 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
3af60be2
JK
1787 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
1788 FeatureWordInfo *fw = &feature_word_info[i];
1789
1790 listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
1791 (*cpu_fprintf)(f, " %s\n", buf);
1792 }
c6dc6f63
AP
1793}
1794
76b64a7a 1795CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
e3966126
AL
1796{
1797 CpuDefinitionInfoList *cpu_list = NULL;
9576de75 1798 X86CPUDefinition *def;
7fc9b714 1799 int i;
e3966126 1800
7fc9b714 1801 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
e3966126
AL
1802 CpuDefinitionInfoList *entry;
1803 CpuDefinitionInfo *info;
1804
7fc9b714 1805 def = &builtin_x86_defs[i];
e3966126
AL
1806 info = g_malloc0(sizeof(*info));
1807 info->name = g_strdup(def->name);
1808
1809 entry = g_malloc0(sizeof(*entry));
1810 entry->value = info;
1811 entry->next = cpu_list;
1812 cpu_list = entry;
1813 }
1814
1815 return cpu_list;
1816}
1817
bc74b7db
EH
1818static void filter_features_for_kvm(X86CPU *cpu)
1819{
1820 CPUX86State *env = &cpu->env;
1821 KVMState *s = kvm_state;
bd87d2a2 1822 FeatureWord w;
bc74b7db 1823
bd87d2a2
EH
1824 for (w = 0; w < FEATURE_WORDS; w++) {
1825 FeatureWordInfo *wi = &feature_word_info[w];
034acf4a
EH
1826 uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax,
1827 wi->cpuid_ecx,
1828 wi->cpuid_reg);
1829 uint32_t requested_features = env->features[w];
1830 env->features[w] &= host_feat;
1831 cpu->filtered_features[w] = requested_features & ~env->features[w];
bd87d2a2 1832 }
bc74b7db 1833}
bc74b7db 1834
c080e30e
EH
1835/* Load CPU definition for a given CPU model name
1836 */
1837static void x86_cpu_load_def(X86CPU *cpu, const char *name, Error **errp)
c6dc6f63 1838{
61dcd775 1839 CPUX86State *env = &cpu->env;
9576de75 1840 X86CPUDefinition def1, *def = &def1;
74f54bc4
EH
1841 const char *vendor;
1842 char host_vendor[CPUID_VENDOR_SZ + 1];
c6dc6f63 1843
db0ad1ba
JR
1844 memset(def, 0, sizeof(*def));
1845
c1399112 1846 if (cpu_x86_find_by_name(cpu, def, name) < 0) {
2d64255b
AF
1847 error_setg(errp, "Unable to find CPU definition: %s", name);
1848 return;
8f961357
EH
1849 }
1850
2d64255b
AF
1851 object_property_set_int(OBJECT(cpu), def->level, "level", errp);
1852 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
1853 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
1854 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
0514ef2f
EH
1855 env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX];
1856 env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX];
1857 env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX];
1858 env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX];
2d64255b 1859 object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
0514ef2f
EH
1860 env->features[FEAT_KVM] = def->features[FEAT_KVM];
1861 env->features[FEAT_SVM] = def->features[FEAT_SVM];
1862 env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
1863 env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
b3baa152 1864 env->cpuid_xlevel2 = def->xlevel2;
787aaf57 1865 cpu->cache_info_passthrough = def->cache_info_passthrough;
3b671a40 1866
2d64255b 1867 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
82beb536 1868
9576de75 1869 /* Special cases not set in the X86CPUDefinition structs: */
82beb536 1870 if (kvm_enabled()) {
5fcca9ff
EH
1871 FeatureWord w;
1872 for (w = 0; w < FEATURE_WORDS; w++) {
1873 env->features[w] |= kvm_default_features[w];
1874 }
82beb536 1875 }
5fcca9ff 1876
82beb536 1877 env->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
7c08db30
EH
1878
1879 /* sysenter isn't supported in compatibility mode on AMD,
1880 * syscall isn't supported in compatibility mode on Intel.
1881 * Normally we advertise the actual CPU vendor, but you can
1882 * override this using the 'vendor' property if you want to use
1883 * KVM's sysenter/syscall emulation in compatibility mode and
1884 * when doing cross vendor migration
1885 */
74f54bc4 1886 vendor = def->vendor;
7c08db30
EH
1887 if (kvm_enabled()) {
1888 uint32_t ebx = 0, ecx = 0, edx = 0;
1889 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
1890 x86_cpu_vendor_words2str(host_vendor, ebx, edx, ecx);
1891 vendor = host_vendor;
1892 }
1893
1894 object_property_set_str(OBJECT(cpu), vendor, "vendor", errp);
1895
c6dc6f63
AP
1896}
1897
62fc403f
IM
1898X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
1899 Error **errp)
5c3c6a68 1900{
2d64255b 1901 X86CPU *cpu = NULL;
500050d1 1902 ObjectClass *oc;
2d64255b
AF
1903 gchar **model_pieces;
1904 char *name, *features;
ba2bc7a4 1905 char *typename;
5c3c6a68
AF
1906 Error *error = NULL;
1907
2d64255b
AF
1908 model_pieces = g_strsplit(cpu_model, ",", 2);
1909 if (!model_pieces[0]) {
1910 error_setg(&error, "Invalid/empty CPU model name");
1911 goto out;
1912 }
1913 name = model_pieces[0];
1914 features = model_pieces[1];
1915
500050d1
AF
1916 oc = x86_cpu_class_by_name(name);
1917 if (oc == NULL) {
1918 error_setg(&error, "Unable to find CPU definition: %s", name);
1919 goto out;
1920 }
1921 cpu = X86_CPU(object_new(object_class_get_name(oc)));
285f025d
EH
1922 x86_cpu_load_def(cpu, name, &error);
1923 if (error) {
1924 goto out;
1925 }
1926
62fc403f
IM
1927#ifndef CONFIG_USER_ONLY
1928 if (icc_bridge == NULL) {
1929 error_setg(&error, "Invalid icc-bridge value");
1930 goto out;
1931 }
1932 qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
1933 object_unref(OBJECT(cpu));
1934#endif
5c3c6a68 1935
ba2bc7a4
AF
1936 /* Emulate per-model subclasses for global properties */
1937 typename = g_strdup_printf("%s-" TYPE_X86_CPU, name);
1938 qdev_prop_set_globals_for_type(DEVICE(cpu), typename, &error);
1939 g_free(typename);
1940 if (error) {
1941 goto out;
1942 }
1943
2d64255b
AF
1944 cpu_x86_parse_featurestr(cpu, features, &error);
1945 if (error) {
1946 goto out;
5c3c6a68
AF
1947 }
1948
7f833247 1949out:
cd7b87ff
AF
1950 if (error != NULL) {
1951 error_propagate(errp, error);
500050d1
AF
1952 if (cpu) {
1953 object_unref(OBJECT(cpu));
1954 cpu = NULL;
1955 }
cd7b87ff 1956 }
7f833247
IM
1957 g_strfreev(model_pieces);
1958 return cpu;
1959}
1960
1961X86CPU *cpu_x86_init(const char *cpu_model)
1962{
1963 Error *error = NULL;
1964 X86CPU *cpu;
1965
62fc403f 1966 cpu = cpu_x86_create(cpu_model, NULL, &error);
5c3c6a68 1967 if (error) {
2d64255b
AF
1968 goto out;
1969 }
1970
7f833247
IM
1971 object_property_set_bool(OBJECT(cpu), true, "realized", &error);
1972
2d64255b 1973out:
2d64255b 1974 if (error) {
4a44d85e 1975 error_report("%s", error_get_pretty(error));
5c3c6a68 1976 error_free(error);
2d64255b
AF
1977 if (cpu != NULL) {
1978 object_unref(OBJECT(cpu));
1979 cpu = NULL;
1980 }
5c3c6a68
AF
1981 }
1982 return cpu;
1983}
1984
c6dc6f63 1985#if !defined(CONFIG_USER_ONLY)
c6dc6f63 1986
0e26b7b8
BS
1987void cpu_clear_apic_feature(CPUX86State *env)
1988{
0514ef2f 1989 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
0e26b7b8
BS
1990}
1991
c6dc6f63
AP
1992#endif /* !CONFIG_USER_ONLY */
1993
c04321b3 1994/* Initialize list of CPU models, filling some non-static fields if necessary
c6dc6f63
AP
1995 */
1996void x86_cpudef_setup(void)
1997{
93bfef4c
CV
1998 int i, j;
1999 static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
c6dc6f63
AP
2000
2001 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
9576de75 2002 X86CPUDefinition *def = &builtin_x86_defs[i];
93bfef4c
CV
2003
2004 /* Look for specific "cpudef" models that */
09faecf2 2005 /* have the QEMU version in .model_id */
93bfef4c 2006 for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
bc3e1291
EH
2007 if (strcmp(model_with_versions[j], def->name) == 0) {
2008 pstrcpy(def->model_id, sizeof(def->model_id),
2009 "QEMU Virtual CPU version ");
2010 pstrcat(def->model_id, sizeof(def->model_id),
2011 qemu_get_version());
93bfef4c
CV
2012 break;
2013 }
2014 }
c6dc6f63 2015 }
c6dc6f63
AP
2016}
2017
c6dc6f63
AP
2018static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
2019 uint32_t *ecx, uint32_t *edx)
2020{
2021 *ebx = env->cpuid_vendor1;
2022 *edx = env->cpuid_vendor2;
2023 *ecx = env->cpuid_vendor3;
c6dc6f63
AP
2024}
2025
2026void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
2027 uint32_t *eax, uint32_t *ebx,
2028 uint32_t *ecx, uint32_t *edx)
2029{
a60f24b5
AF
2030 X86CPU *cpu = x86_env_get_cpu(env);
2031 CPUState *cs = CPU(cpu);
2032
c6dc6f63
AP
2033 /* test if maximum index reached */
2034 if (index & 0x80000000) {
b3baa152
BW
2035 if (index > env->cpuid_xlevel) {
2036 if (env->cpuid_xlevel2 > 0) {
2037 /* Handle the Centaur's CPUID instruction. */
2038 if (index > env->cpuid_xlevel2) {
2039 index = env->cpuid_xlevel2;
2040 } else if (index < 0xC0000000) {
2041 index = env->cpuid_xlevel;
2042 }
2043 } else {
57f26ae7
EH
2044 /* Intel documentation states that invalid EAX input will
2045 * return the same information as EAX=cpuid_level
2046 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
2047 */
2048 index = env->cpuid_level;
b3baa152
BW
2049 }
2050 }
c6dc6f63
AP
2051 } else {
2052 if (index > env->cpuid_level)
2053 index = env->cpuid_level;
2054 }
2055
2056 switch(index) {
2057 case 0:
2058 *eax = env->cpuid_level;
2059 get_cpuid_vendor(env, ebx, ecx, edx);
2060 break;
2061 case 1:
2062 *eax = env->cpuid_version;
2063 *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
0514ef2f
EH
2064 *ecx = env->features[FEAT_1_ECX];
2065 *edx = env->features[FEAT_1_EDX];
ce3960eb
AF
2066 if (cs->nr_cores * cs->nr_threads > 1) {
2067 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
c6dc6f63
AP
2068 *edx |= 1 << 28; /* HTT bit */
2069 }
2070 break;
2071 case 2:
2072 /* cache info: needed for Pentium Pro compatibility */
787aaf57
BC
2073 if (cpu->cache_info_passthrough) {
2074 host_cpuid(index, 0, eax, ebx, ecx, edx);
2075 break;
2076 }
5e891bf8 2077 *eax = 1; /* Number of CPUID[EAX=2] calls required */
c6dc6f63
AP
2078 *ebx = 0;
2079 *ecx = 0;
5e891bf8
EH
2080 *edx = (L1D_DESCRIPTOR << 16) | \
2081 (L1I_DESCRIPTOR << 8) | \
2082 (L2_DESCRIPTOR);
c6dc6f63
AP
2083 break;
2084 case 4:
2085 /* cache info: needed for Core compatibility */
787aaf57
BC
2086 if (cpu->cache_info_passthrough) {
2087 host_cpuid(index, count, eax, ebx, ecx, edx);
76c2975a 2088 *eax &= ~0xFC000000;
c6dc6f63 2089 } else {
2f7a21c4 2090 *eax = 0;
76c2975a 2091 switch (count) {
c6dc6f63 2092 case 0: /* L1 dcache info */
5e891bf8
EH
2093 *eax |= CPUID_4_TYPE_DCACHE | \
2094 CPUID_4_LEVEL(1) | \
2095 CPUID_4_SELF_INIT_LEVEL;
2096 *ebx = (L1D_LINE_SIZE - 1) | \
2097 ((L1D_PARTITIONS - 1) << 12) | \
2098 ((L1D_ASSOCIATIVITY - 1) << 22);
2099 *ecx = L1D_SETS - 1;
2100 *edx = CPUID_4_NO_INVD_SHARING;
c6dc6f63
AP
2101 break;
2102 case 1: /* L1 icache info */
5e891bf8
EH
2103 *eax |= CPUID_4_TYPE_ICACHE | \
2104 CPUID_4_LEVEL(1) | \
2105 CPUID_4_SELF_INIT_LEVEL;
2106 *ebx = (L1I_LINE_SIZE - 1) | \
2107 ((L1I_PARTITIONS - 1) << 12) | \
2108 ((L1I_ASSOCIATIVITY - 1) << 22);
2109 *ecx = L1I_SETS - 1;
2110 *edx = CPUID_4_NO_INVD_SHARING;
c6dc6f63
AP
2111 break;
2112 case 2: /* L2 cache info */
5e891bf8
EH
2113 *eax |= CPUID_4_TYPE_UNIFIED | \
2114 CPUID_4_LEVEL(2) | \
2115 CPUID_4_SELF_INIT_LEVEL;
ce3960eb
AF
2116 if (cs->nr_threads > 1) {
2117 *eax |= (cs->nr_threads - 1) << 14;
c6dc6f63 2118 }
5e891bf8
EH
2119 *ebx = (L2_LINE_SIZE - 1) | \
2120 ((L2_PARTITIONS - 1) << 12) | \
2121 ((L2_ASSOCIATIVITY - 1) << 22);
2122 *ecx = L2_SETS - 1;
2123 *edx = CPUID_4_NO_INVD_SHARING;
c6dc6f63
AP
2124 break;
2125 default: /* end of info */
2126 *eax = 0;
2127 *ebx = 0;
2128 *ecx = 0;
2129 *edx = 0;
2130 break;
76c2975a
PB
2131 }
2132 }
2133
2134 /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
2135 if ((*eax & 31) && cs->nr_cores > 1) {
2136 *eax |= (cs->nr_cores - 1) << 26;
c6dc6f63
AP
2137 }
2138 break;
2139 case 5:
2140 /* mwait info: needed for Core compatibility */
2141 *eax = 0; /* Smallest monitor-line size in bytes */
2142 *ebx = 0; /* Largest monitor-line size in bytes */
2143 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
2144 *edx = 0;
2145 break;
2146 case 6:
2147 /* Thermal and Power Leaf */
2148 *eax = 0;
2149 *ebx = 0;
2150 *ecx = 0;
2151 *edx = 0;
2152 break;
f7911686 2153 case 7:
13526728
EH
2154 /* Structured Extended Feature Flags Enumeration Leaf */
2155 if (count == 0) {
2156 *eax = 0; /* Maximum ECX value for sub-leaves */
0514ef2f 2157 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
13526728
EH
2158 *ecx = 0; /* Reserved */
2159 *edx = 0; /* Reserved */
f7911686
YW
2160 } else {
2161 *eax = 0;
2162 *ebx = 0;
2163 *ecx = 0;
2164 *edx = 0;
2165 }
2166 break;
c6dc6f63
AP
2167 case 9:
2168 /* Direct Cache Access Information Leaf */
2169 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2170 *ebx = 0;
2171 *ecx = 0;
2172 *edx = 0;
2173 break;
2174 case 0xA:
2175 /* Architectural Performance Monitoring Leaf */
9337e3b6 2176 if (kvm_enabled() && cpu->enable_pmu) {
a60f24b5 2177 KVMState *s = cs->kvm_state;
a0fa8208
GN
2178
2179 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
2180 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
2181 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
2182 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
2183 } else {
2184 *eax = 0;
2185 *ebx = 0;
2186 *ecx = 0;
2187 *edx = 0;
2188 }
c6dc6f63 2189 break;
2560f19f
PB
2190 case 0xD: {
2191 KVMState *s = cs->kvm_state;
2192 uint64_t kvm_mask;
2193 int i;
2194
51e49430 2195 /* Processor Extended State */
2560f19f
PB
2196 *eax = 0;
2197 *ebx = 0;
2198 *ecx = 0;
2199 *edx = 0;
2200 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) || !kvm_enabled()) {
51e49430
SY
2201 break;
2202 }
2560f19f
PB
2203 kvm_mask =
2204 kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX) |
2205 ((uint64_t)kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX) << 32);
ba9bc59e 2206
2560f19f
PB
2207 if (count == 0) {
2208 *ecx = 0x240;
2209 for (i = 2; i < ARRAY_SIZE(ext_save_areas); i++) {
2210 const ExtSaveArea *esa = &ext_save_areas[i];
2211 if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2212 (kvm_mask & (1 << i)) != 0) {
2213 if (i < 32) {
2214 *eax |= 1 << i;
2215 } else {
2216 *edx |= 1 << (i - 32);
2217 }
2218 *ecx = MAX(*ecx, esa->offset + esa->size);
2219 }
2220 }
2221 *eax |= kvm_mask & (XSTATE_FP | XSTATE_SSE);
2222 *ebx = *ecx;
2223 } else if (count == 1) {
2224 *eax = kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
2225 } else if (count < ARRAY_SIZE(ext_save_areas)) {
2226 const ExtSaveArea *esa = &ext_save_areas[count];
2227 if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2228 (kvm_mask & (1 << count)) != 0) {
33f373d7
LJ
2229 *eax = esa->size;
2230 *ebx = esa->offset;
2560f19f 2231 }
51e49430
SY
2232 }
2233 break;
2560f19f 2234 }
c6dc6f63
AP
2235 case 0x80000000:
2236 *eax = env->cpuid_xlevel;
2237 *ebx = env->cpuid_vendor1;
2238 *edx = env->cpuid_vendor2;
2239 *ecx = env->cpuid_vendor3;
2240 break;
2241 case 0x80000001:
2242 *eax = env->cpuid_version;
2243 *ebx = 0;
0514ef2f
EH
2244 *ecx = env->features[FEAT_8000_0001_ECX];
2245 *edx = env->features[FEAT_8000_0001_EDX];
c6dc6f63
AP
2246
2247 /* The Linux kernel checks for the CMPLegacy bit and
2248 * discards multiple thread information if it is set.
2249 * So dont set it here for Intel to make Linux guests happy.
2250 */
ce3960eb 2251 if (cs->nr_cores * cs->nr_threads > 1) {
c6dc6f63
AP
2252 uint32_t tebx, tecx, tedx;
2253 get_cpuid_vendor(env, &tebx, &tecx, &tedx);
2254 if (tebx != CPUID_VENDOR_INTEL_1 ||
2255 tedx != CPUID_VENDOR_INTEL_2 ||
2256 tecx != CPUID_VENDOR_INTEL_3) {
2257 *ecx |= 1 << 1; /* CmpLegacy bit */
2258 }
2259 }
c6dc6f63
AP
2260 break;
2261 case 0x80000002:
2262 case 0x80000003:
2263 case 0x80000004:
2264 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2265 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2266 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2267 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2268 break;
2269 case 0x80000005:
2270 /* cache info (L1 cache) */
787aaf57
BC
2271 if (cpu->cache_info_passthrough) {
2272 host_cpuid(index, 0, eax, ebx, ecx, edx);
2273 break;
2274 }
5e891bf8
EH
2275 *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \
2276 (L1_ITLB_2M_ASSOC << 8) | (L1_ITLB_2M_ENTRIES);
2277 *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
2278 (L1_ITLB_4K_ASSOC << 8) | (L1_ITLB_4K_ENTRIES);
2279 *ecx = (L1D_SIZE_KB_AMD << 24) | (L1D_ASSOCIATIVITY_AMD << 16) | \
2280 (L1D_LINES_PER_TAG << 8) | (L1D_LINE_SIZE);
2281 *edx = (L1I_SIZE_KB_AMD << 24) | (L1I_ASSOCIATIVITY_AMD << 16) | \
2282 (L1I_LINES_PER_TAG << 8) | (L1I_LINE_SIZE);
c6dc6f63
AP
2283 break;
2284 case 0x80000006:
2285 /* cache info (L2 cache) */
787aaf57
BC
2286 if (cpu->cache_info_passthrough) {
2287 host_cpuid(index, 0, eax, ebx, ecx, edx);
2288 break;
2289 }
5e891bf8
EH
2290 *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \
2291 (L2_DTLB_2M_ENTRIES << 16) | \
2292 (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \
2293 (L2_ITLB_2M_ENTRIES);
2294 *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) | \
2295 (L2_DTLB_4K_ENTRIES << 16) | \
2296 (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
2297 (L2_ITLB_4K_ENTRIES);
2298 *ecx = (L2_SIZE_KB_AMD << 16) | \
2299 (AMD_ENC_ASSOC(L2_ASSOCIATIVITY) << 12) | \
2300 (L2_LINES_PER_TAG << 8) | (L2_LINE_SIZE);
2301 *edx = ((L3_SIZE_KB/512) << 18) | \
2302 (AMD_ENC_ASSOC(L3_ASSOCIATIVITY) << 12) | \
2303 (L3_LINES_PER_TAG << 8) | (L3_LINE_SIZE);
c6dc6f63
AP
2304 break;
2305 case 0x80000008:
2306 /* virtual & phys address size in low 2 bytes. */
2307/* XXX: This value must match the one used in the MMU code. */
0514ef2f 2308 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
c6dc6f63
AP
2309 /* 64 bit processor */
2310/* XXX: The physical address space is limited to 42 bits in exec.c. */
dd13e088 2311 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
c6dc6f63 2312 } else {
0514ef2f 2313 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
c6dc6f63 2314 *eax = 0x00000024; /* 36 bits physical */
dd13e088 2315 } else {
c6dc6f63 2316 *eax = 0x00000020; /* 32 bits physical */
dd13e088 2317 }
c6dc6f63
AP
2318 }
2319 *ebx = 0;
2320 *ecx = 0;
2321 *edx = 0;
ce3960eb
AF
2322 if (cs->nr_cores * cs->nr_threads > 1) {
2323 *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
c6dc6f63
AP
2324 }
2325 break;
2326 case 0x8000000A:
0514ef2f 2327 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
9f3fb565
EH
2328 *eax = 0x00000001; /* SVM Revision */
2329 *ebx = 0x00000010; /* nr of ASIDs */
2330 *ecx = 0;
0514ef2f 2331 *edx = env->features[FEAT_SVM]; /* optional features */
9f3fb565
EH
2332 } else {
2333 *eax = 0;
2334 *ebx = 0;
2335 *ecx = 0;
2336 *edx = 0;
2337 }
c6dc6f63 2338 break;
b3baa152
BW
2339 case 0xC0000000:
2340 *eax = env->cpuid_xlevel2;
2341 *ebx = 0;
2342 *ecx = 0;
2343 *edx = 0;
2344 break;
2345 case 0xC0000001:
2346 /* Support for VIA CPU's CPUID instruction */
2347 *eax = env->cpuid_version;
2348 *ebx = 0;
2349 *ecx = 0;
0514ef2f 2350 *edx = env->features[FEAT_C000_0001_EDX];
b3baa152
BW
2351 break;
2352 case 0xC0000002:
2353 case 0xC0000003:
2354 case 0xC0000004:
2355 /* Reserved for the future, and now filled with zero */
2356 *eax = 0;
2357 *ebx = 0;
2358 *ecx = 0;
2359 *edx = 0;
2360 break;
c6dc6f63
AP
2361 default:
2362 /* reserved values: zero */
2363 *eax = 0;
2364 *ebx = 0;
2365 *ecx = 0;
2366 *edx = 0;
2367 break;
2368 }
2369}
5fd2087a
AF
2370
2371/* CPUClass::reset() */
2372static void x86_cpu_reset(CPUState *s)
2373{
2374 X86CPU *cpu = X86_CPU(s);
2375 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2376 CPUX86State *env = &cpu->env;
c1958aea
AF
2377 int i;
2378
5fd2087a
AF
2379 xcc->parent_reset(s);
2380
c1958aea
AF
2381
2382 memset(env, 0, offsetof(CPUX86State, breakpoints));
2383
2384 tlb_flush(env, 1);
2385
2386 env->old_exception = -1;
2387
2388 /* init to reset state */
2389
2390#ifdef CONFIG_SOFTMMU
2391 env->hflags |= HF_SOFTMMU_MASK;
2392#endif
2393 env->hflags2 |= HF2_GIF_MASK;
2394
2395 cpu_x86_update_cr0(env, 0x60000010);
2396 env->a20_mask = ~0x0;
2397 env->smbase = 0x30000;
2398
2399 env->idt.limit = 0xffff;
2400 env->gdt.limit = 0xffff;
2401 env->ldt.limit = 0xffff;
2402 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2403 env->tr.limit = 0xffff;
2404 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2405
2406 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2407 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2408 DESC_R_MASK | DESC_A_MASK);
2409 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2410 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2411 DESC_A_MASK);
2412 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
2413 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2414 DESC_A_MASK);
2415 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
2416 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2417 DESC_A_MASK);
2418 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
2419 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2420 DESC_A_MASK);
2421 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
2422 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2423 DESC_A_MASK);
2424
2425 env->eip = 0xfff0;
2426 env->regs[R_EDX] = env->cpuid_version;
2427
2428 env->eflags = 0x2;
2429
2430 /* FPU init */
2431 for (i = 0; i < 8; i++) {
2432 env->fptags[i] = 1;
2433 }
2434 env->fpuc = 0x37f;
2435
2436 env->mxcsr = 0x1f80;
c74f41bb 2437 env->xstate_bv = XSTATE_FP | XSTATE_SSE;
c1958aea
AF
2438
2439 env->pat = 0x0007040600070406ULL;
2440 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2441
2442 memset(env->dr, 0, sizeof(env->dr));
2443 env->dr[6] = DR6_FIXED_1;
2444 env->dr[7] = DR7_FIXED_1;
2445 cpu_breakpoint_remove_all(env, BP_CPU);
2446 cpu_watchpoint_remove_all(env, BP_CPU);
dd673288 2447
0522604b
FLVC
2448 env->tsc_adjust = 0;
2449 env->tsc = 0;
2450
dd673288
IM
2451#if !defined(CONFIG_USER_ONLY)
2452 /* We hard-wire the BSP to the first CPU. */
55e5c285 2453 if (s->cpu_index == 0) {
02e51483 2454 apic_designate_bsp(cpu->apic_state);
dd673288
IM
2455 }
2456
259186a7 2457 s->halted = !cpu_is_bsp(cpu);
dd673288 2458#endif
5fd2087a
AF
2459}
2460
dd673288
IM
2461#ifndef CONFIG_USER_ONLY
2462bool cpu_is_bsp(X86CPU *cpu)
2463{
02e51483 2464 return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
dd673288 2465}
65dee380
IM
2466
2467/* TODO: remove me, when reset over QOM tree is implemented */
2468static void x86_cpu_machine_reset_cb(void *opaque)
2469{
2470 X86CPU *cpu = opaque;
2471 cpu_reset(CPU(cpu));
2472}
dd673288
IM
2473#endif
2474
de024815
AF
2475static void mce_init(X86CPU *cpu)
2476{
2477 CPUX86State *cenv = &cpu->env;
2478 unsigned int bank;
2479
2480 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
0514ef2f 2481 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
de024815
AF
2482 (CPUID_MCE | CPUID_MCA)) {
2483 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2484 cenv->mcg_ctl = ~(uint64_t)0;
2485 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2486 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2487 }
2488 }
2489}
2490
bdeec802 2491#ifndef CONFIG_USER_ONLY
d3c64d6a 2492static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
bdeec802 2493{
bdeec802 2494 CPUX86State *env = &cpu->env;
53a89e26 2495 DeviceState *dev = DEVICE(cpu);
449994eb 2496 APICCommonState *apic;
bdeec802
IM
2497 const char *apic_type = "apic";
2498
2499 if (kvm_irqchip_in_kernel()) {
2500 apic_type = "kvm-apic";
2501 } else if (xen_enabled()) {
2502 apic_type = "xen-apic";
2503 }
2504
02e51483
CF
2505 cpu->apic_state = qdev_try_create(qdev_get_parent_bus(dev), apic_type);
2506 if (cpu->apic_state == NULL) {
bdeec802
IM
2507 error_setg(errp, "APIC device '%s' could not be created", apic_type);
2508 return;
2509 }
2510
2511 object_property_add_child(OBJECT(cpu), "apic",
02e51483
CF
2512 OBJECT(cpu->apic_state), NULL);
2513 qdev_prop_set_uint8(cpu->apic_state, "id", env->cpuid_apic_id);
bdeec802 2514 /* TODO: convert to link<> */
02e51483 2515 apic = APIC_COMMON(cpu->apic_state);
60671e58 2516 apic->cpu = cpu;
d3c64d6a
IM
2517}
2518
2519static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2520{
02e51483 2521 if (cpu->apic_state == NULL) {
d3c64d6a
IM
2522 return;
2523 }
bdeec802 2524
02e51483 2525 if (qdev_init(cpu->apic_state)) {
bdeec802 2526 error_setg(errp, "APIC device '%s' could not be initialized",
02e51483 2527 object_get_typename(OBJECT(cpu->apic_state)));
bdeec802
IM
2528 return;
2529 }
bdeec802 2530}
d3c64d6a
IM
2531#else
2532static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2533{
2534}
bdeec802
IM
2535#endif
2536
2b6f294c 2537static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
7a059953 2538{
14a10fc3 2539 CPUState *cs = CPU(dev);
2b6f294c
AF
2540 X86CPU *cpu = X86_CPU(dev);
2541 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
b34d12d1 2542 CPUX86State *env = &cpu->env;
2b6f294c 2543 Error *local_err = NULL;
b34d12d1 2544
0514ef2f 2545 if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
b34d12d1
IM
2546 env->cpuid_level = 7;
2547 }
7a059953 2548
9b15cd9e
IM
2549 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
2550 * CPUID[1].EDX.
2551 */
2552 if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
2553 env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
2554 env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
0514ef2f
EH
2555 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
2556 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
9b15cd9e
IM
2557 & CPUID_EXT2_AMD_ALIASES);
2558 }
2559
4586f157 2560 if (!kvm_enabled()) {
0514ef2f
EH
2561 env->features[FEAT_1_EDX] &= TCG_FEATURES;
2562 env->features[FEAT_1_ECX] &= TCG_EXT_FEATURES;
2563 env->features[FEAT_8000_0001_EDX] &= (TCG_EXT2_FEATURES
4586f157
IM
2564#ifdef TARGET_X86_64
2565 | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
2566#endif
2567 );
0514ef2f
EH
2568 env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES;
2569 env->features[FEAT_SVM] &= TCG_SVM_FEATURES;
4586f157 2570 } else {
f0b9b111 2571 KVMState *s = kvm_state;
912ffc47 2572 if ((cpu->check_cpuid || cpu->enforce_cpuid)
f0b9b111 2573 && kvm_check_features_against_host(s, cpu) && cpu->enforce_cpuid) {
4dc1f449
IM
2574 error_setg(&local_err,
2575 "Host's CPU doesn't support requested features");
2576 goto out;
5ec01c2e 2577 }
a509d632 2578 filter_features_for_kvm(cpu);
4586f157
IM
2579 }
2580
65dee380
IM
2581#ifndef CONFIG_USER_ONLY
2582 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
bdeec802 2583
0514ef2f 2584 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
d3c64d6a 2585 x86_cpu_apic_create(cpu, &local_err);
2b6f294c 2586 if (local_err != NULL) {
4dc1f449 2587 goto out;
bdeec802
IM
2588 }
2589 }
65dee380
IM
2590#endif
2591
7a059953 2592 mce_init(cpu);
14a10fc3 2593 qemu_init_vcpu(cs);
d3c64d6a
IM
2594
2595 x86_cpu_apic_realize(cpu, &local_err);
2596 if (local_err != NULL) {
2597 goto out;
2598 }
14a10fc3 2599 cpu_reset(cs);
2b6f294c 2600
4dc1f449
IM
2601 xcc->parent_realize(dev, &local_err);
2602out:
2603 if (local_err != NULL) {
2604 error_propagate(errp, local_err);
2605 return;
2606 }
7a059953
AF
2607}
2608
8932cfdf
EH
2609/* Enables contiguous-apic-ID mode, for compatibility */
2610static bool compat_apic_id_mode;
2611
2612void enable_compat_apic_id_mode(void)
2613{
2614 compat_apic_id_mode = true;
2615}
2616
cb41bad3
EH
2617/* Calculates initial APIC ID for a specific CPU index
2618 *
2619 * Currently we need to be able to calculate the APIC ID from the CPU index
2620 * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
2621 * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
2622 * all CPUs up to max_cpus.
2623 */
2624uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
2625{
8932cfdf
EH
2626 uint32_t correct_id;
2627 static bool warned;
2628
2629 correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
2630 if (compat_apic_id_mode) {
2631 if (cpu_index != correct_id && !warned) {
2632 error_report("APIC IDs set in compatibility mode, "
2633 "CPU topology won't match the configuration");
2634 warned = true;
2635 }
2636 return cpu_index;
2637 } else {
2638 return correct_id;
2639 }
cb41bad3
EH
2640}
2641
de024815
AF
2642static void x86_cpu_initfn(Object *obj)
2643{
55e5c285 2644 CPUState *cs = CPU(obj);
de024815
AF
2645 X86CPU *cpu = X86_CPU(obj);
2646 CPUX86State *env = &cpu->env;
d65e9815 2647 static int inited;
de024815 2648
c05efcb1 2649 cs->env_ptr = env;
de024815 2650 cpu_exec_init(env);
71ad61d3
AF
2651
2652 object_property_add(obj, "family", "int",
95b8519d 2653 x86_cpuid_version_get_family,
71ad61d3 2654 x86_cpuid_version_set_family, NULL, NULL, NULL);
c5291a4f 2655 object_property_add(obj, "model", "int",
67e30c83 2656 x86_cpuid_version_get_model,
c5291a4f 2657 x86_cpuid_version_set_model, NULL, NULL, NULL);
036e2222 2658 object_property_add(obj, "stepping", "int",
35112e41 2659 x86_cpuid_version_get_stepping,
036e2222 2660 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
8e1898bf
AF
2661 object_property_add(obj, "level", "int",
2662 x86_cpuid_get_level,
2663 x86_cpuid_set_level, NULL, NULL, NULL);
16b93aa8
AF
2664 object_property_add(obj, "xlevel", "int",
2665 x86_cpuid_get_xlevel,
2666 x86_cpuid_set_xlevel, NULL, NULL, NULL);
d480e1af
AF
2667 object_property_add_str(obj, "vendor",
2668 x86_cpuid_get_vendor,
2669 x86_cpuid_set_vendor, NULL);
938d4c25 2670 object_property_add_str(obj, "model-id",
63e886eb 2671 x86_cpuid_get_model_id,
938d4c25 2672 x86_cpuid_set_model_id, NULL);
89e48965
AF
2673 object_property_add(obj, "tsc-frequency", "int",
2674 x86_cpuid_get_tsc_freq,
2675 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
31050930
IM
2676 object_property_add(obj, "apic-id", "int",
2677 x86_cpuid_get_apic_id,
2678 x86_cpuid_set_apic_id, NULL, NULL, NULL);
8e8aba50
EH
2679 object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
2680 x86_cpu_get_feature_words,
7e5292b5
EH
2681 NULL, NULL, (void *)env->features, NULL);
2682 object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
2683 x86_cpu_get_feature_words,
2684 NULL, NULL, (void *)cpu->filtered_features, NULL);
71ad61d3 2685
92067bf4 2686 cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
cb41bad3 2687 env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
d65e9815
IM
2688
2689 /* init various static tables used in TCG mode */
2690 if (tcg_enabled() && !inited) {
2691 inited = 1;
2692 optimize_flags_init();
2693#ifndef CONFIG_USER_ONLY
2694 cpu_set_debug_excp_handler(breakpoint_handler);
2695#endif
2696 }
de024815
AF
2697}
2698
997395d3
IM
2699static int64_t x86_cpu_get_arch_id(CPUState *cs)
2700{
2701 X86CPU *cpu = X86_CPU(cs);
2702 CPUX86State *env = &cpu->env;
2703
2704 return env->cpuid_apic_id;
2705}
2706
444d5590
AF
2707static bool x86_cpu_get_paging_enabled(const CPUState *cs)
2708{
2709 X86CPU *cpu = X86_CPU(cs);
2710
2711 return cpu->env.cr[0] & CR0_PG_MASK;
2712}
2713
f45748f1
AF
2714static void x86_cpu_set_pc(CPUState *cs, vaddr value)
2715{
2716 X86CPU *cpu = X86_CPU(cs);
2717
2718 cpu->env.eip = value;
2719}
2720
bdf7ae5b
AF
2721static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
2722{
2723 X86CPU *cpu = X86_CPU(cs);
2724
2725 cpu->env.eip = tb->pc - tb->cs_base;
2726}
2727
8c2e1b00
AF
2728static bool x86_cpu_has_work(CPUState *cs)
2729{
2730 X86CPU *cpu = X86_CPU(cs);
2731 CPUX86State *env = &cpu->env;
2732
2733 return ((cs->interrupt_request & (CPU_INTERRUPT_HARD |
2734 CPU_INTERRUPT_POLL)) &&
2735 (env->eflags & IF_MASK)) ||
2736 (cs->interrupt_request & (CPU_INTERRUPT_NMI |
2737 CPU_INTERRUPT_INIT |
2738 CPU_INTERRUPT_SIPI |
2739 CPU_INTERRUPT_MCE));
2740}
2741
9337e3b6
EH
2742static Property x86_cpu_properties[] = {
2743 DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
c8f0f88e 2744 { .name = "hv-spinlocks", .info = &qdev_prop_spinlocks },
89314504 2745 DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false),
0f46685d 2746 DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false),
48a5f3bc 2747 DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false),
912ffc47
IM
2748 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false),
2749 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
9337e3b6
EH
2750 DEFINE_PROP_END_OF_LIST()
2751};
2752
5fd2087a
AF
2753static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
2754{
2755 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2756 CPUClass *cc = CPU_CLASS(oc);
2b6f294c
AF
2757 DeviceClass *dc = DEVICE_CLASS(oc);
2758
2759 xcc->parent_realize = dc->realize;
2760 dc->realize = x86_cpu_realizefn;
62fc403f 2761 dc->bus_type = TYPE_ICC_BUS;
9337e3b6 2762 dc->props = x86_cpu_properties;
5fd2087a
AF
2763
2764 xcc->parent_reset = cc->reset;
2765 cc->reset = x86_cpu_reset;
91b1df8c 2766 cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
f56e3a14 2767
500050d1 2768 cc->class_by_name = x86_cpu_class_by_name;
8c2e1b00 2769 cc->has_work = x86_cpu_has_work;
97a8ea5a 2770 cc->do_interrupt = x86_cpu_do_interrupt;
878096ee 2771 cc->dump_state = x86_cpu_dump_state;
f45748f1 2772 cc->set_pc = x86_cpu_set_pc;
bdf7ae5b 2773 cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
5b50e790
AF
2774 cc->gdb_read_register = x86_cpu_gdb_read_register;
2775 cc->gdb_write_register = x86_cpu_gdb_write_register;
444d5590
AF
2776 cc->get_arch_id = x86_cpu_get_arch_id;
2777 cc->get_paging_enabled = x86_cpu_get_paging_enabled;
c72bf468 2778#ifndef CONFIG_USER_ONLY
a23bbfda 2779 cc->get_memory_mapping = x86_cpu_get_memory_mapping;
00b941e5 2780 cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
c72bf468
JF
2781 cc->write_elf64_note = x86_cpu_write_elf64_note;
2782 cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
2783 cc->write_elf32_note = x86_cpu_write_elf32_note;
2784 cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
00b941e5 2785 cc->vmsd = &vmstate_x86_cpu;
c72bf468 2786#endif
a0e372f0 2787 cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
5fd2087a
AF
2788}
2789
2790static const TypeInfo x86_cpu_type_info = {
2791 .name = TYPE_X86_CPU,
2792 .parent = TYPE_CPU,
2793 .instance_size = sizeof(X86CPU),
de024815 2794 .instance_init = x86_cpu_initfn,
5fd2087a
AF
2795 .abstract = false,
2796 .class_size = sizeof(X86CPUClass),
2797 .class_init = x86_cpu_common_class_init,
2798};
2799
2800static void x86_cpu_register_types(void)
2801{
2802 type_register_static(&x86_cpu_type_info);
2803}
2804
2805type_init(x86_cpu_register_types)