]> git.proxmox.com Git - qemu.git/blame - target-i386/cpu.c
target-i386: cpu: make -cpu host/check/enforce code KVM-specific
[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 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
6e746f30
EH
769/* Fill a x86_def_t struct with information about the host CPU, and
770 * the CPU features supported by the host hardware + host kernel
771 *
772 * This function may be called only if KVM is enabled.
773 */
774static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
c6dc6f63
AP
775{
776 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
777
6e746f30
EH
778 assert(kvm_enabled());
779
c6dc6f63
AP
780 x86_cpu_def->name = "host";
781 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
782 x86_cpu_def->level = eax;
783 x86_cpu_def->vendor1 = ebx;
784 x86_cpu_def->vendor2 = edx;
785 x86_cpu_def->vendor3 = ecx;
786
787 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
788 x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
789 x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
790 x86_cpu_def->stepping = eax & 0x0F;
791 x86_cpu_def->ext_features = ecx;
792 x86_cpu_def->features = edx;
793
6e746f30 794 if (x86_cpu_def->level >= 7) {
13526728
EH
795 x86_cpu_def->cpuid_7_0_ebx_features = kvm_arch_get_supported_cpuid(kvm_state, 0x7, 0, R_EBX);
796 } else {
797 x86_cpu_def->cpuid_7_0_ebx_features = 0;
798 }
799
c6dc6f63
AP
800 host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
801 x86_cpu_def->xlevel = eax;
802
803 host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
804 x86_cpu_def->ext2_features = edx;
805 x86_cpu_def->ext3_features = ecx;
806 cpu_x86_fill_model_id(x86_cpu_def->model_id);
807 x86_cpu_def->vendor_override = 0;
808
b3baa152 809 /* Call Centaur's CPUID instruction. */
810 if (x86_cpu_def->vendor1 == CPUID_VENDOR_VIA_1 &&
811 x86_cpu_def->vendor2 == CPUID_VENDOR_VIA_2 &&
812 x86_cpu_def->vendor3 == CPUID_VENDOR_VIA_3) {
813 host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
814 if (eax >= 0xC0000001) {
815 /* Support VIA max extended level */
816 x86_cpu_def->xlevel2 = eax;
817 host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
818 x86_cpu_def->ext4_features = edx;
819 }
820 }
296acb64
JR
821
822 /*
823 * Every SVM feature requires emulation support in KVM - so we can't just
824 * read the host features here. KVM might even support SVM features not
825 * available on the host hardware. Just set all bits and mask out the
826 * unsupported ones later.
827 */
828 x86_cpu_def->svm_features = -1;
c6dc6f63
AP
829}
830
831static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
832{
833 int i;
834
835 for (i = 0; i < 32; ++i)
836 if (1 << i & mask) {
837 fprintf(stderr, "warning: host cpuid %04x_%04x lacks requested"
838 " flag '%s' [0x%08x]\n",
839 f->cpuid >> 16, f->cpuid & 0xffff,
840 f->flag_names[i] ? f->flag_names[i] : "[reserved]", mask);
841 break;
842 }
843 return 0;
844}
845
846/* best effort attempt to inform user requested cpu flags aren't making
847 * their way to the guest. Note: ft[].check_feat ideally should be
848 * specified via a guest_def field to suppress report of extraneous flags.
6e746f30
EH
849 *
850 * This function may be called only if KVM is enabled.
c6dc6f63 851 */
6e746f30 852static int kvm_check_features_against_host(x86_def_t *guest_def)
c6dc6f63
AP
853{
854 x86_def_t host_def;
855 uint32_t mask;
856 int rv, i;
857 struct model_features_t ft[] = {
858 {&guest_def->features, &host_def.features,
859 ~0, feature_name, 0x00000000},
860 {&guest_def->ext_features, &host_def.ext_features,
861 ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
862 {&guest_def->ext2_features, &host_def.ext2_features,
863 ~PPRO_FEATURES, ext2_feature_name, 0x80000000},
864 {&guest_def->ext3_features, &host_def.ext3_features,
865 ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
866
6e746f30
EH
867 assert(kvm_enabled());
868
869 kvm_cpu_fill_host(&host_def);
66fe09ee 870 for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i)
c6dc6f63
AP
871 for (mask = 1; mask; mask <<= 1)
872 if (ft[i].check_feat & mask && *ft[i].guest_feat & mask &&
873 !(*ft[i].host_feat & mask)) {
874 unavailable_host_feature(&ft[i], mask);
875 rv = 1;
876 }
877 return rv;
878}
879
95b8519d
AF
880static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
881 const char *name, Error **errp)
882{
883 X86CPU *cpu = X86_CPU(obj);
884 CPUX86State *env = &cpu->env;
885 int64_t value;
886
887 value = (env->cpuid_version >> 8) & 0xf;
888 if (value == 0xf) {
889 value += (env->cpuid_version >> 20) & 0xff;
890 }
891 visit_type_int(v, &value, name, errp);
892}
893
71ad61d3
AF
894static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
895 const char *name, Error **errp)
ed5e1ec3 896{
71ad61d3
AF
897 X86CPU *cpu = X86_CPU(obj);
898 CPUX86State *env = &cpu->env;
899 const int64_t min = 0;
900 const int64_t max = 0xff + 0xf;
901 int64_t value;
902
903 visit_type_int(v, &value, name, errp);
904 if (error_is_set(errp)) {
905 return;
906 }
907 if (value < min || value > max) {
908 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
909 name ? name : "null", value, min, max);
910 return;
911 }
912
ed5e1ec3 913 env->cpuid_version &= ~0xff00f00;
71ad61d3
AF
914 if (value > 0x0f) {
915 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
ed5e1ec3 916 } else {
71ad61d3 917 env->cpuid_version |= value << 8;
ed5e1ec3
AF
918 }
919}
920
67e30c83
AF
921static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
922 const char *name, Error **errp)
923{
924 X86CPU *cpu = X86_CPU(obj);
925 CPUX86State *env = &cpu->env;
926 int64_t value;
927
928 value = (env->cpuid_version >> 4) & 0xf;
929 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
930 visit_type_int(v, &value, name, errp);
931}
932
c5291a4f
AF
933static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
934 const char *name, Error **errp)
b0704cbd 935{
c5291a4f
AF
936 X86CPU *cpu = X86_CPU(obj);
937 CPUX86State *env = &cpu->env;
938 const int64_t min = 0;
939 const int64_t max = 0xff;
940 int64_t value;
941
942 visit_type_int(v, &value, name, errp);
943 if (error_is_set(errp)) {
944 return;
945 }
946 if (value < min || value > max) {
947 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
948 name ? name : "null", value, min, max);
949 return;
950 }
951
b0704cbd 952 env->cpuid_version &= ~0xf00f0;
c5291a4f 953 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
b0704cbd
AF
954}
955
35112e41
AF
956static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
957 void *opaque, const char *name,
958 Error **errp)
959{
960 X86CPU *cpu = X86_CPU(obj);
961 CPUX86State *env = &cpu->env;
962 int64_t value;
963
964 value = env->cpuid_version & 0xf;
965 visit_type_int(v, &value, name, errp);
966}
967
036e2222
AF
968static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
969 void *opaque, const char *name,
970 Error **errp)
38c3dc46 971{
036e2222
AF
972 X86CPU *cpu = X86_CPU(obj);
973 CPUX86State *env = &cpu->env;
974 const int64_t min = 0;
975 const int64_t max = 0xf;
976 int64_t value;
977
978 visit_type_int(v, &value, name, errp);
979 if (error_is_set(errp)) {
980 return;
981 }
982 if (value < min || value > max) {
983 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
984 name ? name : "null", value, min, max);
985 return;
986 }
987
38c3dc46 988 env->cpuid_version &= ~0xf;
036e2222 989 env->cpuid_version |= value & 0xf;
38c3dc46
AF
990}
991
8e1898bf
AF
992static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
993 const char *name, Error **errp)
994{
995 X86CPU *cpu = X86_CPU(obj);
8e1898bf 996
fa029887 997 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
8e1898bf
AF
998}
999
1000static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
1001 const char *name, Error **errp)
1002{
1003 X86CPU *cpu = X86_CPU(obj);
8e1898bf 1004
fa029887 1005 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
8e1898bf
AF
1006}
1007
16b93aa8
AF
1008static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
1009 const char *name, Error **errp)
1010{
1011 X86CPU *cpu = X86_CPU(obj);
16b93aa8 1012
fa029887 1013 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
16b93aa8
AF
1014}
1015
1016static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
1017 const char *name, Error **errp)
1018{
1019 X86CPU *cpu = X86_CPU(obj);
16b93aa8 1020
fa029887 1021 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
16b93aa8
AF
1022}
1023
d480e1af
AF
1024static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1025{
1026 X86CPU *cpu = X86_CPU(obj);
1027 CPUX86State *env = &cpu->env;
1028 char *value;
1029 int i;
1030
1031 value = (char *)g_malloc(12 + 1);
1032 for (i = 0; i < 4; i++) {
1033 value[i ] = env->cpuid_vendor1 >> (8 * i);
1034 value[i + 4] = env->cpuid_vendor2 >> (8 * i);
1035 value[i + 8] = env->cpuid_vendor3 >> (8 * i);
1036 }
1037 value[12] = '\0';
1038 return value;
1039}
1040
1041static void x86_cpuid_set_vendor(Object *obj, const char *value,
1042 Error **errp)
1043{
1044 X86CPU *cpu = X86_CPU(obj);
1045 CPUX86State *env = &cpu->env;
1046 int i;
1047
1048 if (strlen(value) != 12) {
1049 error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
1050 "vendor", value);
1051 return;
1052 }
1053
1054 env->cpuid_vendor1 = 0;
1055 env->cpuid_vendor2 = 0;
1056 env->cpuid_vendor3 = 0;
1057 for (i = 0; i < 4; i++) {
1058 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1059 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1060 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1061 }
1062 env->cpuid_vendor_override = 1;
1063}
1064
63e886eb
AF
1065static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1066{
1067 X86CPU *cpu = X86_CPU(obj);
1068 CPUX86State *env = &cpu->env;
1069 char *value;
1070 int i;
1071
1072 value = g_malloc(48 + 1);
1073 for (i = 0; i < 48; i++) {
1074 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1075 }
1076 value[48] = '\0';
1077 return value;
1078}
1079
938d4c25
AF
1080static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1081 Error **errp)
dcce6675 1082{
938d4c25
AF
1083 X86CPU *cpu = X86_CPU(obj);
1084 CPUX86State *env = &cpu->env;
dcce6675
AF
1085 int c, len, i;
1086
1087 if (model_id == NULL) {
1088 model_id = "";
1089 }
1090 len = strlen(model_id);
d0a6acf4 1091 memset(env->cpuid_model, 0, 48);
dcce6675
AF
1092 for (i = 0; i < 48; i++) {
1093 if (i >= len) {
1094 c = '\0';
1095 } else {
1096 c = (uint8_t)model_id[i];
1097 }
1098 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1099 }
1100}
1101
89e48965
AF
1102static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
1103 const char *name, Error **errp)
1104{
1105 X86CPU *cpu = X86_CPU(obj);
1106 int64_t value;
1107
1108 value = cpu->env.tsc_khz * 1000;
1109 visit_type_int(v, &value, name, errp);
1110}
1111
1112static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
1113 const char *name, Error **errp)
1114{
1115 X86CPU *cpu = X86_CPU(obj);
1116 const int64_t min = 0;
2e84849a 1117 const int64_t max = INT64_MAX;
89e48965
AF
1118 int64_t value;
1119
1120 visit_type_int(v, &value, name, errp);
1121 if (error_is_set(errp)) {
1122 return;
1123 }
1124 if (value < min || value > max) {
1125 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1126 name ? name : "null", value, min, max);
1127 return;
1128 }
1129
1130 cpu->env.tsc_khz = value / 1000;
1131}
1132
c6dc6f63
AP
1133static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
1134{
1135 unsigned int i;
1136 x86_def_t *def;
1137
d3c481b3 1138 char *s = g_strdup(cpu_model);
c6dc6f63 1139 char *featurestr, *name = strtok(s, ",");
296acb64
JR
1140 /* Features to be added*/
1141 uint32_t plus_features = 0, plus_ext_features = 0;
1142 uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
dc59944b 1143 uint32_t plus_kvm_features = kvm_default_features, plus_svm_features = 0;
a9321a4d 1144 uint32_t plus_7_0_ebx_features = 0;
296acb64
JR
1145 /* Features to be removed */
1146 uint32_t minus_features = 0, minus_ext_features = 0;
1147 uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
1148 uint32_t minus_kvm_features = 0, minus_svm_features = 0;
a9321a4d 1149 uint32_t minus_7_0_ebx_features = 0;
c6dc6f63
AP
1150 uint32_t numvalue;
1151
1152 for (def = x86_defs; def; def = def->next)
04c5b17a 1153 if (name && !strcmp(name, def->name))
c6dc6f63 1154 break;
04c5b17a 1155 if (kvm_enabled() && name && strcmp(name, "host") == 0) {
6e746f30 1156 kvm_cpu_fill_host(x86_cpu_def);
c6dc6f63
AP
1157 } else if (!def) {
1158 goto error;
1159 } else {
1160 memcpy(x86_cpu_def, def, sizeof(*def));
1161 }
1162
c6dc6f63 1163 add_flagname_to_bitmaps("hypervisor", &plus_features,
a9321a4d
PA
1164 &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
1165 &plus_kvm_features, &plus_svm_features, &plus_7_0_ebx_features);
c6dc6f63
AP
1166
1167 featurestr = strtok(NULL, ",");
1168
1169 while (featurestr) {
1170 char *val;
1171 if (featurestr[0] == '+') {
296acb64
JR
1172 add_flagname_to_bitmaps(featurestr + 1, &plus_features,
1173 &plus_ext_features, &plus_ext2_features,
1174 &plus_ext3_features, &plus_kvm_features,
a9321a4d 1175 &plus_svm_features, &plus_7_0_ebx_features);
c6dc6f63 1176 } else if (featurestr[0] == '-') {
296acb64
JR
1177 add_flagname_to_bitmaps(featurestr + 1, &minus_features,
1178 &minus_ext_features, &minus_ext2_features,
1179 &minus_ext3_features, &minus_kvm_features,
a9321a4d 1180 &minus_svm_features, &minus_7_0_ebx_features);
c6dc6f63
AP
1181 } else if ((val = strchr(featurestr, '='))) {
1182 *val = 0; val++;
1183 if (!strcmp(featurestr, "family")) {
1184 char *err;
1185 numvalue = strtoul(val, &err, 0);
a88a677f 1186 if (!*val || *err || numvalue > 0xff + 0xf) {
c6dc6f63
AP
1187 fprintf(stderr, "bad numerical value %s\n", val);
1188 goto error;
1189 }
1190 x86_cpu_def->family = numvalue;
1191 } else if (!strcmp(featurestr, "model")) {
1192 char *err;
1193 numvalue = strtoul(val, &err, 0);
1194 if (!*val || *err || numvalue > 0xff) {
1195 fprintf(stderr, "bad numerical value %s\n", val);
1196 goto error;
1197 }
1198 x86_cpu_def->model = numvalue;
1199 } else if (!strcmp(featurestr, "stepping")) {
1200 char *err;
1201 numvalue = strtoul(val, &err, 0);
1202 if (!*val || *err || numvalue > 0xf) {
1203 fprintf(stderr, "bad numerical value %s\n", val);
1204 goto error;
1205 }
1206 x86_cpu_def->stepping = numvalue ;
1207 } else if (!strcmp(featurestr, "level")) {
1208 char *err;
1209 numvalue = strtoul(val, &err, 0);
1210 if (!*val || *err) {
1211 fprintf(stderr, "bad numerical value %s\n", val);
1212 goto error;
1213 }
1214 x86_cpu_def->level = numvalue;
1215 } else if (!strcmp(featurestr, "xlevel")) {
1216 char *err;
1217 numvalue = strtoul(val, &err, 0);
1218 if (!*val || *err) {
1219 fprintf(stderr, "bad numerical value %s\n", val);
1220 goto error;
1221 }
1222 if (numvalue < 0x80000000) {
2f7a21c4 1223 numvalue += 0x80000000;
c6dc6f63
AP
1224 }
1225 x86_cpu_def->xlevel = numvalue;
1226 } else if (!strcmp(featurestr, "vendor")) {
1227 if (strlen(val) != 12) {
1228 fprintf(stderr, "vendor string must be 12 chars long\n");
1229 goto error;
1230 }
1231 x86_cpu_def->vendor1 = 0;
1232 x86_cpu_def->vendor2 = 0;
1233 x86_cpu_def->vendor3 = 0;
1234 for(i = 0; i < 4; i++) {
1235 x86_cpu_def->vendor1 |= ((uint8_t)val[i ]) << (8 * i);
1236 x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
1237 x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
1238 }
1239 x86_cpu_def->vendor_override = 1;
1240 } else if (!strcmp(featurestr, "model_id")) {
1241 pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
1242 val);
b862d1fe
JR
1243 } else if (!strcmp(featurestr, "tsc_freq")) {
1244 int64_t tsc_freq;
1245 char *err;
1246
1247 tsc_freq = strtosz_suffix_unit(val, &err,
1248 STRTOSZ_DEFSUFFIX_B, 1000);
45009a30 1249 if (tsc_freq < 0 || *err) {
b862d1fe
JR
1250 fprintf(stderr, "bad numerical value %s\n", val);
1251 goto error;
1252 }
1253 x86_cpu_def->tsc_khz = tsc_freq / 1000;
28f52cc0
VR
1254 } else if (!strcmp(featurestr, "hv_spinlocks")) {
1255 char *err;
1256 numvalue = strtoul(val, &err, 0);
1257 if (!*val || *err) {
1258 fprintf(stderr, "bad numerical value %s\n", val);
1259 goto error;
1260 }
1261 hyperv_set_spinlock_retries(numvalue);
c6dc6f63
AP
1262 } else {
1263 fprintf(stderr, "unrecognized feature %s\n", featurestr);
1264 goto error;
1265 }
1266 } else if (!strcmp(featurestr, "check")) {
1267 check_cpuid = 1;
1268 } else if (!strcmp(featurestr, "enforce")) {
1269 check_cpuid = enforce_cpuid = 1;
28f52cc0
VR
1270 } else if (!strcmp(featurestr, "hv_relaxed")) {
1271 hyperv_enable_relaxed_timing(true);
1272 } else if (!strcmp(featurestr, "hv_vapic")) {
1273 hyperv_enable_vapic_recommended(true);
c6dc6f63
AP
1274 } else {
1275 fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
1276 goto error;
1277 }
1278 featurestr = strtok(NULL, ",");
1279 }
1280 x86_cpu_def->features |= plus_features;
1281 x86_cpu_def->ext_features |= plus_ext_features;
1282 x86_cpu_def->ext2_features |= plus_ext2_features;
1283 x86_cpu_def->ext3_features |= plus_ext3_features;
1284 x86_cpu_def->kvm_features |= plus_kvm_features;
296acb64 1285 x86_cpu_def->svm_features |= plus_svm_features;
a9321a4d 1286 x86_cpu_def->cpuid_7_0_ebx_features |= plus_7_0_ebx_features;
c6dc6f63
AP
1287 x86_cpu_def->features &= ~minus_features;
1288 x86_cpu_def->ext_features &= ~minus_ext_features;
1289 x86_cpu_def->ext2_features &= ~minus_ext2_features;
1290 x86_cpu_def->ext3_features &= ~minus_ext3_features;
1291 x86_cpu_def->kvm_features &= ~minus_kvm_features;
296acb64 1292 x86_cpu_def->svm_features &= ~minus_svm_features;
a9321a4d 1293 x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_7_0_ebx_features;
6e746f30
EH
1294 if (check_cpuid && kvm_enabled()) {
1295 if (kvm_check_features_against_host(x86_cpu_def) && enforce_cpuid)
c6dc6f63
AP
1296 goto error;
1297 }
a9321a4d
PA
1298 if (x86_cpu_def->cpuid_7_0_ebx_features && x86_cpu_def->level < 7) {
1299 x86_cpu_def->level = 7;
1300 }
d3c481b3 1301 g_free(s);
c6dc6f63
AP
1302 return 0;
1303
1304error:
d3c481b3 1305 g_free(s);
c6dc6f63
AP
1306 return -1;
1307}
1308
1309/* generate a composite string into buf of all cpuid names in featureset
1310 * selected by fbits. indicate truncation at bufsize in the event of overflow.
1311 * if flags, suppress names undefined in featureset.
1312 */
1313static void listflags(char *buf, int bufsize, uint32_t fbits,
1314 const char **featureset, uint32_t flags)
1315{
1316 const char **p = &featureset[31];
1317 char *q, *b, bit;
1318 int nc;
1319
1320 b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1321 *buf = '\0';
1322 for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1323 if (fbits & 1 << bit && (*p || !flags)) {
1324 if (*p)
1325 nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1326 else
1327 nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1328 if (bufsize <= nc) {
1329 if (b) {
1330 memcpy(b, "...", sizeof("..."));
1331 }
1332 return;
1333 }
1334 q += nc;
1335 bufsize -= nc;
1336 }
1337}
1338
e916cbf8
PM
1339/* generate CPU information. */
1340void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
c6dc6f63 1341{
c6dc6f63
AP
1342 x86_def_t *def;
1343 char buf[256];
1344
c6dc6f63 1345 for (def = x86_defs; def; def = def->next) {
c04321b3 1346 snprintf(buf, sizeof(buf), "%s", def->name);
6cdf8854 1347 (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
c6dc6f63 1348 }
ed2c54d4
AP
1349 if (kvm_enabled()) {
1350 (*cpu_fprintf)(f, "x86 %16s\n", "[host]");
1351 }
6cdf8854
PM
1352 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
1353 listflags(buf, sizeof(buf), (uint32_t)~0, feature_name, 1);
4a19e505 1354 (*cpu_fprintf)(f, " %s\n", buf);
6cdf8854 1355 listflags(buf, sizeof(buf), (uint32_t)~0, ext_feature_name, 1);
4a19e505 1356 (*cpu_fprintf)(f, " %s\n", buf);
6cdf8854 1357 listflags(buf, sizeof(buf), (uint32_t)~0, ext2_feature_name, 1);
4a19e505 1358 (*cpu_fprintf)(f, " %s\n", buf);
6cdf8854 1359 listflags(buf, sizeof(buf), (uint32_t)~0, ext3_feature_name, 1);
4a19e505 1360 (*cpu_fprintf)(f, " %s\n", buf);
c6dc6f63
AP
1361}
1362
76b64a7a 1363CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
e3966126
AL
1364{
1365 CpuDefinitionInfoList *cpu_list = NULL;
1366 x86_def_t *def;
1367
1368 for (def = x86_defs; def; def = def->next) {
1369 CpuDefinitionInfoList *entry;
1370 CpuDefinitionInfo *info;
1371
1372 info = g_malloc0(sizeof(*info));
1373 info->name = g_strdup(def->name);
1374
1375 entry = g_malloc0(sizeof(*entry));
1376 entry->value = info;
1377 entry->next = cpu_list;
1378 cpu_list = entry;
1379 }
1380
1381 return cpu_list;
1382}
1383
bc74b7db
EH
1384#ifdef CONFIG_KVM
1385static void filter_features_for_kvm(X86CPU *cpu)
1386{
1387 CPUX86State *env = &cpu->env;
1388 KVMState *s = kvm_state;
1389
b8091f24
EH
1390 env->cpuid_features &=
1391 kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
1392 env->cpuid_ext_features &=
1393 kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX);
1394 env->cpuid_ext2_features &=
1395 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
1396 env->cpuid_ext3_features &=
1397 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
1398 env->cpuid_svm_features &=
1399 kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
ffa8c11f
EH
1400 env->cpuid_7_0_ebx_features &=
1401 kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX);
bc74b7db 1402 env->cpuid_kvm_features &=
b8091f24
EH
1403 kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
1404 env->cpuid_ext4_features &=
1405 kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
bc74b7db
EH
1406
1407}
1408#endif
1409
61dcd775 1410int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
c6dc6f63 1411{
61dcd775 1412 CPUX86State *env = &cpu->env;
c6dc6f63 1413 x86_def_t def1, *def = &def1;
71ad61d3 1414 Error *error = NULL;
c6dc6f63 1415
db0ad1ba
JR
1416 memset(def, 0, sizeof(*def));
1417
c6dc6f63
AP
1418 if (cpu_x86_find_by_name(def, cpu_model) < 0)
1419 return -1;
1420 if (def->vendor1) {
1421 env->cpuid_vendor1 = def->vendor1;
1422 env->cpuid_vendor2 = def->vendor2;
1423 env->cpuid_vendor3 = def->vendor3;
1424 } else {
1425 env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
1426 env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
1427 env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
1428 }
1429 env->cpuid_vendor_override = def->vendor_override;
8e1898bf 1430 object_property_set_int(OBJECT(cpu), def->level, "level", &error);
71ad61d3 1431 object_property_set_int(OBJECT(cpu), def->family, "family", &error);
c5291a4f 1432 object_property_set_int(OBJECT(cpu), def->model, "model", &error);
036e2222 1433 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", &error);
c6dc6f63 1434 env->cpuid_features = def->features;
c6dc6f63
AP
1435 env->cpuid_ext_features = def->ext_features;
1436 env->cpuid_ext2_features = def->ext2_features;
4d067ed7 1437 env->cpuid_ext3_features = def->ext3_features;
16b93aa8 1438 object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", &error);
c6dc6f63 1439 env->cpuid_kvm_features = def->kvm_features;
296acb64 1440 env->cpuid_svm_features = def->svm_features;
b3baa152 1441 env->cpuid_ext4_features = def->ext4_features;
a9321a4d 1442 env->cpuid_7_0_ebx_features = def->cpuid_7_0_ebx_features;
b3baa152 1443 env->cpuid_xlevel2 = def->xlevel2;
89e48965
AF
1444 object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
1445 "tsc-frequency", &error);
3b671a40
EH
1446
1447 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
1448 * CPUID[1].EDX.
1449 */
1450 if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
1451 env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
1452 env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
1453 env->cpuid_ext2_features &= ~CPUID_EXT2_AMD_ALIASES;
1454 env->cpuid_ext2_features |= (def->features & CPUID_EXT2_AMD_ALIASES);
1455 }
1456
551a2dec
AP
1457 if (!kvm_enabled()) {
1458 env->cpuid_features &= TCG_FEATURES;
1459 env->cpuid_ext_features &= TCG_EXT_FEATURES;
1460 env->cpuid_ext2_features &= (TCG_EXT2_FEATURES
1461#ifdef TARGET_X86_64
1462 | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
1463#endif
1464 );
1465 env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
296acb64 1466 env->cpuid_svm_features &= TCG_SVM_FEATURES;
bc74b7db
EH
1467 } else {
1468#ifdef CONFIG_KVM
1469 filter_features_for_kvm(cpu);
1470#endif
551a2dec 1471 }
938d4c25 1472 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", &error);
71ad61d3
AF
1473 if (error_is_set(&error)) {
1474 error_free(error);
1475 return -1;
1476 }
c6dc6f63
AP
1477 return 0;
1478}
1479
1480#if !defined(CONFIG_USER_ONLY)
c6dc6f63 1481
0e26b7b8
BS
1482void cpu_clear_apic_feature(CPUX86State *env)
1483{
1484 env->cpuid_features &= ~CPUID_APIC;
1485}
1486
c6dc6f63
AP
1487#endif /* !CONFIG_USER_ONLY */
1488
c04321b3 1489/* Initialize list of CPU models, filling some non-static fields if necessary
c6dc6f63
AP
1490 */
1491void x86_cpudef_setup(void)
1492{
93bfef4c
CV
1493 int i, j;
1494 static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
c6dc6f63
AP
1495
1496 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
bc3e1291
EH
1497 x86_def_t *def = &builtin_x86_defs[i];
1498 def->next = x86_defs;
93bfef4c
CV
1499
1500 /* Look for specific "cpudef" models that */
09faecf2 1501 /* have the QEMU version in .model_id */
93bfef4c 1502 for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
bc3e1291
EH
1503 if (strcmp(model_with_versions[j], def->name) == 0) {
1504 pstrcpy(def->model_id, sizeof(def->model_id),
1505 "QEMU Virtual CPU version ");
1506 pstrcat(def->model_id, sizeof(def->model_id),
1507 qemu_get_version());
93bfef4c
CV
1508 break;
1509 }
1510 }
1511
bc3e1291 1512 x86_defs = def;
c6dc6f63 1513 }
c6dc6f63
AP
1514}
1515
c6dc6f63
AP
1516static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
1517 uint32_t *ecx, uint32_t *edx)
1518{
1519 *ebx = env->cpuid_vendor1;
1520 *edx = env->cpuid_vendor2;
1521 *ecx = env->cpuid_vendor3;
1522
1523 /* sysenter isn't supported on compatibility mode on AMD, syscall
1524 * isn't supported in compatibility mode on Intel.
1525 * Normally we advertise the actual cpu vendor, but you can override
1526 * this if you want to use KVM's sysenter/syscall emulation
1527 * in compatibility mode and when doing cross vendor migration
1528 */
89354998 1529 if (kvm_enabled() && ! env->cpuid_vendor_override) {
c6dc6f63
AP
1530 host_cpuid(0, 0, NULL, ebx, ecx, edx);
1531 }
1532}
1533
1534void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1535 uint32_t *eax, uint32_t *ebx,
1536 uint32_t *ecx, uint32_t *edx)
1537{
1538 /* test if maximum index reached */
1539 if (index & 0x80000000) {
b3baa152 1540 if (index > env->cpuid_xlevel) {
1541 if (env->cpuid_xlevel2 > 0) {
1542 /* Handle the Centaur's CPUID instruction. */
1543 if (index > env->cpuid_xlevel2) {
1544 index = env->cpuid_xlevel2;
1545 } else if (index < 0xC0000000) {
1546 index = env->cpuid_xlevel;
1547 }
1548 } else {
1549 index = env->cpuid_xlevel;
1550 }
1551 }
c6dc6f63
AP
1552 } else {
1553 if (index > env->cpuid_level)
1554 index = env->cpuid_level;
1555 }
1556
1557 switch(index) {
1558 case 0:
1559 *eax = env->cpuid_level;
1560 get_cpuid_vendor(env, ebx, ecx, edx);
1561 break;
1562 case 1:
1563 *eax = env->cpuid_version;
1564 *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
1565 *ecx = env->cpuid_ext_features;
1566 *edx = env->cpuid_features;
1567 if (env->nr_cores * env->nr_threads > 1) {
1568 *ebx |= (env->nr_cores * env->nr_threads) << 16;
1569 *edx |= 1 << 28; /* HTT bit */
1570 }
1571 break;
1572 case 2:
1573 /* cache info: needed for Pentium Pro compatibility */
1574 *eax = 1;
1575 *ebx = 0;
1576 *ecx = 0;
1577 *edx = 0x2c307d;
1578 break;
1579 case 4:
1580 /* cache info: needed for Core compatibility */
1581 if (env->nr_cores > 1) {
2f7a21c4 1582 *eax = (env->nr_cores - 1) << 26;
c6dc6f63 1583 } else {
2f7a21c4 1584 *eax = 0;
c6dc6f63
AP
1585 }
1586 switch (count) {
1587 case 0: /* L1 dcache info */
1588 *eax |= 0x0000121;
1589 *ebx = 0x1c0003f;
1590 *ecx = 0x000003f;
1591 *edx = 0x0000001;
1592 break;
1593 case 1: /* L1 icache info */
1594 *eax |= 0x0000122;
1595 *ebx = 0x1c0003f;
1596 *ecx = 0x000003f;
1597 *edx = 0x0000001;
1598 break;
1599 case 2: /* L2 cache info */
1600 *eax |= 0x0000143;
1601 if (env->nr_threads > 1) {
1602 *eax |= (env->nr_threads - 1) << 14;
1603 }
1604 *ebx = 0x3c0003f;
1605 *ecx = 0x0000fff;
1606 *edx = 0x0000001;
1607 break;
1608 default: /* end of info */
1609 *eax = 0;
1610 *ebx = 0;
1611 *ecx = 0;
1612 *edx = 0;
1613 break;
1614 }
1615 break;
1616 case 5:
1617 /* mwait info: needed for Core compatibility */
1618 *eax = 0; /* Smallest monitor-line size in bytes */
1619 *ebx = 0; /* Largest monitor-line size in bytes */
1620 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
1621 *edx = 0;
1622 break;
1623 case 6:
1624 /* Thermal and Power Leaf */
1625 *eax = 0;
1626 *ebx = 0;
1627 *ecx = 0;
1628 *edx = 0;
1629 break;
f7911686 1630 case 7:
13526728
EH
1631 /* Structured Extended Feature Flags Enumeration Leaf */
1632 if (count == 0) {
1633 *eax = 0; /* Maximum ECX value for sub-leaves */
a9321a4d 1634 *ebx = env->cpuid_7_0_ebx_features; /* Feature flags */
13526728
EH
1635 *ecx = 0; /* Reserved */
1636 *edx = 0; /* Reserved */
f7911686
YW
1637 } else {
1638 *eax = 0;
1639 *ebx = 0;
1640 *ecx = 0;
1641 *edx = 0;
1642 }
1643 break;
c6dc6f63
AP
1644 case 9:
1645 /* Direct Cache Access Information Leaf */
1646 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
1647 *ebx = 0;
1648 *ecx = 0;
1649 *edx = 0;
1650 break;
1651 case 0xA:
1652 /* Architectural Performance Monitoring Leaf */
a0fa8208
GN
1653 if (kvm_enabled()) {
1654 KVMState *s = env->kvm_state;
1655
1656 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
1657 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
1658 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
1659 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
1660 } else {
1661 *eax = 0;
1662 *ebx = 0;
1663 *ecx = 0;
1664 *edx = 0;
1665 }
c6dc6f63 1666 break;
51e49430
SY
1667 case 0xD:
1668 /* Processor Extended State */
1669 if (!(env->cpuid_ext_features & CPUID_EXT_XSAVE)) {
1670 *eax = 0;
1671 *ebx = 0;
1672 *ecx = 0;
1673 *edx = 0;
1674 break;
1675 }
1676 if (kvm_enabled()) {
ba9bc59e
JK
1677 KVMState *s = env->kvm_state;
1678
1679 *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX);
1680 *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX);
1681 *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX);
1682 *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX);
51e49430
SY
1683 } else {
1684 *eax = 0;
1685 *ebx = 0;
1686 *ecx = 0;
1687 *edx = 0;
1688 }
1689 break;
c6dc6f63
AP
1690 case 0x80000000:
1691 *eax = env->cpuid_xlevel;
1692 *ebx = env->cpuid_vendor1;
1693 *edx = env->cpuid_vendor2;
1694 *ecx = env->cpuid_vendor3;
1695 break;
1696 case 0x80000001:
1697 *eax = env->cpuid_version;
1698 *ebx = 0;
1699 *ecx = env->cpuid_ext3_features;
1700 *edx = env->cpuid_ext2_features;
1701
1702 /* The Linux kernel checks for the CMPLegacy bit and
1703 * discards multiple thread information if it is set.
1704 * So dont set it here for Intel to make Linux guests happy.
1705 */
1706 if (env->nr_cores * env->nr_threads > 1) {
1707 uint32_t tebx, tecx, tedx;
1708 get_cpuid_vendor(env, &tebx, &tecx, &tedx);
1709 if (tebx != CPUID_VENDOR_INTEL_1 ||
1710 tedx != CPUID_VENDOR_INTEL_2 ||
1711 tecx != CPUID_VENDOR_INTEL_3) {
1712 *ecx |= 1 << 1; /* CmpLegacy bit */
1713 }
1714 }
c6dc6f63
AP
1715 break;
1716 case 0x80000002:
1717 case 0x80000003:
1718 case 0x80000004:
1719 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
1720 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
1721 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
1722 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
1723 break;
1724 case 0x80000005:
1725 /* cache info (L1 cache) */
1726 *eax = 0x01ff01ff;
1727 *ebx = 0x01ff01ff;
1728 *ecx = 0x40020140;
1729 *edx = 0x40020140;
1730 break;
1731 case 0x80000006:
1732 /* cache info (L2 cache) */
1733 *eax = 0;
1734 *ebx = 0x42004200;
1735 *ecx = 0x02008140;
1736 *edx = 0;
1737 break;
1738 case 0x80000008:
1739 /* virtual & phys address size in low 2 bytes. */
1740/* XXX: This value must match the one used in the MMU code. */
1741 if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
1742 /* 64 bit processor */
1743/* XXX: The physical address space is limited to 42 bits in exec.c. */
1744 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
1745 } else {
1746 if (env->cpuid_features & CPUID_PSE36)
1747 *eax = 0x00000024; /* 36 bits physical */
1748 else
1749 *eax = 0x00000020; /* 32 bits physical */
1750 }
1751 *ebx = 0;
1752 *ecx = 0;
1753 *edx = 0;
1754 if (env->nr_cores * env->nr_threads > 1) {
1755 *ecx |= (env->nr_cores * env->nr_threads) - 1;
1756 }
1757 break;
1758 case 0x8000000A:
296acb64
JR
1759 if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
1760 *eax = 0x00000001; /* SVM Revision */
1761 *ebx = 0x00000010; /* nr of ASIDs */
1762 *ecx = 0;
1763 *edx = env->cpuid_svm_features; /* optional features */
1764 } else {
1765 *eax = 0;
1766 *ebx = 0;
1767 *ecx = 0;
1768 *edx = 0;
1769 }
c6dc6f63 1770 break;
b3baa152 1771 case 0xC0000000:
1772 *eax = env->cpuid_xlevel2;
1773 *ebx = 0;
1774 *ecx = 0;
1775 *edx = 0;
1776 break;
1777 case 0xC0000001:
1778 /* Support for VIA CPU's CPUID instruction */
1779 *eax = env->cpuid_version;
1780 *ebx = 0;
1781 *ecx = 0;
1782 *edx = env->cpuid_ext4_features;
1783 break;
1784 case 0xC0000002:
1785 case 0xC0000003:
1786 case 0xC0000004:
1787 /* Reserved for the future, and now filled with zero */
1788 *eax = 0;
1789 *ebx = 0;
1790 *ecx = 0;
1791 *edx = 0;
1792 break;
c6dc6f63
AP
1793 default:
1794 /* reserved values: zero */
1795 *eax = 0;
1796 *ebx = 0;
1797 *ecx = 0;
1798 *edx = 0;
1799 break;
1800 }
1801}
5fd2087a
AF
1802
1803/* CPUClass::reset() */
1804static void x86_cpu_reset(CPUState *s)
1805{
1806 X86CPU *cpu = X86_CPU(s);
1807 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
1808 CPUX86State *env = &cpu->env;
c1958aea
AF
1809 int i;
1810
1811 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
1812 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
6fd2a026 1813 log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP);
c1958aea 1814 }
5fd2087a
AF
1815
1816 xcc->parent_reset(s);
1817
c1958aea
AF
1818
1819 memset(env, 0, offsetof(CPUX86State, breakpoints));
1820
1821 tlb_flush(env, 1);
1822
1823 env->old_exception = -1;
1824
1825 /* init to reset state */
1826
1827#ifdef CONFIG_SOFTMMU
1828 env->hflags |= HF_SOFTMMU_MASK;
1829#endif
1830 env->hflags2 |= HF2_GIF_MASK;
1831
1832 cpu_x86_update_cr0(env, 0x60000010);
1833 env->a20_mask = ~0x0;
1834 env->smbase = 0x30000;
1835
1836 env->idt.limit = 0xffff;
1837 env->gdt.limit = 0xffff;
1838 env->ldt.limit = 0xffff;
1839 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
1840 env->tr.limit = 0xffff;
1841 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
1842
1843 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
1844 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
1845 DESC_R_MASK | DESC_A_MASK);
1846 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
1847 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1848 DESC_A_MASK);
1849 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
1850 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1851 DESC_A_MASK);
1852 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
1853 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1854 DESC_A_MASK);
1855 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
1856 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1857 DESC_A_MASK);
1858 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
1859 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1860 DESC_A_MASK);
1861
1862 env->eip = 0xfff0;
1863 env->regs[R_EDX] = env->cpuid_version;
1864
1865 env->eflags = 0x2;
1866
1867 /* FPU init */
1868 for (i = 0; i < 8; i++) {
1869 env->fptags[i] = 1;
1870 }
1871 env->fpuc = 0x37f;
1872
1873 env->mxcsr = 0x1f80;
1874
1875 env->pat = 0x0007040600070406ULL;
1876 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
1877
1878 memset(env->dr, 0, sizeof(env->dr));
1879 env->dr[6] = DR6_FIXED_1;
1880 env->dr[7] = DR7_FIXED_1;
1881 cpu_breakpoint_remove_all(env, BP_CPU);
1882 cpu_watchpoint_remove_all(env, BP_CPU);
dd673288
IM
1883
1884#if !defined(CONFIG_USER_ONLY)
1885 /* We hard-wire the BSP to the first CPU. */
1886 if (env->cpu_index == 0) {
1887 apic_designate_bsp(env->apic_state);
1888 }
1889
1890 env->halted = !cpu_is_bsp(cpu);
1891#endif
5fd2087a
AF
1892}
1893
dd673288
IM
1894#ifndef CONFIG_USER_ONLY
1895bool cpu_is_bsp(X86CPU *cpu)
1896{
1897 return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP;
1898}
65dee380
IM
1899
1900/* TODO: remove me, when reset over QOM tree is implemented */
1901static void x86_cpu_machine_reset_cb(void *opaque)
1902{
1903 X86CPU *cpu = opaque;
1904 cpu_reset(CPU(cpu));
1905}
dd673288
IM
1906#endif
1907
de024815
AF
1908static void mce_init(X86CPU *cpu)
1909{
1910 CPUX86State *cenv = &cpu->env;
1911 unsigned int bank;
1912
1913 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
1914 && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
1915 (CPUID_MCE | CPUID_MCA)) {
1916 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1917 cenv->mcg_ctl = ~(uint64_t)0;
1918 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
1919 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
1920 }
1921 }
1922}
1923
7a059953
AF
1924void x86_cpu_realize(Object *obj, Error **errp)
1925{
1926 X86CPU *cpu = X86_CPU(obj);
1927
65dee380
IM
1928#ifndef CONFIG_USER_ONLY
1929 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
1930#endif
1931
7a059953
AF
1932 mce_init(cpu);
1933 qemu_init_vcpu(&cpu->env);
65dee380 1934 cpu_reset(CPU(cpu));
7a059953
AF
1935}
1936
de024815
AF
1937static void x86_cpu_initfn(Object *obj)
1938{
1939 X86CPU *cpu = X86_CPU(obj);
1940 CPUX86State *env = &cpu->env;
d65e9815 1941 static int inited;
de024815
AF
1942
1943 cpu_exec_init(env);
71ad61d3
AF
1944
1945 object_property_add(obj, "family", "int",
95b8519d 1946 x86_cpuid_version_get_family,
71ad61d3 1947 x86_cpuid_version_set_family, NULL, NULL, NULL);
c5291a4f 1948 object_property_add(obj, "model", "int",
67e30c83 1949 x86_cpuid_version_get_model,
c5291a4f 1950 x86_cpuid_version_set_model, NULL, NULL, NULL);
036e2222 1951 object_property_add(obj, "stepping", "int",
35112e41 1952 x86_cpuid_version_get_stepping,
036e2222 1953 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
8e1898bf
AF
1954 object_property_add(obj, "level", "int",
1955 x86_cpuid_get_level,
1956 x86_cpuid_set_level, NULL, NULL, NULL);
16b93aa8
AF
1957 object_property_add(obj, "xlevel", "int",
1958 x86_cpuid_get_xlevel,
1959 x86_cpuid_set_xlevel, NULL, NULL, NULL);
d480e1af
AF
1960 object_property_add_str(obj, "vendor",
1961 x86_cpuid_get_vendor,
1962 x86_cpuid_set_vendor, NULL);
938d4c25 1963 object_property_add_str(obj, "model-id",
63e886eb 1964 x86_cpuid_get_model_id,
938d4c25 1965 x86_cpuid_set_model_id, NULL);
89e48965
AF
1966 object_property_add(obj, "tsc-frequency", "int",
1967 x86_cpuid_get_tsc_freq,
1968 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
71ad61d3 1969
de024815 1970 env->cpuid_apic_id = env->cpu_index;
d65e9815
IM
1971
1972 /* init various static tables used in TCG mode */
1973 if (tcg_enabled() && !inited) {
1974 inited = 1;
1975 optimize_flags_init();
1976#ifndef CONFIG_USER_ONLY
1977 cpu_set_debug_excp_handler(breakpoint_handler);
1978#endif
1979 }
de024815
AF
1980}
1981
5fd2087a
AF
1982static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
1983{
1984 X86CPUClass *xcc = X86_CPU_CLASS(oc);
1985 CPUClass *cc = CPU_CLASS(oc);
1986
1987 xcc->parent_reset = cc->reset;
1988 cc->reset = x86_cpu_reset;
1989}
1990
1991static const TypeInfo x86_cpu_type_info = {
1992 .name = TYPE_X86_CPU,
1993 .parent = TYPE_CPU,
1994 .instance_size = sizeof(X86CPU),
de024815 1995 .instance_init = x86_cpu_initfn,
5fd2087a
AF
1996 .abstract = false,
1997 .class_size = sizeof(X86CPUClass),
1998 .class_init = x86_cpu_common_class_init,
1999};
2000
2001static void x86_cpu_register_types(void)
2002{
2003 type_register_static(&x86_cpu_type_info);
2004}
2005
2006type_init(x86_cpu_register_types)