2 * i386 CPUID helper functions
4 * Copyright (c) 2003 Fabrice Bellard
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.
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.
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/>.
25 #include "sysemu/kvm.h"
26 #include "sysemu/cpus.h"
29 #include "qemu/option.h"
30 #include "qemu/config-file.h"
31 #include "qapi/qmp/qerror.h"
33 #include "qapi-types.h"
34 #include "qapi-visit.h"
35 #include "qapi/visitor.h"
36 #include "sysemu/arch_init.h"
39 #if defined(CONFIG_KVM)
40 #include <linux/kvm_para.h>
43 #include "sysemu/sysemu.h"
44 #include "hw/qdev-properties.h"
45 #include "hw/cpu/icc_bus.h"
46 #ifndef CONFIG_USER_ONLY
47 #include "hw/xen/xen.h"
48 #include "hw/i386/apic_internal.h"
52 /* Cache topology CPUID constants: */
54 /* CPUID Leaf 2 Descriptors */
56 #define CPUID_2_L1D_32KB_8WAY_64B 0x2c
57 #define CPUID_2_L1I_32KB_8WAY_64B 0x30
58 #define CPUID_2_L2_2MB_8WAY_64B 0x7d
61 /* CPUID Leaf 4 constants: */
64 #define CPUID_4_TYPE_DCACHE 1
65 #define CPUID_4_TYPE_ICACHE 2
66 #define CPUID_4_TYPE_UNIFIED 3
68 #define CPUID_4_LEVEL(l) ((l) << 5)
70 #define CPUID_4_SELF_INIT_LEVEL (1 << 8)
71 #define CPUID_4_FULLY_ASSOC (1 << 9)
74 #define CPUID_4_NO_INVD_SHARING (1 << 0)
75 #define CPUID_4_INCLUSIVE (1 << 1)
76 #define CPUID_4_COMPLEX_IDX (1 << 2)
78 #define ASSOC_FULL 0xFF
80 /* AMD associativity encoding used on CPUID Leaf 0x80000006: */
81 #define AMD_ENC_ASSOC(a) (a <= 1 ? a : \
91 a == ASSOC_FULL ? 0xF : \
92 0 /* invalid value */)
95 /* Definitions of the hardcoded cache entries we expose: */
98 #define L1D_LINE_SIZE 64
99 #define L1D_ASSOCIATIVITY 8
101 #define L1D_PARTITIONS 1
102 /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
103 #define L1D_DESCRIPTOR CPUID_2_L1D_32KB_8WAY_64B
104 /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
105 #define L1D_LINES_PER_TAG 1
106 #define L1D_SIZE_KB_AMD 64
107 #define L1D_ASSOCIATIVITY_AMD 2
109 /* L1 instruction cache: */
110 #define L1I_LINE_SIZE 64
111 #define L1I_ASSOCIATIVITY 8
113 #define L1I_PARTITIONS 1
114 /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
115 #define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
116 /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
117 #define L1I_LINES_PER_TAG 1
118 #define L1I_SIZE_KB_AMD 64
119 #define L1I_ASSOCIATIVITY_AMD 2
121 /* Level 2 unified cache: */
122 #define L2_LINE_SIZE 64
123 #define L2_ASSOCIATIVITY 16
125 #define L2_PARTITIONS 1
126 /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
127 /*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
128 #define L2_DESCRIPTOR CPUID_2_L2_2MB_8WAY_64B
129 /*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
130 #define L2_LINES_PER_TAG 1
131 #define L2_SIZE_KB_AMD 512
134 #define L3_SIZE_KB 0 /* disabled */
135 #define L3_ASSOCIATIVITY 0 /* disabled */
136 #define L3_LINES_PER_TAG 0 /* disabled */
137 #define L3_LINE_SIZE 0 /* disabled */
139 /* TLB definitions: */
141 #define L1_DTLB_2M_ASSOC 1
142 #define L1_DTLB_2M_ENTRIES 255
143 #define L1_DTLB_4K_ASSOC 1
144 #define L1_DTLB_4K_ENTRIES 255
146 #define L1_ITLB_2M_ASSOC 1
147 #define L1_ITLB_2M_ENTRIES 255
148 #define L1_ITLB_4K_ASSOC 1
149 #define L1_ITLB_4K_ENTRIES 255
151 #define L2_DTLB_2M_ASSOC 0 /* disabled */
152 #define L2_DTLB_2M_ENTRIES 0 /* disabled */
153 #define L2_DTLB_4K_ASSOC 4
154 #define L2_DTLB_4K_ENTRIES 512
156 #define L2_ITLB_2M_ASSOC 0 /* disabled */
157 #define L2_ITLB_2M_ENTRIES 0 /* disabled */
158 #define L2_ITLB_4K_ASSOC 4
159 #define L2_ITLB_4K_ENTRIES 512
163 static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
164 uint32_t vendor2, uint32_t vendor3)
167 for (i = 0; i < 4; i++) {
168 dst[i] = vendor1 >> (8 * i);
169 dst[i + 4] = vendor2 >> (8 * i);
170 dst[i + 8] = vendor3 >> (8 * i);
172 dst[CPUID_VENDOR_SZ] = '\0';
175 /* feature flags taken from "Intel Processor Identification and the CPUID
176 * Instruction" and AMD's "CPUID Specification". In cases of disagreement
177 * between feature naming conventions, aliases may be added.
179 static const char *feature_name[] = {
180 "fpu", "vme", "de", "pse",
181 "tsc", "msr", "pae", "mce",
182 "cx8", "apic", NULL, "sep",
183 "mtrr", "pge", "mca", "cmov",
184 "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
185 NULL, "ds" /* Intel dts */, "acpi", "mmx",
186 "fxsr", "sse", "sse2", "ss",
187 "ht" /* Intel htt */, "tm", "ia64", "pbe",
189 static const char *ext_feature_name[] = {
190 "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
191 "ds_cpl", "vmx", "smx", "est",
192 "tm2", "ssse3", "cid", NULL,
193 "fma", "cx16", "xtpr", "pdcm",
194 NULL, "pcid", "dca", "sse4.1|sse4_1",
195 "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
196 "tsc-deadline", "aes", "xsave", "osxsave",
197 "avx", "f16c", "rdrand", "hypervisor",
199 /* Feature names that are already defined on feature_name[] but are set on
200 * CPUID[8000_0001].EDX on AMD CPUs don't have their names on
201 * ext2_feature_name[]. They are copied automatically to cpuid_ext2_features
202 * if and only if CPU vendor is AMD.
204 static const char *ext2_feature_name[] = {
205 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
206 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
207 NULL /* cx8 */ /* AMD CMPXCHG8B */, NULL /* apic */, NULL, "syscall",
208 NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
209 NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
210 "nx|xd", NULL, "mmxext", NULL /* mmx */,
211 NULL /* fxsr */, "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
212 NULL, "lm|i64", "3dnowext", "3dnow",
214 static const char *ext3_feature_name[] = {
215 "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
216 "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
217 "3dnowprefetch", "osvw", "ibs", "xop",
218 "skinit", "wdt", NULL, "lwp",
219 "fma4", "tce", NULL, "nodeid_msr",
220 NULL, "tbm", "topoext", "perfctr_core",
221 "perfctr_nb", NULL, NULL, NULL,
222 NULL, NULL, NULL, NULL,
225 static const char *ext4_feature_name[] = {
226 NULL, NULL, "xstore", "xstore-en",
227 NULL, NULL, "xcrypt", "xcrypt-en",
228 "ace2", "ace2-en", "phe", "phe-en",
229 "pmm", "pmm-en", NULL, NULL,
230 NULL, NULL, NULL, NULL,
231 NULL, NULL, NULL, NULL,
232 NULL, NULL, NULL, NULL,
233 NULL, NULL, NULL, NULL,
236 static const char *kvm_feature_name[] = {
237 "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock",
238 "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", "kvm_pv_unhalt",
239 NULL, NULL, NULL, NULL,
240 NULL, NULL, NULL, NULL,
241 NULL, NULL, NULL, NULL,
242 NULL, NULL, NULL, NULL,
243 NULL, NULL, NULL, NULL,
244 NULL, NULL, NULL, NULL,
247 static const char *svm_feature_name[] = {
248 "npt", "lbrv", "svm_lock", "nrip_save",
249 "tsc_scale", "vmcb_clean", "flushbyasid", "decodeassists",
250 NULL, NULL, "pause_filter", NULL,
251 "pfthreshold", NULL, NULL, NULL,
252 NULL, NULL, NULL, NULL,
253 NULL, NULL, NULL, NULL,
254 NULL, NULL, NULL, NULL,
255 NULL, NULL, NULL, NULL,
258 static const char *cpuid_7_0_ebx_feature_name[] = {
259 "fsgsbase", NULL, NULL, "bmi1", "hle", "avx2", NULL, "smep",
260 "bmi2", "erms", "invpcid", "rtm", NULL, NULL, NULL, NULL,
261 NULL, NULL, "rdseed", "adx", "smap", NULL, NULL, NULL,
262 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
265 typedef struct FeatureWordInfo {
266 const char **feat_names;
267 uint32_t cpuid_eax; /* Input EAX for CPUID */
268 bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
269 uint32_t cpuid_ecx; /* Input ECX value for CPUID */
270 int cpuid_reg; /* output register (R_* constant) */
273 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
275 .feat_names = feature_name,
276 .cpuid_eax = 1, .cpuid_reg = R_EDX,
279 .feat_names = ext_feature_name,
280 .cpuid_eax = 1, .cpuid_reg = R_ECX,
282 [FEAT_8000_0001_EDX] = {
283 .feat_names = ext2_feature_name,
284 .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX,
286 [FEAT_8000_0001_ECX] = {
287 .feat_names = ext3_feature_name,
288 .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
290 [FEAT_C000_0001_EDX] = {
291 .feat_names = ext4_feature_name,
292 .cpuid_eax = 0xC0000001, .cpuid_reg = R_EDX,
295 .feat_names = kvm_feature_name,
296 .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
299 .feat_names = svm_feature_name,
300 .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
303 .feat_names = cpuid_7_0_ebx_feature_name,
305 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
310 typedef struct X86RegisterInfo32 {
311 /* Name of register */
313 /* QAPI enum value register */
314 X86CPURegister32 qapi_enum;
317 #define REGISTER(reg) \
318 [R_##reg] = { .name = #reg, .qapi_enum = X86_CPU_REGISTER32_##reg }
319 X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
331 typedef struct ExtSaveArea {
332 uint32_t feature, bits;
333 uint32_t offset, size;
336 static const ExtSaveArea ext_save_areas[] = {
337 [2] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
338 .offset = 0x240, .size = 0x100 },
339 [3] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
340 .offset = 0x3c0, .size = 0x40 },
341 [4] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
342 .offset = 0x400, .size = 0x40 },
345 const char *get_register_name_32(unsigned int reg)
347 if (reg >= CPU_NB_REGS32) {
350 return x86_reg_info_32[reg].name;
353 /* collects per-function cpuid data
355 typedef struct model_features_t {
356 uint32_t *guest_feat;
358 FeatureWord feat_word;
361 /* KVM-specific features that are automatically added to all CPU models
362 * when KVM is enabled.
364 static uint32_t kvm_default_features[FEATURE_WORDS] = {
365 [FEAT_KVM] = (1 << KVM_FEATURE_CLOCKSOURCE) |
366 (1 << KVM_FEATURE_NOP_IO_DELAY) |
367 (1 << KVM_FEATURE_CLOCKSOURCE2) |
368 (1 << KVM_FEATURE_ASYNC_PF) |
369 (1 << KVM_FEATURE_STEAL_TIME) |
370 (1 << KVM_FEATURE_PV_EOI) |
371 (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT),
372 [FEAT_1_ECX] = CPUID_EXT_X2APIC,
375 void x86_cpu_compat_disable_kvm_features(FeatureWord w, uint32_t features)
377 kvm_default_features[w] &= ~features;
380 void host_cpuid(uint32_t function, uint32_t count,
381 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
387 : "=a"(vec[0]), "=b"(vec[1]),
388 "=c"(vec[2]), "=d"(vec[3])
389 : "0"(function), "c"(count) : "cc");
390 #elif defined(__i386__)
391 asm volatile("pusha \n\t"
393 "mov %%eax, 0(%2) \n\t"
394 "mov %%ebx, 4(%2) \n\t"
395 "mov %%ecx, 8(%2) \n\t"
396 "mov %%edx, 12(%2) \n\t"
398 : : "a"(function), "c"(count), "S"(vec)
414 #define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
416 /* general substring compare of *[s1..e1) and *[s2..e2). sx is start of
417 * a substring. ex if !NULL points to the first char after a substring,
418 * otherwise the string is assumed to sized by a terminating nul.
419 * Return lexical ordering of *s1:*s2.
421 static int sstrcmp(const char *s1, const char *e1, const char *s2,
425 if (!*s1 || !*s2 || *s1 != *s2)
428 if (s1 == e1 && s2 == e2)
437 /* compare *[s..e) to *altstr. *altstr may be a simple string or multiple
438 * '|' delimited (possibly empty) strings in which case search for a match
439 * within the alternatives proceeds left to right. Return 0 for success,
440 * non-zero otherwise.
442 static int altcmp(const char *s, const char *e, const char *altstr)
446 for (q = p = altstr; ; ) {
447 while (*p && *p != '|')
449 if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
458 /* search featureset for flag *[s..e), if found set corresponding bit in
459 * *pval and return true, otherwise return false
461 static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
462 const char **featureset)
468 for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
469 if (*ppc && !altcmp(s, e, *ppc)) {
477 static void add_flagname_to_bitmaps(const char *flagname,
478 FeatureWordArray words)
481 for (w = 0; w < FEATURE_WORDS; w++) {
482 FeatureWordInfo *wi = &feature_word_info[w];
483 if (wi->feat_names &&
484 lookup_feature(&words[w], flagname, NULL, wi->feat_names)) {
488 if (w == FEATURE_WORDS) {
489 fprintf(stderr, "CPU feature %s not found\n", flagname);
493 static ObjectClass *x86_cpu_class_by_name(const char *cpu_model)
495 if (cpu_model == NULL) {
499 return object_class_by_name(TYPE_X86_CPU);
502 typedef struct X86CPUDefinition {
507 /* vendor is zero-terminated, 12 character ASCII string */
508 char vendor[CPUID_VENDOR_SZ + 1];
512 FeatureWordArray features;
514 bool cache_info_passthrough;
517 #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
518 #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
519 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
520 #define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
521 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
522 CPUID_PSE36 | CPUID_FXSR)
523 #define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
524 #define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
525 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
526 CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
527 CPUID_PAE | CPUID_SEP | CPUID_APIC)
529 #define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
530 CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
531 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
532 CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
533 CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
534 /* partly implemented:
535 CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
536 CPUID_PSE36 (needed for Solaris) */
538 CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
539 #define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
540 CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
541 CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
542 CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
544 CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
545 CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
546 CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
547 CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_XSAVE,
548 CPUID_EXT_OSXSAVE, CPUID_EXT_AVX, CPUID_EXT_F16C,
550 #define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
551 CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
552 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
554 CPUID_EXT2_PDPE1GB */
555 #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
556 CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
557 #define TCG_SVM_FEATURES 0
558 #define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP \
559 CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX)
561 CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
562 CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
563 CPUID_7_0_EBX_RDSEED */
565 /* built-in CPU model definitions
567 static X86CPUDefinition builtin_x86_defs[] = {
571 .vendor = CPUID_VENDOR_AMD,
575 .features[FEAT_1_EDX] =
577 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
579 .features[FEAT_1_ECX] =
580 CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
581 .features[FEAT_8000_0001_EDX] =
582 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
583 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
584 .features[FEAT_8000_0001_ECX] =
585 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
586 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
587 .xlevel = 0x8000000A,
592 .vendor = CPUID_VENDOR_AMD,
596 .features[FEAT_1_EDX] =
598 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
599 CPUID_PSE36 | CPUID_VME | CPUID_HT,
600 .features[FEAT_1_ECX] =
601 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
603 .features[FEAT_8000_0001_EDX] =
604 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
605 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
606 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
607 CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
608 /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
610 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
611 CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
612 .features[FEAT_8000_0001_ECX] =
613 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
614 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
615 .features[FEAT_SVM] =
616 CPUID_SVM_NPT | CPUID_SVM_LBRV,
617 .xlevel = 0x8000001A,
618 .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
623 .vendor = CPUID_VENDOR_INTEL,
627 .features[FEAT_1_EDX] =
629 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
630 CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
631 CPUID_HT | CPUID_TM | CPUID_PBE,
632 .features[FEAT_1_ECX] =
633 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
634 CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
635 CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
636 .features[FEAT_8000_0001_EDX] =
637 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
638 .features[FEAT_8000_0001_ECX] =
640 .xlevel = 0x80000008,
641 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
646 .vendor = CPUID_VENDOR_INTEL,
650 /* Missing: CPUID_VME, CPUID_HT */
651 .features[FEAT_1_EDX] =
653 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
655 /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
656 .features[FEAT_1_ECX] =
657 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
658 /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
659 .features[FEAT_8000_0001_EDX] =
660 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
661 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
662 /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
663 CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
664 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
665 CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
666 .features[FEAT_8000_0001_ECX] =
668 .xlevel = 0x80000008,
669 .model_id = "Common KVM processor"
674 .vendor = CPUID_VENDOR_INTEL,
678 .features[FEAT_1_EDX] =
680 .features[FEAT_1_ECX] =
681 CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
682 .xlevel = 0x80000004,
687 .vendor = CPUID_VENDOR_INTEL,
691 .features[FEAT_1_EDX] =
693 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
694 .features[FEAT_1_ECX] =
696 .features[FEAT_8000_0001_EDX] =
697 PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES,
698 .features[FEAT_8000_0001_ECX] =
700 .xlevel = 0x80000008,
701 .model_id = "Common 32-bit KVM processor"
706 .vendor = CPUID_VENDOR_INTEL,
710 .features[FEAT_1_EDX] =
711 PPRO_FEATURES | CPUID_VME |
712 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
713 CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
714 .features[FEAT_1_ECX] =
715 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
716 CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
717 .features[FEAT_8000_0001_EDX] =
719 .xlevel = 0x80000008,
720 .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
725 .vendor = CPUID_VENDOR_INTEL,
729 .features[FEAT_1_EDX] =
736 .vendor = CPUID_VENDOR_INTEL,
740 .features[FEAT_1_EDX] =
747 .vendor = CPUID_VENDOR_INTEL,
751 .features[FEAT_1_EDX] =
758 .vendor = CPUID_VENDOR_INTEL,
762 .features[FEAT_1_EDX] =
769 .vendor = CPUID_VENDOR_AMD,
773 .features[FEAT_1_EDX] =
774 PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
776 .features[FEAT_8000_0001_EDX] =
777 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
778 CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
779 .xlevel = 0x80000008,
783 /* original is on level 10 */
785 .vendor = CPUID_VENDOR_INTEL,
789 .features[FEAT_1_EDX] =
791 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
792 CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
793 /* Some CPUs got no CPUID_SEP */
794 .features[FEAT_1_ECX] =
795 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
796 CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR |
798 .features[FEAT_8000_0001_EDX] =
799 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
801 .features[FEAT_8000_0001_ECX] =
803 .xlevel = 0x8000000A,
804 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
809 .vendor = CPUID_VENDOR_INTEL,
813 .features[FEAT_1_EDX] =
814 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
815 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
816 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
817 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
818 CPUID_DE | CPUID_FP87,
819 .features[FEAT_1_ECX] =
820 CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
821 .features[FEAT_8000_0001_EDX] =
822 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
823 .features[FEAT_8000_0001_ECX] =
825 .xlevel = 0x8000000A,
826 .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
831 .vendor = CPUID_VENDOR_INTEL,
835 .features[FEAT_1_EDX] =
836 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
837 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
838 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
839 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
840 CPUID_DE | CPUID_FP87,
841 .features[FEAT_1_ECX] =
842 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
844 .features[FEAT_8000_0001_EDX] =
845 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
846 .features[FEAT_8000_0001_ECX] =
848 .xlevel = 0x8000000A,
849 .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
854 .vendor = CPUID_VENDOR_INTEL,
858 .features[FEAT_1_EDX] =
859 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
860 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
861 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
862 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
863 CPUID_DE | CPUID_FP87,
864 .features[FEAT_1_ECX] =
865 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
866 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
867 .features[FEAT_8000_0001_EDX] =
868 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
869 .features[FEAT_8000_0001_ECX] =
871 .xlevel = 0x8000000A,
872 .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
877 .vendor = CPUID_VENDOR_INTEL,
881 .features[FEAT_1_EDX] =
882 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
883 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
884 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
885 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
886 CPUID_DE | CPUID_FP87,
887 .features[FEAT_1_ECX] =
888 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
889 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
890 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
891 .features[FEAT_8000_0001_EDX] =
892 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
893 .features[FEAT_8000_0001_ECX] =
895 .xlevel = 0x8000000A,
896 .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
899 .name = "SandyBridge",
901 .vendor = CPUID_VENDOR_INTEL,
905 .features[FEAT_1_EDX] =
906 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
907 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
908 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
909 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
910 CPUID_DE | CPUID_FP87,
911 .features[FEAT_1_ECX] =
912 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
913 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
914 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
915 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
917 .features[FEAT_8000_0001_EDX] =
918 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
920 .features[FEAT_8000_0001_ECX] =
922 .xlevel = 0x8000000A,
923 .model_id = "Intel Xeon E312xx (Sandy Bridge)",
928 .vendor = CPUID_VENDOR_INTEL,
932 .features[FEAT_1_EDX] =
933 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
934 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
935 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
936 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
937 CPUID_DE | CPUID_FP87,
938 .features[FEAT_1_ECX] =
939 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
940 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
941 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
942 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
943 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
945 .features[FEAT_8000_0001_EDX] =
946 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
948 .features[FEAT_8000_0001_ECX] =
950 .features[FEAT_7_0_EBX] =
951 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
952 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
953 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
955 .xlevel = 0x8000000A,
956 .model_id = "Intel Core Processor (Haswell)",
959 .name = "Opteron_G1",
961 .vendor = CPUID_VENDOR_AMD,
965 .features[FEAT_1_EDX] =
966 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
967 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
968 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
969 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
970 CPUID_DE | CPUID_FP87,
971 .features[FEAT_1_ECX] =
973 .features[FEAT_8000_0001_EDX] =
974 CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
975 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
976 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
977 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
978 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
979 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
980 .xlevel = 0x80000008,
981 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
984 .name = "Opteron_G2",
986 .vendor = CPUID_VENDOR_AMD,
990 .features[FEAT_1_EDX] =
991 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
992 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
993 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
994 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
995 CPUID_DE | CPUID_FP87,
996 .features[FEAT_1_ECX] =
997 CPUID_EXT_CX16 | CPUID_EXT_SSE3,
998 .features[FEAT_8000_0001_EDX] =
999 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
1000 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1001 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1002 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1003 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1004 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1005 CPUID_EXT2_DE | CPUID_EXT2_FPU,
1006 .features[FEAT_8000_0001_ECX] =
1007 CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
1008 .xlevel = 0x80000008,
1009 .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
1012 .name = "Opteron_G3",
1014 .vendor = CPUID_VENDOR_AMD,
1018 .features[FEAT_1_EDX] =
1019 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1020 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1021 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1022 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1023 CPUID_DE | CPUID_FP87,
1024 .features[FEAT_1_ECX] =
1025 CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
1027 .features[FEAT_8000_0001_EDX] =
1028 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
1029 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1030 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1031 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1032 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1033 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1034 CPUID_EXT2_DE | CPUID_EXT2_FPU,
1035 .features[FEAT_8000_0001_ECX] =
1036 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
1037 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
1038 .xlevel = 0x80000008,
1039 .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
1042 .name = "Opteron_G4",
1044 .vendor = CPUID_VENDOR_AMD,
1048 .features[FEAT_1_EDX] =
1049 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1050 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1051 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1052 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1053 CPUID_DE | CPUID_FP87,
1054 .features[FEAT_1_ECX] =
1055 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1056 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1057 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1059 .features[FEAT_8000_0001_EDX] =
1060 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
1061 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1062 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1063 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1064 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1065 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1066 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
1067 .features[FEAT_8000_0001_ECX] =
1068 CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1069 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1070 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1072 .xlevel = 0x8000001A,
1073 .model_id = "AMD Opteron 62xx class CPU",
1076 .name = "Opteron_G5",
1078 .vendor = CPUID_VENDOR_AMD,
1082 .features[FEAT_1_EDX] =
1083 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1084 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1085 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1086 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1087 CPUID_DE | CPUID_FP87,
1088 .features[FEAT_1_ECX] =
1089 CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
1090 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1091 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
1092 CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1093 .features[FEAT_8000_0001_EDX] =
1094 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
1095 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1096 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1097 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1098 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1099 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1100 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
1101 .features[FEAT_8000_0001_ECX] =
1102 CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1103 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1104 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1106 .xlevel = 0x8000001A,
1107 .model_id = "AMD Opteron 63xx class CPU",
1112 * x86_cpu_compat_set_features:
1113 * @cpu_model: CPU model name to be changed. If NULL, all CPU models are changed
1114 * @w: Identifies the feature word to be changed.
1115 * @feat_add: Feature bits to be added to feature word
1116 * @feat_remove: Feature bits to be removed from feature word
1118 * Change CPU model feature bits for compatibility.
1120 * This function may be used by machine-type compatibility functions
1121 * to enable or disable feature bits on specific CPU models.
1123 void x86_cpu_compat_set_features(const char *cpu_model, FeatureWord w,
1124 uint32_t feat_add, uint32_t feat_remove)
1126 X86CPUDefinition *def;
1128 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1129 def = &builtin_x86_defs[i];
1130 if (!cpu_model || !strcmp(cpu_model, def->name)) {
1131 def->features[w] |= feat_add;
1132 def->features[w] &= ~feat_remove;
1137 static int cpu_x86_fill_model_id(char *str)
1139 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1142 for (i = 0; i < 3; i++) {
1143 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
1144 memcpy(str + i * 16 + 0, &eax, 4);
1145 memcpy(str + i * 16 + 4, &ebx, 4);
1146 memcpy(str + i * 16 + 8, &ecx, 4);
1147 memcpy(str + i * 16 + 12, &edx, 4);
1152 /* Fill a X86CPUDefinition struct with information about the host CPU, and
1153 * the CPU features supported by the host hardware + host kernel
1155 * This function may be called only if KVM is enabled.
1157 static void kvm_cpu_fill_host(X86CPUDefinition *x86_cpu_def)
1159 KVMState *s = kvm_state;
1160 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1163 assert(kvm_enabled());
1165 x86_cpu_def->name = "host";
1166 x86_cpu_def->cache_info_passthrough = true;
1167 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
1168 x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1170 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
1171 x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1172 x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1173 x86_cpu_def->stepping = eax & 0x0F;
1175 x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
1176 x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
1177 x86_cpu_def->xlevel2 =
1178 kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
1180 cpu_x86_fill_model_id(x86_cpu_def->model_id);
1182 for (w = 0; w < FEATURE_WORDS; w++) {
1183 FeatureWordInfo *wi = &feature_word_info[w];
1184 x86_cpu_def->features[w] =
1185 kvm_arch_get_supported_cpuid(s, wi->cpuid_eax, wi->cpuid_ecx,
1190 static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask)
1194 for (i = 0; i < 32; ++i)
1195 if (1 << i & mask) {
1196 const char *reg = get_register_name_32(f->cpuid_reg);
1198 fprintf(stderr, "warning: host doesn't support requested feature: "
1199 "CPUID.%02XH:%s%s%s [bit %d]\n",
1201 f->feat_names[i] ? "." : "",
1202 f->feat_names[i] ? f->feat_names[i] : "", i);
1208 /* Check if all requested cpu flags are making their way to the guest
1210 * Returns 0 if all flags are supported by the host, non-zero otherwise.
1212 * This function may be called only if KVM is enabled.
1214 static int kvm_check_features_against_host(KVMState *s, X86CPU *cpu)
1216 CPUX86State *env = &cpu->env;
1220 assert(kvm_enabled());
1222 for (w = 0; w < FEATURE_WORDS; w++) {
1223 FeatureWordInfo *wi = &feature_word_info[w];
1224 uint32_t guest_feat = env->features[w];
1225 uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax,
1229 for (mask = 1; mask; mask <<= 1) {
1230 if (guest_feat & mask && !(host_feat & mask)) {
1231 unavailable_host_feature(wi, mask);
1239 static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
1240 const char *name, Error **errp)
1242 X86CPU *cpu = X86_CPU(obj);
1243 CPUX86State *env = &cpu->env;
1246 value = (env->cpuid_version >> 8) & 0xf;
1248 value += (env->cpuid_version >> 20) & 0xff;
1250 visit_type_int(v, &value, name, errp);
1253 static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
1254 const char *name, Error **errp)
1256 X86CPU *cpu = X86_CPU(obj);
1257 CPUX86State *env = &cpu->env;
1258 const int64_t min = 0;
1259 const int64_t max = 0xff + 0xf;
1262 visit_type_int(v, &value, name, errp);
1263 if (error_is_set(errp)) {
1266 if (value < min || value > max) {
1267 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1268 name ? name : "null", value, min, max);
1272 env->cpuid_version &= ~0xff00f00;
1274 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
1276 env->cpuid_version |= value << 8;
1280 static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
1281 const char *name, Error **errp)
1283 X86CPU *cpu = X86_CPU(obj);
1284 CPUX86State *env = &cpu->env;
1287 value = (env->cpuid_version >> 4) & 0xf;
1288 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
1289 visit_type_int(v, &value, name, errp);
1292 static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
1293 const char *name, Error **errp)
1295 X86CPU *cpu = X86_CPU(obj);
1296 CPUX86State *env = &cpu->env;
1297 const int64_t min = 0;
1298 const int64_t max = 0xff;
1301 visit_type_int(v, &value, name, errp);
1302 if (error_is_set(errp)) {
1305 if (value < min || value > max) {
1306 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1307 name ? name : "null", value, min, max);
1311 env->cpuid_version &= ~0xf00f0;
1312 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
1315 static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
1316 void *opaque, const char *name,
1319 X86CPU *cpu = X86_CPU(obj);
1320 CPUX86State *env = &cpu->env;
1323 value = env->cpuid_version & 0xf;
1324 visit_type_int(v, &value, name, errp);
1327 static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
1328 void *opaque, const char *name,
1331 X86CPU *cpu = X86_CPU(obj);
1332 CPUX86State *env = &cpu->env;
1333 const int64_t min = 0;
1334 const int64_t max = 0xf;
1337 visit_type_int(v, &value, name, errp);
1338 if (error_is_set(errp)) {
1341 if (value < min || value > max) {
1342 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1343 name ? name : "null", value, min, max);
1347 env->cpuid_version &= ~0xf;
1348 env->cpuid_version |= value & 0xf;
1351 static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
1352 const char *name, Error **errp)
1354 X86CPU *cpu = X86_CPU(obj);
1356 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
1359 static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
1360 const char *name, Error **errp)
1362 X86CPU *cpu = X86_CPU(obj);
1364 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
1367 static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
1368 const char *name, Error **errp)
1370 X86CPU *cpu = X86_CPU(obj);
1372 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1375 static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
1376 const char *name, Error **errp)
1378 X86CPU *cpu = X86_CPU(obj);
1380 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1383 static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1385 X86CPU *cpu = X86_CPU(obj);
1386 CPUX86State *env = &cpu->env;
1389 value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
1390 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
1391 env->cpuid_vendor3);
1395 static void x86_cpuid_set_vendor(Object *obj, const char *value,
1398 X86CPU *cpu = X86_CPU(obj);
1399 CPUX86State *env = &cpu->env;
1402 if (strlen(value) != CPUID_VENDOR_SZ) {
1403 error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
1408 env->cpuid_vendor1 = 0;
1409 env->cpuid_vendor2 = 0;
1410 env->cpuid_vendor3 = 0;
1411 for (i = 0; i < 4; i++) {
1412 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1413 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1414 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1418 static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1420 X86CPU *cpu = X86_CPU(obj);
1421 CPUX86State *env = &cpu->env;
1425 value = g_malloc(48 + 1);
1426 for (i = 0; i < 48; i++) {
1427 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1433 static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1436 X86CPU *cpu = X86_CPU(obj);
1437 CPUX86State *env = &cpu->env;
1440 if (model_id == NULL) {
1443 len = strlen(model_id);
1444 memset(env->cpuid_model, 0, 48);
1445 for (i = 0; i < 48; i++) {
1449 c = (uint8_t)model_id[i];
1451 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1455 static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
1456 const char *name, Error **errp)
1458 X86CPU *cpu = X86_CPU(obj);
1461 value = cpu->env.tsc_khz * 1000;
1462 visit_type_int(v, &value, name, errp);
1465 static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
1466 const char *name, Error **errp)
1468 X86CPU *cpu = X86_CPU(obj);
1469 const int64_t min = 0;
1470 const int64_t max = INT64_MAX;
1473 visit_type_int(v, &value, name, errp);
1474 if (error_is_set(errp)) {
1477 if (value < min || value > max) {
1478 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1479 name ? name : "null", value, min, max);
1483 cpu->env.tsc_khz = value / 1000;
1486 static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, void *opaque,
1487 const char *name, Error **errp)
1489 X86CPU *cpu = X86_CPU(obj);
1490 int64_t value = cpu->env.cpuid_apic_id;
1492 visit_type_int(v, &value, name, errp);
1495 static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque,
1496 const char *name, Error **errp)
1498 X86CPU *cpu = X86_CPU(obj);
1499 DeviceState *dev = DEVICE(obj);
1500 const int64_t min = 0;
1501 const int64_t max = UINT32_MAX;
1502 Error *error = NULL;
1505 if (dev->realized) {
1506 error_setg(errp, "Attempt to set property '%s' on '%s' after "
1507 "it was realized", name, object_get_typename(obj));
1511 visit_type_int(v, &value, name, &error);
1513 error_propagate(errp, error);
1516 if (value < min || value > max) {
1517 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1518 " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
1519 object_get_typename(obj), name, value, min, max);
1523 if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
1524 error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
1527 cpu->env.cpuid_apic_id = value;
1530 /* Generic getter for "feature-words" and "filtered-features" properties */
1531 static void x86_cpu_get_feature_words(Object *obj, Visitor *v, void *opaque,
1532 const char *name, Error **errp)
1534 uint32_t *array = (uint32_t *)opaque;
1537 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
1538 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
1539 X86CPUFeatureWordInfoList *list = NULL;
1541 for (w = 0; w < FEATURE_WORDS; w++) {
1542 FeatureWordInfo *wi = &feature_word_info[w];
1543 X86CPUFeatureWordInfo *qwi = &word_infos[w];
1544 qwi->cpuid_input_eax = wi->cpuid_eax;
1545 qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
1546 qwi->cpuid_input_ecx = wi->cpuid_ecx;
1547 qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
1548 qwi->features = array[w];
1550 /* List will be in reverse order, but order shouldn't matter */
1551 list_entries[w].next = list;
1552 list_entries[w].value = &word_infos[w];
1553 list = &list_entries[w];
1556 visit_type_X86CPUFeatureWordInfoList(v, &list, "feature-words", &err);
1557 error_propagate(errp, err);
1560 static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
1561 const char *name, Error **errp)
1563 X86CPU *cpu = X86_CPU(obj);
1564 int64_t value = cpu->hyperv_spinlock_attempts;
1566 visit_type_int(v, &value, name, errp);
1569 static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
1570 const char *name, Error **errp)
1572 const int64_t min = 0xFFF;
1573 const int64_t max = UINT_MAX;
1574 X86CPU *cpu = X86_CPU(obj);
1578 visit_type_int(v, &value, name, &err);
1580 error_propagate(errp, err);
1584 if (value < min || value > max) {
1585 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1586 " (minimum: %" PRId64 ", maximum: %" PRId64 ")",
1587 object_get_typename(obj), name ? name : "null",
1591 cpu->hyperv_spinlock_attempts = value;
1594 static PropertyInfo qdev_prop_spinlocks = {
1596 .get = x86_get_hv_spinlocks,
1597 .set = x86_set_hv_spinlocks,
1600 static int cpu_x86_find_by_name(X86CPU *cpu, X86CPUDefinition *x86_cpu_def,
1603 X86CPUDefinition *def;
1609 if (kvm_enabled() && strcmp(name, "host") == 0) {
1610 kvm_cpu_fill_host(x86_cpu_def);
1611 object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
1615 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1616 def = &builtin_x86_defs[i];
1617 if (strcmp(name, def->name) == 0) {
1618 memcpy(x86_cpu_def, def, sizeof(*def));
1626 /* Convert all '_' in a feature string option name to '-', to make feature
1627 * name conform to QOM property naming rule, which uses '-' instead of '_'.
1629 static inline void feat2prop(char *s)
1631 while ((s = strchr(s, '_'))) {
1636 /* Parse "+feature,-feature,feature=foo" CPU feature string
1638 static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
1640 char *featurestr; /* Single 'key=value" string being parsed */
1641 /* Features to be added */
1642 FeatureWordArray plus_features = { 0 };
1643 /* Features to be removed */
1644 FeatureWordArray minus_features = { 0 };
1646 CPUX86State *env = &cpu->env;
1648 featurestr = features ? strtok(features, ",") : NULL;
1650 while (featurestr) {
1652 if (featurestr[0] == '+') {
1653 add_flagname_to_bitmaps(featurestr + 1, plus_features);
1654 } else if (featurestr[0] == '-') {
1655 add_flagname_to_bitmaps(featurestr + 1, minus_features);
1656 } else if ((val = strchr(featurestr, '='))) {
1658 feat2prop(featurestr);
1659 if (!strcmp(featurestr, "xlevel")) {
1663 numvalue = strtoul(val, &err, 0);
1664 if (!*val || *err) {
1665 error_setg(errp, "bad numerical value %s", val);
1668 if (numvalue < 0x80000000) {
1669 fprintf(stderr, "xlevel value shall always be >= 0x80000000"
1670 ", fixup will be removed in future versions\n");
1671 numvalue += 0x80000000;
1673 snprintf(num, sizeof(num), "%" PRIu32, numvalue);
1674 object_property_parse(OBJECT(cpu), num, featurestr, errp);
1675 } else if (!strcmp(featurestr, "tsc-freq")) {
1680 tsc_freq = strtosz_suffix_unit(val, &err,
1681 STRTOSZ_DEFSUFFIX_B, 1000);
1682 if (tsc_freq < 0 || *err) {
1683 error_setg(errp, "bad numerical value %s", val);
1686 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
1687 object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
1688 } else if (!strcmp(featurestr, "hv-spinlocks")) {
1690 const int min = 0xFFF;
1692 numvalue = strtoul(val, &err, 0);
1693 if (!*val || *err) {
1694 error_setg(errp, "bad numerical value %s", val);
1697 if (numvalue < min) {
1698 fprintf(stderr, "hv-spinlocks value shall always be >= 0x%x"
1699 ", fixup will be removed in future versions\n",
1703 snprintf(num, sizeof(num), "%" PRId32, numvalue);
1704 object_property_parse(OBJECT(cpu), num, featurestr, errp);
1706 object_property_parse(OBJECT(cpu), val, featurestr, errp);
1709 feat2prop(featurestr);
1710 object_property_parse(OBJECT(cpu), "on", featurestr, errp);
1712 if (error_is_set(errp)) {
1715 featurestr = strtok(NULL, ",");
1717 env->features[FEAT_1_EDX] |= plus_features[FEAT_1_EDX];
1718 env->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX];
1719 env->features[FEAT_8000_0001_EDX] |= plus_features[FEAT_8000_0001_EDX];
1720 env->features[FEAT_8000_0001_ECX] |= plus_features[FEAT_8000_0001_ECX];
1721 env->features[FEAT_C000_0001_EDX] |= plus_features[FEAT_C000_0001_EDX];
1722 env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
1723 env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
1724 env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
1725 env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
1726 env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
1727 env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX];
1728 env->features[FEAT_8000_0001_ECX] &= ~minus_features[FEAT_8000_0001_ECX];
1729 env->features[FEAT_C000_0001_EDX] &= ~minus_features[FEAT_C000_0001_EDX];
1730 env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
1731 env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
1732 env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
1738 /* generate a composite string into buf of all cpuid names in featureset
1739 * selected by fbits. indicate truncation at bufsize in the event of overflow.
1740 * if flags, suppress names undefined in featureset.
1742 static void listflags(char *buf, int bufsize, uint32_t fbits,
1743 const char **featureset, uint32_t flags)
1745 const char **p = &featureset[31];
1749 b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1751 for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1752 if (fbits & 1 << bit && (*p || !flags)) {
1754 nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1756 nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1757 if (bufsize <= nc) {
1759 memcpy(b, "...", sizeof("..."));
1768 /* generate CPU information. */
1769 void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
1771 X86CPUDefinition *def;
1775 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1776 def = &builtin_x86_defs[i];
1777 snprintf(buf, sizeof(buf), "%s", def->name);
1778 (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
1781 (*cpu_fprintf)(f, "x86 %16s %-48s\n", "host",
1782 "KVM processor with all supported host features "
1783 "(only available in KVM mode)");
1786 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
1787 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
1788 FeatureWordInfo *fw = &feature_word_info[i];
1790 listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
1791 (*cpu_fprintf)(f, " %s\n", buf);
1795 CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
1797 CpuDefinitionInfoList *cpu_list = NULL;
1798 X86CPUDefinition *def;
1801 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1802 CpuDefinitionInfoList *entry;
1803 CpuDefinitionInfo *info;
1805 def = &builtin_x86_defs[i];
1806 info = g_malloc0(sizeof(*info));
1807 info->name = g_strdup(def->name);
1809 entry = g_malloc0(sizeof(*entry));
1810 entry->value = info;
1811 entry->next = cpu_list;
1818 static void filter_features_for_kvm(X86CPU *cpu)
1820 CPUX86State *env = &cpu->env;
1821 KVMState *s = kvm_state;
1824 for (w = 0; w < FEATURE_WORDS; w++) {
1825 FeatureWordInfo *wi = &feature_word_info[w];
1826 uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax,
1829 uint32_t requested_features = env->features[w];
1830 env->features[w] &= host_feat;
1831 cpu->filtered_features[w] = requested_features & ~env->features[w];
1835 /* Load CPU definition for a given CPU model name
1837 static void x86_cpu_load_def(X86CPU *cpu, const char *name, Error **errp)
1839 CPUX86State *env = &cpu->env;
1840 X86CPUDefinition def1, *def = &def1;
1842 char host_vendor[CPUID_VENDOR_SZ + 1];
1844 memset(def, 0, sizeof(*def));
1846 if (cpu_x86_find_by_name(cpu, def, name) < 0) {
1847 error_setg(errp, "Unable to find CPU definition: %s", name);
1851 object_property_set_int(OBJECT(cpu), def->level, "level", errp);
1852 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
1853 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
1854 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
1855 env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX];
1856 env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX];
1857 env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX];
1858 env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX];
1859 object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
1860 env->features[FEAT_KVM] = def->features[FEAT_KVM];
1861 env->features[FEAT_SVM] = def->features[FEAT_SVM];
1862 env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
1863 env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
1864 env->cpuid_xlevel2 = def->xlevel2;
1865 cpu->cache_info_passthrough = def->cache_info_passthrough;
1867 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
1869 /* Special cases not set in the X86CPUDefinition structs: */
1870 if (kvm_enabled()) {
1872 for (w = 0; w < FEATURE_WORDS; w++) {
1873 env->features[w] |= kvm_default_features[w];
1877 env->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
1879 /* sysenter isn't supported in compatibility mode on AMD,
1880 * syscall isn't supported in compatibility mode on Intel.
1881 * Normally we advertise the actual CPU vendor, but you can
1882 * override this using the 'vendor' property if you want to use
1883 * KVM's sysenter/syscall emulation in compatibility mode and
1884 * when doing cross vendor migration
1886 vendor = def->vendor;
1887 if (kvm_enabled()) {
1888 uint32_t ebx = 0, ecx = 0, edx = 0;
1889 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
1890 x86_cpu_vendor_words2str(host_vendor, ebx, edx, ecx);
1891 vendor = host_vendor;
1894 object_property_set_str(OBJECT(cpu), vendor, "vendor", errp);
1898 X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
1903 gchar **model_pieces;
1904 char *name, *features;
1906 Error *error = NULL;
1908 model_pieces = g_strsplit(cpu_model, ",", 2);
1909 if (!model_pieces[0]) {
1910 error_setg(&error, "Invalid/empty CPU model name");
1913 name = model_pieces[0];
1914 features = model_pieces[1];
1916 oc = x86_cpu_class_by_name(name);
1918 error_setg(&error, "Unable to find CPU definition: %s", name);
1921 cpu = X86_CPU(object_new(object_class_get_name(oc)));
1922 x86_cpu_load_def(cpu, name, &error);
1927 #ifndef CONFIG_USER_ONLY
1928 if (icc_bridge == NULL) {
1929 error_setg(&error, "Invalid icc-bridge value");
1932 qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
1933 object_unref(OBJECT(cpu));
1936 /* Emulate per-model subclasses for global properties */
1937 typename = g_strdup_printf("%s-" TYPE_X86_CPU, name);
1938 qdev_prop_set_globals_for_type(DEVICE(cpu), typename, &error);
1944 cpu_x86_parse_featurestr(cpu, features, &error);
1950 if (error != NULL) {
1951 error_propagate(errp, error);
1953 object_unref(OBJECT(cpu));
1957 g_strfreev(model_pieces);
1961 X86CPU *cpu_x86_init(const char *cpu_model)
1963 Error *error = NULL;
1966 cpu = cpu_x86_create(cpu_model, NULL, &error);
1971 object_property_set_bool(OBJECT(cpu), true, "realized", &error);
1975 error_report("%s", error_get_pretty(error));
1978 object_unref(OBJECT(cpu));
1985 #if !defined(CONFIG_USER_ONLY)
1987 void cpu_clear_apic_feature(CPUX86State *env)
1989 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
1992 #endif /* !CONFIG_USER_ONLY */
1994 /* Initialize list of CPU models, filling some non-static fields if necessary
1996 void x86_cpudef_setup(void)
1999 static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
2001 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
2002 X86CPUDefinition *def = &builtin_x86_defs[i];
2004 /* Look for specific "cpudef" models that */
2005 /* have the QEMU version in .model_id */
2006 for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
2007 if (strcmp(model_with_versions[j], def->name) == 0) {
2008 pstrcpy(def->model_id, sizeof(def->model_id),
2009 "QEMU Virtual CPU version ");
2010 pstrcat(def->model_id, sizeof(def->model_id),
2011 qemu_get_version());
2018 static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
2019 uint32_t *ecx, uint32_t *edx)
2021 *ebx = env->cpuid_vendor1;
2022 *edx = env->cpuid_vendor2;
2023 *ecx = env->cpuid_vendor3;
2026 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
2027 uint32_t *eax, uint32_t *ebx,
2028 uint32_t *ecx, uint32_t *edx)
2030 X86CPU *cpu = x86_env_get_cpu(env);
2031 CPUState *cs = CPU(cpu);
2033 /* test if maximum index reached */
2034 if (index & 0x80000000) {
2035 if (index > env->cpuid_xlevel) {
2036 if (env->cpuid_xlevel2 > 0) {
2037 /* Handle the Centaur's CPUID instruction. */
2038 if (index > env->cpuid_xlevel2) {
2039 index = env->cpuid_xlevel2;
2040 } else if (index < 0xC0000000) {
2041 index = env->cpuid_xlevel;
2044 /* Intel documentation states that invalid EAX input will
2045 * return the same information as EAX=cpuid_level
2046 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
2048 index = env->cpuid_level;
2052 if (index > env->cpuid_level)
2053 index = env->cpuid_level;
2058 *eax = env->cpuid_level;
2059 get_cpuid_vendor(env, ebx, ecx, edx);
2062 *eax = env->cpuid_version;
2063 *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
2064 *ecx = env->features[FEAT_1_ECX];
2065 *edx = env->features[FEAT_1_EDX];
2066 if (cs->nr_cores * cs->nr_threads > 1) {
2067 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
2068 *edx |= 1 << 28; /* HTT bit */
2072 /* cache info: needed for Pentium Pro compatibility */
2073 if (cpu->cache_info_passthrough) {
2074 host_cpuid(index, 0, eax, ebx, ecx, edx);
2077 *eax = 1; /* Number of CPUID[EAX=2] calls required */
2080 *edx = (L1D_DESCRIPTOR << 16) | \
2081 (L1I_DESCRIPTOR << 8) | \
2085 /* cache info: needed for Core compatibility */
2086 if (cpu->cache_info_passthrough) {
2087 host_cpuid(index, count, eax, ebx, ecx, edx);
2088 *eax &= ~0xFC000000;
2092 case 0: /* L1 dcache info */
2093 *eax |= CPUID_4_TYPE_DCACHE | \
2094 CPUID_4_LEVEL(1) | \
2095 CPUID_4_SELF_INIT_LEVEL;
2096 *ebx = (L1D_LINE_SIZE - 1) | \
2097 ((L1D_PARTITIONS - 1) << 12) | \
2098 ((L1D_ASSOCIATIVITY - 1) << 22);
2099 *ecx = L1D_SETS - 1;
2100 *edx = CPUID_4_NO_INVD_SHARING;
2102 case 1: /* L1 icache info */
2103 *eax |= CPUID_4_TYPE_ICACHE | \
2104 CPUID_4_LEVEL(1) | \
2105 CPUID_4_SELF_INIT_LEVEL;
2106 *ebx = (L1I_LINE_SIZE - 1) | \
2107 ((L1I_PARTITIONS - 1) << 12) | \
2108 ((L1I_ASSOCIATIVITY - 1) << 22);
2109 *ecx = L1I_SETS - 1;
2110 *edx = CPUID_4_NO_INVD_SHARING;
2112 case 2: /* L2 cache info */
2113 *eax |= CPUID_4_TYPE_UNIFIED | \
2114 CPUID_4_LEVEL(2) | \
2115 CPUID_4_SELF_INIT_LEVEL;
2116 if (cs->nr_threads > 1) {
2117 *eax |= (cs->nr_threads - 1) << 14;
2119 *ebx = (L2_LINE_SIZE - 1) | \
2120 ((L2_PARTITIONS - 1) << 12) | \
2121 ((L2_ASSOCIATIVITY - 1) << 22);
2123 *edx = CPUID_4_NO_INVD_SHARING;
2125 default: /* end of info */
2134 /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
2135 if ((*eax & 31) && cs->nr_cores > 1) {
2136 *eax |= (cs->nr_cores - 1) << 26;
2140 /* mwait info: needed for Core compatibility */
2141 *eax = 0; /* Smallest monitor-line size in bytes */
2142 *ebx = 0; /* Largest monitor-line size in bytes */
2143 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
2147 /* Thermal and Power Leaf */
2154 /* Structured Extended Feature Flags Enumeration Leaf */
2156 *eax = 0; /* Maximum ECX value for sub-leaves */
2157 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
2158 *ecx = 0; /* Reserved */
2159 *edx = 0; /* Reserved */
2168 /* Direct Cache Access Information Leaf */
2169 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2175 /* Architectural Performance Monitoring Leaf */
2176 if (kvm_enabled() && cpu->enable_pmu) {
2177 KVMState *s = cs->kvm_state;
2179 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
2180 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
2181 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
2182 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
2191 KVMState *s = cs->kvm_state;
2195 /* Processor Extended State */
2200 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) || !kvm_enabled()) {
2204 kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX) |
2205 ((uint64_t)kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX) << 32);
2209 for (i = 2; i < ARRAY_SIZE(ext_save_areas); i++) {
2210 const ExtSaveArea *esa = &ext_save_areas[i];
2211 if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2212 (kvm_mask & (1 << i)) != 0) {
2216 *edx |= 1 << (i - 32);
2218 *ecx = MAX(*ecx, esa->offset + esa->size);
2221 *eax |= kvm_mask & (XSTATE_FP | XSTATE_SSE);
2223 } else if (count == 1) {
2224 *eax = kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
2225 } else if (count < ARRAY_SIZE(ext_save_areas)) {
2226 const ExtSaveArea *esa = &ext_save_areas[count];
2227 if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2228 (kvm_mask & (1 << count)) != 0) {
2236 *eax = env->cpuid_xlevel;
2237 *ebx = env->cpuid_vendor1;
2238 *edx = env->cpuid_vendor2;
2239 *ecx = env->cpuid_vendor3;
2242 *eax = env->cpuid_version;
2244 *ecx = env->features[FEAT_8000_0001_ECX];
2245 *edx = env->features[FEAT_8000_0001_EDX];
2247 /* The Linux kernel checks for the CMPLegacy bit and
2248 * discards multiple thread information if it is set.
2249 * So dont set it here for Intel to make Linux guests happy.
2251 if (cs->nr_cores * cs->nr_threads > 1) {
2252 uint32_t tebx, tecx, tedx;
2253 get_cpuid_vendor(env, &tebx, &tecx, &tedx);
2254 if (tebx != CPUID_VENDOR_INTEL_1 ||
2255 tedx != CPUID_VENDOR_INTEL_2 ||
2256 tecx != CPUID_VENDOR_INTEL_3) {
2257 *ecx |= 1 << 1; /* CmpLegacy bit */
2264 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2265 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2266 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2267 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2270 /* cache info (L1 cache) */
2271 if (cpu->cache_info_passthrough) {
2272 host_cpuid(index, 0, eax, ebx, ecx, edx);
2275 *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \
2276 (L1_ITLB_2M_ASSOC << 8) | (L1_ITLB_2M_ENTRIES);
2277 *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
2278 (L1_ITLB_4K_ASSOC << 8) | (L1_ITLB_4K_ENTRIES);
2279 *ecx = (L1D_SIZE_KB_AMD << 24) | (L1D_ASSOCIATIVITY_AMD << 16) | \
2280 (L1D_LINES_PER_TAG << 8) | (L1D_LINE_SIZE);
2281 *edx = (L1I_SIZE_KB_AMD << 24) | (L1I_ASSOCIATIVITY_AMD << 16) | \
2282 (L1I_LINES_PER_TAG << 8) | (L1I_LINE_SIZE);
2285 /* cache info (L2 cache) */
2286 if (cpu->cache_info_passthrough) {
2287 host_cpuid(index, 0, eax, ebx, ecx, edx);
2290 *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \
2291 (L2_DTLB_2M_ENTRIES << 16) | \
2292 (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \
2293 (L2_ITLB_2M_ENTRIES);
2294 *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) | \
2295 (L2_DTLB_4K_ENTRIES << 16) | \
2296 (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
2297 (L2_ITLB_4K_ENTRIES);
2298 *ecx = (L2_SIZE_KB_AMD << 16) | \
2299 (AMD_ENC_ASSOC(L2_ASSOCIATIVITY) << 12) | \
2300 (L2_LINES_PER_TAG << 8) | (L2_LINE_SIZE);
2301 *edx = ((L3_SIZE_KB/512) << 18) | \
2302 (AMD_ENC_ASSOC(L3_ASSOCIATIVITY) << 12) | \
2303 (L3_LINES_PER_TAG << 8) | (L3_LINE_SIZE);
2306 /* virtual & phys address size in low 2 bytes. */
2307 /* XXX: This value must match the one used in the MMU code. */
2308 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
2309 /* 64 bit processor */
2310 /* XXX: The physical address space is limited to 42 bits in exec.c. */
2311 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
2313 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
2314 *eax = 0x00000024; /* 36 bits physical */
2316 *eax = 0x00000020; /* 32 bits physical */
2322 if (cs->nr_cores * cs->nr_threads > 1) {
2323 *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
2327 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
2328 *eax = 0x00000001; /* SVM Revision */
2329 *ebx = 0x00000010; /* nr of ASIDs */
2331 *edx = env->features[FEAT_SVM]; /* optional features */
2340 *eax = env->cpuid_xlevel2;
2346 /* Support for VIA CPU's CPUID instruction */
2347 *eax = env->cpuid_version;
2350 *edx = env->features[FEAT_C000_0001_EDX];
2355 /* Reserved for the future, and now filled with zero */
2362 /* reserved values: zero */
2371 /* CPUClass::reset() */
2372 static void x86_cpu_reset(CPUState *s)
2374 X86CPU *cpu = X86_CPU(s);
2375 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2376 CPUX86State *env = &cpu->env;
2379 xcc->parent_reset(s);
2382 memset(env, 0, offsetof(CPUX86State, breakpoints));
2386 env->old_exception = -1;
2388 /* init to reset state */
2390 #ifdef CONFIG_SOFTMMU
2391 env->hflags |= HF_SOFTMMU_MASK;
2393 env->hflags2 |= HF2_GIF_MASK;
2395 cpu_x86_update_cr0(env, 0x60000010);
2396 env->a20_mask = ~0x0;
2397 env->smbase = 0x30000;
2399 env->idt.limit = 0xffff;
2400 env->gdt.limit = 0xffff;
2401 env->ldt.limit = 0xffff;
2402 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2403 env->tr.limit = 0xffff;
2404 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2406 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2407 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2408 DESC_R_MASK | DESC_A_MASK);
2409 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2410 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2412 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
2413 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2415 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
2416 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2418 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
2419 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2421 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
2422 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2426 env->regs[R_EDX] = env->cpuid_version;
2431 for (i = 0; i < 8; i++) {
2436 env->mxcsr = 0x1f80;
2437 env->xstate_bv = XSTATE_FP | XSTATE_SSE;
2439 env->pat = 0x0007040600070406ULL;
2440 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2442 memset(env->dr, 0, sizeof(env->dr));
2443 env->dr[6] = DR6_FIXED_1;
2444 env->dr[7] = DR7_FIXED_1;
2445 cpu_breakpoint_remove_all(env, BP_CPU);
2446 cpu_watchpoint_remove_all(env, BP_CPU);
2448 env->tsc_adjust = 0;
2451 #if !defined(CONFIG_USER_ONLY)
2452 /* We hard-wire the BSP to the first CPU. */
2453 if (s->cpu_index == 0) {
2454 apic_designate_bsp(cpu->apic_state);
2457 s->halted = !cpu_is_bsp(cpu);
2461 #ifndef CONFIG_USER_ONLY
2462 bool cpu_is_bsp(X86CPU *cpu)
2464 return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
2467 /* TODO: remove me, when reset over QOM tree is implemented */
2468 static void x86_cpu_machine_reset_cb(void *opaque)
2470 X86CPU *cpu = opaque;
2471 cpu_reset(CPU(cpu));
2475 static void mce_init(X86CPU *cpu)
2477 CPUX86State *cenv = &cpu->env;
2480 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
2481 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
2482 (CPUID_MCE | CPUID_MCA)) {
2483 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2484 cenv->mcg_ctl = ~(uint64_t)0;
2485 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2486 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2491 #ifndef CONFIG_USER_ONLY
2492 static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
2494 CPUX86State *env = &cpu->env;
2495 DeviceState *dev = DEVICE(cpu);
2496 APICCommonState *apic;
2497 const char *apic_type = "apic";
2499 if (kvm_irqchip_in_kernel()) {
2500 apic_type = "kvm-apic";
2501 } else if (xen_enabled()) {
2502 apic_type = "xen-apic";
2505 cpu->apic_state = qdev_try_create(qdev_get_parent_bus(dev), apic_type);
2506 if (cpu->apic_state == NULL) {
2507 error_setg(errp, "APIC device '%s' could not be created", apic_type);
2511 object_property_add_child(OBJECT(cpu), "apic",
2512 OBJECT(cpu->apic_state), NULL);
2513 qdev_prop_set_uint8(cpu->apic_state, "id", env->cpuid_apic_id);
2514 /* TODO: convert to link<> */
2515 apic = APIC_COMMON(cpu->apic_state);
2519 static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2521 if (cpu->apic_state == NULL) {
2525 if (qdev_init(cpu->apic_state)) {
2526 error_setg(errp, "APIC device '%s' could not be initialized",
2527 object_get_typename(OBJECT(cpu->apic_state)));
2532 static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2537 static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
2539 CPUState *cs = CPU(dev);
2540 X86CPU *cpu = X86_CPU(dev);
2541 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
2542 CPUX86State *env = &cpu->env;
2543 Error *local_err = NULL;
2545 if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
2546 env->cpuid_level = 7;
2549 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
2552 if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
2553 env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
2554 env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
2555 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
2556 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
2557 & CPUID_EXT2_AMD_ALIASES);
2560 if (!kvm_enabled()) {
2561 env->features[FEAT_1_EDX] &= TCG_FEATURES;
2562 env->features[FEAT_1_ECX] &= TCG_EXT_FEATURES;
2563 env->features[FEAT_8000_0001_EDX] &= (TCG_EXT2_FEATURES
2564 #ifdef TARGET_X86_64
2565 | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
2568 env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES;
2569 env->features[FEAT_SVM] &= TCG_SVM_FEATURES;
2571 KVMState *s = kvm_state;
2572 if ((cpu->check_cpuid || cpu->enforce_cpuid)
2573 && kvm_check_features_against_host(s, cpu) && cpu->enforce_cpuid) {
2574 error_setg(&local_err,
2575 "Host's CPU doesn't support requested features");
2578 filter_features_for_kvm(cpu);
2581 #ifndef CONFIG_USER_ONLY
2582 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
2584 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
2585 x86_cpu_apic_create(cpu, &local_err);
2586 if (local_err != NULL) {
2595 x86_cpu_apic_realize(cpu, &local_err);
2596 if (local_err != NULL) {
2601 xcc->parent_realize(dev, &local_err);
2603 if (local_err != NULL) {
2604 error_propagate(errp, local_err);
2609 /* Enables contiguous-apic-ID mode, for compatibility */
2610 static bool compat_apic_id_mode;
2612 void enable_compat_apic_id_mode(void)
2614 compat_apic_id_mode = true;
2617 /* Calculates initial APIC ID for a specific CPU index
2619 * Currently we need to be able to calculate the APIC ID from the CPU index
2620 * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
2621 * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
2622 * all CPUs up to max_cpus.
2624 uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
2626 uint32_t correct_id;
2629 correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
2630 if (compat_apic_id_mode) {
2631 if (cpu_index != correct_id && !warned) {
2632 error_report("APIC IDs set in compatibility mode, "
2633 "CPU topology won't match the configuration");
2642 static void x86_cpu_initfn(Object *obj)
2644 CPUState *cs = CPU(obj);
2645 X86CPU *cpu = X86_CPU(obj);
2646 CPUX86State *env = &cpu->env;
2652 object_property_add(obj, "family", "int",
2653 x86_cpuid_version_get_family,
2654 x86_cpuid_version_set_family, NULL, NULL, NULL);
2655 object_property_add(obj, "model", "int",
2656 x86_cpuid_version_get_model,
2657 x86_cpuid_version_set_model, NULL, NULL, NULL);
2658 object_property_add(obj, "stepping", "int",
2659 x86_cpuid_version_get_stepping,
2660 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
2661 object_property_add(obj, "level", "int",
2662 x86_cpuid_get_level,
2663 x86_cpuid_set_level, NULL, NULL, NULL);
2664 object_property_add(obj, "xlevel", "int",
2665 x86_cpuid_get_xlevel,
2666 x86_cpuid_set_xlevel, NULL, NULL, NULL);
2667 object_property_add_str(obj, "vendor",
2668 x86_cpuid_get_vendor,
2669 x86_cpuid_set_vendor, NULL);
2670 object_property_add_str(obj, "model-id",
2671 x86_cpuid_get_model_id,
2672 x86_cpuid_set_model_id, NULL);
2673 object_property_add(obj, "tsc-frequency", "int",
2674 x86_cpuid_get_tsc_freq,
2675 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
2676 object_property_add(obj, "apic-id", "int",
2677 x86_cpuid_get_apic_id,
2678 x86_cpuid_set_apic_id, NULL, NULL, NULL);
2679 object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
2680 x86_cpu_get_feature_words,
2681 NULL, NULL, (void *)env->features, NULL);
2682 object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
2683 x86_cpu_get_feature_words,
2684 NULL, NULL, (void *)cpu->filtered_features, NULL);
2686 cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
2687 env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
2689 /* init various static tables used in TCG mode */
2690 if (tcg_enabled() && !inited) {
2692 optimize_flags_init();
2693 #ifndef CONFIG_USER_ONLY
2694 cpu_set_debug_excp_handler(breakpoint_handler);
2699 static int64_t x86_cpu_get_arch_id(CPUState *cs)
2701 X86CPU *cpu = X86_CPU(cs);
2702 CPUX86State *env = &cpu->env;
2704 return env->cpuid_apic_id;
2707 static bool x86_cpu_get_paging_enabled(const CPUState *cs)
2709 X86CPU *cpu = X86_CPU(cs);
2711 return cpu->env.cr[0] & CR0_PG_MASK;
2714 static void x86_cpu_set_pc(CPUState *cs, vaddr value)
2716 X86CPU *cpu = X86_CPU(cs);
2718 cpu->env.eip = value;
2721 static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
2723 X86CPU *cpu = X86_CPU(cs);
2725 cpu->env.eip = tb->pc - tb->cs_base;
2728 static bool x86_cpu_has_work(CPUState *cs)
2730 X86CPU *cpu = X86_CPU(cs);
2731 CPUX86State *env = &cpu->env;
2733 return ((cs->interrupt_request & (CPU_INTERRUPT_HARD |
2734 CPU_INTERRUPT_POLL)) &&
2735 (env->eflags & IF_MASK)) ||
2736 (cs->interrupt_request & (CPU_INTERRUPT_NMI |
2737 CPU_INTERRUPT_INIT |
2738 CPU_INTERRUPT_SIPI |
2739 CPU_INTERRUPT_MCE));
2742 static Property x86_cpu_properties[] = {
2743 DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
2744 { .name = "hv-spinlocks", .info = &qdev_prop_spinlocks },
2745 DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false),
2746 DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false),
2747 DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false),
2748 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false),
2749 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
2750 DEFINE_PROP_END_OF_LIST()
2753 static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
2755 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2756 CPUClass *cc = CPU_CLASS(oc);
2757 DeviceClass *dc = DEVICE_CLASS(oc);
2759 xcc->parent_realize = dc->realize;
2760 dc->realize = x86_cpu_realizefn;
2761 dc->bus_type = TYPE_ICC_BUS;
2762 dc->props = x86_cpu_properties;
2764 xcc->parent_reset = cc->reset;
2765 cc->reset = x86_cpu_reset;
2766 cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
2768 cc->class_by_name = x86_cpu_class_by_name;
2769 cc->has_work = x86_cpu_has_work;
2770 cc->do_interrupt = x86_cpu_do_interrupt;
2771 cc->dump_state = x86_cpu_dump_state;
2772 cc->set_pc = x86_cpu_set_pc;
2773 cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
2774 cc->gdb_read_register = x86_cpu_gdb_read_register;
2775 cc->gdb_write_register = x86_cpu_gdb_write_register;
2776 cc->get_arch_id = x86_cpu_get_arch_id;
2777 cc->get_paging_enabled = x86_cpu_get_paging_enabled;
2778 #ifndef CONFIG_USER_ONLY
2779 cc->get_memory_mapping = x86_cpu_get_memory_mapping;
2780 cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
2781 cc->write_elf64_note = x86_cpu_write_elf64_note;
2782 cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
2783 cc->write_elf32_note = x86_cpu_write_elf32_note;
2784 cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
2785 cc->vmsd = &vmstate_x86_cpu;
2787 cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
2790 static const TypeInfo x86_cpu_type_info = {
2791 .name = TYPE_X86_CPU,
2793 .instance_size = sizeof(X86CPU),
2794 .instance_init = x86_cpu_initfn,
2796 .class_size = sizeof(X86CPUClass),
2797 .class_init = x86_cpu_common_class_init,
2800 static void x86_cpu_register_types(void)
2802 type_register_static(&x86_cpu_type_info);
2805 type_init(x86_cpu_register_types)