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