]> git.proxmox.com Git - mirror_qemu.git/blame - target-i386/cpu.c
target-i386: Introduce generic CPUID feature compat function
[mirror_qemu.git] / target-i386 / cpu.c
CommitLineData
c6dc6f63
AP
1/*
2 * i386 CPUID helper functions
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19#include <stdlib.h>
20#include <stdio.h>
21#include <string.h>
22#include <inttypes.h>
23
24#include "cpu.h"
9c17d615 25#include "sysemu/kvm.h"
8932cfdf
EH
26#include "sysemu/cpus.h"
27#include "topology.h"
c6dc6f63 28
1de7afc9
PB
29#include "qemu/option.h"
30#include "qemu/config-file.h"
7b1b5d19 31#include "qapi/qmp/qerror.h"
c6dc6f63 32
8e8aba50
EH
33#include "qapi-types.h"
34#include "qapi-visit.h"
7b1b5d19 35#include "qapi/visitor.h"
9c17d615 36#include "sysemu/arch_init.h"
71ad61d3 37
28f52cc0
VR
38#include "hyperv.h"
39
65dee380 40#include "hw/hw.h"
b834b508 41#if defined(CONFIG_KVM)
ef8621b1 42#include <linux/kvm_para.h>
b834b508 43#endif
65dee380 44
9c17d615 45#include "sysemu/sysemu.h"
53a89e26 46#include "hw/qdev-properties.h"
62fc403f 47#include "hw/cpu/icc_bus.h"
bdeec802 48#ifndef CONFIG_USER_ONLY
0d09e41a 49#include "hw/xen/xen.h"
0d09e41a 50#include "hw/i386/apic_internal.h"
bdeec802
IM
51#endif
52
99b88a17
IM
53static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
54 uint32_t vendor2, uint32_t vendor3)
55{
56 int i;
57 for (i = 0; i < 4; i++) {
58 dst[i] = vendor1 >> (8 * i);
59 dst[i + 4] = vendor2 >> (8 * i);
60 dst[i + 8] = vendor3 >> (8 * i);
61 }
62 dst[CPUID_VENDOR_SZ] = '\0';
63}
64
c6dc6f63
AP
65/* feature flags taken from "Intel Processor Identification and the CPUID
66 * Instruction" and AMD's "CPUID Specification". In cases of disagreement
67 * between feature naming conventions, aliases may be added.
68 */
69static const char *feature_name[] = {
70 "fpu", "vme", "de", "pse",
71 "tsc", "msr", "pae", "mce",
72 "cx8", "apic", NULL, "sep",
73 "mtrr", "pge", "mca", "cmov",
74 "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
75 NULL, "ds" /* Intel dts */, "acpi", "mmx",
76 "fxsr", "sse", "sse2", "ss",
77 "ht" /* Intel htt */, "tm", "ia64", "pbe",
78};
79static const char *ext_feature_name[] = {
f370be3c 80 "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
e117f772 81 "ds_cpl", "vmx", "smx", "est",
c6dc6f63 82 "tm2", "ssse3", "cid", NULL,
e117f772 83 "fma", "cx16", "xtpr", "pdcm",
434acb81 84 NULL, "pcid", "dca", "sse4.1|sse4_1",
e117f772 85 "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
eaf3f097 86 "tsc-deadline", "aes", "xsave", "osxsave",
c8acc380 87 "avx", "f16c", "rdrand", "hypervisor",
c6dc6f63 88};
3b671a40
EH
89/* Feature names that are already defined on feature_name[] but are set on
90 * CPUID[8000_0001].EDX on AMD CPUs don't have their names on
91 * ext2_feature_name[]. They are copied automatically to cpuid_ext2_features
92 * if and only if CPU vendor is AMD.
93 */
c6dc6f63 94static const char *ext2_feature_name[] = {
3b671a40
EH
95 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
96 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
97 NULL /* cx8 */ /* AMD CMPXCHG8B */, NULL /* apic */, NULL, "syscall",
98 NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
99 NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
100 "nx|xd", NULL, "mmxext", NULL /* mmx */,
101 NULL /* fxsr */, "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
01f590d5 102 NULL, "lm|i64", "3dnowext", "3dnow",
c6dc6f63
AP
103};
104static const char *ext3_feature_name[] = {
105 "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
106 "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
e117f772 107 "3dnowprefetch", "osvw", "ibs", "xop",
c8acc380
AP
108 "skinit", "wdt", NULL, "lwp",
109 "fma4", "tce", NULL, "nodeid_msr",
110 NULL, "tbm", "topoext", "perfctr_core",
111 "perfctr_nb", NULL, NULL, NULL,
c6dc6f63
AP
112 NULL, NULL, NULL, NULL,
113};
114
89e49c8b
EH
115static const char *ext4_feature_name[] = {
116 NULL, NULL, "xstore", "xstore-en",
117 NULL, NULL, "xcrypt", "xcrypt-en",
118 "ace2", "ace2-en", "phe", "phe-en",
119 "pmm", "pmm-en", NULL, NULL,
120 NULL, NULL, NULL, NULL,
121 NULL, NULL, NULL, NULL,
122 NULL, NULL, NULL, NULL,
123 NULL, NULL, NULL, NULL,
124};
125
c6dc6f63 126static const char *kvm_feature_name[] = {
c3d39807
DS
127 "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock",
128 "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", NULL,
129 NULL, NULL, NULL, NULL,
130 NULL, NULL, NULL, NULL,
131 NULL, NULL, NULL, NULL,
132 NULL, NULL, NULL, NULL,
133 NULL, NULL, NULL, NULL,
134 NULL, NULL, NULL, NULL,
c6dc6f63
AP
135};
136
296acb64
JR
137static const char *svm_feature_name[] = {
138 "npt", "lbrv", "svm_lock", "nrip_save",
139 "tsc_scale", "vmcb_clean", "flushbyasid", "decodeassists",
140 NULL, NULL, "pause_filter", NULL,
141 "pfthreshold", NULL, NULL, NULL,
142 NULL, NULL, NULL, NULL,
143 NULL, NULL, NULL, NULL,
144 NULL, NULL, NULL, NULL,
145 NULL, NULL, NULL, NULL,
146};
147
a9321a4d 148static const char *cpuid_7_0_ebx_feature_name[] = {
811a8ae0
EH
149 "fsgsbase", NULL, NULL, "bmi1", "hle", "avx2", NULL, "smep",
150 "bmi2", "erms", "invpcid", "rtm", NULL, NULL, NULL, NULL,
c8acc380 151 NULL, NULL, "rdseed", "adx", "smap", NULL, NULL, NULL,
a9321a4d
PA
152 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
153};
154
5ef57876
EH
155typedef struct FeatureWordInfo {
156 const char **feat_names;
04d104b6
EH
157 uint32_t cpuid_eax; /* Input EAX for CPUID */
158 bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
159 uint32_t cpuid_ecx; /* Input ECX value for CPUID */
160 int cpuid_reg; /* output register (R_* constant) */
5ef57876
EH
161} FeatureWordInfo;
162
163static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
bffd67b0
EH
164 [FEAT_1_EDX] = {
165 .feat_names = feature_name,
166 .cpuid_eax = 1, .cpuid_reg = R_EDX,
167 },
168 [FEAT_1_ECX] = {
169 .feat_names = ext_feature_name,
170 .cpuid_eax = 1, .cpuid_reg = R_ECX,
171 },
172 [FEAT_8000_0001_EDX] = {
173 .feat_names = ext2_feature_name,
174 .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX,
175 },
176 [FEAT_8000_0001_ECX] = {
177 .feat_names = ext3_feature_name,
178 .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
179 },
89e49c8b
EH
180 [FEAT_C000_0001_EDX] = {
181 .feat_names = ext4_feature_name,
182 .cpuid_eax = 0xC0000001, .cpuid_reg = R_EDX,
183 },
bffd67b0
EH
184 [FEAT_KVM] = {
185 .feat_names = kvm_feature_name,
186 .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
187 },
188 [FEAT_SVM] = {
189 .feat_names = svm_feature_name,
190 .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
191 },
192 [FEAT_7_0_EBX] = {
193 .feat_names = cpuid_7_0_ebx_feature_name,
04d104b6
EH
194 .cpuid_eax = 7,
195 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
196 .cpuid_reg = R_EBX,
bffd67b0 197 },
5ef57876
EH
198};
199
8e8aba50
EH
200typedef struct X86RegisterInfo32 {
201 /* Name of register */
202 const char *name;
203 /* QAPI enum value register */
204 X86CPURegister32 qapi_enum;
205} X86RegisterInfo32;
206
207#define REGISTER(reg) \
208 [R_##reg] = { .name = #reg, .qapi_enum = X86_C_P_U_REGISTER32_##reg }
209X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
210 REGISTER(EAX),
211 REGISTER(ECX),
212 REGISTER(EDX),
213 REGISTER(EBX),
214 REGISTER(ESP),
215 REGISTER(EBP),
216 REGISTER(ESI),
217 REGISTER(EDI),
218};
219#undef REGISTER
220
221
8b4beddc
EH
222const char *get_register_name_32(unsigned int reg)
223{
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 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 |
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
0668af54
EH
974/**
975 * x86_cpu_compat_set_features:
976 * @cpu_model: CPU model name to be changed. If NULL, all CPU models are changed
977 * @w: Identifies the feature word to be changed.
978 * @feat_add: Feature bits to be added to feature word
979 * @feat_remove: Feature bits to be removed from feature word
980 *
981 * Change CPU model feature bits for compatibility.
982 *
983 * This function may be used by machine-type compatibility functions
984 * to enable or disable feature bits on specific CPU models.
985 */
986void x86_cpu_compat_set_features(const char *cpu_model, FeatureWord w,
987 uint32_t feat_add, uint32_t feat_remove)
988{
989 x86_def_t *def;
990 int i;
991 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
992 def = &builtin_x86_defs[i];
993 if (!cpu_model || !strcmp(cpu_model, def->name)) {
994 def->features[w] |= feat_add;
995 def->features[w] &= ~feat_remove;
996 }
997 }
998}
999
e4ab0d6b 1000#ifdef CONFIG_KVM
c6dc6f63
AP
1001static int cpu_x86_fill_model_id(char *str)
1002{
1003 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1004 int i;
1005
1006 for (i = 0; i < 3; i++) {
1007 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
1008 memcpy(str + i * 16 + 0, &eax, 4);
1009 memcpy(str + i * 16 + 4, &ebx, 4);
1010 memcpy(str + i * 16 + 8, &ecx, 4);
1011 memcpy(str + i * 16 + 12, &edx, 4);
1012 }
1013 return 0;
1014}
e4ab0d6b 1015#endif
c6dc6f63 1016
6e746f30
EH
1017/* Fill a x86_def_t struct with information about the host CPU, and
1018 * the CPU features supported by the host hardware + host kernel
1019 *
1020 * This function may be called only if KVM is enabled.
1021 */
1022static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
c6dc6f63 1023{
e4ab0d6b 1024#ifdef CONFIG_KVM
12869995 1025 KVMState *s = kvm_state;
c6dc6f63
AP
1026 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1027
6e746f30
EH
1028 assert(kvm_enabled());
1029
c6dc6f63
AP
1030 x86_cpu_def->name = "host";
1031 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
99b88a17 1032 x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
c6dc6f63
AP
1033
1034 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
1035 x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1036 x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1037 x86_cpu_def->stepping = eax & 0x0F;
c6dc6f63 1038
12869995 1039 x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
0514ef2f 1040 x86_cpu_def->features[FEAT_1_EDX] =
27861ecc 1041 kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX);
0514ef2f 1042 x86_cpu_def->features[FEAT_1_ECX] =
27861ecc 1043 kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX);
c6dc6f63 1044
6e746f30 1045 if (x86_cpu_def->level >= 7) {
0514ef2f 1046 x86_cpu_def->features[FEAT_7_0_EBX] =
12869995 1047 kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX);
13526728 1048 } else {
0514ef2f 1049 x86_cpu_def->features[FEAT_7_0_EBX] = 0;
13526728
EH
1050 }
1051
12869995 1052 x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
0514ef2f 1053 x86_cpu_def->features[FEAT_8000_0001_EDX] =
12869995 1054 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
0514ef2f 1055 x86_cpu_def->features[FEAT_8000_0001_ECX] =
12869995 1056 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
c6dc6f63 1057
c6dc6f63 1058 cpu_x86_fill_model_id(x86_cpu_def->model_id);
c6dc6f63 1059
b3baa152 1060 /* Call Centaur's CPUID instruction. */
99b88a17 1061 if (!strcmp(x86_cpu_def->vendor, CPUID_VENDOR_VIA)) {
b3baa152 1062 host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
12869995 1063 eax = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
b3baa152
BW
1064 if (eax >= 0xC0000001) {
1065 /* Support VIA max extended level */
1066 x86_cpu_def->xlevel2 = eax;
1067 host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
0514ef2f 1068 x86_cpu_def->features[FEAT_C000_0001_EDX] =
12869995 1069 kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
b3baa152
BW
1070 }
1071 }
296acb64 1072
fcb93c03 1073 /* Other KVM-specific feature fields: */
0514ef2f 1074 x86_cpu_def->features[FEAT_SVM] =
fcb93c03 1075 kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
0514ef2f 1076 x86_cpu_def->features[FEAT_KVM] =
bd004bef 1077 kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
fcb93c03 1078
e4ab0d6b 1079#endif /* CONFIG_KVM */
c6dc6f63
AP
1080}
1081
bffd67b0 1082static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask)
c6dc6f63
AP
1083{
1084 int i;
1085
1086 for (i = 0; i < 32; ++i)
1087 if (1 << i & mask) {
bffd67b0 1088 const char *reg = get_register_name_32(f->cpuid_reg);
8b4beddc
EH
1089 assert(reg);
1090 fprintf(stderr, "warning: host doesn't support requested feature: "
1091 "CPUID.%02XH:%s%s%s [bit %d]\n",
bffd67b0
EH
1092 f->cpuid_eax, reg,
1093 f->feat_names[i] ? "." : "",
1094 f->feat_names[i] ? f->feat_names[i] : "", i);
c6dc6f63
AP
1095 break;
1096 }
1097 return 0;
1098}
1099
07ca5945
EH
1100/* Check if all requested cpu flags are making their way to the guest
1101 *
1102 * Returns 0 if all flags are supported by the host, non-zero otherwise.
6e746f30
EH
1103 *
1104 * This function may be called only if KVM is enabled.
c6dc6f63 1105 */
5ec01c2e 1106static int kvm_check_features_against_host(X86CPU *cpu)
c6dc6f63 1107{
5ec01c2e 1108 CPUX86State *env = &cpu->env;
c6dc6f63
AP
1109 x86_def_t host_def;
1110 uint32_t mask;
1111 int rv, i;
1112 struct model_features_t ft[] = {
0514ef2f
EH
1113 {&env->features[FEAT_1_EDX],
1114 &host_def.features[FEAT_1_EDX],
bffd67b0 1115 FEAT_1_EDX },
0514ef2f
EH
1116 {&env->features[FEAT_1_ECX],
1117 &host_def.features[FEAT_1_ECX],
bffd67b0 1118 FEAT_1_ECX },
0514ef2f
EH
1119 {&env->features[FEAT_8000_0001_EDX],
1120 &host_def.features[FEAT_8000_0001_EDX],
bffd67b0 1121 FEAT_8000_0001_EDX },
0514ef2f
EH
1122 {&env->features[FEAT_8000_0001_ECX],
1123 &host_def.features[FEAT_8000_0001_ECX],
bffd67b0 1124 FEAT_8000_0001_ECX },
0514ef2f
EH
1125 {&env->features[FEAT_C000_0001_EDX],
1126 &host_def.features[FEAT_C000_0001_EDX],
07ca5945 1127 FEAT_C000_0001_EDX },
0514ef2f
EH
1128 {&env->features[FEAT_7_0_EBX],
1129 &host_def.features[FEAT_7_0_EBX],
07ca5945 1130 FEAT_7_0_EBX },
0514ef2f
EH
1131 {&env->features[FEAT_SVM],
1132 &host_def.features[FEAT_SVM],
07ca5945 1133 FEAT_SVM },
0514ef2f
EH
1134 {&env->features[FEAT_KVM],
1135 &host_def.features[FEAT_KVM],
07ca5945 1136 FEAT_KVM },
8b4beddc 1137 };
c6dc6f63 1138
6e746f30
EH
1139 assert(kvm_enabled());
1140
1141 kvm_cpu_fill_host(&host_def);
bffd67b0
EH
1142 for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i) {
1143 FeatureWord w = ft[i].feat_word;
1144 FeatureWordInfo *wi = &feature_word_info[w];
1145 for (mask = 1; mask; mask <<= 1) {
e8beac00 1146 if (*ft[i].guest_feat & mask &&
c6dc6f63 1147 !(*ft[i].host_feat & mask)) {
bffd67b0
EH
1148 unavailable_host_feature(wi, mask);
1149 rv = 1;
1150 }
1151 }
1152 }
c6dc6f63
AP
1153 return rv;
1154}
1155
95b8519d
AF
1156static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
1157 const char *name, Error **errp)
1158{
1159 X86CPU *cpu = X86_CPU(obj);
1160 CPUX86State *env = &cpu->env;
1161 int64_t value;
1162
1163 value = (env->cpuid_version >> 8) & 0xf;
1164 if (value == 0xf) {
1165 value += (env->cpuid_version >> 20) & 0xff;
1166 }
1167 visit_type_int(v, &value, name, errp);
1168}
1169
71ad61d3
AF
1170static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
1171 const char *name, Error **errp)
ed5e1ec3 1172{
71ad61d3
AF
1173 X86CPU *cpu = X86_CPU(obj);
1174 CPUX86State *env = &cpu->env;
1175 const int64_t min = 0;
1176 const int64_t max = 0xff + 0xf;
1177 int64_t value;
1178
1179 visit_type_int(v, &value, name, errp);
1180 if (error_is_set(errp)) {
1181 return;
1182 }
1183 if (value < min || value > max) {
1184 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1185 name ? name : "null", value, min, max);
1186 return;
1187 }
1188
ed5e1ec3 1189 env->cpuid_version &= ~0xff00f00;
71ad61d3
AF
1190 if (value > 0x0f) {
1191 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
ed5e1ec3 1192 } else {
71ad61d3 1193 env->cpuid_version |= value << 8;
ed5e1ec3
AF
1194 }
1195}
1196
67e30c83
AF
1197static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
1198 const char *name, Error **errp)
1199{
1200 X86CPU *cpu = X86_CPU(obj);
1201 CPUX86State *env = &cpu->env;
1202 int64_t value;
1203
1204 value = (env->cpuid_version >> 4) & 0xf;
1205 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
1206 visit_type_int(v, &value, name, errp);
1207}
1208
c5291a4f
AF
1209static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
1210 const char *name, Error **errp)
b0704cbd 1211{
c5291a4f
AF
1212 X86CPU *cpu = X86_CPU(obj);
1213 CPUX86State *env = &cpu->env;
1214 const int64_t min = 0;
1215 const int64_t max = 0xff;
1216 int64_t value;
1217
1218 visit_type_int(v, &value, name, errp);
1219 if (error_is_set(errp)) {
1220 return;
1221 }
1222 if (value < min || value > max) {
1223 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1224 name ? name : "null", value, min, max);
1225 return;
1226 }
1227
b0704cbd 1228 env->cpuid_version &= ~0xf00f0;
c5291a4f 1229 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
b0704cbd
AF
1230}
1231
35112e41
AF
1232static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
1233 void *opaque, const char *name,
1234 Error **errp)
1235{
1236 X86CPU *cpu = X86_CPU(obj);
1237 CPUX86State *env = &cpu->env;
1238 int64_t value;
1239
1240 value = env->cpuid_version & 0xf;
1241 visit_type_int(v, &value, name, errp);
1242}
1243
036e2222
AF
1244static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
1245 void *opaque, const char *name,
1246 Error **errp)
38c3dc46 1247{
036e2222
AF
1248 X86CPU *cpu = X86_CPU(obj);
1249 CPUX86State *env = &cpu->env;
1250 const int64_t min = 0;
1251 const int64_t max = 0xf;
1252 int64_t value;
1253
1254 visit_type_int(v, &value, name, errp);
1255 if (error_is_set(errp)) {
1256 return;
1257 }
1258 if (value < min || value > max) {
1259 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1260 name ? name : "null", value, min, max);
1261 return;
1262 }
1263
38c3dc46 1264 env->cpuid_version &= ~0xf;
036e2222 1265 env->cpuid_version |= value & 0xf;
38c3dc46
AF
1266}
1267
8e1898bf
AF
1268static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
1269 const char *name, Error **errp)
1270{
1271 X86CPU *cpu = X86_CPU(obj);
8e1898bf 1272
fa029887 1273 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
8e1898bf
AF
1274}
1275
1276static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
1277 const char *name, Error **errp)
1278{
1279 X86CPU *cpu = X86_CPU(obj);
8e1898bf 1280
fa029887 1281 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
8e1898bf
AF
1282}
1283
16b93aa8
AF
1284static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
1285 const char *name, Error **errp)
1286{
1287 X86CPU *cpu = X86_CPU(obj);
16b93aa8 1288
fa029887 1289 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
16b93aa8
AF
1290}
1291
1292static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
1293 const char *name, Error **errp)
1294{
1295 X86CPU *cpu = X86_CPU(obj);
16b93aa8 1296
fa029887 1297 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
16b93aa8
AF
1298}
1299
d480e1af
AF
1300static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1301{
1302 X86CPU *cpu = X86_CPU(obj);
1303 CPUX86State *env = &cpu->env;
1304 char *value;
d480e1af 1305
9df694ee 1306 value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
99b88a17
IM
1307 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
1308 env->cpuid_vendor3);
d480e1af
AF
1309 return value;
1310}
1311
1312static void x86_cpuid_set_vendor(Object *obj, const char *value,
1313 Error **errp)
1314{
1315 X86CPU *cpu = X86_CPU(obj);
1316 CPUX86State *env = &cpu->env;
1317 int i;
1318
9df694ee 1319 if (strlen(value) != CPUID_VENDOR_SZ) {
d480e1af
AF
1320 error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
1321 "vendor", value);
1322 return;
1323 }
1324
1325 env->cpuid_vendor1 = 0;
1326 env->cpuid_vendor2 = 0;
1327 env->cpuid_vendor3 = 0;
1328 for (i = 0; i < 4; i++) {
1329 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1330 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1331 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1332 }
d480e1af
AF
1333}
1334
63e886eb
AF
1335static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1336{
1337 X86CPU *cpu = X86_CPU(obj);
1338 CPUX86State *env = &cpu->env;
1339 char *value;
1340 int i;
1341
1342 value = g_malloc(48 + 1);
1343 for (i = 0; i < 48; i++) {
1344 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1345 }
1346 value[48] = '\0';
1347 return value;
1348}
1349
938d4c25
AF
1350static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1351 Error **errp)
dcce6675 1352{
938d4c25
AF
1353 X86CPU *cpu = X86_CPU(obj);
1354 CPUX86State *env = &cpu->env;
dcce6675
AF
1355 int c, len, i;
1356
1357 if (model_id == NULL) {
1358 model_id = "";
1359 }
1360 len = strlen(model_id);
d0a6acf4 1361 memset(env->cpuid_model, 0, 48);
dcce6675
AF
1362 for (i = 0; i < 48; i++) {
1363 if (i >= len) {
1364 c = '\0';
1365 } else {
1366 c = (uint8_t)model_id[i];
1367 }
1368 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1369 }
1370}
1371
89e48965
AF
1372static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
1373 const char *name, Error **errp)
1374{
1375 X86CPU *cpu = X86_CPU(obj);
1376 int64_t value;
1377
1378 value = cpu->env.tsc_khz * 1000;
1379 visit_type_int(v, &value, name, errp);
1380}
1381
1382static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
1383 const char *name, Error **errp)
1384{
1385 X86CPU *cpu = X86_CPU(obj);
1386 const int64_t min = 0;
2e84849a 1387 const int64_t max = INT64_MAX;
89e48965
AF
1388 int64_t value;
1389
1390 visit_type_int(v, &value, name, errp);
1391 if (error_is_set(errp)) {
1392 return;
1393 }
1394 if (value < min || value > max) {
1395 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1396 name ? name : "null", value, min, max);
1397 return;
1398 }
1399
1400 cpu->env.tsc_khz = value / 1000;
1401}
1402
31050930
IM
1403static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, void *opaque,
1404 const char *name, Error **errp)
1405{
1406 X86CPU *cpu = X86_CPU(obj);
1407 int64_t value = cpu->env.cpuid_apic_id;
1408
1409 visit_type_int(v, &value, name, errp);
1410}
1411
1412static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque,
1413 const char *name, Error **errp)
1414{
1415 X86CPU *cpu = X86_CPU(obj);
8d6d4980 1416 DeviceState *dev = DEVICE(obj);
31050930
IM
1417 const int64_t min = 0;
1418 const int64_t max = UINT32_MAX;
1419 Error *error = NULL;
1420 int64_t value;
1421
8d6d4980
IM
1422 if (dev->realized) {
1423 error_setg(errp, "Attempt to set property '%s' on '%s' after "
1424 "it was realized", name, object_get_typename(obj));
1425 return;
1426 }
1427
31050930
IM
1428 visit_type_int(v, &value, name, &error);
1429 if (error) {
1430 error_propagate(errp, error);
1431 return;
1432 }
1433 if (value < min || value > max) {
1434 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1435 " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
1436 object_get_typename(obj), name, value, min, max);
1437 return;
1438 }
1439
1440 if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
1441 error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
1442 return;
1443 }
1444 cpu->env.cpuid_apic_id = value;
1445}
1446
7e5292b5 1447/* Generic getter for "feature-words" and "filtered-features" properties */
8e8aba50
EH
1448static void x86_cpu_get_feature_words(Object *obj, Visitor *v, void *opaque,
1449 const char *name, Error **errp)
1450{
7e5292b5 1451 uint32_t *array = (uint32_t *)opaque;
8e8aba50
EH
1452 FeatureWord w;
1453 Error *err = NULL;
1454 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
1455 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
1456 X86CPUFeatureWordInfoList *list = NULL;
1457
1458 for (w = 0; w < FEATURE_WORDS; w++) {
1459 FeatureWordInfo *wi = &feature_word_info[w];
1460 X86CPUFeatureWordInfo *qwi = &word_infos[w];
1461 qwi->cpuid_input_eax = wi->cpuid_eax;
1462 qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
1463 qwi->cpuid_input_ecx = wi->cpuid_ecx;
1464 qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
7e5292b5 1465 qwi->features = array[w];
8e8aba50
EH
1466
1467 /* List will be in reverse order, but order shouldn't matter */
1468 list_entries[w].next = list;
1469 list_entries[w].value = &word_infos[w];
1470 list = &list_entries[w];
1471 }
1472
1473 visit_type_X86CPUFeatureWordInfoList(v, &list, "feature-words", &err);
1474 error_propagate(errp, err);
1475}
1476
8f961357 1477static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *name)
c6dc6f63 1478{
c6dc6f63 1479 x86_def_t *def;
7fc9b714 1480 int i;
c6dc6f63 1481
4bfe910d
AF
1482 if (name == NULL) {
1483 return -1;
9f3fb565 1484 }
4bfe910d 1485 if (kvm_enabled() && strcmp(name, "host") == 0) {
6e746f30 1486 kvm_cpu_fill_host(x86_cpu_def);
4bfe910d 1487 return 0;
c6dc6f63
AP
1488 }
1489
7fc9b714
AF
1490 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1491 def = &builtin_x86_defs[i];
4bfe910d
AF
1492 if (strcmp(name, def->name) == 0) {
1493 memcpy(x86_cpu_def, def, sizeof(*def));
11acfdd5
IM
1494 /* sysenter isn't supported in compatibility mode on AMD,
1495 * syscall isn't supported in compatibility mode on Intel.
1496 * Normally we advertise the actual CPU vendor, but you can
1497 * override this using the 'vendor' property if you want to use
1498 * KVM's sysenter/syscall emulation in compatibility mode and
1499 * when doing cross vendor migration
1500 */
1501 if (kvm_enabled()) {
1502 uint32_t ebx = 0, ecx = 0, edx = 0;
1503 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
1504 x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1505 }
4bfe910d
AF
1506 return 0;
1507 }
1508 }
1509
1510 return -1;
8f961357
EH
1511}
1512
72ac2e87
IM
1513/* Convert all '_' in a feature string option name to '-', to make feature
1514 * name conform to QOM property naming rule, which uses '-' instead of '_'.
1515 */
1516static inline void feat2prop(char *s)
1517{
1518 while ((s = strchr(s, '_'))) {
1519 *s = '-';
1520 }
1521}
1522
8f961357
EH
1523/* Parse "+feature,-feature,feature=foo" CPU feature string
1524 */
a91987c2 1525static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
8f961357 1526{
8f961357
EH
1527 char *featurestr; /* Single 'key=value" string being parsed */
1528 /* Features to be added */
077c68c3 1529 FeatureWordArray plus_features = { 0 };
8f961357 1530 /* Features to be removed */
5ef57876 1531 FeatureWordArray minus_features = { 0 };
8f961357 1532 uint32_t numvalue;
a91987c2 1533 CPUX86State *env = &cpu->env;
8f961357 1534
8f961357 1535 featurestr = features ? strtok(features, ",") : NULL;
c6dc6f63
AP
1536
1537 while (featurestr) {
1538 char *val;
1539 if (featurestr[0] == '+') {
5ef57876 1540 add_flagname_to_bitmaps(featurestr + 1, plus_features);
c6dc6f63 1541 } else if (featurestr[0] == '-') {
5ef57876 1542 add_flagname_to_bitmaps(featurestr + 1, minus_features);
c6dc6f63
AP
1543 } else if ((val = strchr(featurestr, '='))) {
1544 *val = 0; val++;
72ac2e87 1545 feat2prop(featurestr);
c6dc6f63 1546 if (!strcmp(featurestr, "family")) {
a91987c2 1547 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63 1548 } else if (!strcmp(featurestr, "model")) {
a91987c2 1549 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63 1550 } else if (!strcmp(featurestr, "stepping")) {
a91987c2 1551 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63 1552 } else if (!strcmp(featurestr, "level")) {
a91987c2 1553 object_property_parse(OBJECT(cpu), val, featurestr, errp);
c6dc6f63
AP
1554 } else if (!strcmp(featurestr, "xlevel")) {
1555 char *err;
a91987c2
IM
1556 char num[32];
1557
c6dc6f63
AP
1558 numvalue = strtoul(val, &err, 0);
1559 if (!*val || *err) {
312fd5f2 1560 error_setg(errp, "bad numerical value %s", val);
a91987c2 1561 goto out;
c6dc6f63
AP
1562 }
1563 if (numvalue < 0x80000000) {
8ba8a698
IM
1564 fprintf(stderr, "xlevel value shall always be >= 0x80000000"
1565 ", fixup will be removed in future versions\n");
2f7a21c4 1566 numvalue += 0x80000000;
c6dc6f63 1567 }
a91987c2
IM
1568 snprintf(num, sizeof(num), "%" PRIu32, numvalue);
1569 object_property_parse(OBJECT(cpu), num, featurestr, errp);
c6dc6f63 1570 } else if (!strcmp(featurestr, "vendor")) {
a91987c2 1571 object_property_parse(OBJECT(cpu), val, featurestr, errp);
72ac2e87
IM
1572 } else if (!strcmp(featurestr, "model-id")) {
1573 object_property_parse(OBJECT(cpu), val, featurestr, errp);
1574 } else if (!strcmp(featurestr, "tsc-freq")) {
b862d1fe
JR
1575 int64_t tsc_freq;
1576 char *err;
a91987c2 1577 char num[32];
b862d1fe
JR
1578
1579 tsc_freq = strtosz_suffix_unit(val, &err,
1580 STRTOSZ_DEFSUFFIX_B, 1000);
45009a30 1581 if (tsc_freq < 0 || *err) {
312fd5f2 1582 error_setg(errp, "bad numerical value %s", val);
a91987c2 1583 goto out;
b862d1fe 1584 }
a91987c2
IM
1585 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
1586 object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
72ac2e87 1587 } else if (!strcmp(featurestr, "hv-spinlocks")) {
28f52cc0
VR
1588 char *err;
1589 numvalue = strtoul(val, &err, 0);
1590 if (!*val || *err) {
312fd5f2 1591 error_setg(errp, "bad numerical value %s", val);
a91987c2 1592 goto out;
28f52cc0
VR
1593 }
1594 hyperv_set_spinlock_retries(numvalue);
c6dc6f63 1595 } else {
312fd5f2 1596 error_setg(errp, "unrecognized feature %s", featurestr);
a91987c2 1597 goto out;
c6dc6f63
AP
1598 }
1599 } else if (!strcmp(featurestr, "check")) {
1600 check_cpuid = 1;
1601 } else if (!strcmp(featurestr, "enforce")) {
1602 check_cpuid = enforce_cpuid = 1;
28f52cc0
VR
1603 } else if (!strcmp(featurestr, "hv_relaxed")) {
1604 hyperv_enable_relaxed_timing(true);
1605 } else if (!strcmp(featurestr, "hv_vapic")) {
1606 hyperv_enable_vapic_recommended(true);
c6dc6f63 1607 } else {
a91987c2 1608 error_setg(errp, "feature string `%s' not in format (+feature|"
312fd5f2 1609 "-feature|feature=xyz)", featurestr);
a91987c2
IM
1610 goto out;
1611 }
1612 if (error_is_set(errp)) {
1613 goto out;
c6dc6f63
AP
1614 }
1615 featurestr = strtok(NULL, ",");
1616 }
0514ef2f
EH
1617 env->features[FEAT_1_EDX] |= plus_features[FEAT_1_EDX];
1618 env->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX];
1619 env->features[FEAT_8000_0001_EDX] |= plus_features[FEAT_8000_0001_EDX];
1620 env->features[FEAT_8000_0001_ECX] |= plus_features[FEAT_8000_0001_ECX];
1621 env->features[FEAT_C000_0001_EDX] |= plus_features[FEAT_C000_0001_EDX];
1622 env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
1623 env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
1624 env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
1625 env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
1626 env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
1627 env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX];
1628 env->features[FEAT_8000_0001_ECX] &= ~minus_features[FEAT_8000_0001_ECX];
1629 env->features[FEAT_C000_0001_EDX] &= ~minus_features[FEAT_C000_0001_EDX];
1630 env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
1631 env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
1632 env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
c6dc6f63 1633
a91987c2
IM
1634out:
1635 return;
c6dc6f63
AP
1636}
1637
1638/* generate a composite string into buf of all cpuid names in featureset
1639 * selected by fbits. indicate truncation at bufsize in the event of overflow.
1640 * if flags, suppress names undefined in featureset.
1641 */
1642static void listflags(char *buf, int bufsize, uint32_t fbits,
1643 const char **featureset, uint32_t flags)
1644{
1645 const char **p = &featureset[31];
1646 char *q, *b, bit;
1647 int nc;
1648
1649 b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1650 *buf = '\0';
1651 for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1652 if (fbits & 1 << bit && (*p || !flags)) {
1653 if (*p)
1654 nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1655 else
1656 nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1657 if (bufsize <= nc) {
1658 if (b) {
1659 memcpy(b, "...", sizeof("..."));
1660 }
1661 return;
1662 }
1663 q += nc;
1664 bufsize -= nc;
1665 }
1666}
1667
e916cbf8
PM
1668/* generate CPU information. */
1669void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
c6dc6f63 1670{
c6dc6f63
AP
1671 x86_def_t *def;
1672 char buf[256];
7fc9b714 1673 int i;
c6dc6f63 1674
7fc9b714
AF
1675 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1676 def = &builtin_x86_defs[i];
c04321b3 1677 snprintf(buf, sizeof(buf), "%s", def->name);
6cdf8854 1678 (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
c6dc6f63 1679 }
21ad7789
JK
1680#ifdef CONFIG_KVM
1681 (*cpu_fprintf)(f, "x86 %16s %-48s\n", "host",
1682 "KVM processor with all supported host features "
1683 "(only available in KVM mode)");
1684#endif
1685
6cdf8854 1686 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
3af60be2
JK
1687 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
1688 FeatureWordInfo *fw = &feature_word_info[i];
1689
1690 listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
1691 (*cpu_fprintf)(f, " %s\n", buf);
1692 }
c6dc6f63
AP
1693}
1694
76b64a7a 1695CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
e3966126
AL
1696{
1697 CpuDefinitionInfoList *cpu_list = NULL;
1698 x86_def_t *def;
7fc9b714 1699 int i;
e3966126 1700
7fc9b714 1701 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
e3966126
AL
1702 CpuDefinitionInfoList *entry;
1703 CpuDefinitionInfo *info;
1704
7fc9b714 1705 def = &builtin_x86_defs[i];
e3966126
AL
1706 info = g_malloc0(sizeof(*info));
1707 info->name = g_strdup(def->name);
1708
1709 entry = g_malloc0(sizeof(*entry));
1710 entry->value = info;
1711 entry->next = cpu_list;
1712 cpu_list = entry;
1713 }
1714
1715 return cpu_list;
1716}
1717
bc74b7db
EH
1718#ifdef CONFIG_KVM
1719static void filter_features_for_kvm(X86CPU *cpu)
1720{
1721 CPUX86State *env = &cpu->env;
1722 KVMState *s = kvm_state;
bd87d2a2 1723 FeatureWord w;
bc74b7db 1724
bd87d2a2
EH
1725 for (w = 0; w < FEATURE_WORDS; w++) {
1726 FeatureWordInfo *wi = &feature_word_info[w];
034acf4a
EH
1727 uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax,
1728 wi->cpuid_ecx,
1729 wi->cpuid_reg);
1730 uint32_t requested_features = env->features[w];
1731 env->features[w] &= host_feat;
1732 cpu->filtered_features[w] = requested_features & ~env->features[w];
bd87d2a2 1733 }
bc74b7db
EH
1734}
1735#endif
1736
2d64255b 1737static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
c6dc6f63 1738{
61dcd775 1739 CPUX86State *env = &cpu->env;
c6dc6f63
AP
1740 x86_def_t def1, *def = &def1;
1741
db0ad1ba
JR
1742 memset(def, 0, sizeof(*def));
1743
8f961357 1744 if (cpu_x86_find_by_name(def, name) < 0) {
2d64255b
AF
1745 error_setg(errp, "Unable to find CPU definition: %s", name);
1746 return;
8f961357
EH
1747 }
1748
aa87d458 1749 if (kvm_enabled()) {
0514ef2f 1750 def->features[FEAT_KVM] |= kvm_default_features;
aa87d458 1751 }
0514ef2f 1752 def->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
077c68c3 1753
2d64255b
AF
1754 object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp);
1755 object_property_set_int(OBJECT(cpu), def->level, "level", errp);
1756 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
1757 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
1758 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
0514ef2f
EH
1759 env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX];
1760 env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX];
1761 env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX];
1762 env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX];
2d64255b 1763 object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
0514ef2f
EH
1764 env->features[FEAT_KVM] = def->features[FEAT_KVM];
1765 env->features[FEAT_SVM] = def->features[FEAT_SVM];
1766 env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
1767 env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
b3baa152 1768 env->cpuid_xlevel2 = def->xlevel2;
3b671a40 1769
2d64255b 1770 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
c6dc6f63
AP
1771}
1772
62fc403f
IM
1773X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
1774 Error **errp)
5c3c6a68 1775{
2d64255b 1776 X86CPU *cpu = NULL;
5c3c6a68 1777 CPUX86State *env;
2d64255b
AF
1778 gchar **model_pieces;
1779 char *name, *features;
ba2bc7a4 1780 char *typename;
5c3c6a68
AF
1781 Error *error = NULL;
1782
2d64255b
AF
1783 model_pieces = g_strsplit(cpu_model, ",", 2);
1784 if (!model_pieces[0]) {
1785 error_setg(&error, "Invalid/empty CPU model name");
1786 goto out;
1787 }
1788 name = model_pieces[0];
1789 features = model_pieces[1];
1790
5c3c6a68 1791 cpu = X86_CPU(object_new(TYPE_X86_CPU));
62fc403f
IM
1792#ifndef CONFIG_USER_ONLY
1793 if (icc_bridge == NULL) {
1794 error_setg(&error, "Invalid icc-bridge value");
1795 goto out;
1796 }
1797 qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
1798 object_unref(OBJECT(cpu));
1799#endif
5c3c6a68
AF
1800 env = &cpu->env;
1801 env->cpu_model_str = cpu_model;
1802
2d64255b
AF
1803 cpu_x86_register(cpu, name, &error);
1804 if (error) {
1805 goto out;
1806 }
1807
ba2bc7a4
AF
1808 /* Emulate per-model subclasses for global properties */
1809 typename = g_strdup_printf("%s-" TYPE_X86_CPU, name);
1810 qdev_prop_set_globals_for_type(DEVICE(cpu), typename, &error);
1811 g_free(typename);
1812 if (error) {
1813 goto out;
1814 }
1815
2d64255b
AF
1816 cpu_x86_parse_featurestr(cpu, features, &error);
1817 if (error) {
1818 goto out;
5c3c6a68
AF
1819 }
1820
7f833247
IM
1821out:
1822 error_propagate(errp, error);
1823 g_strfreev(model_pieces);
1824 return cpu;
1825}
1826
1827X86CPU *cpu_x86_init(const char *cpu_model)
1828{
1829 Error *error = NULL;
1830 X86CPU *cpu;
1831
62fc403f 1832 cpu = cpu_x86_create(cpu_model, NULL, &error);
5c3c6a68 1833 if (error) {
2d64255b
AF
1834 goto out;
1835 }
1836
7f833247
IM
1837 object_property_set_bool(OBJECT(cpu), true, "realized", &error);
1838
2d64255b 1839out:
2d64255b
AF
1840 if (error) {
1841 fprintf(stderr, "%s\n", error_get_pretty(error));
5c3c6a68 1842 error_free(error);
2d64255b
AF
1843 if (cpu != NULL) {
1844 object_unref(OBJECT(cpu));
1845 cpu = NULL;
1846 }
5c3c6a68
AF
1847 }
1848 return cpu;
1849}
1850
c6dc6f63 1851#if !defined(CONFIG_USER_ONLY)
c6dc6f63 1852
0e26b7b8
BS
1853void cpu_clear_apic_feature(CPUX86State *env)
1854{
0514ef2f 1855 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
0e26b7b8
BS
1856}
1857
c6dc6f63
AP
1858#endif /* !CONFIG_USER_ONLY */
1859
c04321b3 1860/* Initialize list of CPU models, filling some non-static fields if necessary
c6dc6f63
AP
1861 */
1862void x86_cpudef_setup(void)
1863{
93bfef4c
CV
1864 int i, j;
1865 static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
c6dc6f63
AP
1866
1867 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
bc3e1291 1868 x86_def_t *def = &builtin_x86_defs[i];
93bfef4c
CV
1869
1870 /* Look for specific "cpudef" models that */
09faecf2 1871 /* have the QEMU version in .model_id */
93bfef4c 1872 for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
bc3e1291
EH
1873 if (strcmp(model_with_versions[j], def->name) == 0) {
1874 pstrcpy(def->model_id, sizeof(def->model_id),
1875 "QEMU Virtual CPU version ");
1876 pstrcat(def->model_id, sizeof(def->model_id),
1877 qemu_get_version());
93bfef4c
CV
1878 break;
1879 }
1880 }
c6dc6f63 1881 }
c6dc6f63
AP
1882}
1883
c6dc6f63
AP
1884static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
1885 uint32_t *ecx, uint32_t *edx)
1886{
1887 *ebx = env->cpuid_vendor1;
1888 *edx = env->cpuid_vendor2;
1889 *ecx = env->cpuid_vendor3;
c6dc6f63
AP
1890}
1891
1892void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1893 uint32_t *eax, uint32_t *ebx,
1894 uint32_t *ecx, uint32_t *edx)
1895{
a60f24b5
AF
1896 X86CPU *cpu = x86_env_get_cpu(env);
1897 CPUState *cs = CPU(cpu);
1898
c6dc6f63
AP
1899 /* test if maximum index reached */
1900 if (index & 0x80000000) {
b3baa152
BW
1901 if (index > env->cpuid_xlevel) {
1902 if (env->cpuid_xlevel2 > 0) {
1903 /* Handle the Centaur's CPUID instruction. */
1904 if (index > env->cpuid_xlevel2) {
1905 index = env->cpuid_xlevel2;
1906 } else if (index < 0xC0000000) {
1907 index = env->cpuid_xlevel;
1908 }
1909 } else {
57f26ae7
EH
1910 /* Intel documentation states that invalid EAX input will
1911 * return the same information as EAX=cpuid_level
1912 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
1913 */
1914 index = env->cpuid_level;
b3baa152
BW
1915 }
1916 }
c6dc6f63
AP
1917 } else {
1918 if (index > env->cpuid_level)
1919 index = env->cpuid_level;
1920 }
1921
1922 switch(index) {
1923 case 0:
1924 *eax = env->cpuid_level;
1925 get_cpuid_vendor(env, ebx, ecx, edx);
1926 break;
1927 case 1:
1928 *eax = env->cpuid_version;
1929 *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
0514ef2f
EH
1930 *ecx = env->features[FEAT_1_ECX];
1931 *edx = env->features[FEAT_1_EDX];
ce3960eb
AF
1932 if (cs->nr_cores * cs->nr_threads > 1) {
1933 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
c6dc6f63
AP
1934 *edx |= 1 << 28; /* HTT bit */
1935 }
1936 break;
1937 case 2:
1938 /* cache info: needed for Pentium Pro compatibility */
1939 *eax = 1;
1940 *ebx = 0;
1941 *ecx = 0;
1942 *edx = 0x2c307d;
1943 break;
1944 case 4:
1945 /* cache info: needed for Core compatibility */
ce3960eb
AF
1946 if (cs->nr_cores > 1) {
1947 *eax = (cs->nr_cores - 1) << 26;
c6dc6f63 1948 } else {
2f7a21c4 1949 *eax = 0;
c6dc6f63
AP
1950 }
1951 switch (count) {
1952 case 0: /* L1 dcache info */
1953 *eax |= 0x0000121;
1954 *ebx = 0x1c0003f;
1955 *ecx = 0x000003f;
1956 *edx = 0x0000001;
1957 break;
1958 case 1: /* L1 icache info */
1959 *eax |= 0x0000122;
1960 *ebx = 0x1c0003f;
1961 *ecx = 0x000003f;
1962 *edx = 0x0000001;
1963 break;
1964 case 2: /* L2 cache info */
1965 *eax |= 0x0000143;
ce3960eb
AF
1966 if (cs->nr_threads > 1) {
1967 *eax |= (cs->nr_threads - 1) << 14;
c6dc6f63
AP
1968 }
1969 *ebx = 0x3c0003f;
1970 *ecx = 0x0000fff;
1971 *edx = 0x0000001;
1972 break;
1973 default: /* end of info */
1974 *eax = 0;
1975 *ebx = 0;
1976 *ecx = 0;
1977 *edx = 0;
1978 break;
1979 }
1980 break;
1981 case 5:
1982 /* mwait info: needed for Core compatibility */
1983 *eax = 0; /* Smallest monitor-line size in bytes */
1984 *ebx = 0; /* Largest monitor-line size in bytes */
1985 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
1986 *edx = 0;
1987 break;
1988 case 6:
1989 /* Thermal and Power Leaf */
1990 *eax = 0;
1991 *ebx = 0;
1992 *ecx = 0;
1993 *edx = 0;
1994 break;
f7911686 1995 case 7:
13526728
EH
1996 /* Structured Extended Feature Flags Enumeration Leaf */
1997 if (count == 0) {
1998 *eax = 0; /* Maximum ECX value for sub-leaves */
0514ef2f 1999 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
13526728
EH
2000 *ecx = 0; /* Reserved */
2001 *edx = 0; /* Reserved */
f7911686
YW
2002 } else {
2003 *eax = 0;
2004 *ebx = 0;
2005 *ecx = 0;
2006 *edx = 0;
2007 }
2008 break;
c6dc6f63
AP
2009 case 9:
2010 /* Direct Cache Access Information Leaf */
2011 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2012 *ebx = 0;
2013 *ecx = 0;
2014 *edx = 0;
2015 break;
2016 case 0xA:
2017 /* Architectural Performance Monitoring Leaf */
a0fa8208 2018 if (kvm_enabled()) {
a60f24b5 2019 KVMState *s = cs->kvm_state;
a0fa8208
GN
2020
2021 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
2022 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
2023 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
2024 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
2025 } else {
2026 *eax = 0;
2027 *ebx = 0;
2028 *ecx = 0;
2029 *edx = 0;
2030 }
c6dc6f63 2031 break;
51e49430
SY
2032 case 0xD:
2033 /* Processor Extended State */
0514ef2f 2034 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
51e49430
SY
2035 *eax = 0;
2036 *ebx = 0;
2037 *ecx = 0;
2038 *edx = 0;
2039 break;
2040 }
2041 if (kvm_enabled()) {
a60f24b5 2042 KVMState *s = cs->kvm_state;
ba9bc59e
JK
2043
2044 *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX);
2045 *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX);
2046 *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX);
2047 *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX);
51e49430
SY
2048 } else {
2049 *eax = 0;
2050 *ebx = 0;
2051 *ecx = 0;
2052 *edx = 0;
2053 }
2054 break;
c6dc6f63
AP
2055 case 0x80000000:
2056 *eax = env->cpuid_xlevel;
2057 *ebx = env->cpuid_vendor1;
2058 *edx = env->cpuid_vendor2;
2059 *ecx = env->cpuid_vendor3;
2060 break;
2061 case 0x80000001:
2062 *eax = env->cpuid_version;
2063 *ebx = 0;
0514ef2f
EH
2064 *ecx = env->features[FEAT_8000_0001_ECX];
2065 *edx = env->features[FEAT_8000_0001_EDX];
c6dc6f63
AP
2066
2067 /* The Linux kernel checks for the CMPLegacy bit and
2068 * discards multiple thread information if it is set.
2069 * So dont set it here for Intel to make Linux guests happy.
2070 */
ce3960eb 2071 if (cs->nr_cores * cs->nr_threads > 1) {
c6dc6f63
AP
2072 uint32_t tebx, tecx, tedx;
2073 get_cpuid_vendor(env, &tebx, &tecx, &tedx);
2074 if (tebx != CPUID_VENDOR_INTEL_1 ||
2075 tedx != CPUID_VENDOR_INTEL_2 ||
2076 tecx != CPUID_VENDOR_INTEL_3) {
2077 *ecx |= 1 << 1; /* CmpLegacy bit */
2078 }
2079 }
c6dc6f63
AP
2080 break;
2081 case 0x80000002:
2082 case 0x80000003:
2083 case 0x80000004:
2084 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2085 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2086 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2087 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2088 break;
2089 case 0x80000005:
2090 /* cache info (L1 cache) */
2091 *eax = 0x01ff01ff;
2092 *ebx = 0x01ff01ff;
2093 *ecx = 0x40020140;
2094 *edx = 0x40020140;
2095 break;
2096 case 0x80000006:
2097 /* cache info (L2 cache) */
2098 *eax = 0;
2099 *ebx = 0x42004200;
2100 *ecx = 0x02008140;
2101 *edx = 0;
2102 break;
2103 case 0x80000008:
2104 /* virtual & phys address size in low 2 bytes. */
2105/* XXX: This value must match the one used in the MMU code. */
0514ef2f 2106 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
c6dc6f63
AP
2107 /* 64 bit processor */
2108/* XXX: The physical address space is limited to 42 bits in exec.c. */
dd13e088 2109 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
c6dc6f63 2110 } else {
0514ef2f 2111 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
c6dc6f63 2112 *eax = 0x00000024; /* 36 bits physical */
dd13e088 2113 } else {
c6dc6f63 2114 *eax = 0x00000020; /* 32 bits physical */
dd13e088 2115 }
c6dc6f63
AP
2116 }
2117 *ebx = 0;
2118 *ecx = 0;
2119 *edx = 0;
ce3960eb
AF
2120 if (cs->nr_cores * cs->nr_threads > 1) {
2121 *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
c6dc6f63
AP
2122 }
2123 break;
2124 case 0x8000000A:
0514ef2f 2125 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
9f3fb565
EH
2126 *eax = 0x00000001; /* SVM Revision */
2127 *ebx = 0x00000010; /* nr of ASIDs */
2128 *ecx = 0;
0514ef2f 2129 *edx = env->features[FEAT_SVM]; /* optional features */
9f3fb565
EH
2130 } else {
2131 *eax = 0;
2132 *ebx = 0;
2133 *ecx = 0;
2134 *edx = 0;
2135 }
c6dc6f63 2136 break;
b3baa152
BW
2137 case 0xC0000000:
2138 *eax = env->cpuid_xlevel2;
2139 *ebx = 0;
2140 *ecx = 0;
2141 *edx = 0;
2142 break;
2143 case 0xC0000001:
2144 /* Support for VIA CPU's CPUID instruction */
2145 *eax = env->cpuid_version;
2146 *ebx = 0;
2147 *ecx = 0;
0514ef2f 2148 *edx = env->features[FEAT_C000_0001_EDX];
b3baa152
BW
2149 break;
2150 case 0xC0000002:
2151 case 0xC0000003:
2152 case 0xC0000004:
2153 /* Reserved for the future, and now filled with zero */
2154 *eax = 0;
2155 *ebx = 0;
2156 *ecx = 0;
2157 *edx = 0;
2158 break;
c6dc6f63
AP
2159 default:
2160 /* reserved values: zero */
2161 *eax = 0;
2162 *ebx = 0;
2163 *ecx = 0;
2164 *edx = 0;
2165 break;
2166 }
2167}
5fd2087a
AF
2168
2169/* CPUClass::reset() */
2170static void x86_cpu_reset(CPUState *s)
2171{
2172 X86CPU *cpu = X86_CPU(s);
2173 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2174 CPUX86State *env = &cpu->env;
c1958aea
AF
2175 int i;
2176
2177 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
55e5c285 2178 qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
6fd2a026 2179 log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP);
c1958aea 2180 }
5fd2087a
AF
2181
2182 xcc->parent_reset(s);
2183
c1958aea
AF
2184
2185 memset(env, 0, offsetof(CPUX86State, breakpoints));
2186
2187 tlb_flush(env, 1);
2188
2189 env->old_exception = -1;
2190
2191 /* init to reset state */
2192
2193#ifdef CONFIG_SOFTMMU
2194 env->hflags |= HF_SOFTMMU_MASK;
2195#endif
2196 env->hflags2 |= HF2_GIF_MASK;
2197
2198 cpu_x86_update_cr0(env, 0x60000010);
2199 env->a20_mask = ~0x0;
2200 env->smbase = 0x30000;
2201
2202 env->idt.limit = 0xffff;
2203 env->gdt.limit = 0xffff;
2204 env->ldt.limit = 0xffff;
2205 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2206 env->tr.limit = 0xffff;
2207 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2208
2209 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2210 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2211 DESC_R_MASK | DESC_A_MASK);
2212 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2213 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2214 DESC_A_MASK);
2215 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
2216 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2217 DESC_A_MASK);
2218 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
2219 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2220 DESC_A_MASK);
2221 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
2222 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2223 DESC_A_MASK);
2224 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
2225 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2226 DESC_A_MASK);
2227
2228 env->eip = 0xfff0;
2229 env->regs[R_EDX] = env->cpuid_version;
2230
2231 env->eflags = 0x2;
2232
2233 /* FPU init */
2234 for (i = 0; i < 8; i++) {
2235 env->fptags[i] = 1;
2236 }
2237 env->fpuc = 0x37f;
2238
2239 env->mxcsr = 0x1f80;
2240
2241 env->pat = 0x0007040600070406ULL;
2242 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2243
2244 memset(env->dr, 0, sizeof(env->dr));
2245 env->dr[6] = DR6_FIXED_1;
2246 env->dr[7] = DR7_FIXED_1;
2247 cpu_breakpoint_remove_all(env, BP_CPU);
2248 cpu_watchpoint_remove_all(env, BP_CPU);
dd673288
IM
2249
2250#if !defined(CONFIG_USER_ONLY)
2251 /* We hard-wire the BSP to the first CPU. */
55e5c285 2252 if (s->cpu_index == 0) {
dd673288
IM
2253 apic_designate_bsp(env->apic_state);
2254 }
2255
259186a7 2256 s->halted = !cpu_is_bsp(cpu);
dd673288 2257#endif
5fd2087a
AF
2258}
2259
dd673288
IM
2260#ifndef CONFIG_USER_ONLY
2261bool cpu_is_bsp(X86CPU *cpu)
2262{
2263 return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP;
2264}
65dee380
IM
2265
2266/* TODO: remove me, when reset over QOM tree is implemented */
2267static void x86_cpu_machine_reset_cb(void *opaque)
2268{
2269 X86CPU *cpu = opaque;
2270 cpu_reset(CPU(cpu));
2271}
dd673288
IM
2272#endif
2273
de024815
AF
2274static void mce_init(X86CPU *cpu)
2275{
2276 CPUX86State *cenv = &cpu->env;
2277 unsigned int bank;
2278
2279 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
0514ef2f 2280 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
de024815
AF
2281 (CPUID_MCE | CPUID_MCA)) {
2282 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2283 cenv->mcg_ctl = ~(uint64_t)0;
2284 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2285 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2286 }
2287 }
2288}
2289
bdeec802 2290#ifndef CONFIG_USER_ONLY
d3c64d6a 2291static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
bdeec802 2292{
bdeec802 2293 CPUX86State *env = &cpu->env;
53a89e26 2294 DeviceState *dev = DEVICE(cpu);
449994eb 2295 APICCommonState *apic;
bdeec802
IM
2296 const char *apic_type = "apic";
2297
2298 if (kvm_irqchip_in_kernel()) {
2299 apic_type = "kvm-apic";
2300 } else if (xen_enabled()) {
2301 apic_type = "xen-apic";
2302 }
2303
53a89e26 2304 env->apic_state = qdev_try_create(qdev_get_parent_bus(dev), apic_type);
bdeec802
IM
2305 if (env->apic_state == NULL) {
2306 error_setg(errp, "APIC device '%s' could not be created", apic_type);
2307 return;
2308 }
2309
2310 object_property_add_child(OBJECT(cpu), "apic",
2311 OBJECT(env->apic_state), NULL);
2312 qdev_prop_set_uint8(env->apic_state, "id", env->cpuid_apic_id);
2313 /* TODO: convert to link<> */
449994eb 2314 apic = APIC_COMMON(env->apic_state);
60671e58 2315 apic->cpu = cpu;
d3c64d6a
IM
2316}
2317
2318static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2319{
2320 CPUX86State *env = &cpu->env;
d3c64d6a
IM
2321
2322 if (env->apic_state == NULL) {
2323 return;
2324 }
bdeec802
IM
2325
2326 if (qdev_init(env->apic_state)) {
2327 error_setg(errp, "APIC device '%s' could not be initialized",
2328 object_get_typename(OBJECT(env->apic_state)));
2329 return;
2330 }
bdeec802 2331}
d3c64d6a
IM
2332#else
2333static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2334{
2335}
bdeec802
IM
2336#endif
2337
2b6f294c 2338static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
7a059953 2339{
2b6f294c
AF
2340 X86CPU *cpu = X86_CPU(dev);
2341 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
b34d12d1 2342 CPUX86State *env = &cpu->env;
2b6f294c 2343 Error *local_err = NULL;
b34d12d1 2344
0514ef2f 2345 if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
b34d12d1
IM
2346 env->cpuid_level = 7;
2347 }
7a059953 2348
9b15cd9e
IM
2349 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
2350 * CPUID[1].EDX.
2351 */
2352 if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
2353 env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
2354 env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
0514ef2f
EH
2355 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
2356 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
9b15cd9e
IM
2357 & CPUID_EXT2_AMD_ALIASES);
2358 }
2359
4586f157 2360 if (!kvm_enabled()) {
0514ef2f
EH
2361 env->features[FEAT_1_EDX] &= TCG_FEATURES;
2362 env->features[FEAT_1_ECX] &= TCG_EXT_FEATURES;
2363 env->features[FEAT_8000_0001_EDX] &= (TCG_EXT2_FEATURES
4586f157
IM
2364#ifdef TARGET_X86_64
2365 | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
2366#endif
2367 );
0514ef2f
EH
2368 env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES;
2369 env->features[FEAT_SVM] &= TCG_SVM_FEATURES;
4586f157 2370 } else {
5ec01c2e
IM
2371 if (check_cpuid && kvm_check_features_against_host(cpu)
2372 && enforce_cpuid) {
4dc1f449
IM
2373 error_setg(&local_err,
2374 "Host's CPU doesn't support requested features");
2375 goto out;
5ec01c2e 2376 }
a509d632
EH
2377#ifdef CONFIG_KVM
2378 filter_features_for_kvm(cpu);
2379#endif
4586f157
IM
2380 }
2381
65dee380
IM
2382#ifndef CONFIG_USER_ONLY
2383 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
bdeec802 2384
0514ef2f 2385 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
d3c64d6a 2386 x86_cpu_apic_create(cpu, &local_err);
2b6f294c 2387 if (local_err != NULL) {
4dc1f449 2388 goto out;
bdeec802
IM
2389 }
2390 }
65dee380
IM
2391#endif
2392
7a059953
AF
2393 mce_init(cpu);
2394 qemu_init_vcpu(&cpu->env);
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
5fd2087a
AF
2507static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
2508{
2509 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2510 CPUClass *cc = CPU_CLASS(oc);
2b6f294c
AF
2511 DeviceClass *dc = DEVICE_CLASS(oc);
2512
2513 xcc->parent_realize = dc->realize;
2514 dc->realize = x86_cpu_realizefn;
62fc403f 2515 dc->bus_type = TYPE_ICC_BUS;
5fd2087a
AF
2516
2517 xcc->parent_reset = cc->reset;
2518 cc->reset = x86_cpu_reset;
f56e3a14 2519
97a8ea5a 2520 cc->do_interrupt = x86_cpu_do_interrupt;
c72bf468
JF
2521#ifndef CONFIG_USER_ONLY
2522 cc->write_elf64_note = x86_cpu_write_elf64_note;
2523 cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
2524 cc->write_elf32_note = x86_cpu_write_elf32_note;
2525 cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
2526#endif
f56e3a14 2527 cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
997395d3
IM
2528
2529 cc->get_arch_id = x86_cpu_get_arch_id;
5fd2087a
AF
2530}
2531
2532static const TypeInfo x86_cpu_type_info = {
2533 .name = TYPE_X86_CPU,
2534 .parent = TYPE_CPU,
2535 .instance_size = sizeof(X86CPU),
de024815 2536 .instance_init = x86_cpu_initfn,
5fd2087a
AF
2537 .abstract = false,
2538 .class_size = sizeof(X86CPUClass),
2539 .class_init = x86_cpu_common_class_init,
2540};
2541
2542static void x86_cpu_register_types(void)
2543{
2544 type_register_static(&x86_cpu_type_info);
2545}
2546
2547type_init(x86_cpu_register_types)