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