]> git.proxmox.com Git - mirror_qemu.git/blame - target-i386/cpu.c
target-i386: Emulate X86CPU subclasses for global properties
[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{
8b4beddc
EH
224 if (reg > CPU_NB_REGS32) {
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
AP
590 .family = 4,
591 .model = 0,
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 |
8560efed 660 CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR,
0514ef2f 661 .features[FEAT_8000_0001_EDX] =
27861ecc 662 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
60032ac0 663 CPUID_EXT2_NX,
0514ef2f 664 .features[FEAT_8000_0001_ECX] =
27861ecc 665 CPUID_EXT3_LAHF_LM,
c6dc6f63
AP
666 .xlevel = 0x8000000A,
667 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
668 },
3eca4642
EH
669 {
670 .name = "Conroe",
671 .level = 2,
99b88a17 672 .vendor = CPUID_VENDOR_INTEL,
3eca4642
EH
673 .family = 6,
674 .model = 2,
675 .stepping = 3,
0514ef2f 676 .features[FEAT_1_EDX] =
27861ecc 677 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
678 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
679 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
680 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
681 CPUID_DE | CPUID_FP87,
0514ef2f 682 .features[FEAT_1_ECX] =
27861ecc 683 CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
0514ef2f 684 .features[FEAT_8000_0001_EDX] =
27861ecc 685 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
0514ef2f 686 .features[FEAT_8000_0001_ECX] =
27861ecc 687 CPUID_EXT3_LAHF_LM,
3eca4642
EH
688 .xlevel = 0x8000000A,
689 .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
690 },
691 {
692 .name = "Penryn",
693 .level = 2,
99b88a17 694 .vendor = CPUID_VENDOR_INTEL,
3eca4642
EH
695 .family = 6,
696 .model = 2,
697 .stepping = 3,
0514ef2f 698 .features[FEAT_1_EDX] =
27861ecc 699 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
700 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
701 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
702 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
703 CPUID_DE | CPUID_FP87,
0514ef2f 704 .features[FEAT_1_ECX] =
27861ecc 705 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
3eca4642 706 CPUID_EXT_SSE3,
0514ef2f 707 .features[FEAT_8000_0001_EDX] =
27861ecc 708 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
0514ef2f 709 .features[FEAT_8000_0001_ECX] =
27861ecc 710 CPUID_EXT3_LAHF_LM,
3eca4642
EH
711 .xlevel = 0x8000000A,
712 .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
713 },
714 {
715 .name = "Nehalem",
716 .level = 2,
99b88a17 717 .vendor = CPUID_VENDOR_INTEL,
3eca4642
EH
718 .family = 6,
719 .model = 2,
720 .stepping = 3,
0514ef2f 721 .features[FEAT_1_EDX] =
27861ecc 722 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
723 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
724 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
725 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
726 CPUID_DE | CPUID_FP87,
0514ef2f 727 .features[FEAT_1_ECX] =
27861ecc 728 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
3eca4642 729 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
0514ef2f 730 .features[FEAT_8000_0001_EDX] =
27861ecc 731 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
0514ef2f 732 .features[FEAT_8000_0001_ECX] =
27861ecc 733 CPUID_EXT3_LAHF_LM,
3eca4642
EH
734 .xlevel = 0x8000000A,
735 .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
736 },
737 {
738 .name = "Westmere",
739 .level = 11,
99b88a17 740 .vendor = CPUID_VENDOR_INTEL,
3eca4642
EH
741 .family = 6,
742 .model = 44,
743 .stepping = 1,
0514ef2f 744 .features[FEAT_1_EDX] =
27861ecc 745 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
746 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
747 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
748 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
749 CPUID_DE | CPUID_FP87,
0514ef2f 750 .features[FEAT_1_ECX] =
27861ecc 751 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
3eca4642 752 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
41cb383f 753 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
0514ef2f 754 .features[FEAT_8000_0001_EDX] =
27861ecc 755 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
0514ef2f 756 .features[FEAT_8000_0001_ECX] =
27861ecc 757 CPUID_EXT3_LAHF_LM,
3eca4642
EH
758 .xlevel = 0x8000000A,
759 .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
760 },
761 {
762 .name = "SandyBridge",
763 .level = 0xd,
99b88a17 764 .vendor = CPUID_VENDOR_INTEL,
3eca4642
EH
765 .family = 6,
766 .model = 42,
767 .stepping = 1,
0514ef2f 768 .features[FEAT_1_EDX] =
27861ecc 769 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
770 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
771 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
772 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
773 CPUID_DE | CPUID_FP87,
0514ef2f 774 .features[FEAT_1_ECX] =
27861ecc 775 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
3eca4642
EH
776 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
777 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
778 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
779 CPUID_EXT_SSE3,
0514ef2f 780 .features[FEAT_8000_0001_EDX] =
27861ecc 781 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
3eca4642 782 CPUID_EXT2_SYSCALL,
0514ef2f 783 .features[FEAT_8000_0001_ECX] =
27861ecc 784 CPUID_EXT3_LAHF_LM,
3eca4642
EH
785 .xlevel = 0x8000000A,
786 .model_id = "Intel Xeon E312xx (Sandy Bridge)",
787 },
37507094
EH
788 {
789 .name = "Haswell",
790 .level = 0xd,
99b88a17 791 .vendor = CPUID_VENDOR_INTEL,
37507094
EH
792 .family = 6,
793 .model = 60,
794 .stepping = 1,
0514ef2f 795 .features[FEAT_1_EDX] =
27861ecc 796 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
37507094 797 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
80ae4160 798 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
37507094
EH
799 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
800 CPUID_DE | CPUID_FP87,
0514ef2f 801 .features[FEAT_1_ECX] =
27861ecc 802 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
37507094
EH
803 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
804 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
805 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
806 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
807 CPUID_EXT_PCID,
0514ef2f 808 .features[FEAT_8000_0001_EDX] =
27861ecc 809 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
80ae4160 810 CPUID_EXT2_SYSCALL,
0514ef2f 811 .features[FEAT_8000_0001_ECX] =
27861ecc 812 CPUID_EXT3_LAHF_LM,
0514ef2f 813 .features[FEAT_7_0_EBX] =
27861ecc 814 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
37507094
EH
815 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
816 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
817 CPUID_7_0_EBX_RTM,
818 .xlevel = 0x8000000A,
819 .model_id = "Intel Core Processor (Haswell)",
820 },
3eca4642
EH
821 {
822 .name = "Opteron_G1",
823 .level = 5,
99b88a17 824 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
825 .family = 15,
826 .model = 6,
827 .stepping = 1,
0514ef2f 828 .features[FEAT_1_EDX] =
27861ecc 829 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
830 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
831 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
832 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
833 CPUID_DE | CPUID_FP87,
0514ef2f 834 .features[FEAT_1_ECX] =
27861ecc 835 CPUID_EXT_SSE3,
0514ef2f 836 .features[FEAT_8000_0001_EDX] =
27861ecc 837 CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
3eca4642
EH
838 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
839 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
840 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
841 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
842 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
843 .xlevel = 0x80000008,
844 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
845 },
846 {
847 .name = "Opteron_G2",
848 .level = 5,
99b88a17 849 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
850 .family = 15,
851 .model = 6,
852 .stepping = 1,
0514ef2f 853 .features[FEAT_1_EDX] =
27861ecc 854 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
855 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
856 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
857 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
858 CPUID_DE | CPUID_FP87,
0514ef2f 859 .features[FEAT_1_ECX] =
27861ecc 860 CPUID_EXT_CX16 | CPUID_EXT_SSE3,
0514ef2f 861 .features[FEAT_8000_0001_EDX] =
27861ecc 862 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
3eca4642
EH
863 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
864 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
865 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
866 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
867 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
868 CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 869 .features[FEAT_8000_0001_ECX] =
27861ecc 870 CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
3eca4642
EH
871 .xlevel = 0x80000008,
872 .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
873 },
874 {
875 .name = "Opteron_G3",
876 .level = 5,
99b88a17 877 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
878 .family = 15,
879 .model = 6,
880 .stepping = 1,
0514ef2f 881 .features[FEAT_1_EDX] =
27861ecc 882 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
883 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
884 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
885 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
886 CPUID_DE | CPUID_FP87,
0514ef2f 887 .features[FEAT_1_ECX] =
27861ecc 888 CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
3eca4642 889 CPUID_EXT_SSE3,
0514ef2f 890 .features[FEAT_8000_0001_EDX] =
27861ecc 891 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
3eca4642
EH
892 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
893 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
894 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
895 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
896 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
897 CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 898 .features[FEAT_8000_0001_ECX] =
27861ecc 899 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
3eca4642
EH
900 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
901 .xlevel = 0x80000008,
902 .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
903 },
904 {
905 .name = "Opteron_G4",
906 .level = 0xd,
99b88a17 907 .vendor = CPUID_VENDOR_AMD,
3eca4642
EH
908 .family = 21,
909 .model = 1,
910 .stepping = 2,
0514ef2f 911 .features[FEAT_1_EDX] =
27861ecc 912 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
3eca4642
EH
913 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
914 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
915 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
916 CPUID_DE | CPUID_FP87,
0514ef2f 917 .features[FEAT_1_ECX] =
27861ecc 918 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
3eca4642
EH
919 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
920 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
921 CPUID_EXT_SSE3,
0514ef2f 922 .features[FEAT_8000_0001_EDX] =
27861ecc 923 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
3eca4642
EH
924 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
925 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
926 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
927 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
928 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
929 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 930 .features[FEAT_8000_0001_ECX] =
27861ecc 931 CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
3eca4642
EH
932 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
933 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
934 CPUID_EXT3_LAHF_LM,
935 .xlevel = 0x8000001A,
936 .model_id = "AMD Opteron 62xx class CPU",
937 },
021941b9
AP
938 {
939 .name = "Opteron_G5",
940 .level = 0xd,
99b88a17 941 .vendor = CPUID_VENDOR_AMD,
021941b9
AP
942 .family = 21,
943 .model = 2,
944 .stepping = 0,
0514ef2f 945 .features[FEAT_1_EDX] =
27861ecc 946 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
021941b9
AP
947 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
948 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
949 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
950 CPUID_DE | CPUID_FP87,
0514ef2f 951 .features[FEAT_1_ECX] =
27861ecc 952 CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
021941b9
AP
953 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
954 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
955 CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
0514ef2f 956 .features[FEAT_8000_0001_EDX] =
27861ecc 957 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
021941b9
AP
958 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
959 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
960 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
961 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
962 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
963 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
0514ef2f 964 .features[FEAT_8000_0001_ECX] =
27861ecc 965 CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
021941b9
AP
966 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
967 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
968 CPUID_EXT3_LAHF_LM,
969 .xlevel = 0x8000001A,
970 .model_id = "AMD Opteron 63xx class CPU",
971 },
c6dc6f63
AP
972};
973
e4ab0d6b 974#ifdef CONFIG_KVM
c6dc6f63
AP
975static int cpu_x86_fill_model_id(char *str)
976{
977 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
978 int i;
979
980 for (i = 0; i < 3; i++) {
981 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
982 memcpy(str + i * 16 + 0, &eax, 4);
983 memcpy(str + i * 16 + 4, &ebx, 4);
984 memcpy(str + i * 16 + 8, &ecx, 4);
985 memcpy(str + i * 16 + 12, &edx, 4);
986 }
987 return 0;
988}
e4ab0d6b 989#endif
c6dc6f63 990
6e746f30
EH
991/* Fill a x86_def_t struct with information about the host CPU, and
992 * the CPU features supported by the host hardware + host kernel
993 *
994 * This function may be called only if KVM is enabled.
995 */
996static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
c6dc6f63 997{
e4ab0d6b 998#ifdef CONFIG_KVM
12869995 999 KVMState *s = kvm_state;
c6dc6f63
AP
1000 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1001
6e746f30
EH
1002 assert(kvm_enabled());
1003
c6dc6f63
AP
1004 x86_cpu_def->name = "host";
1005 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
99b88a17 1006 x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
c6dc6f63
AP
1007
1008 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
1009 x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1010 x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1011 x86_cpu_def->stepping = eax & 0x0F;
c6dc6f63 1012
12869995 1013 x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
0514ef2f 1014 x86_cpu_def->features[FEAT_1_EDX] =
27861ecc 1015 kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX);
0514ef2f 1016 x86_cpu_def->features[FEAT_1_ECX] =
27861ecc 1017 kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX);
c6dc6f63 1018
6e746f30 1019 if (x86_cpu_def->level >= 7) {
0514ef2f 1020 x86_cpu_def->features[FEAT_7_0_EBX] =
12869995 1021 kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX);
13526728 1022 } else {
0514ef2f 1023 x86_cpu_def->features[FEAT_7_0_EBX] = 0;
13526728
EH
1024 }
1025
12869995 1026 x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
0514ef2f 1027 x86_cpu_def->features[FEAT_8000_0001_EDX] =
12869995 1028 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
0514ef2f 1029 x86_cpu_def->features[FEAT_8000_0001_ECX] =
12869995 1030 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
c6dc6f63 1031
c6dc6f63 1032 cpu_x86_fill_model_id(x86_cpu_def->model_id);
c6dc6f63 1033
b3baa152 1034 /* Call Centaur's CPUID instruction. */
99b88a17 1035 if (!strcmp(x86_cpu_def->vendor, CPUID_VENDOR_VIA)) {
b3baa152 1036 host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
12869995 1037 eax = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
b3baa152
BW
1038 if (eax >= 0xC0000001) {
1039 /* Support VIA max extended level */
1040 x86_cpu_def->xlevel2 = eax;
1041 host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
0514ef2f 1042 x86_cpu_def->features[FEAT_C000_0001_EDX] =
12869995 1043 kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
b3baa152
BW
1044 }
1045 }
296acb64 1046
fcb93c03 1047 /* Other KVM-specific feature fields: */
0514ef2f 1048 x86_cpu_def->features[FEAT_SVM] =
fcb93c03 1049 kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
0514ef2f 1050 x86_cpu_def->features[FEAT_KVM] =
bd004bef 1051 kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
fcb93c03 1052
e4ab0d6b 1053#endif /* CONFIG_KVM */
c6dc6f63
AP
1054}
1055
bffd67b0 1056static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask)
c6dc6f63
AP
1057{
1058 int i;
1059
1060 for (i = 0; i < 32; ++i)
1061 if (1 << i & mask) {
bffd67b0 1062 const char *reg = get_register_name_32(f->cpuid_reg);
8b4beddc
EH
1063 assert(reg);
1064 fprintf(stderr, "warning: host doesn't support requested feature: "
1065 "CPUID.%02XH:%s%s%s [bit %d]\n",
bffd67b0
EH
1066 f->cpuid_eax, reg,
1067 f->feat_names[i] ? "." : "",
1068 f->feat_names[i] ? f->feat_names[i] : "", i);
c6dc6f63
AP
1069 break;
1070 }
1071 return 0;
1072}
1073
07ca5945
EH
1074/* Check if all requested cpu flags are making their way to the guest
1075 *
1076 * Returns 0 if all flags are supported by the host, non-zero otherwise.
6e746f30
EH
1077 *
1078 * This function may be called only if KVM is enabled.
c6dc6f63 1079 */
5ec01c2e 1080static int kvm_check_features_against_host(X86CPU *cpu)
c6dc6f63 1081{
5ec01c2e 1082 CPUX86State *env = &cpu->env;
c6dc6f63
AP
1083 x86_def_t host_def;
1084 uint32_t mask;
1085 int rv, i;
1086 struct model_features_t ft[] = {
0514ef2f
EH
1087 {&env->features[FEAT_1_EDX],
1088 &host_def.features[FEAT_1_EDX],
bffd67b0 1089 FEAT_1_EDX },
0514ef2f
EH
1090 {&env->features[FEAT_1_ECX],
1091 &host_def.features[FEAT_1_ECX],
bffd67b0 1092 FEAT_1_ECX },
0514ef2f
EH
1093 {&env->features[FEAT_8000_0001_EDX],
1094 &host_def.features[FEAT_8000_0001_EDX],
bffd67b0 1095 FEAT_8000_0001_EDX },
0514ef2f
EH
1096 {&env->features[FEAT_8000_0001_ECX],
1097 &host_def.features[FEAT_8000_0001_ECX],
bffd67b0 1098 FEAT_8000_0001_ECX },
0514ef2f
EH
1099 {&env->features[FEAT_C000_0001_EDX],
1100 &host_def.features[FEAT_C000_0001_EDX],
07ca5945 1101 FEAT_C000_0001_EDX },
0514ef2f
EH
1102 {&env->features[FEAT_7_0_EBX],
1103 &host_def.features[FEAT_7_0_EBX],
07ca5945 1104 FEAT_7_0_EBX },
0514ef2f
EH
1105 {&env->features[FEAT_SVM],
1106 &host_def.features[FEAT_SVM],
07ca5945 1107 FEAT_SVM },
0514ef2f
EH
1108 {&env->features[FEAT_KVM],
1109 &host_def.features[FEAT_KVM],
07ca5945 1110 FEAT_KVM },
8b4beddc 1111 };
c6dc6f63 1112
6e746f30
EH
1113 assert(kvm_enabled());
1114
1115 kvm_cpu_fill_host(&host_def);
bffd67b0
EH
1116 for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i) {
1117 FeatureWord w = ft[i].feat_word;
1118 FeatureWordInfo *wi = &feature_word_info[w];
1119 for (mask = 1; mask; mask <<= 1) {
e8beac00 1120 if (*ft[i].guest_feat & mask &&
c6dc6f63 1121 !(*ft[i].host_feat & mask)) {
bffd67b0
EH
1122 unavailable_host_feature(wi, mask);
1123 rv = 1;
1124 }
1125 }
1126 }
c6dc6f63
AP
1127 return rv;
1128}
1129
95b8519d
AF
1130static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
1131 const char *name, Error **errp)
1132{
1133 X86CPU *cpu = X86_CPU(obj);
1134 CPUX86State *env = &cpu->env;
1135 int64_t value;
1136
1137 value = (env->cpuid_version >> 8) & 0xf;
1138 if (value == 0xf) {
1139 value += (env->cpuid_version >> 20) & 0xff;
1140 }
1141 visit_type_int(v, &value, name, errp);
1142}
1143
71ad61d3
AF
1144static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
1145 const char *name, Error **errp)
ed5e1ec3 1146{
71ad61d3
AF
1147 X86CPU *cpu = X86_CPU(obj);
1148 CPUX86State *env = &cpu->env;
1149 const int64_t min = 0;
1150 const int64_t max = 0xff + 0xf;
1151 int64_t value;
1152
1153 visit_type_int(v, &value, name, errp);
1154 if (error_is_set(errp)) {
1155 return;
1156 }
1157 if (value < min || value > max) {
1158 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1159 name ? name : "null", value, min, max);
1160 return;
1161 }
1162
ed5e1ec3 1163 env->cpuid_version &= ~0xff00f00;
71ad61d3
AF
1164 if (value > 0x0f) {
1165 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
ed5e1ec3 1166 } else {
71ad61d3 1167 env->cpuid_version |= value << 8;
ed5e1ec3
AF
1168 }
1169}
1170
67e30c83
AF
1171static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
1172 const char *name, Error **errp)
1173{
1174 X86CPU *cpu = X86_CPU(obj);
1175 CPUX86State *env = &cpu->env;
1176 int64_t value;
1177
1178 value = (env->cpuid_version >> 4) & 0xf;
1179 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
1180 visit_type_int(v, &value, name, errp);
1181}
1182
c5291a4f
AF
1183static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
1184 const char *name, Error **errp)
b0704cbd 1185{
c5291a4f
AF
1186 X86CPU *cpu = X86_CPU(obj);
1187 CPUX86State *env = &cpu->env;
1188 const int64_t min = 0;
1189 const int64_t max = 0xff;
1190 int64_t value;
1191
1192 visit_type_int(v, &value, name, errp);
1193 if (error_is_set(errp)) {
1194 return;
1195 }
1196 if (value < min || value > max) {
1197 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1198 name ? name : "null", value, min, max);
1199 return;
1200 }
1201
b0704cbd 1202 env->cpuid_version &= ~0xf00f0;
c5291a4f 1203 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
b0704cbd
AF
1204}
1205
35112e41
AF
1206static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
1207 void *opaque, const char *name,
1208 Error **errp)
1209{
1210 X86CPU *cpu = X86_CPU(obj);
1211 CPUX86State *env = &cpu->env;
1212 int64_t value;
1213
1214 value = env->cpuid_version & 0xf;
1215 visit_type_int(v, &value, name, errp);
1216}
1217
036e2222
AF
1218static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
1219 void *opaque, const char *name,
1220 Error **errp)
38c3dc46 1221{
036e2222
AF
1222 X86CPU *cpu = X86_CPU(obj);
1223 CPUX86State *env = &cpu->env;
1224 const int64_t min = 0;
1225 const int64_t max = 0xf;
1226 int64_t value;
1227
1228 visit_type_int(v, &value, name, errp);
1229 if (error_is_set(errp)) {
1230 return;
1231 }
1232 if (value < min || value > max) {
1233 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1234 name ? name : "null", value, min, max);
1235 return;
1236 }
1237
38c3dc46 1238 env->cpuid_version &= ~0xf;
036e2222 1239 env->cpuid_version |= value & 0xf;
38c3dc46
AF
1240}
1241
8e1898bf
AF
1242static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
1243 const char *name, Error **errp)
1244{
1245 X86CPU *cpu = X86_CPU(obj);
8e1898bf 1246
fa029887 1247 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
8e1898bf
AF
1248}
1249
1250static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
1251 const char *name, Error **errp)
1252{
1253 X86CPU *cpu = X86_CPU(obj);
8e1898bf 1254
fa029887 1255 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
8e1898bf
AF
1256}
1257
16b93aa8
AF
1258static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
1259 const char *name, Error **errp)
1260{
1261 X86CPU *cpu = X86_CPU(obj);
16b93aa8 1262
fa029887 1263 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
16b93aa8
AF
1264}
1265
1266static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
1267 const char *name, Error **errp)
1268{
1269 X86CPU *cpu = X86_CPU(obj);
16b93aa8 1270
fa029887 1271 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
16b93aa8
AF
1272}
1273
d480e1af
AF
1274static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1275{
1276 X86CPU *cpu = X86_CPU(obj);
1277 CPUX86State *env = &cpu->env;
1278 char *value;
d480e1af 1279
9df694ee 1280 value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
99b88a17
IM
1281 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
1282 env->cpuid_vendor3);
d480e1af
AF
1283 return value;
1284}
1285
1286static void x86_cpuid_set_vendor(Object *obj, const char *value,
1287 Error **errp)
1288{
1289 X86CPU *cpu = X86_CPU(obj);
1290 CPUX86State *env = &cpu->env;
1291 int i;
1292
9df694ee 1293 if (strlen(value) != CPUID_VENDOR_SZ) {
d480e1af
AF
1294 error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
1295 "vendor", value);
1296 return;
1297 }
1298
1299 env->cpuid_vendor1 = 0;
1300 env->cpuid_vendor2 = 0;
1301 env->cpuid_vendor3 = 0;
1302 for (i = 0; i < 4; i++) {
1303 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1304 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1305 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1306 }
d480e1af
AF
1307}
1308
63e886eb
AF
1309static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1310{
1311 X86CPU *cpu = X86_CPU(obj);
1312 CPUX86State *env = &cpu->env;
1313 char *value;
1314 int i;
1315
1316 value = g_malloc(48 + 1);
1317 for (i = 0; i < 48; i++) {
1318 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1319 }
1320 value[48] = '\0';
1321 return value;
1322}
1323
938d4c25
AF
1324static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1325 Error **errp)
dcce6675 1326{
938d4c25
AF
1327 X86CPU *cpu = X86_CPU(obj);
1328 CPUX86State *env = &cpu->env;
dcce6675
AF
1329 int c, len, i;
1330
1331 if (model_id == NULL) {
1332 model_id = "";
1333 }
1334 len = strlen(model_id);
d0a6acf4 1335 memset(env->cpuid_model, 0, 48);
dcce6675
AF
1336 for (i = 0; i < 48; i++) {
1337 if (i >= len) {
1338 c = '\0';
1339 } else {
1340 c = (uint8_t)model_id[i];
1341 }
1342 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1343 }
1344}
1345
89e48965
AF
1346static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
1347 const char *name, Error **errp)
1348{
1349 X86CPU *cpu = X86_CPU(obj);
1350 int64_t value;
1351
1352 value = cpu->env.tsc_khz * 1000;
1353 visit_type_int(v, &value, name, errp);
1354}
1355
1356static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
1357 const char *name, Error **errp)
1358{
1359 X86CPU *cpu = X86_CPU(obj);
1360 const int64_t min = 0;
2e84849a 1361 const int64_t max = INT64_MAX;
89e48965
AF
1362 int64_t value;
1363
1364 visit_type_int(v, &value, name, errp);
1365 if (error_is_set(errp)) {
1366 return;
1367 }
1368 if (value < min || value > max) {
1369 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1370 name ? name : "null", value, min, max);
1371 return;
1372 }
1373
1374 cpu->env.tsc_khz = value / 1000;
1375}
1376
31050930
IM
1377static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, void *opaque,
1378 const char *name, Error **errp)
1379{
1380 X86CPU *cpu = X86_CPU(obj);
1381 int64_t value = cpu->env.cpuid_apic_id;
1382
1383 visit_type_int(v, &value, name, errp);
1384}
1385
1386static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque,
1387 const char *name, Error **errp)
1388{
1389 X86CPU *cpu = X86_CPU(obj);
8d6d4980 1390 DeviceState *dev = DEVICE(obj);
31050930
IM
1391 const int64_t min = 0;
1392 const int64_t max = UINT32_MAX;
1393 Error *error = NULL;
1394 int64_t value;
1395
8d6d4980
IM
1396 if (dev->realized) {
1397 error_setg(errp, "Attempt to set property '%s' on '%s' after "
1398 "it was realized", name, object_get_typename(obj));
1399 return;
1400 }
1401
31050930
IM
1402 visit_type_int(v, &value, name, &error);
1403 if (error) {
1404 error_propagate(errp, error);
1405 return;
1406 }
1407 if (value < min || value > max) {
1408 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1409 " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
1410 object_get_typename(obj), name, value, min, max);
1411 return;
1412 }
1413
1414 if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
1415 error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
1416 return;
1417 }
1418 cpu->env.cpuid_apic_id = value;
1419}
1420
7e5292b5 1421/* Generic getter for "feature-words" and "filtered-features" properties */
8e8aba50
EH
1422static void x86_cpu_get_feature_words(Object *obj, Visitor *v, void *opaque,
1423 const char *name, Error **errp)
1424{
7e5292b5 1425 uint32_t *array = (uint32_t *)opaque;
8e8aba50
EH
1426 FeatureWord w;
1427 Error *err = NULL;
1428 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
1429 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
1430 X86CPUFeatureWordInfoList *list = NULL;
1431
1432 for (w = 0; w < FEATURE_WORDS; w++) {
1433 FeatureWordInfo *wi = &feature_word_info[w];
1434 X86CPUFeatureWordInfo *qwi = &word_infos[w];
1435 qwi->cpuid_input_eax = wi->cpuid_eax;
1436 qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
1437 qwi->cpuid_input_ecx = wi->cpuid_ecx;
1438 qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
7e5292b5 1439 qwi->features = array[w];
8e8aba50
EH
1440
1441 /* List will be in reverse order, but order shouldn't matter */
1442 list_entries[w].next = list;
1443 list_entries[w].value = &word_infos[w];
1444 list = &list_entries[w];
1445 }
1446
1447 visit_type_X86CPUFeatureWordInfoList(v, &list, "feature-words", &err);
1448 error_propagate(errp, err);
1449}
1450
8f961357 1451static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *name)
c6dc6f63 1452{
c6dc6f63 1453 x86_def_t *def;
7fc9b714 1454 int i;
c6dc6f63 1455
4bfe910d
AF
1456 if (name == NULL) {
1457 return -1;
9f3fb565 1458 }
4bfe910d 1459 if (kvm_enabled() && strcmp(name, "host") == 0) {
6e746f30 1460 kvm_cpu_fill_host(x86_cpu_def);
4bfe910d 1461 return 0;
c6dc6f63
AP
1462 }
1463
7fc9b714
AF
1464 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1465 def = &builtin_x86_defs[i];
4bfe910d
AF
1466 if (strcmp(name, def->name) == 0) {
1467 memcpy(x86_cpu_def, def, sizeof(*def));
11acfdd5
IM
1468 /* sysenter isn't supported in compatibility mode on AMD,
1469 * syscall isn't supported in compatibility mode on Intel.
1470 * Normally we advertise the actual CPU vendor, but you can
1471 * override this using the 'vendor' property if you want to use
1472 * KVM's sysenter/syscall emulation in compatibility mode and
1473 * when doing cross vendor migration
1474 */
1475 if (kvm_enabled()) {
1476 uint32_t ebx = 0, ecx = 0, edx = 0;
1477 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
1478 x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1479 }
4bfe910d
AF
1480 return 0;
1481 }
1482 }
1483
1484 return -1;
8f961357
EH
1485}
1486
72ac2e87
IM
1487/* Convert all '_' in a feature string option name to '-', to make feature
1488 * name conform to QOM property naming rule, which uses '-' instead of '_'.
1489 */
1490static inline void feat2prop(char *s)
1491{
1492 while ((s = strchr(s, '_'))) {
1493 *s = '-';
1494 }
1495}
1496
8f961357
EH
1497/* Parse "+feature,-feature,feature=foo" CPU feature string
1498 */
a91987c2 1499static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
8f961357 1500{
8f961357
EH
1501 char *featurestr; /* Single 'key=value" string being parsed */
1502 /* Features to be added */
077c68c3 1503 FeatureWordArray plus_features = { 0 };
8f961357 1504 /* Features to be removed */
5ef57876 1505 FeatureWordArray minus_features = { 0 };
8f961357 1506 uint32_t numvalue;
a91987c2 1507 CPUX86State *env = &cpu->env;
8f961357 1508
8f961357 1509 featurestr = features ? strtok(features, ",") : NULL;
c6dc6f63
AP
1510
1511 while (featurestr) {
1512 char *val;
1513 if (featurestr[0] == '+') {
5ef57876 1514 add_flagname_to_bitmaps(featurestr + 1, plus_features);
c6dc6f63 1515 } else if (featurestr[0] == '-') {
5ef57876 1516 add_flagname_to_bitmaps(featurestr + 1, minus_features);
c6dc6f63
AP
1517 } else if ((val = strchr(featurestr, '='))) {
1518 *val = 0; val++;
72ac2e87 1519 feat2prop(featurestr);
c6dc6f63 1520 if (!strcmp(featurestr, "family")) {
a91987c2 1521 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63 1522 } else if (!strcmp(featurestr, "model")) {
a91987c2 1523 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63 1524 } else if (!strcmp(featurestr, "stepping")) {
a91987c2 1525 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63 1526 } else if (!strcmp(featurestr, "level")) {
a91987c2 1527 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63
AP
1528 } else if (!strcmp(featurestr, "xlevel")) {
1529 char *err;
a91987c2
IM
1530 char num[32];
1531
c6dc6f63
AP
1532 numvalue = strtoul(val, &err, 0);
1533 if (!*val || *err) {
312fd5f2 1534 error_setg(errp, "bad numerical value %s", val);
a91987c2 1535 goto out;
c6dc6f63
AP
1536 }
1537 if (numvalue < 0x80000000) {
8ba8a698
IM
1538 fprintf(stderr, "xlevel value shall always be >= 0x80000000"
1539 ", fixup will be removed in future versions\n");
2f7a21c4 1540 numvalue += 0x80000000;
c6dc6f63 1541 }
a91987c2
IM
1542 snprintf(num, sizeof(num), "%" PRIu32, numvalue);
1543 object_property_parse(OBJECT(cpu), num, featurestr, errp);
c6dc6f63 1544 } else if (!strcmp(featurestr, "vendor")) {
a91987c2 1545 object_property_parse(OBJECT(cpu), val, featurestr, errp);
72ac2e87
IM
1546 } else if (!strcmp(featurestr, "model-id")) {
1547 object_property_parse(OBJECT(cpu), val, featurestr, errp);
1548 } else if (!strcmp(featurestr, "tsc-freq")) {
b862d1fe
JR
1549 int64_t tsc_freq;
1550 char *err;
a91987c2 1551 char num[32];
b862d1fe
JR
1552
1553 tsc_freq = strtosz_suffix_unit(val, &err,
1554 STRTOSZ_DEFSUFFIX_B, 1000);
45009a30 1555 if (tsc_freq < 0 || *err) {
312fd5f2 1556 error_setg(errp, "bad numerical value %s", val);
a91987c2 1557 goto out;
b862d1fe 1558 }
a91987c2
IM
1559 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
1560 object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
72ac2e87 1561 } else if (!strcmp(featurestr, "hv-spinlocks")) {
28f52cc0
VR
1562 char *err;
1563 numvalue = strtoul(val, &err, 0);
1564 if (!*val || *err) {
312fd5f2 1565 error_setg(errp, "bad numerical value %s", val);
a91987c2 1566 goto out;
28f52cc0
VR
1567 }
1568 hyperv_set_spinlock_retries(numvalue);
c6dc6f63 1569 } else {
312fd5f2 1570 error_setg(errp, "unrecognized feature %s", featurestr);
a91987c2 1571 goto out;
c6dc6f63
AP
1572 }
1573 } else if (!strcmp(featurestr, "check")) {
1574 check_cpuid = 1;
1575 } else if (!strcmp(featurestr, "enforce")) {
1576 check_cpuid = enforce_cpuid = 1;
28f52cc0
VR
1577 } else if (!strcmp(featurestr, "hv_relaxed")) {
1578 hyperv_enable_relaxed_timing(true);
1579 } else if (!strcmp(featurestr, "hv_vapic")) {
1580 hyperv_enable_vapic_recommended(true);
c6dc6f63 1581 } else {
a91987c2 1582 error_setg(errp, "feature string `%s' not in format (+feature|"
312fd5f2 1583 "-feature|feature=xyz)", featurestr);
a91987c2
IM
1584 goto out;
1585 }
1586 if (error_is_set(errp)) {
1587 goto out;
c6dc6f63
AP
1588 }
1589 featurestr = strtok(NULL, ",");
1590 }
0514ef2f
EH
1591 env->features[FEAT_1_EDX] |= plus_features[FEAT_1_EDX];
1592 env->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX];
1593 env->features[FEAT_8000_0001_EDX] |= plus_features[FEAT_8000_0001_EDX];
1594 env->features[FEAT_8000_0001_ECX] |= plus_features[FEAT_8000_0001_ECX];
1595 env->features[FEAT_C000_0001_EDX] |= plus_features[FEAT_C000_0001_EDX];
1596 env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
1597 env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
1598 env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
1599 env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
1600 env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
1601 env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX];
1602 env->features[FEAT_8000_0001_ECX] &= ~minus_features[FEAT_8000_0001_ECX];
1603 env->features[FEAT_C000_0001_EDX] &= ~minus_features[FEAT_C000_0001_EDX];
1604 env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
1605 env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
1606 env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
c6dc6f63 1607
a91987c2
IM
1608out:
1609 return;
c6dc6f63
AP
1610}
1611
1612/* generate a composite string into buf of all cpuid names in featureset
1613 * selected by fbits. indicate truncation at bufsize in the event of overflow.
1614 * if flags, suppress names undefined in featureset.
1615 */
1616static void listflags(char *buf, int bufsize, uint32_t fbits,
1617 const char **featureset, uint32_t flags)
1618{
1619 const char **p = &featureset[31];
1620 char *q, *b, bit;
1621 int nc;
1622
1623 b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1624 *buf = '\0';
1625 for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1626 if (fbits & 1 << bit && (*p || !flags)) {
1627 if (*p)
1628 nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1629 else
1630 nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1631 if (bufsize <= nc) {
1632 if (b) {
1633 memcpy(b, "...", sizeof("..."));
1634 }
1635 return;
1636 }
1637 q += nc;
1638 bufsize -= nc;
1639 }
1640}
1641
e916cbf8
PM
1642/* generate CPU information. */
1643void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
c6dc6f63 1644{
c6dc6f63
AP
1645 x86_def_t *def;
1646 char buf[256];
7fc9b714 1647 int i;
c6dc6f63 1648
7fc9b714
AF
1649 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1650 def = &builtin_x86_defs[i];
c04321b3 1651 snprintf(buf, sizeof(buf), "%s", def->name);
6cdf8854 1652 (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
c6dc6f63 1653 }
21ad7789
JK
1654#ifdef CONFIG_KVM
1655 (*cpu_fprintf)(f, "x86 %16s %-48s\n", "host",
1656 "KVM processor with all supported host features "
1657 "(only available in KVM mode)");
1658#endif
1659
6cdf8854 1660 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
3af60be2
JK
1661 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
1662 FeatureWordInfo *fw = &feature_word_info[i];
1663
1664 listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
1665 (*cpu_fprintf)(f, " %s\n", buf);
1666 }
c6dc6f63
AP
1667}
1668
76b64a7a 1669CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
e3966126
AL
1670{
1671 CpuDefinitionInfoList *cpu_list = NULL;
1672 x86_def_t *def;
7fc9b714 1673 int i;
e3966126 1674
7fc9b714 1675 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
e3966126
AL
1676 CpuDefinitionInfoList *entry;
1677 CpuDefinitionInfo *info;
1678
7fc9b714 1679 def = &builtin_x86_defs[i];
e3966126
AL
1680 info = g_malloc0(sizeof(*info));
1681 info->name = g_strdup(def->name);
1682
1683 entry = g_malloc0(sizeof(*entry));
1684 entry->value = info;
1685 entry->next = cpu_list;
1686 cpu_list = entry;
1687 }
1688
1689 return cpu_list;
1690}
1691
bc74b7db
EH
1692#ifdef CONFIG_KVM
1693static void filter_features_for_kvm(X86CPU *cpu)
1694{
1695 CPUX86State *env = &cpu->env;
1696 KVMState *s = kvm_state;
bd87d2a2 1697 FeatureWord w;
bc74b7db 1698
bd87d2a2
EH
1699 for (w = 0; w < FEATURE_WORDS; w++) {
1700 FeatureWordInfo *wi = &feature_word_info[w];
034acf4a
EH
1701 uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax,
1702 wi->cpuid_ecx,
1703 wi->cpuid_reg);
1704 uint32_t requested_features = env->features[w];
1705 env->features[w] &= host_feat;
1706 cpu->filtered_features[w] = requested_features & ~env->features[w];
bd87d2a2 1707 }
bc74b7db
EH
1708}
1709#endif
1710
2d64255b 1711static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
c6dc6f63 1712{
61dcd775 1713 CPUX86State *env = &cpu->env;
c6dc6f63
AP
1714 x86_def_t def1, *def = &def1;
1715
db0ad1ba
JR
1716 memset(def, 0, sizeof(*def));
1717
8f961357 1718 if (cpu_x86_find_by_name(def, name) < 0) {
2d64255b
AF
1719 error_setg(errp, "Unable to find CPU definition: %s", name);
1720 return;
8f961357
EH
1721 }
1722
aa87d458 1723 if (kvm_enabled()) {
0514ef2f 1724 def->features[FEAT_KVM] |= kvm_default_features;
aa87d458 1725 }
0514ef2f 1726 def->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
077c68c3 1727
2d64255b
AF
1728 object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp);
1729 object_property_set_int(OBJECT(cpu), def->level, "level", errp);
1730 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
1731 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
1732 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
0514ef2f
EH
1733 env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX];
1734 env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX];
1735 env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX];
1736 env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX];
2d64255b 1737 object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
0514ef2f
EH
1738 env->features[FEAT_KVM] = def->features[FEAT_KVM];
1739 env->features[FEAT_SVM] = def->features[FEAT_SVM];
1740 env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
1741 env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
b3baa152 1742 env->cpuid_xlevel2 = def->xlevel2;
3b671a40 1743
2d64255b 1744 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
c6dc6f63
AP
1745}
1746
62fc403f
IM
1747X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
1748 Error **errp)
5c3c6a68 1749{
2d64255b 1750 X86CPU *cpu = NULL;
5c3c6a68 1751 CPUX86State *env;
2d64255b
AF
1752 gchar **model_pieces;
1753 char *name, *features;
ba2bc7a4 1754 char *typename;
5c3c6a68
AF
1755 Error *error = NULL;
1756
2d64255b
AF
1757 model_pieces = g_strsplit(cpu_model, ",", 2);
1758 if (!model_pieces[0]) {
1759 error_setg(&error, "Invalid/empty CPU model name");
1760 goto out;
1761 }
1762 name = model_pieces[0];
1763 features = model_pieces[1];
1764
5c3c6a68 1765 cpu = X86_CPU(object_new(TYPE_X86_CPU));
62fc403f
IM
1766#ifndef CONFIG_USER_ONLY
1767 if (icc_bridge == NULL) {
1768 error_setg(&error, "Invalid icc-bridge value");
1769 goto out;
1770 }
1771 qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
1772 object_unref(OBJECT(cpu));
1773#endif
5c3c6a68
AF
1774 env = &cpu->env;
1775 env->cpu_model_str = cpu_model;
1776
2d64255b
AF
1777 cpu_x86_register(cpu, name, &error);
1778 if (error) {
1779 goto out;
1780 }
1781
ba2bc7a4
AF
1782 /* Emulate per-model subclasses for global properties */
1783 typename = g_strdup_printf("%s-" TYPE_X86_CPU, name);
1784 qdev_prop_set_globals_for_type(DEVICE(cpu), typename, &error);
1785 g_free(typename);
1786 if (error) {
1787 goto out;
1788 }
1789
2d64255b
AF
1790 cpu_x86_parse_featurestr(cpu, features, &error);
1791 if (error) {
1792 goto out;
5c3c6a68
AF
1793 }
1794
7f833247
IM
1795out:
1796 error_propagate(errp, error);
1797 g_strfreev(model_pieces);
1798 return cpu;
1799}
1800
1801X86CPU *cpu_x86_init(const char *cpu_model)
1802{
1803 Error *error = NULL;
1804 X86CPU *cpu;
1805
62fc403f 1806 cpu = cpu_x86_create(cpu_model, NULL, &error);
5c3c6a68 1807 if (error) {
2d64255b
AF
1808 goto out;
1809 }
1810
7f833247
IM
1811 object_property_set_bool(OBJECT(cpu), true, "realized", &error);
1812
2d64255b 1813out:
2d64255b
AF
1814 if (error) {
1815 fprintf(stderr, "%s\n", error_get_pretty(error));
5c3c6a68 1816 error_free(error);
2d64255b
AF
1817 if (cpu != NULL) {
1818 object_unref(OBJECT(cpu));
1819 cpu = NULL;
1820 }
5c3c6a68
AF
1821 }
1822 return cpu;
1823}
1824
c6dc6f63 1825#if !defined(CONFIG_USER_ONLY)
c6dc6f63 1826
0e26b7b8
BS
1827void cpu_clear_apic_feature(CPUX86State *env)
1828{
0514ef2f 1829 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
0e26b7b8
BS
1830}
1831
c6dc6f63
AP
1832#endif /* !CONFIG_USER_ONLY */
1833
c04321b3 1834/* Initialize list of CPU models, filling some non-static fields if necessary
c6dc6f63
AP
1835 */
1836void x86_cpudef_setup(void)
1837{
93bfef4c
CV
1838 int i, j;
1839 static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
c6dc6f63
AP
1840
1841 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
bc3e1291 1842 x86_def_t *def = &builtin_x86_defs[i];
93bfef4c
CV
1843
1844 /* Look for specific "cpudef" models that */
09faecf2 1845 /* have the QEMU version in .model_id */
93bfef4c 1846 for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
bc3e1291
EH
1847 if (strcmp(model_with_versions[j], def->name) == 0) {
1848 pstrcpy(def->model_id, sizeof(def->model_id),
1849 "QEMU Virtual CPU version ");
1850 pstrcat(def->model_id, sizeof(def->model_id),
1851 qemu_get_version());
93bfef4c
CV
1852 break;
1853 }
1854 }
c6dc6f63 1855 }
c6dc6f63
AP
1856}
1857
c6dc6f63
AP
1858static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
1859 uint32_t *ecx, uint32_t *edx)
1860{
1861 *ebx = env->cpuid_vendor1;
1862 *edx = env->cpuid_vendor2;
1863 *ecx = env->cpuid_vendor3;
c6dc6f63
AP
1864}
1865
1866void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1867 uint32_t *eax, uint32_t *ebx,
1868 uint32_t *ecx, uint32_t *edx)
1869{
a60f24b5
AF
1870 X86CPU *cpu = x86_env_get_cpu(env);
1871 CPUState *cs = CPU(cpu);
1872
c6dc6f63
AP
1873 /* test if maximum index reached */
1874 if (index & 0x80000000) {
b3baa152
BW
1875 if (index > env->cpuid_xlevel) {
1876 if (env->cpuid_xlevel2 > 0) {
1877 /* Handle the Centaur's CPUID instruction. */
1878 if (index > env->cpuid_xlevel2) {
1879 index = env->cpuid_xlevel2;
1880 } else if (index < 0xC0000000) {
1881 index = env->cpuid_xlevel;
1882 }
1883 } else {
57f26ae7
EH
1884 /* Intel documentation states that invalid EAX input will
1885 * return the same information as EAX=cpuid_level
1886 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
1887 */
1888 index = env->cpuid_level;
b3baa152
BW
1889 }
1890 }
c6dc6f63
AP
1891 } else {
1892 if (index > env->cpuid_level)
1893 index = env->cpuid_level;
1894 }
1895
1896 switch(index) {
1897 case 0:
1898 *eax = env->cpuid_level;
1899 get_cpuid_vendor(env, ebx, ecx, edx);
1900 break;
1901 case 1:
1902 *eax = env->cpuid_version;
1903 *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
0514ef2f
EH
1904 *ecx = env->features[FEAT_1_ECX];
1905 *edx = env->features[FEAT_1_EDX];
ce3960eb
AF
1906 if (cs->nr_cores * cs->nr_threads > 1) {
1907 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
c6dc6f63
AP
1908 *edx |= 1 << 28; /* HTT bit */
1909 }
1910 break;
1911 case 2:
1912 /* cache info: needed for Pentium Pro compatibility */
1913 *eax = 1;
1914 *ebx = 0;
1915 *ecx = 0;
1916 *edx = 0x2c307d;
1917 break;
1918 case 4:
1919 /* cache info: needed for Core compatibility */
ce3960eb
AF
1920 if (cs->nr_cores > 1) {
1921 *eax = (cs->nr_cores - 1) << 26;
c6dc6f63 1922 } else {
2f7a21c4 1923 *eax = 0;
c6dc6f63
AP
1924 }
1925 switch (count) {
1926 case 0: /* L1 dcache info */
1927 *eax |= 0x0000121;
1928 *ebx = 0x1c0003f;
1929 *ecx = 0x000003f;
1930 *edx = 0x0000001;
1931 break;
1932 case 1: /* L1 icache info */
1933 *eax |= 0x0000122;
1934 *ebx = 0x1c0003f;
1935 *ecx = 0x000003f;
1936 *edx = 0x0000001;
1937 break;
1938 case 2: /* L2 cache info */
1939 *eax |= 0x0000143;
ce3960eb
AF
1940 if (cs->nr_threads > 1) {
1941 *eax |= (cs->nr_threads - 1) << 14;
c6dc6f63
AP
1942 }
1943 *ebx = 0x3c0003f;
1944 *ecx = 0x0000fff;
1945 *edx = 0x0000001;
1946 break;
1947 default: /* end of info */
1948 *eax = 0;
1949 *ebx = 0;
1950 *ecx = 0;
1951 *edx = 0;
1952 break;
1953 }
1954 break;
1955 case 5:
1956 /* mwait info: needed for Core compatibility */
1957 *eax = 0; /* Smallest monitor-line size in bytes */
1958 *ebx = 0; /* Largest monitor-line size in bytes */
1959 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
1960 *edx = 0;
1961 break;
1962 case 6:
1963 /* Thermal and Power Leaf */
1964 *eax = 0;
1965 *ebx = 0;
1966 *ecx = 0;
1967 *edx = 0;
1968 break;
f7911686 1969 case 7:
13526728
EH
1970 /* Structured Extended Feature Flags Enumeration Leaf */
1971 if (count == 0) {
1972 *eax = 0; /* Maximum ECX value for sub-leaves */
0514ef2f 1973 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
13526728
EH
1974 *ecx = 0; /* Reserved */
1975 *edx = 0; /* Reserved */
f7911686
YW
1976 } else {
1977 *eax = 0;
1978 *ebx = 0;
1979 *ecx = 0;
1980 *edx = 0;
1981 }
1982 break;
c6dc6f63
AP
1983 case 9:
1984 /* Direct Cache Access Information Leaf */
1985 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
1986 *ebx = 0;
1987 *ecx = 0;
1988 *edx = 0;
1989 break;
1990 case 0xA:
1991 /* Architectural Performance Monitoring Leaf */
a0fa8208 1992 if (kvm_enabled()) {
a60f24b5 1993 KVMState *s = cs->kvm_state;
a0fa8208
GN
1994
1995 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
1996 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
1997 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
1998 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
1999 } else {
2000 *eax = 0;
2001 *ebx = 0;
2002 *ecx = 0;
2003 *edx = 0;
2004 }
c6dc6f63 2005 break;
51e49430
SY
2006 case 0xD:
2007 /* Processor Extended State */
0514ef2f 2008 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
51e49430
SY
2009 *eax = 0;
2010 *ebx = 0;
2011 *ecx = 0;
2012 *edx = 0;
2013 break;
2014 }
2015 if (kvm_enabled()) {
a60f24b5 2016 KVMState *s = cs->kvm_state;
ba9bc59e
JK
2017
2018 *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX);
2019 *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX);
2020 *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX);
2021 *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX);
51e49430
SY
2022 } else {
2023 *eax = 0;
2024 *ebx = 0;
2025 *ecx = 0;
2026 *edx = 0;
2027 }
2028 break;
c6dc6f63
AP
2029 case 0x80000000:
2030 *eax = env->cpuid_xlevel;
2031 *ebx = env->cpuid_vendor1;
2032 *edx = env->cpuid_vendor2;
2033 *ecx = env->cpuid_vendor3;
2034 break;
2035 case 0x80000001:
2036 *eax = env->cpuid_version;
2037 *ebx = 0;
0514ef2f
EH
2038 *ecx = env->features[FEAT_8000_0001_ECX];
2039 *edx = env->features[FEAT_8000_0001_EDX];
c6dc6f63
AP
2040
2041 /* The Linux kernel checks for the CMPLegacy bit and
2042 * discards multiple thread information if it is set.
2043 * So dont set it here for Intel to make Linux guests happy.
2044 */
ce3960eb 2045 if (cs->nr_cores * cs->nr_threads > 1) {
c6dc6f63
AP
2046 uint32_t tebx, tecx, tedx;
2047 get_cpuid_vendor(env, &tebx, &tecx, &tedx);
2048 if (tebx != CPUID_VENDOR_INTEL_1 ||
2049 tedx != CPUID_VENDOR_INTEL_2 ||
2050 tecx != CPUID_VENDOR_INTEL_3) {
2051 *ecx |= 1 << 1; /* CmpLegacy bit */
2052 }
2053 }
c6dc6f63
AP
2054 break;
2055 case 0x80000002:
2056 case 0x80000003:
2057 case 0x80000004:
2058 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2059 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2060 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2061 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2062 break;
2063 case 0x80000005:
2064 /* cache info (L1 cache) */
2065 *eax = 0x01ff01ff;
2066 *ebx = 0x01ff01ff;
2067 *ecx = 0x40020140;
2068 *edx = 0x40020140;
2069 break;
2070 case 0x80000006:
2071 /* cache info (L2 cache) */
2072 *eax = 0;
2073 *ebx = 0x42004200;
2074 *ecx = 0x02008140;
2075 *edx = 0;
2076 break;
2077 case 0x80000008:
2078 /* virtual & phys address size in low 2 bytes. */
2079/* XXX: This value must match the one used in the MMU code. */
0514ef2f 2080 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
c6dc6f63
AP
2081 /* 64 bit processor */
2082/* XXX: The physical address space is limited to 42 bits in exec.c. */
dd13e088 2083 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
c6dc6f63 2084 } else {
0514ef2f 2085 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
c6dc6f63 2086 *eax = 0x00000024; /* 36 bits physical */
dd13e088 2087 } else {
c6dc6f63 2088 *eax = 0x00000020; /* 32 bits physical */
dd13e088 2089 }
c6dc6f63
AP
2090 }
2091 *ebx = 0;
2092 *ecx = 0;
2093 *edx = 0;
ce3960eb
AF
2094 if (cs->nr_cores * cs->nr_threads > 1) {
2095 *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
c6dc6f63
AP
2096 }
2097 break;
2098 case 0x8000000A:
0514ef2f 2099 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
9f3fb565
EH
2100 *eax = 0x00000001; /* SVM Revision */
2101 *ebx = 0x00000010; /* nr of ASIDs */
2102 *ecx = 0;
0514ef2f 2103 *edx = env->features[FEAT_SVM]; /* optional features */
9f3fb565
EH
2104 } else {
2105 *eax = 0;
2106 *ebx = 0;
2107 *ecx = 0;
2108 *edx = 0;
2109 }
c6dc6f63 2110 break;
b3baa152
BW
2111 case 0xC0000000:
2112 *eax = env->cpuid_xlevel2;
2113 *ebx = 0;
2114 *ecx = 0;
2115 *edx = 0;
2116 break;
2117 case 0xC0000001:
2118 /* Support for VIA CPU's CPUID instruction */
2119 *eax = env->cpuid_version;
2120 *ebx = 0;
2121 *ecx = 0;
0514ef2f 2122 *edx = env->features[FEAT_C000_0001_EDX];
b3baa152
BW
2123 break;
2124 case 0xC0000002:
2125 case 0xC0000003:
2126 case 0xC0000004:
2127 /* Reserved for the future, and now filled with zero */
2128 *eax = 0;
2129 *ebx = 0;
2130 *ecx = 0;
2131 *edx = 0;
2132 break;
c6dc6f63
AP
2133 default:
2134 /* reserved values: zero */
2135 *eax = 0;
2136 *ebx = 0;
2137 *ecx = 0;
2138 *edx = 0;
2139 break;
2140 }
2141}
5fd2087a
AF
2142
2143/* CPUClass::reset() */
2144static void x86_cpu_reset(CPUState *s)
2145{
2146 X86CPU *cpu = X86_CPU(s);
2147 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2148 CPUX86State *env = &cpu->env;
c1958aea
AF
2149 int i;
2150
2151 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
55e5c285 2152 qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
6fd2a026 2153 log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP);
c1958aea 2154 }
5fd2087a
AF
2155
2156 xcc->parent_reset(s);
2157
c1958aea
AF
2158
2159 memset(env, 0, offsetof(CPUX86State, breakpoints));
2160
2161 tlb_flush(env, 1);
2162
2163 env->old_exception = -1;
2164
2165 /* init to reset state */
2166
2167#ifdef CONFIG_SOFTMMU
2168 env->hflags |= HF_SOFTMMU_MASK;
2169#endif
2170 env->hflags2 |= HF2_GIF_MASK;
2171
2172 cpu_x86_update_cr0(env, 0x60000010);
2173 env->a20_mask = ~0x0;
2174 env->smbase = 0x30000;
2175
2176 env->idt.limit = 0xffff;
2177 env->gdt.limit = 0xffff;
2178 env->ldt.limit = 0xffff;
2179 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2180 env->tr.limit = 0xffff;
2181 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2182
2183 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2184 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2185 DESC_R_MASK | DESC_A_MASK);
2186 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2187 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2188 DESC_A_MASK);
2189 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
2190 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2191 DESC_A_MASK);
2192 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
2193 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2194 DESC_A_MASK);
2195 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
2196 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2197 DESC_A_MASK);
2198 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
2199 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2200 DESC_A_MASK);
2201
2202 env->eip = 0xfff0;
2203 env->regs[R_EDX] = env->cpuid_version;
2204
2205 env->eflags = 0x2;
2206
2207 /* FPU init */
2208 for (i = 0; i < 8; i++) {
2209 env->fptags[i] = 1;
2210 }
2211 env->fpuc = 0x37f;
2212
2213 env->mxcsr = 0x1f80;
2214
2215 env->pat = 0x0007040600070406ULL;
2216 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2217
2218 memset(env->dr, 0, sizeof(env->dr));
2219 env->dr[6] = DR6_FIXED_1;
2220 env->dr[7] = DR7_FIXED_1;
2221 cpu_breakpoint_remove_all(env, BP_CPU);
2222 cpu_watchpoint_remove_all(env, BP_CPU);
dd673288
IM
2223
2224#if !defined(CONFIG_USER_ONLY)
2225 /* We hard-wire the BSP to the first CPU. */
55e5c285 2226 if (s->cpu_index == 0) {
dd673288
IM
2227 apic_designate_bsp(env->apic_state);
2228 }
2229
259186a7 2230 s->halted = !cpu_is_bsp(cpu);
dd673288 2231#endif
5fd2087a
AF
2232}
2233
dd673288
IM
2234#ifndef CONFIG_USER_ONLY
2235bool cpu_is_bsp(X86CPU *cpu)
2236{
2237 return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP;
2238}
65dee380
IM
2239
2240/* TODO: remove me, when reset over QOM tree is implemented */
2241static void x86_cpu_machine_reset_cb(void *opaque)
2242{
2243 X86CPU *cpu = opaque;
2244 cpu_reset(CPU(cpu));
2245}
dd673288
IM
2246#endif
2247
de024815
AF
2248static void mce_init(X86CPU *cpu)
2249{
2250 CPUX86State *cenv = &cpu->env;
2251 unsigned int bank;
2252
2253 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
0514ef2f 2254 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
de024815
AF
2255 (CPUID_MCE | CPUID_MCA)) {
2256 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2257 cenv->mcg_ctl = ~(uint64_t)0;
2258 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2259 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2260 }
2261 }
2262}
2263
bdeec802 2264#ifndef CONFIG_USER_ONLY
d3c64d6a 2265static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
bdeec802 2266{
bdeec802 2267 CPUX86State *env = &cpu->env;
53a89e26 2268 DeviceState *dev = DEVICE(cpu);
449994eb 2269 APICCommonState *apic;
bdeec802
IM
2270 const char *apic_type = "apic";
2271
2272 if (kvm_irqchip_in_kernel()) {
2273 apic_type = "kvm-apic";
2274 } else if (xen_enabled()) {
2275 apic_type = "xen-apic";
2276 }
2277
53a89e26 2278 env->apic_state = qdev_try_create(qdev_get_parent_bus(dev), apic_type);
bdeec802
IM
2279 if (env->apic_state == NULL) {
2280 error_setg(errp, "APIC device '%s' could not be created", apic_type);
2281 return;
2282 }
2283
2284 object_property_add_child(OBJECT(cpu), "apic",
2285 OBJECT(env->apic_state), NULL);
2286 qdev_prop_set_uint8(env->apic_state, "id", env->cpuid_apic_id);
2287 /* TODO: convert to link<> */
449994eb 2288 apic = APIC_COMMON(env->apic_state);
60671e58 2289 apic->cpu = cpu;
d3c64d6a
IM
2290}
2291
2292static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2293{
2294 CPUX86State *env = &cpu->env;
d3c64d6a
IM
2295
2296 if (env->apic_state == NULL) {
2297 return;
2298 }
bdeec802
IM
2299
2300 if (qdev_init(env->apic_state)) {
2301 error_setg(errp, "APIC device '%s' could not be initialized",
2302 object_get_typename(OBJECT(env->apic_state)));
2303 return;
2304 }
bdeec802 2305}
d3c64d6a
IM
2306#else
2307static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2308{
2309}
bdeec802
IM
2310#endif
2311
2b6f294c 2312static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
7a059953 2313{
2b6f294c
AF
2314 X86CPU *cpu = X86_CPU(dev);
2315 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
b34d12d1 2316 CPUX86State *env = &cpu->env;
2b6f294c 2317 Error *local_err = NULL;
b34d12d1 2318
0514ef2f 2319 if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
b34d12d1
IM
2320 env->cpuid_level = 7;
2321 }
7a059953 2322
9b15cd9e
IM
2323 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
2324 * CPUID[1].EDX.
2325 */
2326 if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
2327 env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
2328 env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
0514ef2f
EH
2329 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
2330 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
9b15cd9e
IM
2331 & CPUID_EXT2_AMD_ALIASES);
2332 }
2333
4586f157 2334 if (!kvm_enabled()) {
0514ef2f
EH
2335 env->features[FEAT_1_EDX] &= TCG_FEATURES;
2336 env->features[FEAT_1_ECX] &= TCG_EXT_FEATURES;
2337 env->features[FEAT_8000_0001_EDX] &= (TCG_EXT2_FEATURES
4586f157
IM
2338#ifdef TARGET_X86_64
2339 | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
2340#endif
2341 );
0514ef2f
EH
2342 env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES;
2343 env->features[FEAT_SVM] &= TCG_SVM_FEATURES;
4586f157 2344 } else {
5ec01c2e
IM
2345 if (check_cpuid && kvm_check_features_against_host(cpu)
2346 && enforce_cpuid) {
4dc1f449
IM
2347 error_setg(&local_err,
2348 "Host's CPU doesn't support requested features");
2349 goto out;
5ec01c2e 2350 }
a509d632
EH
2351#ifdef CONFIG_KVM
2352 filter_features_for_kvm(cpu);
2353#endif
4586f157
IM
2354 }
2355
65dee380
IM
2356#ifndef CONFIG_USER_ONLY
2357 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
bdeec802 2358
0514ef2f 2359 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
d3c64d6a 2360 x86_cpu_apic_create(cpu, &local_err);
2b6f294c 2361 if (local_err != NULL) {
4dc1f449 2362 goto out;
bdeec802
IM
2363 }
2364 }
65dee380
IM
2365#endif
2366
7a059953
AF
2367 mce_init(cpu);
2368 qemu_init_vcpu(&cpu->env);
d3c64d6a
IM
2369
2370 x86_cpu_apic_realize(cpu, &local_err);
2371 if (local_err != NULL) {
2372 goto out;
2373 }
65dee380 2374 cpu_reset(CPU(cpu));
2b6f294c 2375
4dc1f449
IM
2376 xcc->parent_realize(dev, &local_err);
2377out:
2378 if (local_err != NULL) {
2379 error_propagate(errp, local_err);
2380 return;
2381 }
7a059953
AF
2382}
2383
8932cfdf
EH
2384/* Enables contiguous-apic-ID mode, for compatibility */
2385static bool compat_apic_id_mode;
2386
2387void enable_compat_apic_id_mode(void)
2388{
2389 compat_apic_id_mode = true;
2390}
2391
cb41bad3
EH
2392/* Calculates initial APIC ID for a specific CPU index
2393 *
2394 * Currently we need to be able to calculate the APIC ID from the CPU index
2395 * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
2396 * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
2397 * all CPUs up to max_cpus.
2398 */
2399uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
2400{
8932cfdf
EH
2401 uint32_t correct_id;
2402 static bool warned;
2403
2404 correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
2405 if (compat_apic_id_mode) {
2406 if (cpu_index != correct_id && !warned) {
2407 error_report("APIC IDs set in compatibility mode, "
2408 "CPU topology won't match the configuration");
2409 warned = true;
2410 }
2411 return cpu_index;
2412 } else {
2413 return correct_id;
2414 }
cb41bad3
EH
2415}
2416
de024815
AF
2417static void x86_cpu_initfn(Object *obj)
2418{
55e5c285 2419 CPUState *cs = CPU(obj);
de024815
AF
2420 X86CPU *cpu = X86_CPU(obj);
2421 CPUX86State *env = &cpu->env;
d65e9815 2422 static int inited;
de024815 2423
c05efcb1 2424 cs->env_ptr = env;
de024815 2425 cpu_exec_init(env);
71ad61d3
AF
2426
2427 object_property_add(obj, "family", "int",
95b8519d 2428 x86_cpuid_version_get_family,
71ad61d3 2429 x86_cpuid_version_set_family, NULL, NULL, NULL);
c5291a4f 2430 object_property_add(obj, "model", "int",
67e30c83 2431 x86_cpuid_version_get_model,
c5291a4f 2432 x86_cpuid_version_set_model, NULL, NULL, NULL);
036e2222 2433 object_property_add(obj, "stepping", "int",
35112e41 2434 x86_cpuid_version_get_stepping,
036e2222 2435 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
8e1898bf
AF
2436 object_property_add(obj, "level", "int",
2437 x86_cpuid_get_level,
2438 x86_cpuid_set_level, NULL, NULL, NULL);
16b93aa8
AF
2439 object_property_add(obj, "xlevel", "int",
2440 x86_cpuid_get_xlevel,
2441 x86_cpuid_set_xlevel, NULL, NULL, NULL);
d480e1af
AF
2442 object_property_add_str(obj, "vendor",
2443 x86_cpuid_get_vendor,
2444 x86_cpuid_set_vendor, NULL);
938d4c25 2445 object_property_add_str(obj, "model-id",
63e886eb 2446 x86_cpuid_get_model_id,
938d4c25 2447 x86_cpuid_set_model_id, NULL);
89e48965
AF
2448 object_property_add(obj, "tsc-frequency", "int",
2449 x86_cpuid_get_tsc_freq,
2450 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
31050930
IM
2451 object_property_add(obj, "apic-id", "int",
2452 x86_cpuid_get_apic_id,
2453 x86_cpuid_set_apic_id, NULL, NULL, NULL);
8e8aba50
EH
2454 object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
2455 x86_cpu_get_feature_words,
7e5292b5
EH
2456 NULL, NULL, (void *)env->features, NULL);
2457 object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
2458 x86_cpu_get_feature_words,
2459 NULL, NULL, (void *)cpu->filtered_features, NULL);
71ad61d3 2460
cb41bad3 2461 env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
d65e9815
IM
2462
2463 /* init various static tables used in TCG mode */
2464 if (tcg_enabled() && !inited) {
2465 inited = 1;
2466 optimize_flags_init();
2467#ifndef CONFIG_USER_ONLY
2468 cpu_set_debug_excp_handler(breakpoint_handler);
2469#endif
2470 }
de024815
AF
2471}
2472
997395d3
IM
2473static int64_t x86_cpu_get_arch_id(CPUState *cs)
2474{
2475 X86CPU *cpu = X86_CPU(cs);
2476 CPUX86State *env = &cpu->env;
2477
2478 return env->cpuid_apic_id;
2479}
2480
5fd2087a
AF
2481static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
2482{
2483 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2484 CPUClass *cc = CPU_CLASS(oc);
2b6f294c
AF
2485 DeviceClass *dc = DEVICE_CLASS(oc);
2486
2487 xcc->parent_realize = dc->realize;
2488 dc->realize = x86_cpu_realizefn;
62fc403f 2489 dc->bus_type = TYPE_ICC_BUS;
5fd2087a
AF
2490
2491 xcc->parent_reset = cc->reset;
2492 cc->reset = x86_cpu_reset;
f56e3a14 2493
97a8ea5a 2494 cc->do_interrupt = x86_cpu_do_interrupt;
c72bf468
JF
2495#ifndef CONFIG_USER_ONLY
2496 cc->write_elf64_note = x86_cpu_write_elf64_note;
2497 cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
2498 cc->write_elf32_note = x86_cpu_write_elf32_note;
2499 cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
2500#endif
f56e3a14 2501 cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
997395d3
IM
2502
2503 cc->get_arch_id = x86_cpu_get_arch_id;
5fd2087a
AF
2504}
2505
2506static const TypeInfo x86_cpu_type_info = {
2507 .name = TYPE_X86_CPU,
2508 .parent = TYPE_CPU,
2509 .instance_size = sizeof(X86CPU),
de024815 2510 .instance_init = x86_cpu_initfn,
5fd2087a
AF
2511 .abstract = false,
2512 .class_size = sizeof(X86CPUClass),
2513 .class_init = x86_cpu_common_class_init,
2514};
2515
2516static void x86_cpu_register_types(void)
2517{
2518 type_register_static(&x86_cpu_type_info);
2519}
2520
2521type_init(x86_cpu_register_types)