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