]> git.proxmox.com Git - mirror_qemu.git/blame - target-i386/cpu.c
target-i386: make cpu_x86_fill_host() void
[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"
25#include "kvm.h"
26
27#include "qemu-option.h"
28#include "qemu-config.h"
29
71ad61d3 30#include "qapi/qapi-visit-core.h"
76b64a7a 31#include "arch_init.h"
71ad61d3 32
28f52cc0
VR
33#include "hyperv.h"
34
65dee380 35#include "hw/hw.h"
b834b508 36#if defined(CONFIG_KVM)
ef8621b1 37#include <linux/kvm_para.h>
b834b508 38#endif
65dee380 39
c6dc6f63
AP
40/* feature flags taken from "Intel Processor Identification and the CPUID
41 * Instruction" and AMD's "CPUID Specification". In cases of disagreement
42 * between feature naming conventions, aliases may be added.
43 */
44static const char *feature_name[] = {
45 "fpu", "vme", "de", "pse",
46 "tsc", "msr", "pae", "mce",
47 "cx8", "apic", NULL, "sep",
48 "mtrr", "pge", "mca", "cmov",
49 "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
50 NULL, "ds" /* Intel dts */, "acpi", "mmx",
51 "fxsr", "sse", "sse2", "ss",
52 "ht" /* Intel htt */, "tm", "ia64", "pbe",
53};
54static const char *ext_feature_name[] = {
f370be3c 55 "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
e117f772 56 "ds_cpl", "vmx", "smx", "est",
c6dc6f63 57 "tm2", "ssse3", "cid", NULL,
e117f772 58 "fma", "cx16", "xtpr", "pdcm",
434acb81 59 NULL, "pcid", "dca", "sse4.1|sse4_1",
e117f772 60 "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
eaf3f097 61 "tsc-deadline", "aes", "xsave", "osxsave",
e117f772 62 "avx", NULL, NULL, "hypervisor",
c6dc6f63 63};
3b671a40
EH
64/* Feature names that are already defined on feature_name[] but are set on
65 * CPUID[8000_0001].EDX on AMD CPUs don't have their names on
66 * ext2_feature_name[]. They are copied automatically to cpuid_ext2_features
67 * if and only if CPU vendor is AMD.
68 */
c6dc6f63 69static const char *ext2_feature_name[] = {
3b671a40
EH
70 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
71 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
72 NULL /* cx8 */ /* AMD CMPXCHG8B */, NULL /* apic */, NULL, "syscall",
73 NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
74 NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
75 "nx|xd", NULL, "mmxext", NULL /* mmx */,
76 NULL /* fxsr */, "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
01f590d5 77 NULL, "lm|i64", "3dnowext", "3dnow",
c6dc6f63
AP
78};
79static const char *ext3_feature_name[] = {
80 "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
81 "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
e117f772 82 "3dnowprefetch", "osvw", "ibs", "xop",
c6dc6f63 83 "skinit", "wdt", NULL, NULL,
e117f772 84 "fma4", NULL, "cvt16", "nodeid_msr",
c6dc6f63
AP
85 NULL, NULL, NULL, NULL,
86 NULL, NULL, NULL, NULL,
87 NULL, NULL, NULL, NULL,
88};
89
90static const char *kvm_feature_name[] = {
c3d39807
DS
91 "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock",
92 "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", NULL,
93 NULL, NULL, NULL, NULL,
94 NULL, NULL, NULL, NULL,
95 NULL, NULL, NULL, NULL,
96 NULL, NULL, NULL, NULL,
97 NULL, NULL, NULL, NULL,
98 NULL, NULL, NULL, NULL,
c6dc6f63
AP
99};
100
296acb64
JR
101static const char *svm_feature_name[] = {
102 "npt", "lbrv", "svm_lock", "nrip_save",
103 "tsc_scale", "vmcb_clean", "flushbyasid", "decodeassists",
104 NULL, NULL, "pause_filter", NULL,
105 "pfthreshold", NULL, NULL, NULL,
106 NULL, NULL, NULL, NULL,
107 NULL, NULL, NULL, NULL,
108 NULL, NULL, NULL, NULL,
109 NULL, NULL, NULL, NULL,
110};
111
a9321a4d 112static const char *cpuid_7_0_ebx_feature_name[] = {
811a8ae0
EH
113 "fsgsbase", NULL, NULL, "bmi1", "hle", "avx2", NULL, "smep",
114 "bmi2", "erms", "invpcid", "rtm", NULL, NULL, NULL, NULL,
a9321a4d
PA
115 NULL, NULL, NULL, NULL, "smap", NULL, NULL, NULL,
116 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
117};
118
c6dc6f63
AP
119/* collects per-function cpuid data
120 */
121typedef struct model_features_t {
122 uint32_t *guest_feat;
123 uint32_t *host_feat;
124 uint32_t check_feat;
125 const char **flag_names;
126 uint32_t cpuid;
127 } model_features_t;
128
129int check_cpuid = 0;
130int enforce_cpuid = 0;
131
dc59944b
MT
132#if defined(CONFIG_KVM)
133static uint32_t kvm_default_features = (1 << KVM_FEATURE_CLOCKSOURCE) |
134 (1 << KVM_FEATURE_NOP_IO_DELAY) |
135 (1 << KVM_FEATURE_MMU_OP) |
136 (1 << KVM_FEATURE_CLOCKSOURCE2) |
137 (1 << KVM_FEATURE_ASYNC_PF) |
138 (1 << KVM_FEATURE_STEAL_TIME) |
139 (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
140static const uint32_t kvm_pv_eoi_features = (0x1 << KVM_FEATURE_PV_EOI);
141#else
142static uint32_t kvm_default_features = 0;
143static const uint32_t kvm_pv_eoi_features = 0;
144#endif
145
146void enable_kvm_pv_eoi(void)
147{
148 kvm_default_features |= kvm_pv_eoi_features;
149}
150
bb44e0d1
JK
151void host_cpuid(uint32_t function, uint32_t count,
152 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
bdde476a
AP
153{
154#if defined(CONFIG_KVM)
a1fd24af
AL
155 uint32_t vec[4];
156
157#ifdef __x86_64__
158 asm volatile("cpuid"
159 : "=a"(vec[0]), "=b"(vec[1]),
160 "=c"(vec[2]), "=d"(vec[3])
161 : "0"(function), "c"(count) : "cc");
162#else
163 asm volatile("pusha \n\t"
164 "cpuid \n\t"
165 "mov %%eax, 0(%2) \n\t"
166 "mov %%ebx, 4(%2) \n\t"
167 "mov %%ecx, 8(%2) \n\t"
168 "mov %%edx, 12(%2) \n\t"
169 "popa"
170 : : "a"(function), "c"(count), "S"(vec)
171 : "memory", "cc");
172#endif
173
bdde476a 174 if (eax)
a1fd24af 175 *eax = vec[0];
bdde476a 176 if (ebx)
a1fd24af 177 *ebx = vec[1];
bdde476a 178 if (ecx)
a1fd24af 179 *ecx = vec[2];
bdde476a 180 if (edx)
a1fd24af 181 *edx = vec[3];
bdde476a
AP
182#endif
183}
c6dc6f63
AP
184
185#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
186
187/* general substring compare of *[s1..e1) and *[s2..e2). sx is start of
188 * a substring. ex if !NULL points to the first char after a substring,
189 * otherwise the string is assumed to sized by a terminating nul.
190 * Return lexical ordering of *s1:*s2.
191 */
192static int sstrcmp(const char *s1, const char *e1, const char *s2,
193 const char *e2)
194{
195 for (;;) {
196 if (!*s1 || !*s2 || *s1 != *s2)
197 return (*s1 - *s2);
198 ++s1, ++s2;
199 if (s1 == e1 && s2 == e2)
200 return (0);
201 else if (s1 == e1)
202 return (*s2);
203 else if (s2 == e2)
204 return (*s1);
205 }
206}
207
208/* compare *[s..e) to *altstr. *altstr may be a simple string or multiple
209 * '|' delimited (possibly empty) strings in which case search for a match
210 * within the alternatives proceeds left to right. Return 0 for success,
211 * non-zero otherwise.
212 */
213static int altcmp(const char *s, const char *e, const char *altstr)
214{
215 const char *p, *q;
216
217 for (q = p = altstr; ; ) {
218 while (*p && *p != '|')
219 ++p;
220 if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
221 return (0);
222 if (!*p)
223 return (1);
224 else
225 q = ++p;
226 }
227}
228
229/* search featureset for flag *[s..e), if found set corresponding bit in
e41e0fc6 230 * *pval and return true, otherwise return false
c6dc6f63 231 */
e41e0fc6
JK
232static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
233 const char **featureset)
c6dc6f63
AP
234{
235 uint32_t mask;
236 const char **ppc;
e41e0fc6 237 bool found = false;
c6dc6f63 238
e41e0fc6 239 for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
c6dc6f63
AP
240 if (*ppc && !altcmp(s, e, *ppc)) {
241 *pval |= mask;
e41e0fc6 242 found = true;
c6dc6f63 243 }
e41e0fc6
JK
244 }
245 return found;
c6dc6f63
AP
246}
247
248static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
249 uint32_t *ext_features,
250 uint32_t *ext2_features,
251 uint32_t *ext3_features,
296acb64 252 uint32_t *kvm_features,
a9321a4d
PA
253 uint32_t *svm_features,
254 uint32_t *cpuid_7_0_ebx_features)
c6dc6f63
AP
255{
256 if (!lookup_feature(features, flagname, NULL, feature_name) &&
257 !lookup_feature(ext_features, flagname, NULL, ext_feature_name) &&
258 !lookup_feature(ext2_features, flagname, NULL, ext2_feature_name) &&
259 !lookup_feature(ext3_features, flagname, NULL, ext3_feature_name) &&
296acb64 260 !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name) &&
a9321a4d
PA
261 !lookup_feature(svm_features, flagname, NULL, svm_feature_name) &&
262 !lookup_feature(cpuid_7_0_ebx_features, flagname, NULL,
263 cpuid_7_0_ebx_feature_name))
c6dc6f63
AP
264 fprintf(stderr, "CPU feature %s not found\n", flagname);
265}
266
267typedef struct x86_def_t {
268 struct x86_def_t *next;
269 const char *name;
270 uint32_t level;
271 uint32_t vendor1, vendor2, vendor3;
272 int family;
273 int model;
274 int stepping;
b862d1fe 275 int tsc_khz;
296acb64
JR
276 uint32_t features, ext_features, ext2_features, ext3_features;
277 uint32_t kvm_features, svm_features;
c6dc6f63
AP
278 uint32_t xlevel;
279 char model_id[48];
280 int vendor_override;
b3baa152
BW
281 /* Store the results of Centaur's CPUID instructions */
282 uint32_t ext4_features;
283 uint32_t xlevel2;
13526728
EH
284 /* The feature bits on CPUID[EAX=7,ECX=0].EBX */
285 uint32_t cpuid_7_0_ebx_features;
c6dc6f63
AP
286} x86_def_t;
287
288#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
289#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
290 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
291#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
292 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
293 CPUID_PSE36 | CPUID_FXSR)
294#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
295#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
296 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
297 CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
298 CPUID_PAE | CPUID_SEP | CPUID_APIC)
299
551a2dec
AP
300#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
301 CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
302 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
303 CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
304 CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
8560efed
AJ
305 /* partly implemented:
306 CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
307 CPUID_PSE36 (needed for Solaris) */
308 /* missing:
309 CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
551a2dec 310#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | \
8713f8ff 311 CPUID_EXT_CX16 | CPUID_EXT_POPCNT | \
551a2dec 312 CPUID_EXT_HYPERVISOR)
8560efed
AJ
313 /* missing:
314 CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
8713f8ff 315 CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_XSAVE */
60032ac0 316#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
551a2dec
AP
317 CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
318 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
8560efed
AJ
319 /* missing:
320 CPUID_EXT2_PDPE1GB */
551a2dec
AP
321#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
322 CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
296acb64 323#define TCG_SVM_FEATURES 0
a9321a4d 324#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP)
551a2dec 325
c6dc6f63
AP
326/* maintains list of cpu model definitions
327 */
328static x86_def_t *x86_defs = {NULL};
329
330/* built-in cpu model definitions (deprecated)
331 */
332static x86_def_t builtin_x86_defs[] = {
c6dc6f63
AP
333 {
334 .name = "qemu64",
335 .level = 4,
336 .vendor1 = CPUID_VENDOR_AMD_1,
337 .vendor2 = CPUID_VENDOR_AMD_2,
338 .vendor3 = CPUID_VENDOR_AMD_3,
339 .family = 6,
340 .model = 2,
341 .stepping = 3,
342 .features = PPRO_FEATURES |
c6dc6f63 343 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
c6dc6f63
AP
344 CPUID_PSE36,
345 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
60032ac0 346 .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
c6dc6f63
AP
347 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
348 .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
349 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
350 .xlevel = 0x8000000A,
c6dc6f63
AP
351 },
352 {
353 .name = "phenom",
354 .level = 5,
355 .vendor1 = CPUID_VENDOR_AMD_1,
356 .vendor2 = CPUID_VENDOR_AMD_2,
357 .vendor3 = CPUID_VENDOR_AMD_3,
358 .family = 16,
359 .model = 2,
360 .stepping = 3,
c6dc6f63
AP
361 .features = PPRO_FEATURES |
362 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
8560efed 363 CPUID_PSE36 | CPUID_VME | CPUID_HT,
c6dc6f63
AP
364 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
365 CPUID_EXT_POPCNT,
60032ac0 366 .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
c6dc6f63
AP
367 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
368 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
8560efed 369 CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
c6dc6f63
AP
370 /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
371 CPUID_EXT3_CR8LEG,
372 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
373 CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
374 .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
375 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
296acb64 376 .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV,
c6dc6f63
AP
377 .xlevel = 0x8000001A,
378 .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
379 },
380 {
381 .name = "core2duo",
382 .level = 10,
383 .family = 6,
384 .model = 15,
385 .stepping = 11,
c6dc6f63
AP
386 .features = PPRO_FEATURES |
387 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
8560efed
AJ
388 CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
389 CPUID_HT | CPUID_TM | CPUID_PBE,
390 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
391 CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
392 CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
c6dc6f63
AP
393 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
394 .ext3_features = CPUID_EXT3_LAHF_LM,
395 .xlevel = 0x80000008,
396 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
397 },
398 {
399 .name = "kvm64",
400 .level = 5,
401 .vendor1 = CPUID_VENDOR_INTEL_1,
402 .vendor2 = CPUID_VENDOR_INTEL_2,
403 .vendor3 = CPUID_VENDOR_INTEL_3,
404 .family = 15,
405 .model = 6,
406 .stepping = 1,
407 /* Missing: CPUID_VME, CPUID_HT */
408 .features = PPRO_FEATURES |
409 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
410 CPUID_PSE36,
411 /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
412 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
413 /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
60032ac0 414 .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
c6dc6f63
AP
415 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
416 /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
417 CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
418 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
419 CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
420 .ext3_features = 0,
421 .xlevel = 0x80000008,
422 .model_id = "Common KVM processor"
423 },
c6dc6f63
AP
424 {
425 .name = "qemu32",
426 .level = 4,
427 .family = 6,
428 .model = 3,
429 .stepping = 3,
430 .features = PPRO_FEATURES,
431 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
58012d66 432 .xlevel = 0x80000004,
c6dc6f63 433 },
eafaf1e5
AP
434 {
435 .name = "kvm32",
436 .level = 5,
437 .family = 15,
438 .model = 6,
439 .stepping = 1,
440 .features = PPRO_FEATURES |
441 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
442 .ext_features = CPUID_EXT_SSE3,
60032ac0 443 .ext2_features = PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES,
eafaf1e5
AP
444 .ext3_features = 0,
445 .xlevel = 0x80000008,
446 .model_id = "Common 32-bit KVM processor"
447 },
c6dc6f63
AP
448 {
449 .name = "coreduo",
450 .level = 10,
451 .family = 6,
452 .model = 14,
453 .stepping = 8,
c6dc6f63 454 .features = PPRO_FEATURES | CPUID_VME |
8560efed
AJ
455 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
456 CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
457 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
458 CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
c6dc6f63
AP
459 .ext2_features = CPUID_EXT2_NX,
460 .xlevel = 0x80000008,
461 .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
462 },
463 {
464 .name = "486",
58012d66 465 .level = 1,
c6dc6f63
AP
466 .family = 4,
467 .model = 0,
468 .stepping = 0,
469 .features = I486_FEATURES,
470 .xlevel = 0,
471 },
472 {
473 .name = "pentium",
474 .level = 1,
475 .family = 5,
476 .model = 4,
477 .stepping = 3,
478 .features = PENTIUM_FEATURES,
479 .xlevel = 0,
480 },
481 {
482 .name = "pentium2",
483 .level = 2,
484 .family = 6,
485 .model = 5,
486 .stepping = 2,
487 .features = PENTIUM2_FEATURES,
488 .xlevel = 0,
489 },
490 {
491 .name = "pentium3",
492 .level = 2,
493 .family = 6,
494 .model = 7,
495 .stepping = 3,
496 .features = PENTIUM3_FEATURES,
497 .xlevel = 0,
498 },
499 {
500 .name = "athlon",
501 .level = 2,
502 .vendor1 = CPUID_VENDOR_AMD_1,
503 .vendor2 = CPUID_VENDOR_AMD_2,
504 .vendor3 = CPUID_VENDOR_AMD_3,
505 .family = 6,
506 .model = 2,
507 .stepping = 3,
60032ac0
EH
508 .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
509 CPUID_MCA,
510 .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
511 CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
c6dc6f63 512 .xlevel = 0x80000008,
c6dc6f63
AP
513 },
514 {
515 .name = "n270",
516 /* original is on level 10 */
517 .level = 5,
518 .family = 6,
519 .model = 28,
520 .stepping = 2,
521 .features = PPRO_FEATURES |
8560efed
AJ
522 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
523 CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
c6dc6f63 524 /* Some CPUs got no CPUID_SEP */
8560efed
AJ
525 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
526 CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR,
60032ac0
EH
527 .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
528 CPUID_EXT2_NX,
8560efed 529 .ext3_features = CPUID_EXT3_LAHF_LM,
c6dc6f63
AP
530 .xlevel = 0x8000000A,
531 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
532 },
3eca4642
EH
533 {
534 .name = "Conroe",
535 .level = 2,
536 .vendor1 = CPUID_VENDOR_INTEL_1,
537 .vendor2 = CPUID_VENDOR_INTEL_2,
538 .vendor3 = CPUID_VENDOR_INTEL_3,
539 .family = 6,
540 .model = 2,
541 .stepping = 3,
542 .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
543 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
544 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
545 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
546 CPUID_DE | CPUID_FP87,
547 .ext_features = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
548 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
549 .ext3_features = CPUID_EXT3_LAHF_LM,
550 .xlevel = 0x8000000A,
551 .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
552 },
553 {
554 .name = "Penryn",
555 .level = 2,
556 .vendor1 = CPUID_VENDOR_INTEL_1,
557 .vendor2 = CPUID_VENDOR_INTEL_2,
558 .vendor3 = CPUID_VENDOR_INTEL_3,
559 .family = 6,
560 .model = 2,
561 .stepping = 3,
562 .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
563 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
564 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
565 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
566 CPUID_DE | CPUID_FP87,
567 .ext_features = CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
568 CPUID_EXT_SSE3,
569 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
570 .ext3_features = CPUID_EXT3_LAHF_LM,
571 .xlevel = 0x8000000A,
572 .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
573 },
574 {
575 .name = "Nehalem",
576 .level = 2,
577 .vendor1 = CPUID_VENDOR_INTEL_1,
578 .vendor2 = CPUID_VENDOR_INTEL_2,
579 .vendor3 = CPUID_VENDOR_INTEL_3,
580 .family = 6,
581 .model = 2,
582 .stepping = 3,
583 .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
584 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
585 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
586 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
587 CPUID_DE | CPUID_FP87,
588 .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
589 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
590 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
591 .ext3_features = CPUID_EXT3_LAHF_LM,
592 .xlevel = 0x8000000A,
593 .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
594 },
595 {
596 .name = "Westmere",
597 .level = 11,
598 .vendor1 = CPUID_VENDOR_INTEL_1,
599 .vendor2 = CPUID_VENDOR_INTEL_2,
600 .vendor3 = CPUID_VENDOR_INTEL_3,
601 .family = 6,
602 .model = 44,
603 .stepping = 1,
604 .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
605 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
606 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
607 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
608 CPUID_DE | CPUID_FP87,
609 .ext_features = CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
610 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
611 CPUID_EXT_SSE3,
612 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
613 .ext3_features = CPUID_EXT3_LAHF_LM,
614 .xlevel = 0x8000000A,
615 .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
616 },
617 {
618 .name = "SandyBridge",
619 .level = 0xd,
620 .vendor1 = CPUID_VENDOR_INTEL_1,
621 .vendor2 = CPUID_VENDOR_INTEL_2,
622 .vendor3 = CPUID_VENDOR_INTEL_3,
623 .family = 6,
624 .model = 42,
625 .stepping = 1,
626 .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
627 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
628 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
629 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
630 CPUID_DE | CPUID_FP87,
631 .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
632 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
633 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
634 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
635 CPUID_EXT_SSE3,
636 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
637 CPUID_EXT2_SYSCALL,
638 .ext3_features = CPUID_EXT3_LAHF_LM,
639 .xlevel = 0x8000000A,
640 .model_id = "Intel Xeon E312xx (Sandy Bridge)",
641 },
642 {
643 .name = "Opteron_G1",
644 .level = 5,
645 .vendor1 = CPUID_VENDOR_AMD_1,
646 .vendor2 = CPUID_VENDOR_AMD_2,
647 .vendor3 = CPUID_VENDOR_AMD_3,
648 .family = 15,
649 .model = 6,
650 .stepping = 1,
651 .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
652 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
653 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
654 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
655 CPUID_DE | CPUID_FP87,
656 .ext_features = CPUID_EXT_SSE3,
657 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
658 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
659 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
660 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
661 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
662 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
663 .xlevel = 0x80000008,
664 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
665 },
666 {
667 .name = "Opteron_G2",
668 .level = 5,
669 .vendor1 = CPUID_VENDOR_AMD_1,
670 .vendor2 = CPUID_VENDOR_AMD_2,
671 .vendor3 = CPUID_VENDOR_AMD_3,
672 .family = 15,
673 .model = 6,
674 .stepping = 1,
675 .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
676 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
677 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
678 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
679 CPUID_DE | CPUID_FP87,
680 .ext_features = CPUID_EXT_CX16 | CPUID_EXT_SSE3,
681 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
682 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
683 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
684 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
685 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
686 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
687 CPUID_EXT2_DE | CPUID_EXT2_FPU,
688 .ext3_features = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
689 .xlevel = 0x80000008,
690 .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
691 },
692 {
693 .name = "Opteron_G3",
694 .level = 5,
695 .vendor1 = CPUID_VENDOR_AMD_1,
696 .vendor2 = CPUID_VENDOR_AMD_2,
697 .vendor3 = CPUID_VENDOR_AMD_3,
698 .family = 15,
699 .model = 6,
700 .stepping = 1,
701 .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
702 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
703 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
704 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
705 CPUID_DE | CPUID_FP87,
706 .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
707 CPUID_EXT_SSE3,
708 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
709 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
710 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
711 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
712 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
713 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
714 CPUID_EXT2_DE | CPUID_EXT2_FPU,
715 .ext3_features = CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
716 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
717 .xlevel = 0x80000008,
718 .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
719 },
720 {
721 .name = "Opteron_G4",
722 .level = 0xd,
723 .vendor1 = CPUID_VENDOR_AMD_1,
724 .vendor2 = CPUID_VENDOR_AMD_2,
725 .vendor3 = CPUID_VENDOR_AMD_3,
726 .family = 21,
727 .model = 1,
728 .stepping = 2,
729 .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
730 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
731 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
732 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
733 CPUID_DE | CPUID_FP87,
734 .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
735 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
736 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
737 CPUID_EXT_SSE3,
738 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
739 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
740 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
741 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
742 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
743 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
744 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
745 .ext3_features = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
746 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
747 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
748 CPUID_EXT3_LAHF_LM,
749 .xlevel = 0x8000001A,
750 .model_id = "AMD Opteron 62xx class CPU",
751 },
c6dc6f63
AP
752};
753
754static int cpu_x86_fill_model_id(char *str)
755{
756 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
757 int i;
758
759 for (i = 0; i < 3; i++) {
760 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
761 memcpy(str + i * 16 + 0, &eax, 4);
762 memcpy(str + i * 16 + 4, &ebx, 4);
763 memcpy(str + i * 16 + 8, &ecx, 4);
764 memcpy(str + i * 16 + 12, &edx, 4);
765 }
766 return 0;
767}
768
1aefc6b8 769static void cpu_x86_fill_host(x86_def_t *x86_cpu_def)
c6dc6f63
AP
770{
771 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
772
773 x86_cpu_def->name = "host";
774 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
775 x86_cpu_def->level = eax;
776 x86_cpu_def->vendor1 = ebx;
777 x86_cpu_def->vendor2 = edx;
778 x86_cpu_def->vendor3 = ecx;
779
780 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
781 x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
782 x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
783 x86_cpu_def->stepping = eax & 0x0F;
784 x86_cpu_def->ext_features = ecx;
785 x86_cpu_def->features = edx;
786
13526728
EH
787 if (kvm_enabled() && x86_cpu_def->level >= 7) {
788 x86_cpu_def->cpuid_7_0_ebx_features = kvm_arch_get_supported_cpuid(kvm_state, 0x7, 0, R_EBX);
789 } else {
790 x86_cpu_def->cpuid_7_0_ebx_features = 0;
791 }
792
c6dc6f63
AP
793 host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
794 x86_cpu_def->xlevel = eax;
795
796 host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
797 x86_cpu_def->ext2_features = edx;
798 x86_cpu_def->ext3_features = ecx;
799 cpu_x86_fill_model_id(x86_cpu_def->model_id);
800 x86_cpu_def->vendor_override = 0;
801
b3baa152
BW
802 /* Call Centaur's CPUID instruction. */
803 if (x86_cpu_def->vendor1 == CPUID_VENDOR_VIA_1 &&
804 x86_cpu_def->vendor2 == CPUID_VENDOR_VIA_2 &&
805 x86_cpu_def->vendor3 == CPUID_VENDOR_VIA_3) {
806 host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
807 if (eax >= 0xC0000001) {
808 /* Support VIA max extended level */
809 x86_cpu_def->xlevel2 = eax;
810 host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
811 x86_cpu_def->ext4_features = edx;
812 }
813 }
296acb64
JR
814
815 /*
816 * Every SVM feature requires emulation support in KVM - so we can't just
817 * read the host features here. KVM might even support SVM features not
818 * available on the host hardware. Just set all bits and mask out the
819 * unsupported ones later.
820 */
821 x86_cpu_def->svm_features = -1;
c6dc6f63
AP
822}
823
824static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
825{
826 int i;
827
828 for (i = 0; i < 32; ++i)
829 if (1 << i & mask) {
830 fprintf(stderr, "warning: host cpuid %04x_%04x lacks requested"
831 " flag '%s' [0x%08x]\n",
832 f->cpuid >> 16, f->cpuid & 0xffff,
833 f->flag_names[i] ? f->flag_names[i] : "[reserved]", mask);
834 break;
835 }
836 return 0;
837}
838
839/* best effort attempt to inform user requested cpu flags aren't making
840 * their way to the guest. Note: ft[].check_feat ideally should be
841 * specified via a guest_def field to suppress report of extraneous flags.
842 */
843static int check_features_against_host(x86_def_t *guest_def)
844{
845 x86_def_t host_def;
846 uint32_t mask;
847 int rv, i;
848 struct model_features_t ft[] = {
849 {&guest_def->features, &host_def.features,
850 ~0, feature_name, 0x00000000},
851 {&guest_def->ext_features, &host_def.ext_features,
852 ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
853 {&guest_def->ext2_features, &host_def.ext2_features,
854 ~PPRO_FEATURES, ext2_feature_name, 0x80000000},
855 {&guest_def->ext3_features, &host_def.ext3_features,
856 ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
857
858 cpu_x86_fill_host(&host_def);
66fe09ee 859 for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i)
c6dc6f63
AP
860 for (mask = 1; mask; mask <<= 1)
861 if (ft[i].check_feat & mask && *ft[i].guest_feat & mask &&
862 !(*ft[i].host_feat & mask)) {
863 unavailable_host_feature(&ft[i], mask);
864 rv = 1;
865 }
866 return rv;
867}
868
95b8519d
AF
869static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
870 const char *name, Error **errp)
871{
872 X86CPU *cpu = X86_CPU(obj);
873 CPUX86State *env = &cpu->env;
874 int64_t value;
875
876 value = (env->cpuid_version >> 8) & 0xf;
877 if (value == 0xf) {
878 value += (env->cpuid_version >> 20) & 0xff;
879 }
880 visit_type_int(v, &value, name, errp);
881}
882
71ad61d3
AF
883static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
884 const char *name, Error **errp)
ed5e1ec3 885{
71ad61d3
AF
886 X86CPU *cpu = X86_CPU(obj);
887 CPUX86State *env = &cpu->env;
888 const int64_t min = 0;
889 const int64_t max = 0xff + 0xf;
890 int64_t value;
891
892 visit_type_int(v, &value, name, errp);
893 if (error_is_set(errp)) {
894 return;
895 }
896 if (value < min || value > max) {
897 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
898 name ? name : "null", value, min, max);
899 return;
900 }
901
ed5e1ec3 902 env->cpuid_version &= ~0xff00f00;
71ad61d3
AF
903 if (value > 0x0f) {
904 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
ed5e1ec3 905 } else {
71ad61d3 906 env->cpuid_version |= value << 8;
ed5e1ec3
AF
907 }
908}
909
67e30c83
AF
910static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
911 const char *name, Error **errp)
912{
913 X86CPU *cpu = X86_CPU(obj);
914 CPUX86State *env = &cpu->env;
915 int64_t value;
916
917 value = (env->cpuid_version >> 4) & 0xf;
918 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
919 visit_type_int(v, &value, name, errp);
920}
921
c5291a4f
AF
922static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
923 const char *name, Error **errp)
b0704cbd 924{
c5291a4f
AF
925 X86CPU *cpu = X86_CPU(obj);
926 CPUX86State *env = &cpu->env;
927 const int64_t min = 0;
928 const int64_t max = 0xff;
929 int64_t value;
930
931 visit_type_int(v, &value, name, errp);
932 if (error_is_set(errp)) {
933 return;
934 }
935 if (value < min || value > max) {
936 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
937 name ? name : "null", value, min, max);
938 return;
939 }
940
b0704cbd 941 env->cpuid_version &= ~0xf00f0;
c5291a4f 942 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
b0704cbd
AF
943}
944
35112e41
AF
945static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
946 void *opaque, const char *name,
947 Error **errp)
948{
949 X86CPU *cpu = X86_CPU(obj);
950 CPUX86State *env = &cpu->env;
951 int64_t value;
952
953 value = env->cpuid_version & 0xf;
954 visit_type_int(v, &value, name, errp);
955}
956
036e2222
AF
957static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
958 void *opaque, const char *name,
959 Error **errp)
38c3dc46 960{
036e2222
AF
961 X86CPU *cpu = X86_CPU(obj);
962 CPUX86State *env = &cpu->env;
963 const int64_t min = 0;
964 const int64_t max = 0xf;
965 int64_t value;
966
967 visit_type_int(v, &value, name, errp);
968 if (error_is_set(errp)) {
969 return;
970 }
971 if (value < min || value > max) {
972 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
973 name ? name : "null", value, min, max);
974 return;
975 }
976
38c3dc46 977 env->cpuid_version &= ~0xf;
036e2222 978 env->cpuid_version |= value & 0xf;
38c3dc46
AF
979}
980
8e1898bf
AF
981static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
982 const char *name, Error **errp)
983{
984 X86CPU *cpu = X86_CPU(obj);
8e1898bf 985
fa029887 986 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
8e1898bf
AF
987}
988
989static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
990 const char *name, Error **errp)
991{
992 X86CPU *cpu = X86_CPU(obj);
8e1898bf 993
fa029887 994 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
8e1898bf
AF
995}
996
16b93aa8
AF
997static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
998 const char *name, Error **errp)
999{
1000 X86CPU *cpu = X86_CPU(obj);
16b93aa8 1001
fa029887 1002 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
16b93aa8
AF
1003}
1004
1005static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
1006 const char *name, Error **errp)
1007{
1008 X86CPU *cpu = X86_CPU(obj);
16b93aa8 1009
fa029887 1010 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
16b93aa8
AF
1011}
1012
d480e1af
AF
1013static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1014{
1015 X86CPU *cpu = X86_CPU(obj);
1016 CPUX86State *env = &cpu->env;
1017 char *value;
1018 int i;
1019
1020 value = (char *)g_malloc(12 + 1);
1021 for (i = 0; i < 4; i++) {
1022 value[i ] = env->cpuid_vendor1 >> (8 * i);
1023 value[i + 4] = env->cpuid_vendor2 >> (8 * i);
1024 value[i + 8] = env->cpuid_vendor3 >> (8 * i);
1025 }
1026 value[12] = '\0';
1027 return value;
1028}
1029
1030static void x86_cpuid_set_vendor(Object *obj, const char *value,
1031 Error **errp)
1032{
1033 X86CPU *cpu = X86_CPU(obj);
1034 CPUX86State *env = &cpu->env;
1035 int i;
1036
1037 if (strlen(value) != 12) {
1038 error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
1039 "vendor", value);
1040 return;
1041 }
1042
1043 env->cpuid_vendor1 = 0;
1044 env->cpuid_vendor2 = 0;
1045 env->cpuid_vendor3 = 0;
1046 for (i = 0; i < 4; i++) {
1047 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1048 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1049 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1050 }
1051 env->cpuid_vendor_override = 1;
1052}
1053
63e886eb
AF
1054static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1055{
1056 X86CPU *cpu = X86_CPU(obj);
1057 CPUX86State *env = &cpu->env;
1058 char *value;
1059 int i;
1060
1061 value = g_malloc(48 + 1);
1062 for (i = 0; i < 48; i++) {
1063 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1064 }
1065 value[48] = '\0';
1066 return value;
1067}
1068
938d4c25
AF
1069static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1070 Error **errp)
dcce6675 1071{
938d4c25
AF
1072 X86CPU *cpu = X86_CPU(obj);
1073 CPUX86State *env = &cpu->env;
dcce6675
AF
1074 int c, len, i;
1075
1076 if (model_id == NULL) {
1077 model_id = "";
1078 }
1079 len = strlen(model_id);
d0a6acf4 1080 memset(env->cpuid_model, 0, 48);
dcce6675
AF
1081 for (i = 0; i < 48; i++) {
1082 if (i >= len) {
1083 c = '\0';
1084 } else {
1085 c = (uint8_t)model_id[i];
1086 }
1087 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1088 }
1089}
1090
89e48965
AF
1091static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
1092 const char *name, Error **errp)
1093{
1094 X86CPU *cpu = X86_CPU(obj);
1095 int64_t value;
1096
1097 value = cpu->env.tsc_khz * 1000;
1098 visit_type_int(v, &value, name, errp);
1099}
1100
1101static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
1102 const char *name, Error **errp)
1103{
1104 X86CPU *cpu = X86_CPU(obj);
1105 const int64_t min = 0;
2e84849a 1106 const int64_t max = INT64_MAX;
89e48965
AF
1107 int64_t value;
1108
1109 visit_type_int(v, &value, name, errp);
1110 if (error_is_set(errp)) {
1111 return;
1112 }
1113 if (value < min || value > max) {
1114 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1115 name ? name : "null", value, min, max);
1116 return;
1117 }
1118
1119 cpu->env.tsc_khz = value / 1000;
1120}
1121
c6dc6f63
AP
1122static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
1123{
1124 unsigned int i;
1125 x86_def_t *def;
1126
d3c481b3 1127 char *s = g_strdup(cpu_model);
c6dc6f63 1128 char *featurestr, *name = strtok(s, ",");
296acb64
JR
1129 /* Features to be added*/
1130 uint32_t plus_features = 0, plus_ext_features = 0;
1131 uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
dc59944b 1132 uint32_t plus_kvm_features = kvm_default_features, plus_svm_features = 0;
a9321a4d 1133 uint32_t plus_7_0_ebx_features = 0;
296acb64
JR
1134 /* Features to be removed */
1135 uint32_t minus_features = 0, minus_ext_features = 0;
1136 uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
1137 uint32_t minus_kvm_features = 0, minus_svm_features = 0;
a9321a4d 1138 uint32_t minus_7_0_ebx_features = 0;
c6dc6f63
AP
1139 uint32_t numvalue;
1140
1141 for (def = x86_defs; def; def = def->next)
04c5b17a 1142 if (name && !strcmp(name, def->name))
c6dc6f63 1143 break;
04c5b17a 1144 if (kvm_enabled() && name && strcmp(name, "host") == 0) {
c6dc6f63
AP
1145 cpu_x86_fill_host(x86_cpu_def);
1146 } else if (!def) {
1147 goto error;
1148 } else {
1149 memcpy(x86_cpu_def, def, sizeof(*def));
1150 }
1151
c6dc6f63 1152 add_flagname_to_bitmaps("hypervisor", &plus_features,
a9321a4d
PA
1153 &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
1154 &plus_kvm_features, &plus_svm_features, &plus_7_0_ebx_features);
c6dc6f63
AP
1155
1156 featurestr = strtok(NULL, ",");
1157
1158 while (featurestr) {
1159 char *val;
1160 if (featurestr[0] == '+') {
296acb64
JR
1161 add_flagname_to_bitmaps(featurestr + 1, &plus_features,
1162 &plus_ext_features, &plus_ext2_features,
1163 &plus_ext3_features, &plus_kvm_features,
a9321a4d 1164 &plus_svm_features, &plus_7_0_ebx_features);
c6dc6f63 1165 } else if (featurestr[0] == '-') {
296acb64
JR
1166 add_flagname_to_bitmaps(featurestr + 1, &minus_features,
1167 &minus_ext_features, &minus_ext2_features,
1168 &minus_ext3_features, &minus_kvm_features,
a9321a4d 1169 &minus_svm_features, &minus_7_0_ebx_features);
c6dc6f63
AP
1170 } else if ((val = strchr(featurestr, '='))) {
1171 *val = 0; val++;
1172 if (!strcmp(featurestr, "family")) {
1173 char *err;
1174 numvalue = strtoul(val, &err, 0);
a88a677f 1175 if (!*val || *err || numvalue > 0xff + 0xf) {
c6dc6f63
AP
1176 fprintf(stderr, "bad numerical value %s\n", val);
1177 goto error;
1178 }
1179 x86_cpu_def->family = numvalue;
1180 } else if (!strcmp(featurestr, "model")) {
1181 char *err;
1182 numvalue = strtoul(val, &err, 0);
1183 if (!*val || *err || numvalue > 0xff) {
1184 fprintf(stderr, "bad numerical value %s\n", val);
1185 goto error;
1186 }
1187 x86_cpu_def->model = numvalue;
1188 } else if (!strcmp(featurestr, "stepping")) {
1189 char *err;
1190 numvalue = strtoul(val, &err, 0);
1191 if (!*val || *err || numvalue > 0xf) {
1192 fprintf(stderr, "bad numerical value %s\n", val);
1193 goto error;
1194 }
1195 x86_cpu_def->stepping = numvalue ;
1196 } else if (!strcmp(featurestr, "level")) {
1197 char *err;
1198 numvalue = strtoul(val, &err, 0);
1199 if (!*val || *err) {
1200 fprintf(stderr, "bad numerical value %s\n", val);
1201 goto error;
1202 }
1203 x86_cpu_def->level = numvalue;
1204 } else if (!strcmp(featurestr, "xlevel")) {
1205 char *err;
1206 numvalue = strtoul(val, &err, 0);
1207 if (!*val || *err) {
1208 fprintf(stderr, "bad numerical value %s\n", val);
1209 goto error;
1210 }
1211 if (numvalue < 0x80000000) {
2f7a21c4 1212 numvalue += 0x80000000;
c6dc6f63
AP
1213 }
1214 x86_cpu_def->xlevel = numvalue;
1215 } else if (!strcmp(featurestr, "vendor")) {
1216 if (strlen(val) != 12) {
1217 fprintf(stderr, "vendor string must be 12 chars long\n");
1218 goto error;
1219 }
1220 x86_cpu_def->vendor1 = 0;
1221 x86_cpu_def->vendor2 = 0;
1222 x86_cpu_def->vendor3 = 0;
1223 for(i = 0; i < 4; i++) {
1224 x86_cpu_def->vendor1 |= ((uint8_t)val[i ]) << (8 * i);
1225 x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
1226 x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
1227 }
1228 x86_cpu_def->vendor_override = 1;
1229 } else if (!strcmp(featurestr, "model_id")) {
1230 pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
1231 val);
b862d1fe
JR
1232 } else if (!strcmp(featurestr, "tsc_freq")) {
1233 int64_t tsc_freq;
1234 char *err;
1235
1236 tsc_freq = strtosz_suffix_unit(val, &err,
1237 STRTOSZ_DEFSUFFIX_B, 1000);
45009a30 1238 if (tsc_freq < 0 || *err) {
b862d1fe
JR
1239 fprintf(stderr, "bad numerical value %s\n", val);
1240 goto error;
1241 }
1242 x86_cpu_def->tsc_khz = tsc_freq / 1000;
28f52cc0
VR
1243 } else if (!strcmp(featurestr, "hv_spinlocks")) {
1244 char *err;
1245 numvalue = strtoul(val, &err, 0);
1246 if (!*val || *err) {
1247 fprintf(stderr, "bad numerical value %s\n", val);
1248 goto error;
1249 }
1250 hyperv_set_spinlock_retries(numvalue);
c6dc6f63
AP
1251 } else {
1252 fprintf(stderr, "unrecognized feature %s\n", featurestr);
1253 goto error;
1254 }
1255 } else if (!strcmp(featurestr, "check")) {
1256 check_cpuid = 1;
1257 } else if (!strcmp(featurestr, "enforce")) {
1258 check_cpuid = enforce_cpuid = 1;
28f52cc0
VR
1259 } else if (!strcmp(featurestr, "hv_relaxed")) {
1260 hyperv_enable_relaxed_timing(true);
1261 } else if (!strcmp(featurestr, "hv_vapic")) {
1262 hyperv_enable_vapic_recommended(true);
c6dc6f63
AP
1263 } else {
1264 fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
1265 goto error;
1266 }
1267 featurestr = strtok(NULL, ",");
1268 }
1269 x86_cpu_def->features |= plus_features;
1270 x86_cpu_def->ext_features |= plus_ext_features;
1271 x86_cpu_def->ext2_features |= plus_ext2_features;
1272 x86_cpu_def->ext3_features |= plus_ext3_features;
1273 x86_cpu_def->kvm_features |= plus_kvm_features;
296acb64 1274 x86_cpu_def->svm_features |= plus_svm_features;
a9321a4d 1275 x86_cpu_def->cpuid_7_0_ebx_features |= plus_7_0_ebx_features;
c6dc6f63
AP
1276 x86_cpu_def->features &= ~minus_features;
1277 x86_cpu_def->ext_features &= ~minus_ext_features;
1278 x86_cpu_def->ext2_features &= ~minus_ext2_features;
1279 x86_cpu_def->ext3_features &= ~minus_ext3_features;
1280 x86_cpu_def->kvm_features &= ~minus_kvm_features;
296acb64 1281 x86_cpu_def->svm_features &= ~minus_svm_features;
a9321a4d 1282 x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_7_0_ebx_features;
c6dc6f63
AP
1283 if (check_cpuid) {
1284 if (check_features_against_host(x86_cpu_def) && enforce_cpuid)
1285 goto error;
1286 }
a9321a4d
PA
1287 if (x86_cpu_def->cpuid_7_0_ebx_features && x86_cpu_def->level < 7) {
1288 x86_cpu_def->level = 7;
1289 }
d3c481b3 1290 g_free(s);
c6dc6f63
AP
1291 return 0;
1292
1293error:
d3c481b3 1294 g_free(s);
c6dc6f63
AP
1295 return -1;
1296}
1297
1298/* generate a composite string into buf of all cpuid names in featureset
1299 * selected by fbits. indicate truncation at bufsize in the event of overflow.
1300 * if flags, suppress names undefined in featureset.
1301 */
1302static void listflags(char *buf, int bufsize, uint32_t fbits,
1303 const char **featureset, uint32_t flags)
1304{
1305 const char **p = &featureset[31];
1306 char *q, *b, bit;
1307 int nc;
1308
1309 b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1310 *buf = '\0';
1311 for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1312 if (fbits & 1 << bit && (*p || !flags)) {
1313 if (*p)
1314 nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1315 else
1316 nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1317 if (bufsize <= nc) {
1318 if (b) {
1319 memcpy(b, "...", sizeof("..."));
1320 }
1321 return;
1322 }
1323 q += nc;
1324 bufsize -= nc;
1325 }
1326}
1327
e916cbf8
PM
1328/* generate CPU information. */
1329void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
c6dc6f63 1330{
c6dc6f63
AP
1331 x86_def_t *def;
1332 char buf[256];
1333
c6dc6f63 1334 for (def = x86_defs; def; def = def->next) {
c04321b3 1335 snprintf(buf, sizeof(buf), "%s", def->name);
6cdf8854 1336 (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
c6dc6f63 1337 }
ed2c54d4
AP
1338 if (kvm_enabled()) {
1339 (*cpu_fprintf)(f, "x86 %16s\n", "[host]");
1340 }
6cdf8854
PM
1341 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
1342 listflags(buf, sizeof(buf), (uint32_t)~0, feature_name, 1);
4a19e505 1343 (*cpu_fprintf)(f, " %s\n", buf);
6cdf8854 1344 listflags(buf, sizeof(buf), (uint32_t)~0, ext_feature_name, 1);
4a19e505 1345 (*cpu_fprintf)(f, " %s\n", buf);
6cdf8854 1346 listflags(buf, sizeof(buf), (uint32_t)~0, ext2_feature_name, 1);
4a19e505 1347 (*cpu_fprintf)(f, " %s\n", buf);
6cdf8854 1348 listflags(buf, sizeof(buf), (uint32_t)~0, ext3_feature_name, 1);
4a19e505 1349 (*cpu_fprintf)(f, " %s\n", buf);
c6dc6f63
AP
1350}
1351
76b64a7a 1352CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
e3966126
AL
1353{
1354 CpuDefinitionInfoList *cpu_list = NULL;
1355 x86_def_t *def;
1356
1357 for (def = x86_defs; def; def = def->next) {
1358 CpuDefinitionInfoList *entry;
1359 CpuDefinitionInfo *info;
1360
1361 info = g_malloc0(sizeof(*info));
1362 info->name = g_strdup(def->name);
1363
1364 entry = g_malloc0(sizeof(*entry));
1365 entry->value = info;
1366 entry->next = cpu_list;
1367 cpu_list = entry;
1368 }
1369
1370 return cpu_list;
1371}
1372
bc74b7db
EH
1373#ifdef CONFIG_KVM
1374static void filter_features_for_kvm(X86CPU *cpu)
1375{
1376 CPUX86State *env = &cpu->env;
1377 KVMState *s = kvm_state;
1378
b8091f24
EH
1379 env->cpuid_features &=
1380 kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
1381 env->cpuid_ext_features &=
1382 kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX);
1383 env->cpuid_ext2_features &=
1384 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
1385 env->cpuid_ext3_features &=
1386 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
1387 env->cpuid_svm_features &=
1388 kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
ffa8c11f
EH
1389 env->cpuid_7_0_ebx_features &=
1390 kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX);
bc74b7db 1391 env->cpuid_kvm_features &=
b8091f24
EH
1392 kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
1393 env->cpuid_ext4_features &=
1394 kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
bc74b7db
EH
1395
1396}
1397#endif
1398
61dcd775 1399int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
c6dc6f63 1400{
61dcd775 1401 CPUX86State *env = &cpu->env;
c6dc6f63 1402 x86_def_t def1, *def = &def1;
71ad61d3 1403 Error *error = NULL;
c6dc6f63 1404
db0ad1ba
JR
1405 memset(def, 0, sizeof(*def));
1406
c6dc6f63
AP
1407 if (cpu_x86_find_by_name(def, cpu_model) < 0)
1408 return -1;
1409 if (def->vendor1) {
1410 env->cpuid_vendor1 = def->vendor1;
1411 env->cpuid_vendor2 = def->vendor2;
1412 env->cpuid_vendor3 = def->vendor3;
1413 } else {
1414 env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
1415 env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
1416 env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
1417 }
1418 env->cpuid_vendor_override = def->vendor_override;
8e1898bf 1419 object_property_set_int(OBJECT(cpu), def->level, "level", &error);
71ad61d3 1420 object_property_set_int(OBJECT(cpu), def->family, "family", &error);
c5291a4f 1421 object_property_set_int(OBJECT(cpu), def->model, "model", &error);
036e2222 1422 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", &error);
c6dc6f63 1423 env->cpuid_features = def->features;
c6dc6f63
AP
1424 env->cpuid_ext_features = def->ext_features;
1425 env->cpuid_ext2_features = def->ext2_features;
4d067ed7 1426 env->cpuid_ext3_features = def->ext3_features;
16b93aa8 1427 object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", &error);
c6dc6f63 1428 env->cpuid_kvm_features = def->kvm_features;
296acb64 1429 env->cpuid_svm_features = def->svm_features;
b3baa152 1430 env->cpuid_ext4_features = def->ext4_features;
a9321a4d 1431 env->cpuid_7_0_ebx_features = def->cpuid_7_0_ebx_features;
b3baa152 1432 env->cpuid_xlevel2 = def->xlevel2;
89e48965
AF
1433 object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
1434 "tsc-frequency", &error);
3b671a40
EH
1435
1436 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
1437 * CPUID[1].EDX.
1438 */
1439 if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
1440 env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
1441 env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
1442 env->cpuid_ext2_features &= ~CPUID_EXT2_AMD_ALIASES;
1443 env->cpuid_ext2_features |= (def->features & CPUID_EXT2_AMD_ALIASES);
1444 }
1445
551a2dec
AP
1446 if (!kvm_enabled()) {
1447 env->cpuid_features &= TCG_FEATURES;
1448 env->cpuid_ext_features &= TCG_EXT_FEATURES;
1449 env->cpuid_ext2_features &= (TCG_EXT2_FEATURES
1450#ifdef TARGET_X86_64
1451 | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
1452#endif
1453 );
1454 env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
296acb64 1455 env->cpuid_svm_features &= TCG_SVM_FEATURES;
bc74b7db
EH
1456 } else {
1457#ifdef CONFIG_KVM
1458 filter_features_for_kvm(cpu);
1459#endif
551a2dec 1460 }
938d4c25 1461 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", &error);
71ad61d3
AF
1462 if (error_is_set(&error)) {
1463 error_free(error);
1464 return -1;
1465 }
c6dc6f63
AP
1466 return 0;
1467}
1468
1469#if !defined(CONFIG_USER_ONLY)
c6dc6f63 1470
0e26b7b8
BS
1471void cpu_clear_apic_feature(CPUX86State *env)
1472{
1473 env->cpuid_features &= ~CPUID_APIC;
1474}
1475
c6dc6f63
AP
1476#endif /* !CONFIG_USER_ONLY */
1477
c04321b3 1478/* Initialize list of CPU models, filling some non-static fields if necessary
c6dc6f63
AP
1479 */
1480void x86_cpudef_setup(void)
1481{
93bfef4c
CV
1482 int i, j;
1483 static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
c6dc6f63
AP
1484
1485 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
bc3e1291
EH
1486 x86_def_t *def = &builtin_x86_defs[i];
1487 def->next = x86_defs;
93bfef4c
CV
1488
1489 /* Look for specific "cpudef" models that */
09faecf2 1490 /* have the QEMU version in .model_id */
93bfef4c 1491 for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
bc3e1291
EH
1492 if (strcmp(model_with_versions[j], def->name) == 0) {
1493 pstrcpy(def->model_id, sizeof(def->model_id),
1494 "QEMU Virtual CPU version ");
1495 pstrcat(def->model_id, sizeof(def->model_id),
1496 qemu_get_version());
93bfef4c
CV
1497 break;
1498 }
1499 }
1500
bc3e1291 1501 x86_defs = def;
c6dc6f63 1502 }
c6dc6f63
AP
1503}
1504
c6dc6f63
AP
1505static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
1506 uint32_t *ecx, uint32_t *edx)
1507{
1508 *ebx = env->cpuid_vendor1;
1509 *edx = env->cpuid_vendor2;
1510 *ecx = env->cpuid_vendor3;
1511
1512 /* sysenter isn't supported on compatibility mode on AMD, syscall
1513 * isn't supported in compatibility mode on Intel.
1514 * Normally we advertise the actual cpu vendor, but you can override
1515 * this if you want to use KVM's sysenter/syscall emulation
1516 * in compatibility mode and when doing cross vendor migration
1517 */
89354998 1518 if (kvm_enabled() && ! env->cpuid_vendor_override) {
c6dc6f63
AP
1519 host_cpuid(0, 0, NULL, ebx, ecx, edx);
1520 }
1521}
1522
1523void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1524 uint32_t *eax, uint32_t *ebx,
1525 uint32_t *ecx, uint32_t *edx)
1526{
1527 /* test if maximum index reached */
1528 if (index & 0x80000000) {
b3baa152
BW
1529 if (index > env->cpuid_xlevel) {
1530 if (env->cpuid_xlevel2 > 0) {
1531 /* Handle the Centaur's CPUID instruction. */
1532 if (index > env->cpuid_xlevel2) {
1533 index = env->cpuid_xlevel2;
1534 } else if (index < 0xC0000000) {
1535 index = env->cpuid_xlevel;
1536 }
1537 } else {
1538 index = env->cpuid_xlevel;
1539 }
1540 }
c6dc6f63
AP
1541 } else {
1542 if (index > env->cpuid_level)
1543 index = env->cpuid_level;
1544 }
1545
1546 switch(index) {
1547 case 0:
1548 *eax = env->cpuid_level;
1549 get_cpuid_vendor(env, ebx, ecx, edx);
1550 break;
1551 case 1:
1552 *eax = env->cpuid_version;
1553 *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
1554 *ecx = env->cpuid_ext_features;
1555 *edx = env->cpuid_features;
1556 if (env->nr_cores * env->nr_threads > 1) {
1557 *ebx |= (env->nr_cores * env->nr_threads) << 16;
1558 *edx |= 1 << 28; /* HTT bit */
1559 }
1560 break;
1561 case 2:
1562 /* cache info: needed for Pentium Pro compatibility */
1563 *eax = 1;
1564 *ebx = 0;
1565 *ecx = 0;
1566 *edx = 0x2c307d;
1567 break;
1568 case 4:
1569 /* cache info: needed for Core compatibility */
1570 if (env->nr_cores > 1) {
2f7a21c4 1571 *eax = (env->nr_cores - 1) << 26;
c6dc6f63 1572 } else {
2f7a21c4 1573 *eax = 0;
c6dc6f63
AP
1574 }
1575 switch (count) {
1576 case 0: /* L1 dcache info */
1577 *eax |= 0x0000121;
1578 *ebx = 0x1c0003f;
1579 *ecx = 0x000003f;
1580 *edx = 0x0000001;
1581 break;
1582 case 1: /* L1 icache info */
1583 *eax |= 0x0000122;
1584 *ebx = 0x1c0003f;
1585 *ecx = 0x000003f;
1586 *edx = 0x0000001;
1587 break;
1588 case 2: /* L2 cache info */
1589 *eax |= 0x0000143;
1590 if (env->nr_threads > 1) {
1591 *eax |= (env->nr_threads - 1) << 14;
1592 }
1593 *ebx = 0x3c0003f;
1594 *ecx = 0x0000fff;
1595 *edx = 0x0000001;
1596 break;
1597 default: /* end of info */
1598 *eax = 0;
1599 *ebx = 0;
1600 *ecx = 0;
1601 *edx = 0;
1602 break;
1603 }
1604 break;
1605 case 5:
1606 /* mwait info: needed for Core compatibility */
1607 *eax = 0; /* Smallest monitor-line size in bytes */
1608 *ebx = 0; /* Largest monitor-line size in bytes */
1609 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
1610 *edx = 0;
1611 break;
1612 case 6:
1613 /* Thermal and Power Leaf */
1614 *eax = 0;
1615 *ebx = 0;
1616 *ecx = 0;
1617 *edx = 0;
1618 break;
f7911686 1619 case 7:
13526728
EH
1620 /* Structured Extended Feature Flags Enumeration Leaf */
1621 if (count == 0) {
1622 *eax = 0; /* Maximum ECX value for sub-leaves */
a9321a4d 1623 *ebx = env->cpuid_7_0_ebx_features; /* Feature flags */
13526728
EH
1624 *ecx = 0; /* Reserved */
1625 *edx = 0; /* Reserved */
f7911686
YW
1626 } else {
1627 *eax = 0;
1628 *ebx = 0;
1629 *ecx = 0;
1630 *edx = 0;
1631 }
1632 break;
c6dc6f63
AP
1633 case 9:
1634 /* Direct Cache Access Information Leaf */
1635 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
1636 *ebx = 0;
1637 *ecx = 0;
1638 *edx = 0;
1639 break;
1640 case 0xA:
1641 /* Architectural Performance Monitoring Leaf */
a0fa8208
GN
1642 if (kvm_enabled()) {
1643 KVMState *s = env->kvm_state;
1644
1645 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
1646 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
1647 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
1648 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
1649 } else {
1650 *eax = 0;
1651 *ebx = 0;
1652 *ecx = 0;
1653 *edx = 0;
1654 }
c6dc6f63 1655 break;
51e49430
SY
1656 case 0xD:
1657 /* Processor Extended State */
1658 if (!(env->cpuid_ext_features & CPUID_EXT_XSAVE)) {
1659 *eax = 0;
1660 *ebx = 0;
1661 *ecx = 0;
1662 *edx = 0;
1663 break;
1664 }
1665 if (kvm_enabled()) {
ba9bc59e
JK
1666 KVMState *s = env->kvm_state;
1667
1668 *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX);
1669 *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX);
1670 *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX);
1671 *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX);
51e49430
SY
1672 } else {
1673 *eax = 0;
1674 *ebx = 0;
1675 *ecx = 0;
1676 *edx = 0;
1677 }
1678 break;
c6dc6f63
AP
1679 case 0x80000000:
1680 *eax = env->cpuid_xlevel;
1681 *ebx = env->cpuid_vendor1;
1682 *edx = env->cpuid_vendor2;
1683 *ecx = env->cpuid_vendor3;
1684 break;
1685 case 0x80000001:
1686 *eax = env->cpuid_version;
1687 *ebx = 0;
1688 *ecx = env->cpuid_ext3_features;
1689 *edx = env->cpuid_ext2_features;
1690
1691 /* The Linux kernel checks for the CMPLegacy bit and
1692 * discards multiple thread information if it is set.
1693 * So dont set it here for Intel to make Linux guests happy.
1694 */
1695 if (env->nr_cores * env->nr_threads > 1) {
1696 uint32_t tebx, tecx, tedx;
1697 get_cpuid_vendor(env, &tebx, &tecx, &tedx);
1698 if (tebx != CPUID_VENDOR_INTEL_1 ||
1699 tedx != CPUID_VENDOR_INTEL_2 ||
1700 tecx != CPUID_VENDOR_INTEL_3) {
1701 *ecx |= 1 << 1; /* CmpLegacy bit */
1702 }
1703 }
c6dc6f63
AP
1704 break;
1705 case 0x80000002:
1706 case 0x80000003:
1707 case 0x80000004:
1708 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
1709 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
1710 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
1711 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
1712 break;
1713 case 0x80000005:
1714 /* cache info (L1 cache) */
1715 *eax = 0x01ff01ff;
1716 *ebx = 0x01ff01ff;
1717 *ecx = 0x40020140;
1718 *edx = 0x40020140;
1719 break;
1720 case 0x80000006:
1721 /* cache info (L2 cache) */
1722 *eax = 0;
1723 *ebx = 0x42004200;
1724 *ecx = 0x02008140;
1725 *edx = 0;
1726 break;
1727 case 0x80000008:
1728 /* virtual & phys address size in low 2 bytes. */
1729/* XXX: This value must match the one used in the MMU code. */
1730 if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
1731 /* 64 bit processor */
1732/* XXX: The physical address space is limited to 42 bits in exec.c. */
1733 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
1734 } else {
1735 if (env->cpuid_features & CPUID_PSE36)
1736 *eax = 0x00000024; /* 36 bits physical */
1737 else
1738 *eax = 0x00000020; /* 32 bits physical */
1739 }
1740 *ebx = 0;
1741 *ecx = 0;
1742 *edx = 0;
1743 if (env->nr_cores * env->nr_threads > 1) {
1744 *ecx |= (env->nr_cores * env->nr_threads) - 1;
1745 }
1746 break;
1747 case 0x8000000A:
296acb64
JR
1748 if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
1749 *eax = 0x00000001; /* SVM Revision */
1750 *ebx = 0x00000010; /* nr of ASIDs */
1751 *ecx = 0;
1752 *edx = env->cpuid_svm_features; /* optional features */
1753 } else {
1754 *eax = 0;
1755 *ebx = 0;
1756 *ecx = 0;
1757 *edx = 0;
1758 }
c6dc6f63 1759 break;
b3baa152
BW
1760 case 0xC0000000:
1761 *eax = env->cpuid_xlevel2;
1762 *ebx = 0;
1763 *ecx = 0;
1764 *edx = 0;
1765 break;
1766 case 0xC0000001:
1767 /* Support for VIA CPU's CPUID instruction */
1768 *eax = env->cpuid_version;
1769 *ebx = 0;
1770 *ecx = 0;
1771 *edx = env->cpuid_ext4_features;
1772 break;
1773 case 0xC0000002:
1774 case 0xC0000003:
1775 case 0xC0000004:
1776 /* Reserved for the future, and now filled with zero */
1777 *eax = 0;
1778 *ebx = 0;
1779 *ecx = 0;
1780 *edx = 0;
1781 break;
c6dc6f63
AP
1782 default:
1783 /* reserved values: zero */
1784 *eax = 0;
1785 *ebx = 0;
1786 *ecx = 0;
1787 *edx = 0;
1788 break;
1789 }
1790}
5fd2087a
AF
1791
1792/* CPUClass::reset() */
1793static void x86_cpu_reset(CPUState *s)
1794{
1795 X86CPU *cpu = X86_CPU(s);
1796 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
1797 CPUX86State *env = &cpu->env;
c1958aea
AF
1798 int i;
1799
1800 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
1801 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
6fd2a026 1802 log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP);
c1958aea 1803 }
5fd2087a
AF
1804
1805 xcc->parent_reset(s);
1806
c1958aea
AF
1807
1808 memset(env, 0, offsetof(CPUX86State, breakpoints));
1809
1810 tlb_flush(env, 1);
1811
1812 env->old_exception = -1;
1813
1814 /* init to reset state */
1815
1816#ifdef CONFIG_SOFTMMU
1817 env->hflags |= HF_SOFTMMU_MASK;
1818#endif
1819 env->hflags2 |= HF2_GIF_MASK;
1820
1821 cpu_x86_update_cr0(env, 0x60000010);
1822 env->a20_mask = ~0x0;
1823 env->smbase = 0x30000;
1824
1825 env->idt.limit = 0xffff;
1826 env->gdt.limit = 0xffff;
1827 env->ldt.limit = 0xffff;
1828 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
1829 env->tr.limit = 0xffff;
1830 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
1831
1832 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
1833 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
1834 DESC_R_MASK | DESC_A_MASK);
1835 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
1836 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1837 DESC_A_MASK);
1838 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
1839 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1840 DESC_A_MASK);
1841 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
1842 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1843 DESC_A_MASK);
1844 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
1845 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1846 DESC_A_MASK);
1847 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
1848 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1849 DESC_A_MASK);
1850
1851 env->eip = 0xfff0;
1852 env->regs[R_EDX] = env->cpuid_version;
1853
1854 env->eflags = 0x2;
1855
1856 /* FPU init */
1857 for (i = 0; i < 8; i++) {
1858 env->fptags[i] = 1;
1859 }
1860 env->fpuc = 0x37f;
1861
1862 env->mxcsr = 0x1f80;
1863
1864 env->pat = 0x0007040600070406ULL;
1865 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
1866
1867 memset(env->dr, 0, sizeof(env->dr));
1868 env->dr[6] = DR6_FIXED_1;
1869 env->dr[7] = DR7_FIXED_1;
1870 cpu_breakpoint_remove_all(env, BP_CPU);
1871 cpu_watchpoint_remove_all(env, BP_CPU);
dd673288
IM
1872
1873#if !defined(CONFIG_USER_ONLY)
1874 /* We hard-wire the BSP to the first CPU. */
1875 if (env->cpu_index == 0) {
1876 apic_designate_bsp(env->apic_state);
1877 }
1878
1879 env->halted = !cpu_is_bsp(cpu);
1880#endif
5fd2087a
AF
1881}
1882
dd673288
IM
1883#ifndef CONFIG_USER_ONLY
1884bool cpu_is_bsp(X86CPU *cpu)
1885{
1886 return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP;
1887}
65dee380
IM
1888
1889/* TODO: remove me, when reset over QOM tree is implemented */
1890static void x86_cpu_machine_reset_cb(void *opaque)
1891{
1892 X86CPU *cpu = opaque;
1893 cpu_reset(CPU(cpu));
1894}
dd673288
IM
1895#endif
1896
de024815
AF
1897static void mce_init(X86CPU *cpu)
1898{
1899 CPUX86State *cenv = &cpu->env;
1900 unsigned int bank;
1901
1902 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
1903 && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
1904 (CPUID_MCE | CPUID_MCA)) {
1905 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1906 cenv->mcg_ctl = ~(uint64_t)0;
1907 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
1908 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
1909 }
1910 }
1911}
1912
7a059953
AF
1913void x86_cpu_realize(Object *obj, Error **errp)
1914{
1915 X86CPU *cpu = X86_CPU(obj);
1916
65dee380
IM
1917#ifndef CONFIG_USER_ONLY
1918 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
1919#endif
1920
7a059953
AF
1921 mce_init(cpu);
1922 qemu_init_vcpu(&cpu->env);
65dee380 1923 cpu_reset(CPU(cpu));
7a059953
AF
1924}
1925
de024815
AF
1926static void x86_cpu_initfn(Object *obj)
1927{
1928 X86CPU *cpu = X86_CPU(obj);
1929 CPUX86State *env = &cpu->env;
d65e9815 1930 static int inited;
de024815
AF
1931
1932 cpu_exec_init(env);
71ad61d3
AF
1933
1934 object_property_add(obj, "family", "int",
95b8519d 1935 x86_cpuid_version_get_family,
71ad61d3 1936 x86_cpuid_version_set_family, NULL, NULL, NULL);
c5291a4f 1937 object_property_add(obj, "model", "int",
67e30c83 1938 x86_cpuid_version_get_model,
c5291a4f 1939 x86_cpuid_version_set_model, NULL, NULL, NULL);
036e2222 1940 object_property_add(obj, "stepping", "int",
35112e41 1941 x86_cpuid_version_get_stepping,
036e2222 1942 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
8e1898bf
AF
1943 object_property_add(obj, "level", "int",
1944 x86_cpuid_get_level,
1945 x86_cpuid_set_level, NULL, NULL, NULL);
16b93aa8
AF
1946 object_property_add(obj, "xlevel", "int",
1947 x86_cpuid_get_xlevel,
1948 x86_cpuid_set_xlevel, NULL, NULL, NULL);
d480e1af
AF
1949 object_property_add_str(obj, "vendor",
1950 x86_cpuid_get_vendor,
1951 x86_cpuid_set_vendor, NULL);
938d4c25 1952 object_property_add_str(obj, "model-id",
63e886eb 1953 x86_cpuid_get_model_id,
938d4c25 1954 x86_cpuid_set_model_id, NULL);
89e48965
AF
1955 object_property_add(obj, "tsc-frequency", "int",
1956 x86_cpuid_get_tsc_freq,
1957 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
71ad61d3 1958
de024815 1959 env->cpuid_apic_id = env->cpu_index;
d65e9815
IM
1960
1961 /* init various static tables used in TCG mode */
1962 if (tcg_enabled() && !inited) {
1963 inited = 1;
1964 optimize_flags_init();
1965#ifndef CONFIG_USER_ONLY
1966 cpu_set_debug_excp_handler(breakpoint_handler);
1967#endif
1968 }
de024815
AF
1969}
1970
5fd2087a
AF
1971static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
1972{
1973 X86CPUClass *xcc = X86_CPU_CLASS(oc);
1974 CPUClass *cc = CPU_CLASS(oc);
1975
1976 xcc->parent_reset = cc->reset;
1977 cc->reset = x86_cpu_reset;
1978}
1979
1980static const TypeInfo x86_cpu_type_info = {
1981 .name = TYPE_X86_CPU,
1982 .parent = TYPE_CPU,
1983 .instance_size = sizeof(X86CPU),
de024815 1984 .instance_init = x86_cpu_initfn,
5fd2087a
AF
1985 .abstract = false,
1986 .class_size = sizeof(X86CPUClass),
1987 .class_init = x86_cpu_common_class_init,
1988};
1989
1990static void x86_cpu_register_types(void)
1991{
1992 type_register_static(&x86_cpu_type_info);
1993}
1994
1995type_init(x86_cpu_register_types)