]> git.proxmox.com Git - mirror_qemu.git/blame - target-i386/cpu.c
target-ppc: Change LOG_MMU_STATE() argument to CPUState
[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
8f961357 1478static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *name)
c6dc6f63 1479{
c6dc6f63 1480 x86_def_t *def;
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);
4bfe910d 1488 return 0;
c6dc6f63
AP
1489 }
1490
7fc9b714
AF
1491 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1492 def = &builtin_x86_defs[i];
4bfe910d
AF
1493 if (strcmp(name, def->name) == 0) {
1494 memcpy(x86_cpu_def, def, sizeof(*def));
11acfdd5
IM
1495 /* sysenter isn't supported in compatibility mode on AMD,
1496 * syscall isn't supported in compatibility mode on Intel.
1497 * Normally we advertise the actual CPU vendor, but you can
1498 * override this using the 'vendor' property if you want to use
1499 * KVM's sysenter/syscall emulation in compatibility mode and
1500 * when doing cross vendor migration
1501 */
1502 if (kvm_enabled()) {
1503 uint32_t ebx = 0, ecx = 0, edx = 0;
1504 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
1505 x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1506 }
4bfe910d
AF
1507 return 0;
1508 }
1509 }
1510
1511 return -1;
8f961357
EH
1512}
1513
72ac2e87
IM
1514/* Convert all '_' in a feature string option name to '-', to make feature
1515 * name conform to QOM property naming rule, which uses '-' instead of '_'.
1516 */
1517static inline void feat2prop(char *s)
1518{
1519 while ((s = strchr(s, '_'))) {
1520 *s = '-';
1521 }
1522}
1523
8f961357
EH
1524/* Parse "+feature,-feature,feature=foo" CPU feature string
1525 */
a91987c2 1526static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
8f961357 1527{
8f961357
EH
1528 char *featurestr; /* Single 'key=value" string being parsed */
1529 /* Features to be added */
077c68c3 1530 FeatureWordArray plus_features = { 0 };
8f961357 1531 /* Features to be removed */
5ef57876 1532 FeatureWordArray minus_features = { 0 };
8f961357 1533 uint32_t numvalue;
a91987c2 1534 CPUX86State *env = &cpu->env;
8f961357 1535
8f961357 1536 featurestr = features ? strtok(features, ",") : NULL;
c6dc6f63
AP
1537
1538 while (featurestr) {
1539 char *val;
1540 if (featurestr[0] == '+') {
5ef57876 1541 add_flagname_to_bitmaps(featurestr + 1, plus_features);
c6dc6f63 1542 } else if (featurestr[0] == '-') {
5ef57876 1543 add_flagname_to_bitmaps(featurestr + 1, minus_features);
c6dc6f63
AP
1544 } else if ((val = strchr(featurestr, '='))) {
1545 *val = 0; val++;
72ac2e87 1546 feat2prop(featurestr);
c6dc6f63 1547 if (!strcmp(featurestr, "family")) {
a91987c2 1548 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63 1549 } else if (!strcmp(featurestr, "model")) {
a91987c2 1550 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63 1551 } else if (!strcmp(featurestr, "stepping")) {
a91987c2 1552 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63 1553 } else if (!strcmp(featurestr, "level")) {
a91987c2 1554 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63
AP
1555 } else if (!strcmp(featurestr, "xlevel")) {
1556 char *err;
a91987c2
IM
1557 char num[32];
1558
c6dc6f63
AP
1559 numvalue = strtoul(val, &err, 0);
1560 if (!*val || *err) {
312fd5f2 1561 error_setg(errp, "bad numerical value %s", val);
a91987c2 1562 goto out;
c6dc6f63
AP
1563 }
1564 if (numvalue < 0x80000000) {
8ba8a698
IM
1565 fprintf(stderr, "xlevel value shall always be >= 0x80000000"
1566 ", fixup will be removed in future versions\n");
2f7a21c4 1567 numvalue += 0x80000000;
c6dc6f63 1568 }
a91987c2
IM
1569 snprintf(num, sizeof(num), "%" PRIu32, numvalue);
1570 object_property_parse(OBJECT(cpu), num, featurestr, errp);
c6dc6f63 1571 } else if (!strcmp(featurestr, "vendor")) {
a91987c2 1572 object_property_parse(OBJECT(cpu), val, featurestr, errp);
72ac2e87
IM
1573 } else if (!strcmp(featurestr, "model-id")) {
1574 object_property_parse(OBJECT(cpu), val, featurestr, errp);
1575 } else if (!strcmp(featurestr, "tsc-freq")) {
b862d1fe
JR
1576 int64_t tsc_freq;
1577 char *err;
a91987c2 1578 char num[32];
b862d1fe
JR
1579
1580 tsc_freq = strtosz_suffix_unit(val, &err,
1581 STRTOSZ_DEFSUFFIX_B, 1000);
45009a30 1582 if (tsc_freq < 0 || *err) {
312fd5f2 1583 error_setg(errp, "bad numerical value %s", val);
a91987c2 1584 goto out;
b862d1fe 1585 }
a91987c2
IM
1586 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
1587 object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
72ac2e87 1588 } else if (!strcmp(featurestr, "hv-spinlocks")) {
28f52cc0
VR
1589 char *err;
1590 numvalue = strtoul(val, &err, 0);
1591 if (!*val || *err) {
312fd5f2 1592 error_setg(errp, "bad numerical value %s", val);
a91987c2 1593 goto out;
28f52cc0
VR
1594 }
1595 hyperv_set_spinlock_retries(numvalue);
c6dc6f63 1596 } else {
312fd5f2 1597 error_setg(errp, "unrecognized feature %s", featurestr);
a91987c2 1598 goto out;
c6dc6f63
AP
1599 }
1600 } else if (!strcmp(featurestr, "check")) {
1601 check_cpuid = 1;
1602 } else if (!strcmp(featurestr, "enforce")) {
1603 check_cpuid = enforce_cpuid = 1;
28f52cc0
VR
1604 } else if (!strcmp(featurestr, "hv_relaxed")) {
1605 hyperv_enable_relaxed_timing(true);
1606 } else if (!strcmp(featurestr, "hv_vapic")) {
1607 hyperv_enable_vapic_recommended(true);
c6dc6f63 1608 } else {
a91987c2 1609 error_setg(errp, "feature string `%s' not in format (+feature|"
312fd5f2 1610 "-feature|feature=xyz)", featurestr);
a91987c2
IM
1611 goto out;
1612 }
1613 if (error_is_set(errp)) {
1614 goto out;
c6dc6f63
AP
1615 }
1616 featurestr = strtok(NULL, ",");
1617 }
0514ef2f
EH
1618 env->features[FEAT_1_EDX] |= plus_features[FEAT_1_EDX];
1619 env->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX];
1620 env->features[FEAT_8000_0001_EDX] |= plus_features[FEAT_8000_0001_EDX];
1621 env->features[FEAT_8000_0001_ECX] |= plus_features[FEAT_8000_0001_ECX];
1622 env->features[FEAT_C000_0001_EDX] |= plus_features[FEAT_C000_0001_EDX];
1623 env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
1624 env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
1625 env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
1626 env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
1627 env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
1628 env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX];
1629 env->features[FEAT_8000_0001_ECX] &= ~minus_features[FEAT_8000_0001_ECX];
1630 env->features[FEAT_C000_0001_EDX] &= ~minus_features[FEAT_C000_0001_EDX];
1631 env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
1632 env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
1633 env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
c6dc6f63 1634
a91987c2
IM
1635out:
1636 return;
c6dc6f63
AP
1637}
1638
1639/* generate a composite string into buf of all cpuid names in featureset
1640 * selected by fbits. indicate truncation at bufsize in the event of overflow.
1641 * if flags, suppress names undefined in featureset.
1642 */
1643static void listflags(char *buf, int bufsize, uint32_t fbits,
1644 const char **featureset, uint32_t flags)
1645{
1646 const char **p = &featureset[31];
1647 char *q, *b, bit;
1648 int nc;
1649
1650 b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1651 *buf = '\0';
1652 for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1653 if (fbits & 1 << bit && (*p || !flags)) {
1654 if (*p)
1655 nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1656 else
1657 nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1658 if (bufsize <= nc) {
1659 if (b) {
1660 memcpy(b, "...", sizeof("..."));
1661 }
1662 return;
1663 }
1664 q += nc;
1665 bufsize -= nc;
1666 }
1667}
1668
e916cbf8
PM
1669/* generate CPU information. */
1670void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
c6dc6f63 1671{
c6dc6f63
AP
1672 x86_def_t *def;
1673 char buf[256];
7fc9b714 1674 int i;
c6dc6f63 1675
7fc9b714
AF
1676 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1677 def = &builtin_x86_defs[i];
c04321b3 1678 snprintf(buf, sizeof(buf), "%s", def->name);
6cdf8854 1679 (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
c6dc6f63 1680 }
21ad7789
JK
1681#ifdef CONFIG_KVM
1682 (*cpu_fprintf)(f, "x86 %16s %-48s\n", "host",
1683 "KVM processor with all supported host features "
1684 "(only available in KVM mode)");
1685#endif
1686
6cdf8854 1687 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
3af60be2
JK
1688 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
1689 FeatureWordInfo *fw = &feature_word_info[i];
1690
1691 listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
1692 (*cpu_fprintf)(f, " %s\n", buf);
1693 }
c6dc6f63
AP
1694}
1695
76b64a7a 1696CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
e3966126
AL
1697{
1698 CpuDefinitionInfoList *cpu_list = NULL;
1699 x86_def_t *def;
7fc9b714 1700 int i;
e3966126 1701
7fc9b714 1702 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
e3966126
AL
1703 CpuDefinitionInfoList *entry;
1704 CpuDefinitionInfo *info;
1705
7fc9b714 1706 def = &builtin_x86_defs[i];
e3966126
AL
1707 info = g_malloc0(sizeof(*info));
1708 info->name = g_strdup(def->name);
1709
1710 entry = g_malloc0(sizeof(*entry));
1711 entry->value = info;
1712 entry->next = cpu_list;
1713 cpu_list = entry;
1714 }
1715
1716 return cpu_list;
1717}
1718
bc74b7db
EH
1719#ifdef CONFIG_KVM
1720static void filter_features_for_kvm(X86CPU *cpu)
1721{
1722 CPUX86State *env = &cpu->env;
1723 KVMState *s = kvm_state;
bd87d2a2 1724 FeatureWord w;
bc74b7db 1725
bd87d2a2
EH
1726 for (w = 0; w < FEATURE_WORDS; w++) {
1727 FeatureWordInfo *wi = &feature_word_info[w];
034acf4a
EH
1728 uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax,
1729 wi->cpuid_ecx,
1730 wi->cpuid_reg);
1731 uint32_t requested_features = env->features[w];
1732 env->features[w] &= host_feat;
1733 cpu->filtered_features[w] = requested_features & ~env->features[w];
bd87d2a2 1734 }
bc74b7db
EH
1735}
1736#endif
1737
2d64255b 1738static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
c6dc6f63 1739{
61dcd775 1740 CPUX86State *env = &cpu->env;
c6dc6f63
AP
1741 x86_def_t def1, *def = &def1;
1742
db0ad1ba
JR
1743 memset(def, 0, sizeof(*def));
1744
8f961357 1745 if (cpu_x86_find_by_name(def, name) < 0) {
2d64255b
AF
1746 error_setg(errp, "Unable to find CPU definition: %s", name);
1747 return;
8f961357
EH
1748 }
1749
aa87d458 1750 if (kvm_enabled()) {
0514ef2f 1751 def->features[FEAT_KVM] |= kvm_default_features;
aa87d458 1752 }
0514ef2f 1753 def->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
077c68c3 1754
2d64255b
AF
1755 object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp);
1756 object_property_set_int(OBJECT(cpu), def->level, "level", errp);
1757 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
1758 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
1759 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
0514ef2f
EH
1760 env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX];
1761 env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX];
1762 env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX];
1763 env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX];
2d64255b 1764 object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
0514ef2f
EH
1765 env->features[FEAT_KVM] = def->features[FEAT_KVM];
1766 env->features[FEAT_SVM] = def->features[FEAT_SVM];
1767 env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
1768 env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
b3baa152 1769 env->cpuid_xlevel2 = def->xlevel2;
3b671a40 1770
2d64255b 1771 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
c6dc6f63
AP
1772}
1773
62fc403f
IM
1774X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
1775 Error **errp)
5c3c6a68 1776{
2d64255b 1777 X86CPU *cpu = NULL;
5c3c6a68 1778 CPUX86State *env;
2d64255b
AF
1779 gchar **model_pieces;
1780 char *name, *features;
ba2bc7a4 1781 char *typename;
5c3c6a68
AF
1782 Error *error = NULL;
1783
2d64255b
AF
1784 model_pieces = g_strsplit(cpu_model, ",", 2);
1785 if (!model_pieces[0]) {
1786 error_setg(&error, "Invalid/empty CPU model name");
1787 goto out;
1788 }
1789 name = model_pieces[0];
1790 features = model_pieces[1];
1791
5c3c6a68 1792 cpu = X86_CPU(object_new(TYPE_X86_CPU));
62fc403f
IM
1793#ifndef CONFIG_USER_ONLY
1794 if (icc_bridge == NULL) {
1795 error_setg(&error, "Invalid icc-bridge value");
1796 goto out;
1797 }
1798 qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
1799 object_unref(OBJECT(cpu));
1800#endif
5c3c6a68
AF
1801 env = &cpu->env;
1802 env->cpu_model_str = cpu_model;
1803
2d64255b
AF
1804 cpu_x86_register(cpu, name, &error);
1805 if (error) {
1806 goto out;
1807 }
1808
ba2bc7a4
AF
1809 /* Emulate per-model subclasses for global properties */
1810 typename = g_strdup_printf("%s-" TYPE_X86_CPU, name);
1811 qdev_prop_set_globals_for_type(DEVICE(cpu), typename, &error);
1812 g_free(typename);
1813 if (error) {
1814 goto out;
1815 }
1816
2d64255b
AF
1817 cpu_x86_parse_featurestr(cpu, features, &error);
1818 if (error) {
1819 goto out;
5c3c6a68
AF
1820 }
1821
7f833247
IM
1822out:
1823 error_propagate(errp, error);
1824 g_strfreev(model_pieces);
1825 return cpu;
1826}
1827
1828X86CPU *cpu_x86_init(const char *cpu_model)
1829{
1830 Error *error = NULL;
1831 X86CPU *cpu;
1832
62fc403f 1833 cpu = cpu_x86_create(cpu_model, NULL, &error);
5c3c6a68 1834 if (error) {
2d64255b
AF
1835 goto out;
1836 }
1837
7f833247
IM
1838 object_property_set_bool(OBJECT(cpu), true, "realized", &error);
1839
2d64255b 1840out:
2d64255b
AF
1841 if (error) {
1842 fprintf(stderr, "%s\n", error_get_pretty(error));
5c3c6a68 1843 error_free(error);
2d64255b
AF
1844 if (cpu != NULL) {
1845 object_unref(OBJECT(cpu));
1846 cpu = NULL;
1847 }
5c3c6a68
AF
1848 }
1849 return cpu;
1850}
1851
c6dc6f63 1852#if !defined(CONFIG_USER_ONLY)
c6dc6f63 1853
0e26b7b8
BS
1854void cpu_clear_apic_feature(CPUX86State *env)
1855{
0514ef2f 1856 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
0e26b7b8
BS
1857}
1858
c6dc6f63
AP
1859#endif /* !CONFIG_USER_ONLY */
1860
c04321b3 1861/* Initialize list of CPU models, filling some non-static fields if necessary
c6dc6f63
AP
1862 */
1863void x86_cpudef_setup(void)
1864{
93bfef4c
CV
1865 int i, j;
1866 static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
c6dc6f63
AP
1867
1868 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
bc3e1291 1869 x86_def_t *def = &builtin_x86_defs[i];
93bfef4c
CV
1870
1871 /* Look for specific "cpudef" models that */
09faecf2 1872 /* have the QEMU version in .model_id */
93bfef4c 1873 for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
bc3e1291
EH
1874 if (strcmp(model_with_versions[j], def->name) == 0) {
1875 pstrcpy(def->model_id, sizeof(def->model_id),
1876 "QEMU Virtual CPU version ");
1877 pstrcat(def->model_id, sizeof(def->model_id),
1878 qemu_get_version());
93bfef4c
CV
1879 break;
1880 }
1881 }
c6dc6f63 1882 }
c6dc6f63
AP
1883}
1884
c6dc6f63
AP
1885static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
1886 uint32_t *ecx, uint32_t *edx)
1887{
1888 *ebx = env->cpuid_vendor1;
1889 *edx = env->cpuid_vendor2;
1890 *ecx = env->cpuid_vendor3;
c6dc6f63
AP
1891}
1892
1893void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1894 uint32_t *eax, uint32_t *ebx,
1895 uint32_t *ecx, uint32_t *edx)
1896{
a60f24b5
AF
1897 X86CPU *cpu = x86_env_get_cpu(env);
1898 CPUState *cs = CPU(cpu);
1899
c6dc6f63
AP
1900 /* test if maximum index reached */
1901 if (index & 0x80000000) {
b3baa152
BW
1902 if (index > env->cpuid_xlevel) {
1903 if (env->cpuid_xlevel2 > 0) {
1904 /* Handle the Centaur's CPUID instruction. */
1905 if (index > env->cpuid_xlevel2) {
1906 index = env->cpuid_xlevel2;
1907 } else if (index < 0xC0000000) {
1908 index = env->cpuid_xlevel;
1909 }
1910 } else {
57f26ae7
EH
1911 /* Intel documentation states that invalid EAX input will
1912 * return the same information as EAX=cpuid_level
1913 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
1914 */
1915 index = env->cpuid_level;
b3baa152
BW
1916 }
1917 }
c6dc6f63
AP
1918 } else {
1919 if (index > env->cpuid_level)
1920 index = env->cpuid_level;
1921 }
1922
1923 switch(index) {
1924 case 0:
1925 *eax = env->cpuid_level;
1926 get_cpuid_vendor(env, ebx, ecx, edx);
1927 break;
1928 case 1:
1929 *eax = env->cpuid_version;
1930 *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
0514ef2f
EH
1931 *ecx = env->features[FEAT_1_ECX];
1932 *edx = env->features[FEAT_1_EDX];
ce3960eb
AF
1933 if (cs->nr_cores * cs->nr_threads > 1) {
1934 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
c6dc6f63
AP
1935 *edx |= 1 << 28; /* HTT bit */
1936 }
1937 break;
1938 case 2:
1939 /* cache info: needed for Pentium Pro compatibility */
1940 *eax = 1;
1941 *ebx = 0;
1942 *ecx = 0;
1943 *edx = 0x2c307d;
1944 break;
1945 case 4:
1946 /* cache info: needed for Core compatibility */
ce3960eb
AF
1947 if (cs->nr_cores > 1) {
1948 *eax = (cs->nr_cores - 1) << 26;
c6dc6f63 1949 } else {
2f7a21c4 1950 *eax = 0;
c6dc6f63
AP
1951 }
1952 switch (count) {
1953 case 0: /* L1 dcache info */
1954 *eax |= 0x0000121;
1955 *ebx = 0x1c0003f;
1956 *ecx = 0x000003f;
1957 *edx = 0x0000001;
1958 break;
1959 case 1: /* L1 icache info */
1960 *eax |= 0x0000122;
1961 *ebx = 0x1c0003f;
1962 *ecx = 0x000003f;
1963 *edx = 0x0000001;
1964 break;
1965 case 2: /* L2 cache info */
1966 *eax |= 0x0000143;
ce3960eb
AF
1967 if (cs->nr_threads > 1) {
1968 *eax |= (cs->nr_threads - 1) << 14;
c6dc6f63
AP
1969 }
1970 *ebx = 0x3c0003f;
1971 *ecx = 0x0000fff;
1972 *edx = 0x0000001;
1973 break;
1974 default: /* end of info */
1975 *eax = 0;
1976 *ebx = 0;
1977 *ecx = 0;
1978 *edx = 0;
1979 break;
1980 }
1981 break;
1982 case 5:
1983 /* mwait info: needed for Core compatibility */
1984 *eax = 0; /* Smallest monitor-line size in bytes */
1985 *ebx = 0; /* Largest monitor-line size in bytes */
1986 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
1987 *edx = 0;
1988 break;
1989 case 6:
1990 /* Thermal and Power Leaf */
1991 *eax = 0;
1992 *ebx = 0;
1993 *ecx = 0;
1994 *edx = 0;
1995 break;
f7911686 1996 case 7:
13526728
EH
1997 /* Structured Extended Feature Flags Enumeration Leaf */
1998 if (count == 0) {
1999 *eax = 0; /* Maximum ECX value for sub-leaves */
0514ef2f 2000 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
13526728
EH
2001 *ecx = 0; /* Reserved */
2002 *edx = 0; /* Reserved */
f7911686
YW
2003 } else {
2004 *eax = 0;
2005 *ebx = 0;
2006 *ecx = 0;
2007 *edx = 0;
2008 }
2009 break;
c6dc6f63
AP
2010 case 9:
2011 /* Direct Cache Access Information Leaf */
2012 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2013 *ebx = 0;
2014 *ecx = 0;
2015 *edx = 0;
2016 break;
2017 case 0xA:
2018 /* Architectural Performance Monitoring Leaf */
a0fa8208 2019 if (kvm_enabled()) {
a60f24b5 2020 KVMState *s = cs->kvm_state;
a0fa8208
GN
2021
2022 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
2023 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
2024 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
2025 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
2026 } else {
2027 *eax = 0;
2028 *ebx = 0;
2029 *ecx = 0;
2030 *edx = 0;
2031 }
c6dc6f63 2032 break;
51e49430
SY
2033 case 0xD:
2034 /* Processor Extended State */
0514ef2f 2035 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
51e49430
SY
2036 *eax = 0;
2037 *ebx = 0;
2038 *ecx = 0;
2039 *edx = 0;
2040 break;
2041 }
2042 if (kvm_enabled()) {
a60f24b5 2043 KVMState *s = cs->kvm_state;
ba9bc59e
JK
2044
2045 *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX);
2046 *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX);
2047 *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX);
2048 *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX);
51e49430
SY
2049 } else {
2050 *eax = 0;
2051 *ebx = 0;
2052 *ecx = 0;
2053 *edx = 0;
2054 }
2055 break;
c6dc6f63
AP
2056 case 0x80000000:
2057 *eax = env->cpuid_xlevel;
2058 *ebx = env->cpuid_vendor1;
2059 *edx = env->cpuid_vendor2;
2060 *ecx = env->cpuid_vendor3;
2061 break;
2062 case 0x80000001:
2063 *eax = env->cpuid_version;
2064 *ebx = 0;
0514ef2f
EH
2065 *ecx = env->features[FEAT_8000_0001_ECX];
2066 *edx = env->features[FEAT_8000_0001_EDX];
c6dc6f63
AP
2067
2068 /* The Linux kernel checks for the CMPLegacy bit and
2069 * discards multiple thread information if it is set.
2070 * So dont set it here for Intel to make Linux guests happy.
2071 */
ce3960eb 2072 if (cs->nr_cores * cs->nr_threads > 1) {
c6dc6f63
AP
2073 uint32_t tebx, tecx, tedx;
2074 get_cpuid_vendor(env, &tebx, &tecx, &tedx);
2075 if (tebx != CPUID_VENDOR_INTEL_1 ||
2076 tedx != CPUID_VENDOR_INTEL_2 ||
2077 tecx != CPUID_VENDOR_INTEL_3) {
2078 *ecx |= 1 << 1; /* CmpLegacy bit */
2079 }
2080 }
c6dc6f63
AP
2081 break;
2082 case 0x80000002:
2083 case 0x80000003:
2084 case 0x80000004:
2085 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2086 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2087 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2088 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2089 break;
2090 case 0x80000005:
2091 /* cache info (L1 cache) */
2092 *eax = 0x01ff01ff;
2093 *ebx = 0x01ff01ff;
2094 *ecx = 0x40020140;
2095 *edx = 0x40020140;
2096 break;
2097 case 0x80000006:
2098 /* cache info (L2 cache) */
2099 *eax = 0;
2100 *ebx = 0x42004200;
2101 *ecx = 0x02008140;
2102 *edx = 0;
2103 break;
2104 case 0x80000008:
2105 /* virtual & phys address size in low 2 bytes. */
2106/* XXX: This value must match the one used in the MMU code. */
0514ef2f 2107 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
c6dc6f63
AP
2108 /* 64 bit processor */
2109/* XXX: The physical address space is limited to 42 bits in exec.c. */
dd13e088 2110 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
c6dc6f63 2111 } else {
0514ef2f 2112 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
c6dc6f63 2113 *eax = 0x00000024; /* 36 bits physical */
dd13e088 2114 } else {
c6dc6f63 2115 *eax = 0x00000020; /* 32 bits physical */
dd13e088 2116 }
c6dc6f63
AP
2117 }
2118 *ebx = 0;
2119 *ecx = 0;
2120 *edx = 0;
ce3960eb
AF
2121 if (cs->nr_cores * cs->nr_threads > 1) {
2122 *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
c6dc6f63
AP
2123 }
2124 break;
2125 case 0x8000000A:
0514ef2f 2126 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
9f3fb565
EH
2127 *eax = 0x00000001; /* SVM Revision */
2128 *ebx = 0x00000010; /* nr of ASIDs */
2129 *ecx = 0;
0514ef2f 2130 *edx = env->features[FEAT_SVM]; /* optional features */
9f3fb565
EH
2131 } else {
2132 *eax = 0;
2133 *ebx = 0;
2134 *ecx = 0;
2135 *edx = 0;
2136 }
c6dc6f63 2137 break;
b3baa152
BW
2138 case 0xC0000000:
2139 *eax = env->cpuid_xlevel2;
2140 *ebx = 0;
2141 *ecx = 0;
2142 *edx = 0;
2143 break;
2144 case 0xC0000001:
2145 /* Support for VIA CPU's CPUID instruction */
2146 *eax = env->cpuid_version;
2147 *ebx = 0;
2148 *ecx = 0;
0514ef2f 2149 *edx = env->features[FEAT_C000_0001_EDX];
b3baa152
BW
2150 break;
2151 case 0xC0000002:
2152 case 0xC0000003:
2153 case 0xC0000004:
2154 /* Reserved for the future, and now filled with zero */
2155 *eax = 0;
2156 *ebx = 0;
2157 *ecx = 0;
2158 *edx = 0;
2159 break;
c6dc6f63
AP
2160 default:
2161 /* reserved values: zero */
2162 *eax = 0;
2163 *ebx = 0;
2164 *ecx = 0;
2165 *edx = 0;
2166 break;
2167 }
2168}
5fd2087a
AF
2169
2170/* CPUClass::reset() */
2171static void x86_cpu_reset(CPUState *s)
2172{
2173 X86CPU *cpu = X86_CPU(s);
2174 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2175 CPUX86State *env = &cpu->env;
c1958aea
AF
2176 int i;
2177
2178 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
55e5c285 2179 qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
a0762859 2180 log_cpu_state(s, CPU_DUMP_FPU | CPU_DUMP_CCOP);
c1958aea 2181 }
5fd2087a
AF
2182
2183 xcc->parent_reset(s);
2184
c1958aea
AF
2185
2186 memset(env, 0, offsetof(CPUX86State, breakpoints));
2187
2188 tlb_flush(env, 1);
2189
2190 env->old_exception = -1;
2191
2192 /* init to reset state */
2193
2194#ifdef CONFIG_SOFTMMU
2195 env->hflags |= HF_SOFTMMU_MASK;
2196#endif
2197 env->hflags2 |= HF2_GIF_MASK;
2198
2199 cpu_x86_update_cr0(env, 0x60000010);
2200 env->a20_mask = ~0x0;
2201 env->smbase = 0x30000;
2202
2203 env->idt.limit = 0xffff;
2204 env->gdt.limit = 0xffff;
2205 env->ldt.limit = 0xffff;
2206 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2207 env->tr.limit = 0xffff;
2208 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2209
2210 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2211 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2212 DESC_R_MASK | DESC_A_MASK);
2213 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2214 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2215 DESC_A_MASK);
2216 cpu_x86_load_seg_cache(env, R_ES, 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_SS, 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_FS, 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_GS, 0, 0, 0xffff,
2226 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2227 DESC_A_MASK);
2228
2229 env->eip = 0xfff0;
2230 env->regs[R_EDX] = env->cpuid_version;
2231
2232 env->eflags = 0x2;
2233
2234 /* FPU init */
2235 for (i = 0; i < 8; i++) {
2236 env->fptags[i] = 1;
2237 }
2238 env->fpuc = 0x37f;
2239
2240 env->mxcsr = 0x1f80;
2241
2242 env->pat = 0x0007040600070406ULL;
2243 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2244
2245 memset(env->dr, 0, sizeof(env->dr));
2246 env->dr[6] = DR6_FIXED_1;
2247 env->dr[7] = DR7_FIXED_1;
2248 cpu_breakpoint_remove_all(env, BP_CPU);
2249 cpu_watchpoint_remove_all(env, BP_CPU);
dd673288
IM
2250
2251#if !defined(CONFIG_USER_ONLY)
2252 /* We hard-wire the BSP to the first CPU. */
55e5c285 2253 if (s->cpu_index == 0) {
dd673288
IM
2254 apic_designate_bsp(env->apic_state);
2255 }
2256
259186a7 2257 s->halted = !cpu_is_bsp(cpu);
dd673288 2258#endif
5fd2087a
AF
2259}
2260
dd673288
IM
2261#ifndef CONFIG_USER_ONLY
2262bool cpu_is_bsp(X86CPU *cpu)
2263{
2264 return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP;
2265}
65dee380
IM
2266
2267/* TODO: remove me, when reset over QOM tree is implemented */
2268static void x86_cpu_machine_reset_cb(void *opaque)
2269{
2270 X86CPU *cpu = opaque;
2271 cpu_reset(CPU(cpu));
2272}
dd673288
IM
2273#endif
2274
de024815
AF
2275static void mce_init(X86CPU *cpu)
2276{
2277 CPUX86State *cenv = &cpu->env;
2278 unsigned int bank;
2279
2280 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
0514ef2f 2281 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
de024815
AF
2282 (CPUID_MCE | CPUID_MCA)) {
2283 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2284 cenv->mcg_ctl = ~(uint64_t)0;
2285 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2286 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2287 }
2288 }
2289}
2290
bdeec802 2291#ifndef CONFIG_USER_ONLY
d3c64d6a 2292static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
bdeec802 2293{
bdeec802 2294 CPUX86State *env = &cpu->env;
53a89e26 2295 DeviceState *dev = DEVICE(cpu);
449994eb 2296 APICCommonState *apic;
bdeec802
IM
2297 const char *apic_type = "apic";
2298
2299 if (kvm_irqchip_in_kernel()) {
2300 apic_type = "kvm-apic";
2301 } else if (xen_enabled()) {
2302 apic_type = "xen-apic";
2303 }
2304
53a89e26 2305 env->apic_state = qdev_try_create(qdev_get_parent_bus(dev), apic_type);
bdeec802
IM
2306 if (env->apic_state == NULL) {
2307 error_setg(errp, "APIC device '%s' could not be created", apic_type);
2308 return;
2309 }
2310
2311 object_property_add_child(OBJECT(cpu), "apic",
2312 OBJECT(env->apic_state), NULL);
2313 qdev_prop_set_uint8(env->apic_state, "id", env->cpuid_apic_id);
2314 /* TODO: convert to link<> */
449994eb 2315 apic = APIC_COMMON(env->apic_state);
60671e58 2316 apic->cpu = cpu;
d3c64d6a
IM
2317}
2318
2319static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2320{
2321 CPUX86State *env = &cpu->env;
d3c64d6a
IM
2322
2323 if (env->apic_state == NULL) {
2324 return;
2325 }
bdeec802
IM
2326
2327 if (qdev_init(env->apic_state)) {
2328 error_setg(errp, "APIC device '%s' could not be initialized",
2329 object_get_typename(OBJECT(env->apic_state)));
2330 return;
2331 }
bdeec802 2332}
d3c64d6a
IM
2333#else
2334static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2335{
2336}
bdeec802
IM
2337#endif
2338
2b6f294c 2339static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
7a059953 2340{
2b6f294c
AF
2341 X86CPU *cpu = X86_CPU(dev);
2342 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
b34d12d1 2343 CPUX86State *env = &cpu->env;
2b6f294c 2344 Error *local_err = NULL;
b34d12d1 2345
0514ef2f 2346 if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
b34d12d1
IM
2347 env->cpuid_level = 7;
2348 }
7a059953 2349
9b15cd9e
IM
2350 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
2351 * CPUID[1].EDX.
2352 */
2353 if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
2354 env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
2355 env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
0514ef2f
EH
2356 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
2357 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
9b15cd9e
IM
2358 & CPUID_EXT2_AMD_ALIASES);
2359 }
2360
4586f157 2361 if (!kvm_enabled()) {
0514ef2f
EH
2362 env->features[FEAT_1_EDX] &= TCG_FEATURES;
2363 env->features[FEAT_1_ECX] &= TCG_EXT_FEATURES;
2364 env->features[FEAT_8000_0001_EDX] &= (TCG_EXT2_FEATURES
4586f157
IM
2365#ifdef TARGET_X86_64
2366 | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
2367#endif
2368 );
0514ef2f
EH
2369 env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES;
2370 env->features[FEAT_SVM] &= TCG_SVM_FEATURES;
4586f157 2371 } else {
5ec01c2e
IM
2372 if (check_cpuid && kvm_check_features_against_host(cpu)
2373 && enforce_cpuid) {
4dc1f449
IM
2374 error_setg(&local_err,
2375 "Host's CPU doesn't support requested features");
2376 goto out;
5ec01c2e 2377 }
a509d632
EH
2378#ifdef CONFIG_KVM
2379 filter_features_for_kvm(cpu);
2380#endif
4586f157
IM
2381 }
2382
65dee380
IM
2383#ifndef CONFIG_USER_ONLY
2384 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
bdeec802 2385
0514ef2f 2386 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
d3c64d6a 2387 x86_cpu_apic_create(cpu, &local_err);
2b6f294c 2388 if (local_err != NULL) {
4dc1f449 2389 goto out;
bdeec802
IM
2390 }
2391 }
65dee380
IM
2392#endif
2393
7a059953 2394 mce_init(cpu);
d3c64d6a
IM
2395
2396 x86_cpu_apic_realize(cpu, &local_err);
2397 if (local_err != NULL) {
2398 goto out;
2399 }
65dee380 2400 cpu_reset(CPU(cpu));
2b6f294c 2401
4dc1f449
IM
2402 xcc->parent_realize(dev, &local_err);
2403out:
2404 if (local_err != NULL) {
2405 error_propagate(errp, local_err);
2406 return;
2407 }
7a059953
AF
2408}
2409
8932cfdf
EH
2410/* Enables contiguous-apic-ID mode, for compatibility */
2411static bool compat_apic_id_mode;
2412
2413void enable_compat_apic_id_mode(void)
2414{
2415 compat_apic_id_mode = true;
2416}
2417
cb41bad3
EH
2418/* Calculates initial APIC ID for a specific CPU index
2419 *
2420 * Currently we need to be able to calculate the APIC ID from the CPU index
2421 * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
2422 * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
2423 * all CPUs up to max_cpus.
2424 */
2425uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
2426{
8932cfdf
EH
2427 uint32_t correct_id;
2428 static bool warned;
2429
2430 correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
2431 if (compat_apic_id_mode) {
2432 if (cpu_index != correct_id && !warned) {
2433 error_report("APIC IDs set in compatibility mode, "
2434 "CPU topology won't match the configuration");
2435 warned = true;
2436 }
2437 return cpu_index;
2438 } else {
2439 return correct_id;
2440 }
cb41bad3
EH
2441}
2442
de024815
AF
2443static void x86_cpu_initfn(Object *obj)
2444{
55e5c285 2445 CPUState *cs = CPU(obj);
de024815
AF
2446 X86CPU *cpu = X86_CPU(obj);
2447 CPUX86State *env = &cpu->env;
d65e9815 2448 static int inited;
de024815 2449
c05efcb1 2450 cs->env_ptr = env;
de024815 2451 cpu_exec_init(env);
71ad61d3
AF
2452
2453 object_property_add(obj, "family", "int",
95b8519d 2454 x86_cpuid_version_get_family,
71ad61d3 2455 x86_cpuid_version_set_family, NULL, NULL, NULL);
c5291a4f 2456 object_property_add(obj, "model", "int",
67e30c83 2457 x86_cpuid_version_get_model,
c5291a4f 2458 x86_cpuid_version_set_model, NULL, NULL, NULL);
036e2222 2459 object_property_add(obj, "stepping", "int",
35112e41 2460 x86_cpuid_version_get_stepping,
036e2222 2461 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
8e1898bf
AF
2462 object_property_add(obj, "level", "int",
2463 x86_cpuid_get_level,
2464 x86_cpuid_set_level, NULL, NULL, NULL);
16b93aa8
AF
2465 object_property_add(obj, "xlevel", "int",
2466 x86_cpuid_get_xlevel,
2467 x86_cpuid_set_xlevel, NULL, NULL, NULL);
d480e1af
AF
2468 object_property_add_str(obj, "vendor",
2469 x86_cpuid_get_vendor,
2470 x86_cpuid_set_vendor, NULL);
938d4c25 2471 object_property_add_str(obj, "model-id",
63e886eb 2472 x86_cpuid_get_model_id,
938d4c25 2473 x86_cpuid_set_model_id, NULL);
89e48965
AF
2474 object_property_add(obj, "tsc-frequency", "int",
2475 x86_cpuid_get_tsc_freq,
2476 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
31050930
IM
2477 object_property_add(obj, "apic-id", "int",
2478 x86_cpuid_get_apic_id,
2479 x86_cpuid_set_apic_id, NULL, NULL, NULL);
8e8aba50
EH
2480 object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
2481 x86_cpu_get_feature_words,
7e5292b5
EH
2482 NULL, NULL, (void *)env->features, NULL);
2483 object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
2484 x86_cpu_get_feature_words,
2485 NULL, NULL, (void *)cpu->filtered_features, NULL);
71ad61d3 2486
cb41bad3 2487 env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
d65e9815
IM
2488
2489 /* init various static tables used in TCG mode */
2490 if (tcg_enabled() && !inited) {
2491 inited = 1;
2492 optimize_flags_init();
2493#ifndef CONFIG_USER_ONLY
2494 cpu_set_debug_excp_handler(breakpoint_handler);
2495#endif
2496 }
de024815
AF
2497}
2498
997395d3
IM
2499static int64_t x86_cpu_get_arch_id(CPUState *cs)
2500{
2501 X86CPU *cpu = X86_CPU(cs);
2502 CPUX86State *env = &cpu->env;
2503
2504 return env->cpuid_apic_id;
2505}
2506
444d5590
AF
2507static bool x86_cpu_get_paging_enabled(const CPUState *cs)
2508{
2509 X86CPU *cpu = X86_CPU(cs);
2510
2511 return cpu->env.cr[0] & CR0_PG_MASK;
2512}
2513
5fd2087a
AF
2514static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
2515{
2516 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2517 CPUClass *cc = CPU_CLASS(oc);
2b6f294c
AF
2518 DeviceClass *dc = DEVICE_CLASS(oc);
2519
2520 xcc->parent_realize = dc->realize;
2521 dc->realize = x86_cpu_realizefn;
62fc403f 2522 dc->bus_type = TYPE_ICC_BUS;
5fd2087a
AF
2523
2524 xcc->parent_reset = cc->reset;
2525 cc->reset = x86_cpu_reset;
f56e3a14 2526
97a8ea5a 2527 cc->do_interrupt = x86_cpu_do_interrupt;
878096ee 2528 cc->dump_state = x86_cpu_dump_state;
444d5590
AF
2529 cc->get_arch_id = x86_cpu_get_arch_id;
2530 cc->get_paging_enabled = x86_cpu_get_paging_enabled;
c72bf468 2531#ifndef CONFIG_USER_ONLY
a23bbfda 2532 cc->get_memory_mapping = x86_cpu_get_memory_mapping;
c72bf468
JF
2533 cc->write_elf64_note = x86_cpu_write_elf64_note;
2534 cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
2535 cc->write_elf32_note = x86_cpu_write_elf32_note;
2536 cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
2537#endif
f56e3a14 2538 cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
5fd2087a
AF
2539}
2540
2541static const TypeInfo x86_cpu_type_info = {
2542 .name = TYPE_X86_CPU,
2543 .parent = TYPE_CPU,
2544 .instance_size = sizeof(X86CPU),
de024815 2545 .instance_init = x86_cpu_initfn,
5fd2087a
AF
2546 .abstract = false,
2547 .class_size = sizeof(X86CPUClass),
2548 .class_init = x86_cpu_common_class_init,
2549};
2550
2551static void x86_cpu_register_types(void)
2552{
2553 type_register_static(&x86_cpu_type_info);
2554}
2555
2556type_init(x86_cpu_register_types)