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_C_P_U_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 = 0x10 },
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 static uint32_t kvm_default_features = (1 << KVM_FEATURE_CLOCKSOURCE) |
362 (1 << KVM_FEATURE_NOP_IO_DELAY) |
363 (1 << KVM_FEATURE_CLOCKSOURCE2) |
364 (1 << KVM_FEATURE_ASYNC_PF) |
365 (1 << KVM_FEATURE_STEAL_TIME) |
366 (1 << KVM_FEATURE_PV_EOI) |
367 (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
369 void disable_kvm_pv_eoi(void)
371 kvm_default_features &= ~(1UL << KVM_FEATURE_PV_EOI);
374 void host_cpuid(uint32_t function, uint32_t count,
375 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
377 #if defined(CONFIG_KVM)
382 : "=a"(vec[0]), "=b"(vec[1]),
383 "=c"(vec[2]), "=d"(vec[3])
384 : "0"(function), "c"(count) : "cc");
386 asm volatile("pusha \n\t"
388 "mov %%eax, 0(%2) \n\t"
389 "mov %%ebx, 4(%2) \n\t"
390 "mov %%ecx, 8(%2) \n\t"
391 "mov %%edx, 12(%2) \n\t"
393 : : "a"(function), "c"(count), "S"(vec)
408 #define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
410 /* general substring compare of *[s1..e1) and *[s2..e2). sx is start of
411 * a substring. ex if !NULL points to the first char after a substring,
412 * otherwise the string is assumed to sized by a terminating nul.
413 * Return lexical ordering of *s1:*s2.
415 static int sstrcmp(const char *s1, const char *e1, const char *s2,
419 if (!*s1 || !*s2 || *s1 != *s2)
422 if (s1 == e1 && s2 == e2)
431 /* compare *[s..e) to *altstr. *altstr may be a simple string or multiple
432 * '|' delimited (possibly empty) strings in which case search for a match
433 * within the alternatives proceeds left to right. Return 0 for success,
434 * non-zero otherwise.
436 static int altcmp(const char *s, const char *e, const char *altstr)
440 for (q = p = altstr; ; ) {
441 while (*p && *p != '|')
443 if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
452 /* search featureset for flag *[s..e), if found set corresponding bit in
453 * *pval and return true, otherwise return false
455 static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
456 const char **featureset)
462 for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
463 if (*ppc && !altcmp(s, e, *ppc)) {
471 static void add_flagname_to_bitmaps(const char *flagname,
472 FeatureWordArray words)
475 for (w = 0; w < FEATURE_WORDS; w++) {
476 FeatureWordInfo *wi = &feature_word_info[w];
477 if (wi->feat_names &&
478 lookup_feature(&words[w], flagname, NULL, wi->feat_names)) {
482 if (w == FEATURE_WORDS) {
483 fprintf(stderr, "CPU feature %s not found\n", flagname);
487 typedef struct x86_def_t {
492 /* vendor is zero-terminated, 12 character ASCII string */
493 char vendor[CPUID_VENDOR_SZ + 1];
497 FeatureWordArray features;
499 bool cache_info_passthrough;
502 #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
503 #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
504 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
505 #define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
506 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
507 CPUID_PSE36 | CPUID_FXSR)
508 #define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
509 #define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
510 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
511 CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
512 CPUID_PAE | CPUID_SEP | CPUID_APIC)
514 #define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
515 CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
516 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
517 CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
518 CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
519 /* partly implemented:
520 CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
521 CPUID_PSE36 (needed for Solaris) */
523 CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
524 #define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
525 CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
526 CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
527 CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
529 CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
530 CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
531 CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
532 CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_XSAVE,
533 CPUID_EXT_OSXSAVE, CPUID_EXT_AVX, CPUID_EXT_F16C,
535 #define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
536 CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
537 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
539 CPUID_EXT2_PDPE1GB */
540 #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
541 CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
542 #define TCG_SVM_FEATURES 0
543 #define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP \
544 CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX)
546 CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
547 CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
548 CPUID_7_0_EBX_RDSEED */
550 /* built-in CPU model definitions
552 static x86_def_t builtin_x86_defs[] = {
556 .vendor = CPUID_VENDOR_AMD,
560 .features[FEAT_1_EDX] =
562 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
564 .features[FEAT_1_ECX] =
565 CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
566 .features[FEAT_8000_0001_EDX] =
567 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
568 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
569 .features[FEAT_8000_0001_ECX] =
570 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
571 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
572 .xlevel = 0x8000000A,
577 .vendor = CPUID_VENDOR_AMD,
581 .features[FEAT_1_EDX] =
583 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
584 CPUID_PSE36 | CPUID_VME | CPUID_HT,
585 .features[FEAT_1_ECX] =
586 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
588 .features[FEAT_8000_0001_EDX] =
589 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
590 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
591 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
592 CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
593 /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
595 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
596 CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
597 .features[FEAT_8000_0001_ECX] =
598 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
599 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
600 .features[FEAT_SVM] =
601 CPUID_SVM_NPT | CPUID_SVM_LBRV,
602 .xlevel = 0x8000001A,
603 .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
608 .vendor = CPUID_VENDOR_INTEL,
612 .features[FEAT_1_EDX] =
614 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
615 CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
616 CPUID_HT | CPUID_TM | CPUID_PBE,
617 .features[FEAT_1_ECX] =
618 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
619 CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
620 CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
621 .features[FEAT_8000_0001_EDX] =
622 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
623 .features[FEAT_8000_0001_ECX] =
625 .xlevel = 0x80000008,
626 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
631 .vendor = CPUID_VENDOR_INTEL,
635 /* Missing: CPUID_VME, CPUID_HT */
636 .features[FEAT_1_EDX] =
638 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
640 /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
641 .features[FEAT_1_ECX] =
642 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
643 /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
644 .features[FEAT_8000_0001_EDX] =
645 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
646 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
647 /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
648 CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
649 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
650 CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
651 .features[FEAT_8000_0001_ECX] =
653 .xlevel = 0x80000008,
654 .model_id = "Common KVM processor"
659 .vendor = CPUID_VENDOR_INTEL,
663 .features[FEAT_1_EDX] =
665 .features[FEAT_1_ECX] =
666 CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
667 .xlevel = 0x80000004,
672 .vendor = CPUID_VENDOR_INTEL,
676 .features[FEAT_1_EDX] =
678 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
679 .features[FEAT_1_ECX] =
681 .features[FEAT_8000_0001_EDX] =
682 PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES,
683 .features[FEAT_8000_0001_ECX] =
685 .xlevel = 0x80000008,
686 .model_id = "Common 32-bit KVM processor"
691 .vendor = CPUID_VENDOR_INTEL,
695 .features[FEAT_1_EDX] =
696 PPRO_FEATURES | CPUID_VME |
697 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
698 CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
699 .features[FEAT_1_ECX] =
700 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
701 CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
702 .features[FEAT_8000_0001_EDX] =
704 .xlevel = 0x80000008,
705 .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
710 .vendor = CPUID_VENDOR_INTEL,
714 .features[FEAT_1_EDX] =
721 .vendor = CPUID_VENDOR_INTEL,
725 .features[FEAT_1_EDX] =
732 .vendor = CPUID_VENDOR_INTEL,
736 .features[FEAT_1_EDX] =
743 .vendor = CPUID_VENDOR_INTEL,
747 .features[FEAT_1_EDX] =
754 .vendor = CPUID_VENDOR_AMD,
758 .features[FEAT_1_EDX] =
759 PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
761 .features[FEAT_8000_0001_EDX] =
762 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
763 CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
764 .xlevel = 0x80000008,
768 /* original is on level 10 */
770 .vendor = CPUID_VENDOR_INTEL,
774 .features[FEAT_1_EDX] =
776 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
777 CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
778 /* Some CPUs got no CPUID_SEP */
779 .features[FEAT_1_ECX] =
780 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
781 CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR |
783 .features[FEAT_8000_0001_EDX] =
784 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
786 .features[FEAT_8000_0001_ECX] =
788 .xlevel = 0x8000000A,
789 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
794 .vendor = CPUID_VENDOR_INTEL,
798 .features[FEAT_1_EDX] =
799 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
800 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
801 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
802 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
803 CPUID_DE | CPUID_FP87,
804 .features[FEAT_1_ECX] =
805 CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
806 .features[FEAT_8000_0001_EDX] =
807 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
808 .features[FEAT_8000_0001_ECX] =
810 .xlevel = 0x8000000A,
811 .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
816 .vendor = CPUID_VENDOR_INTEL,
820 .features[FEAT_1_EDX] =
821 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
822 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
823 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
824 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
825 CPUID_DE | CPUID_FP87,
826 .features[FEAT_1_ECX] =
827 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
829 .features[FEAT_8000_0001_EDX] =
830 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
831 .features[FEAT_8000_0001_ECX] =
833 .xlevel = 0x8000000A,
834 .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
839 .vendor = CPUID_VENDOR_INTEL,
843 .features[FEAT_1_EDX] =
844 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
845 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
846 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
847 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
848 CPUID_DE | CPUID_FP87,
849 .features[FEAT_1_ECX] =
850 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
851 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
852 .features[FEAT_8000_0001_EDX] =
853 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
854 .features[FEAT_8000_0001_ECX] =
856 .xlevel = 0x8000000A,
857 .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
862 .vendor = CPUID_VENDOR_INTEL,
866 .features[FEAT_1_EDX] =
867 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
868 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
869 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
870 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
871 CPUID_DE | CPUID_FP87,
872 .features[FEAT_1_ECX] =
873 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
874 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
875 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
876 .features[FEAT_8000_0001_EDX] =
877 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
878 .features[FEAT_8000_0001_ECX] =
880 .xlevel = 0x8000000A,
881 .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
884 .name = "SandyBridge",
886 .vendor = CPUID_VENDOR_INTEL,
890 .features[FEAT_1_EDX] =
891 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
892 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
893 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
894 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
895 CPUID_DE | CPUID_FP87,
896 .features[FEAT_1_ECX] =
897 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
898 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
899 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
900 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
902 .features[FEAT_8000_0001_EDX] =
903 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
905 .features[FEAT_8000_0001_ECX] =
907 .xlevel = 0x8000000A,
908 .model_id = "Intel Xeon E312xx (Sandy Bridge)",
913 .vendor = CPUID_VENDOR_INTEL,
917 .features[FEAT_1_EDX] =
918 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
919 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
920 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
921 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
922 CPUID_DE | CPUID_FP87,
923 .features[FEAT_1_ECX] =
924 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
925 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
926 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
927 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
928 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
930 .features[FEAT_8000_0001_EDX] =
931 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
933 .features[FEAT_8000_0001_ECX] =
935 .features[FEAT_7_0_EBX] =
936 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
937 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
938 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
940 .xlevel = 0x8000000A,
941 .model_id = "Intel Core Processor (Haswell)",
944 .name = "Opteron_G1",
946 .vendor = CPUID_VENDOR_AMD,
950 .features[FEAT_1_EDX] =
951 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
952 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
953 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
954 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
955 CPUID_DE | CPUID_FP87,
956 .features[FEAT_1_ECX] =
958 .features[FEAT_8000_0001_EDX] =
959 CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
960 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
961 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
962 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
963 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
964 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
965 .xlevel = 0x80000008,
966 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
969 .name = "Opteron_G2",
971 .vendor = CPUID_VENDOR_AMD,
975 .features[FEAT_1_EDX] =
976 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
977 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
978 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
979 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
980 CPUID_DE | CPUID_FP87,
981 .features[FEAT_1_ECX] =
982 CPUID_EXT_CX16 | CPUID_EXT_SSE3,
983 .features[FEAT_8000_0001_EDX] =
984 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
985 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
986 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
987 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
988 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
989 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
990 CPUID_EXT2_DE | CPUID_EXT2_FPU,
991 .features[FEAT_8000_0001_ECX] =
992 CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
993 .xlevel = 0x80000008,
994 .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
997 .name = "Opteron_G3",
999 .vendor = CPUID_VENDOR_AMD,
1003 .features[FEAT_1_EDX] =
1004 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1005 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1006 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1007 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1008 CPUID_DE | CPUID_FP87,
1009 .features[FEAT_1_ECX] =
1010 CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
1012 .features[FEAT_8000_0001_EDX] =
1013 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
1014 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1015 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1016 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1017 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1018 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1019 CPUID_EXT2_DE | CPUID_EXT2_FPU,
1020 .features[FEAT_8000_0001_ECX] =
1021 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
1022 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
1023 .xlevel = 0x80000008,
1024 .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
1027 .name = "Opteron_G4",
1029 .vendor = CPUID_VENDOR_AMD,
1033 .features[FEAT_1_EDX] =
1034 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1035 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1036 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1037 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1038 CPUID_DE | CPUID_FP87,
1039 .features[FEAT_1_ECX] =
1040 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1041 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1042 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1044 .features[FEAT_8000_0001_EDX] =
1045 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
1046 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1047 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1048 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1049 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1050 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1051 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
1052 .features[FEAT_8000_0001_ECX] =
1053 CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1054 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1055 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1057 .xlevel = 0x8000001A,
1058 .model_id = "AMD Opteron 62xx class CPU",
1061 .name = "Opteron_G5",
1063 .vendor = CPUID_VENDOR_AMD,
1067 .features[FEAT_1_EDX] =
1068 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1069 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1070 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1071 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1072 CPUID_DE | CPUID_FP87,
1073 .features[FEAT_1_ECX] =
1074 CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
1075 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1076 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
1077 CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1078 .features[FEAT_8000_0001_EDX] =
1079 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
1080 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1081 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1082 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1083 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1084 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1085 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
1086 .features[FEAT_8000_0001_ECX] =
1087 CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1088 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1089 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1091 .xlevel = 0x8000001A,
1092 .model_id = "AMD Opteron 63xx class CPU",
1097 * x86_cpu_compat_set_features:
1098 * @cpu_model: CPU model name to be changed. If NULL, all CPU models are changed
1099 * @w: Identifies the feature word to be changed.
1100 * @feat_add: Feature bits to be added to feature word
1101 * @feat_remove: Feature bits to be removed from feature word
1103 * Change CPU model feature bits for compatibility.
1105 * This function may be used by machine-type compatibility functions
1106 * to enable or disable feature bits on specific CPU models.
1108 void x86_cpu_compat_set_features(const char *cpu_model, FeatureWord w,
1109 uint32_t feat_add, uint32_t feat_remove)
1113 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1114 def = &builtin_x86_defs[i];
1115 if (!cpu_model || !strcmp(cpu_model, def->name)) {
1116 def->features[w] |= feat_add;
1117 def->features[w] &= ~feat_remove;
1123 static int cpu_x86_fill_model_id(char *str)
1125 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1128 for (i = 0; i < 3; i++) {
1129 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
1130 memcpy(str + i * 16 + 0, &eax, 4);
1131 memcpy(str + i * 16 + 4, &ebx, 4);
1132 memcpy(str + i * 16 + 8, &ecx, 4);
1133 memcpy(str + i * 16 + 12, &edx, 4);
1139 /* Fill a x86_def_t struct with information about the host CPU, and
1140 * the CPU features supported by the host hardware + host kernel
1142 * This function may be called only if KVM is enabled.
1144 static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
1147 KVMState *s = kvm_state;
1148 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1150 assert(kvm_enabled());
1152 x86_cpu_def->name = "host";
1153 x86_cpu_def->cache_info_passthrough = true;
1154 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
1155 x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1157 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
1158 x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1159 x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1160 x86_cpu_def->stepping = eax & 0x0F;
1162 x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
1163 x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
1164 x86_cpu_def->xlevel2 =
1165 kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
1167 cpu_x86_fill_model_id(x86_cpu_def->model_id);
1169 x86_cpu_def->features[FEAT_1_EDX] =
1170 kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX);
1171 x86_cpu_def->features[FEAT_1_ECX] =
1172 kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX);
1173 x86_cpu_def->features[FEAT_7_0_EBX] =
1174 kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX);
1175 x86_cpu_def->features[FEAT_8000_0001_EDX] =
1176 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
1177 x86_cpu_def->features[FEAT_8000_0001_ECX] =
1178 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
1179 x86_cpu_def->features[FEAT_C000_0001_EDX] =
1180 kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
1181 x86_cpu_def->features[FEAT_SVM] =
1182 kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
1183 x86_cpu_def->features[FEAT_KVM] =
1184 kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
1186 #endif /* CONFIG_KVM */
1189 static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask)
1193 for (i = 0; i < 32; ++i)
1194 if (1 << i & mask) {
1195 const char *reg = get_register_name_32(f->cpuid_reg);
1197 fprintf(stderr, "warning: host doesn't support requested feature: "
1198 "CPUID.%02XH:%s%s%s [bit %d]\n",
1200 f->feat_names[i] ? "." : "",
1201 f->feat_names[i] ? f->feat_names[i] : "", i);
1207 /* Check if all requested cpu flags are making their way to the guest
1209 * Returns 0 if all flags are supported by the host, non-zero otherwise.
1211 * This function may be called only if KVM is enabled.
1213 static int kvm_check_features_against_host(X86CPU *cpu)
1215 CPUX86State *env = &cpu->env;
1219 struct model_features_t ft[] = {
1220 {&env->features[FEAT_1_EDX],
1221 &host_def.features[FEAT_1_EDX],
1223 {&env->features[FEAT_1_ECX],
1224 &host_def.features[FEAT_1_ECX],
1226 {&env->features[FEAT_8000_0001_EDX],
1227 &host_def.features[FEAT_8000_0001_EDX],
1228 FEAT_8000_0001_EDX },
1229 {&env->features[FEAT_8000_0001_ECX],
1230 &host_def.features[FEAT_8000_0001_ECX],
1231 FEAT_8000_0001_ECX },
1232 {&env->features[FEAT_C000_0001_EDX],
1233 &host_def.features[FEAT_C000_0001_EDX],
1234 FEAT_C000_0001_EDX },
1235 {&env->features[FEAT_7_0_EBX],
1236 &host_def.features[FEAT_7_0_EBX],
1238 {&env->features[FEAT_SVM],
1239 &host_def.features[FEAT_SVM],
1241 {&env->features[FEAT_KVM],
1242 &host_def.features[FEAT_KVM],
1246 assert(kvm_enabled());
1248 kvm_cpu_fill_host(&host_def);
1249 for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i) {
1250 FeatureWord w = ft[i].feat_word;
1251 FeatureWordInfo *wi = &feature_word_info[w];
1252 for (mask = 1; mask; mask <<= 1) {
1253 if (*ft[i].guest_feat & mask &&
1254 !(*ft[i].host_feat & mask)) {
1255 unavailable_host_feature(wi, mask);
1263 static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
1264 const char *name, Error **errp)
1266 X86CPU *cpu = X86_CPU(obj);
1267 CPUX86State *env = &cpu->env;
1270 value = (env->cpuid_version >> 8) & 0xf;
1272 value += (env->cpuid_version >> 20) & 0xff;
1274 visit_type_int(v, &value, name, errp);
1277 static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
1278 const char *name, Error **errp)
1280 X86CPU *cpu = X86_CPU(obj);
1281 CPUX86State *env = &cpu->env;
1282 const int64_t min = 0;
1283 const int64_t max = 0xff + 0xf;
1286 visit_type_int(v, &value, name, errp);
1287 if (error_is_set(errp)) {
1290 if (value < min || value > max) {
1291 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1292 name ? name : "null", value, min, max);
1296 env->cpuid_version &= ~0xff00f00;
1298 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
1300 env->cpuid_version |= value << 8;
1304 static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
1305 const char *name, Error **errp)
1307 X86CPU *cpu = X86_CPU(obj);
1308 CPUX86State *env = &cpu->env;
1311 value = (env->cpuid_version >> 4) & 0xf;
1312 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
1313 visit_type_int(v, &value, name, errp);
1316 static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
1317 const char *name, Error **errp)
1319 X86CPU *cpu = X86_CPU(obj);
1320 CPUX86State *env = &cpu->env;
1321 const int64_t min = 0;
1322 const int64_t max = 0xff;
1325 visit_type_int(v, &value, name, errp);
1326 if (error_is_set(errp)) {
1329 if (value < min || value > max) {
1330 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1331 name ? name : "null", value, min, max);
1335 env->cpuid_version &= ~0xf00f0;
1336 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
1339 static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
1340 void *opaque, const char *name,
1343 X86CPU *cpu = X86_CPU(obj);
1344 CPUX86State *env = &cpu->env;
1347 value = env->cpuid_version & 0xf;
1348 visit_type_int(v, &value, name, errp);
1351 static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
1352 void *opaque, const char *name,
1355 X86CPU *cpu = X86_CPU(obj);
1356 CPUX86State *env = &cpu->env;
1357 const int64_t min = 0;
1358 const int64_t max = 0xf;
1361 visit_type_int(v, &value, name, errp);
1362 if (error_is_set(errp)) {
1365 if (value < min || value > max) {
1366 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1367 name ? name : "null", value, min, max);
1371 env->cpuid_version &= ~0xf;
1372 env->cpuid_version |= value & 0xf;
1375 static void x86_cpuid_get_level(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_level, name, errp);
1383 static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
1384 const char *name, Error **errp)
1386 X86CPU *cpu = X86_CPU(obj);
1388 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
1391 static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
1392 const char *name, Error **errp)
1394 X86CPU *cpu = X86_CPU(obj);
1396 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1399 static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
1400 const char *name, Error **errp)
1402 X86CPU *cpu = X86_CPU(obj);
1404 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1407 static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1409 X86CPU *cpu = X86_CPU(obj);
1410 CPUX86State *env = &cpu->env;
1413 value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
1414 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
1415 env->cpuid_vendor3);
1419 static void x86_cpuid_set_vendor(Object *obj, const char *value,
1422 X86CPU *cpu = X86_CPU(obj);
1423 CPUX86State *env = &cpu->env;
1426 if (strlen(value) != CPUID_VENDOR_SZ) {
1427 error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
1432 env->cpuid_vendor1 = 0;
1433 env->cpuid_vendor2 = 0;
1434 env->cpuid_vendor3 = 0;
1435 for (i = 0; i < 4; i++) {
1436 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1437 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1438 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1442 static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1444 X86CPU *cpu = X86_CPU(obj);
1445 CPUX86State *env = &cpu->env;
1449 value = g_malloc(48 + 1);
1450 for (i = 0; i < 48; i++) {
1451 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1457 static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1460 X86CPU *cpu = X86_CPU(obj);
1461 CPUX86State *env = &cpu->env;
1464 if (model_id == NULL) {
1467 len = strlen(model_id);
1468 memset(env->cpuid_model, 0, 48);
1469 for (i = 0; i < 48; i++) {
1473 c = (uint8_t)model_id[i];
1475 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1479 static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
1480 const char *name, Error **errp)
1482 X86CPU *cpu = X86_CPU(obj);
1485 value = cpu->env.tsc_khz * 1000;
1486 visit_type_int(v, &value, name, errp);
1489 static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
1490 const char *name, Error **errp)
1492 X86CPU *cpu = X86_CPU(obj);
1493 const int64_t min = 0;
1494 const int64_t max = INT64_MAX;
1497 visit_type_int(v, &value, name, errp);
1498 if (error_is_set(errp)) {
1501 if (value < min || value > max) {
1502 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1503 name ? name : "null", value, min, max);
1507 cpu->env.tsc_khz = value / 1000;
1510 static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, void *opaque,
1511 const char *name, Error **errp)
1513 X86CPU *cpu = X86_CPU(obj);
1514 int64_t value = cpu->env.cpuid_apic_id;
1516 visit_type_int(v, &value, name, errp);
1519 static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque,
1520 const char *name, Error **errp)
1522 X86CPU *cpu = X86_CPU(obj);
1523 DeviceState *dev = DEVICE(obj);
1524 const int64_t min = 0;
1525 const int64_t max = UINT32_MAX;
1526 Error *error = NULL;
1529 if (dev->realized) {
1530 error_setg(errp, "Attempt to set property '%s' on '%s' after "
1531 "it was realized", name, object_get_typename(obj));
1535 visit_type_int(v, &value, name, &error);
1537 error_propagate(errp, error);
1540 if (value < min || value > max) {
1541 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1542 " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
1543 object_get_typename(obj), name, value, min, max);
1547 if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
1548 error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
1551 cpu->env.cpuid_apic_id = value;
1554 /* Generic getter for "feature-words" and "filtered-features" properties */
1555 static void x86_cpu_get_feature_words(Object *obj, Visitor *v, void *opaque,
1556 const char *name, Error **errp)
1558 uint32_t *array = (uint32_t *)opaque;
1561 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
1562 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
1563 X86CPUFeatureWordInfoList *list = NULL;
1565 for (w = 0; w < FEATURE_WORDS; w++) {
1566 FeatureWordInfo *wi = &feature_word_info[w];
1567 X86CPUFeatureWordInfo *qwi = &word_infos[w];
1568 qwi->cpuid_input_eax = wi->cpuid_eax;
1569 qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
1570 qwi->cpuid_input_ecx = wi->cpuid_ecx;
1571 qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
1572 qwi->features = array[w];
1574 /* List will be in reverse order, but order shouldn't matter */
1575 list_entries[w].next = list;
1576 list_entries[w].value = &word_infos[w];
1577 list = &list_entries[w];
1580 visit_type_X86CPUFeatureWordInfoList(v, &list, "feature-words", &err);
1581 error_propagate(errp, err);
1584 static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
1585 const char *name, Error **errp)
1587 X86CPU *cpu = X86_CPU(obj);
1588 int64_t value = cpu->hyperv_spinlock_attempts;
1590 visit_type_int(v, &value, name, errp);
1593 static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
1594 const char *name, Error **errp)
1596 const int64_t min = 0xFFF;
1597 const int64_t max = UINT_MAX;
1598 X86CPU *cpu = X86_CPU(obj);
1602 visit_type_int(v, &value, name, &err);
1604 error_propagate(errp, err);
1608 if (value < min || value > max) {
1609 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1610 " (minimum: %" PRId64 ", maximum: %" PRId64 ")",
1611 object_get_typename(obj), name ? name : "null",
1615 cpu->hyperv_spinlock_attempts = value;
1618 static PropertyInfo qdev_prop_spinlocks = {
1620 .get = x86_get_hv_spinlocks,
1621 .set = x86_set_hv_spinlocks,
1624 static int cpu_x86_find_by_name(X86CPU *cpu, x86_def_t *x86_cpu_def,
1633 if (kvm_enabled() && strcmp(name, "host") == 0) {
1634 kvm_cpu_fill_host(x86_cpu_def);
1635 object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
1639 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1640 def = &builtin_x86_defs[i];
1641 if (strcmp(name, def->name) == 0) {
1642 memcpy(x86_cpu_def, def, sizeof(*def));
1643 /* sysenter isn't supported in compatibility mode on AMD,
1644 * syscall isn't supported in compatibility mode on Intel.
1645 * Normally we advertise the actual CPU vendor, but you can
1646 * override this using the 'vendor' property if you want to use
1647 * KVM's sysenter/syscall emulation in compatibility mode and
1648 * when doing cross vendor migration
1650 if (kvm_enabled()) {
1651 uint32_t ebx = 0, ecx = 0, edx = 0;
1652 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
1653 x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1662 /* Convert all '_' in a feature string option name to '-', to make feature
1663 * name conform to QOM property naming rule, which uses '-' instead of '_'.
1665 static inline void feat2prop(char *s)
1667 while ((s = strchr(s, '_'))) {
1672 /* Parse "+feature,-feature,feature=foo" CPU feature string
1674 static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
1676 char *featurestr; /* Single 'key=value" string being parsed */
1677 /* Features to be added */
1678 FeatureWordArray plus_features = { 0 };
1679 /* Features to be removed */
1680 FeatureWordArray minus_features = { 0 };
1682 CPUX86State *env = &cpu->env;
1684 featurestr = features ? strtok(features, ",") : NULL;
1686 while (featurestr) {
1688 if (featurestr[0] == '+') {
1689 add_flagname_to_bitmaps(featurestr + 1, plus_features);
1690 } else if (featurestr[0] == '-') {
1691 add_flagname_to_bitmaps(featurestr + 1, minus_features);
1692 } else if ((val = strchr(featurestr, '='))) {
1694 feat2prop(featurestr);
1695 if (!strcmp(featurestr, "xlevel")) {
1699 numvalue = strtoul(val, &err, 0);
1700 if (!*val || *err) {
1701 error_setg(errp, "bad numerical value %s", val);
1704 if (numvalue < 0x80000000) {
1705 fprintf(stderr, "xlevel value shall always be >= 0x80000000"
1706 ", fixup will be removed in future versions\n");
1707 numvalue += 0x80000000;
1709 snprintf(num, sizeof(num), "%" PRIu32, numvalue);
1710 object_property_parse(OBJECT(cpu), num, featurestr, errp);
1711 } else if (!strcmp(featurestr, "tsc-freq")) {
1716 tsc_freq = strtosz_suffix_unit(val, &err,
1717 STRTOSZ_DEFSUFFIX_B, 1000);
1718 if (tsc_freq < 0 || *err) {
1719 error_setg(errp, "bad numerical value %s", val);
1722 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
1723 object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
1724 } else if (!strcmp(featurestr, "hv-spinlocks")) {
1726 const int min = 0xFFF;
1728 numvalue = strtoul(val, &err, 0);
1729 if (!*val || *err) {
1730 error_setg(errp, "bad numerical value %s", val);
1733 if (numvalue < min) {
1734 fprintf(stderr, "hv-spinlocks value shall always be >= 0x%x"
1735 ", fixup will be removed in future versions\n",
1739 snprintf(num, sizeof(num), "%" PRId32, numvalue);
1740 object_property_parse(OBJECT(cpu), num, featurestr, errp);
1742 object_property_parse(OBJECT(cpu), val, featurestr, errp);
1745 feat2prop(featurestr);
1746 object_property_parse(OBJECT(cpu), "on", featurestr, errp);
1748 if (error_is_set(errp)) {
1751 featurestr = strtok(NULL, ",");
1753 env->features[FEAT_1_EDX] |= plus_features[FEAT_1_EDX];
1754 env->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX];
1755 env->features[FEAT_8000_0001_EDX] |= plus_features[FEAT_8000_0001_EDX];
1756 env->features[FEAT_8000_0001_ECX] |= plus_features[FEAT_8000_0001_ECX];
1757 env->features[FEAT_C000_0001_EDX] |= plus_features[FEAT_C000_0001_EDX];
1758 env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
1759 env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
1760 env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
1761 env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
1762 env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
1763 env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX];
1764 env->features[FEAT_8000_0001_ECX] &= ~minus_features[FEAT_8000_0001_ECX];
1765 env->features[FEAT_C000_0001_EDX] &= ~minus_features[FEAT_C000_0001_EDX];
1766 env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
1767 env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
1768 env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
1774 /* generate a composite string into buf of all cpuid names in featureset
1775 * selected by fbits. indicate truncation at bufsize in the event of overflow.
1776 * if flags, suppress names undefined in featureset.
1778 static void listflags(char *buf, int bufsize, uint32_t fbits,
1779 const char **featureset, uint32_t flags)
1781 const char **p = &featureset[31];
1785 b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1787 for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1788 if (fbits & 1 << bit && (*p || !flags)) {
1790 nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1792 nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1793 if (bufsize <= nc) {
1795 memcpy(b, "...", sizeof("..."));
1804 /* generate CPU information. */
1805 void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
1811 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1812 def = &builtin_x86_defs[i];
1813 snprintf(buf, sizeof(buf), "%s", def->name);
1814 (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
1817 (*cpu_fprintf)(f, "x86 %16s %-48s\n", "host",
1818 "KVM processor with all supported host features "
1819 "(only available in KVM mode)");
1822 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
1823 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
1824 FeatureWordInfo *fw = &feature_word_info[i];
1826 listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
1827 (*cpu_fprintf)(f, " %s\n", buf);
1831 CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
1833 CpuDefinitionInfoList *cpu_list = NULL;
1837 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1838 CpuDefinitionInfoList *entry;
1839 CpuDefinitionInfo *info;
1841 def = &builtin_x86_defs[i];
1842 info = g_malloc0(sizeof(*info));
1843 info->name = g_strdup(def->name);
1845 entry = g_malloc0(sizeof(*entry));
1846 entry->value = info;
1847 entry->next = cpu_list;
1855 static void filter_features_for_kvm(X86CPU *cpu)
1857 CPUX86State *env = &cpu->env;
1858 KVMState *s = kvm_state;
1861 for (w = 0; w < FEATURE_WORDS; w++) {
1862 FeatureWordInfo *wi = &feature_word_info[w];
1863 uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax,
1866 uint32_t requested_features = env->features[w];
1867 env->features[w] &= host_feat;
1868 cpu->filtered_features[w] = requested_features & ~env->features[w];
1873 static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
1875 CPUX86State *env = &cpu->env;
1876 x86_def_t def1, *def = &def1;
1878 memset(def, 0, sizeof(*def));
1880 if (cpu_x86_find_by_name(cpu, def, name) < 0) {
1881 error_setg(errp, "Unable to find CPU definition: %s", name);
1885 if (kvm_enabled()) {
1886 def->features[FEAT_KVM] |= kvm_default_features;
1888 def->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
1890 object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp);
1891 object_property_set_int(OBJECT(cpu), def->level, "level", errp);
1892 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
1893 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
1894 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
1895 env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX];
1896 env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX];
1897 env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX];
1898 env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX];
1899 object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
1900 env->features[FEAT_KVM] = def->features[FEAT_KVM];
1901 env->features[FEAT_SVM] = def->features[FEAT_SVM];
1902 env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
1903 env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
1904 env->cpuid_xlevel2 = def->xlevel2;
1905 cpu->cache_info_passthrough = def->cache_info_passthrough;
1907 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
1910 X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
1914 gchar **model_pieces;
1915 char *name, *features;
1917 Error *error = NULL;
1919 model_pieces = g_strsplit(cpu_model, ",", 2);
1920 if (!model_pieces[0]) {
1921 error_setg(&error, "Invalid/empty CPU model name");
1924 name = model_pieces[0];
1925 features = model_pieces[1];
1927 cpu = X86_CPU(object_new(TYPE_X86_CPU));
1928 #ifndef CONFIG_USER_ONLY
1929 if (icc_bridge == NULL) {
1930 error_setg(&error, "Invalid icc-bridge value");
1933 qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
1934 object_unref(OBJECT(cpu));
1937 cpu_x86_register(cpu, name, &error);
1942 /* Emulate per-model subclasses for global properties */
1943 typename = g_strdup_printf("%s-" TYPE_X86_CPU, name);
1944 qdev_prop_set_globals_for_type(DEVICE(cpu), typename, &error);
1950 cpu_x86_parse_featurestr(cpu, features, &error);
1956 if (error != NULL) {
1957 error_propagate(errp, error);
1958 object_unref(OBJECT(cpu));
1961 g_strfreev(model_pieces);
1965 X86CPU *cpu_x86_init(const char *cpu_model)
1967 Error *error = NULL;
1970 cpu = cpu_x86_create(cpu_model, NULL, &error);
1975 object_property_set_bool(OBJECT(cpu), true, "realized", &error);
1979 error_report("%s", error_get_pretty(error));
1982 object_unref(OBJECT(cpu));
1989 #if !defined(CONFIG_USER_ONLY)
1991 void cpu_clear_apic_feature(CPUX86State *env)
1993 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
1996 #endif /* !CONFIG_USER_ONLY */
1998 /* Initialize list of CPU models, filling some non-static fields if necessary
2000 void x86_cpudef_setup(void)
2003 static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
2005 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
2006 x86_def_t *def = &builtin_x86_defs[i];
2008 /* Look for specific "cpudef" models that */
2009 /* have the QEMU version in .model_id */
2010 for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
2011 if (strcmp(model_with_versions[j], def->name) == 0) {
2012 pstrcpy(def->model_id, sizeof(def->model_id),
2013 "QEMU Virtual CPU version ");
2014 pstrcat(def->model_id, sizeof(def->model_id),
2015 qemu_get_version());
2022 static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
2023 uint32_t *ecx, uint32_t *edx)
2025 *ebx = env->cpuid_vendor1;
2026 *edx = env->cpuid_vendor2;
2027 *ecx = env->cpuid_vendor3;
2030 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
2031 uint32_t *eax, uint32_t *ebx,
2032 uint32_t *ecx, uint32_t *edx)
2034 X86CPU *cpu = x86_env_get_cpu(env);
2035 CPUState *cs = CPU(cpu);
2037 /* test if maximum index reached */
2038 if (index & 0x80000000) {
2039 if (index > env->cpuid_xlevel) {
2040 if (env->cpuid_xlevel2 > 0) {
2041 /* Handle the Centaur's CPUID instruction. */
2042 if (index > env->cpuid_xlevel2) {
2043 index = env->cpuid_xlevel2;
2044 } else if (index < 0xC0000000) {
2045 index = env->cpuid_xlevel;
2048 /* Intel documentation states that invalid EAX input will
2049 * return the same information as EAX=cpuid_level
2050 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
2052 index = env->cpuid_level;
2056 if (index > env->cpuid_level)
2057 index = env->cpuid_level;
2062 *eax = env->cpuid_level;
2063 get_cpuid_vendor(env, ebx, ecx, edx);
2066 *eax = env->cpuid_version;
2067 *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
2068 *ecx = env->features[FEAT_1_ECX];
2069 *edx = env->features[FEAT_1_EDX];
2070 if (cs->nr_cores * cs->nr_threads > 1) {
2071 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
2072 *edx |= 1 << 28; /* HTT bit */
2076 /* cache info: needed for Pentium Pro compatibility */
2077 if (cpu->cache_info_passthrough) {
2078 host_cpuid(index, 0, eax, ebx, ecx, edx);
2081 *eax = 1; /* Number of CPUID[EAX=2] calls required */
2084 *edx = (L1D_DESCRIPTOR << 16) | \
2085 (L1I_DESCRIPTOR << 8) | \
2089 /* cache info: needed for Core compatibility */
2090 if (cpu->cache_info_passthrough) {
2091 host_cpuid(index, count, eax, ebx, ecx, edx);
2092 *eax &= ~0xFC000000;
2096 case 0: /* L1 dcache info */
2097 *eax |= CPUID_4_TYPE_DCACHE | \
2098 CPUID_4_LEVEL(1) | \
2099 CPUID_4_SELF_INIT_LEVEL;
2100 *ebx = (L1D_LINE_SIZE - 1) | \
2101 ((L1D_PARTITIONS - 1) << 12) | \
2102 ((L1D_ASSOCIATIVITY - 1) << 22);
2103 *ecx = L1D_SETS - 1;
2104 *edx = CPUID_4_NO_INVD_SHARING;
2106 case 1: /* L1 icache info */
2107 *eax |= CPUID_4_TYPE_ICACHE | \
2108 CPUID_4_LEVEL(1) | \
2109 CPUID_4_SELF_INIT_LEVEL;
2110 *ebx = (L1I_LINE_SIZE - 1) | \
2111 ((L1I_PARTITIONS - 1) << 12) | \
2112 ((L1I_ASSOCIATIVITY - 1) << 22);
2113 *ecx = L1I_SETS - 1;
2114 *edx = CPUID_4_NO_INVD_SHARING;
2116 case 2: /* L2 cache info */
2117 *eax |= CPUID_4_TYPE_UNIFIED | \
2118 CPUID_4_LEVEL(2) | \
2119 CPUID_4_SELF_INIT_LEVEL;
2120 if (cs->nr_threads > 1) {
2121 *eax |= (cs->nr_threads - 1) << 14;
2123 *ebx = (L2_LINE_SIZE - 1) | \
2124 ((L2_PARTITIONS - 1) << 12) | \
2125 ((L2_ASSOCIATIVITY - 1) << 22);
2127 *edx = CPUID_4_NO_INVD_SHARING;
2129 default: /* end of info */
2138 /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
2139 if ((*eax & 31) && cs->nr_cores > 1) {
2140 *eax |= (cs->nr_cores - 1) << 26;
2144 /* mwait info: needed for Core compatibility */
2145 *eax = 0; /* Smallest monitor-line size in bytes */
2146 *ebx = 0; /* Largest monitor-line size in bytes */
2147 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
2151 /* Thermal and Power Leaf */
2158 /* Structured Extended Feature Flags Enumeration Leaf */
2160 *eax = 0; /* Maximum ECX value for sub-leaves */
2161 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
2162 *ecx = 0; /* Reserved */
2163 *edx = 0; /* Reserved */
2172 /* Direct Cache Access Information Leaf */
2173 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2179 /* Architectural Performance Monitoring Leaf */
2180 if (kvm_enabled() && cpu->enable_pmu) {
2181 KVMState *s = cs->kvm_state;
2183 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
2184 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
2185 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
2186 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
2195 KVMState *s = cs->kvm_state;
2199 /* Processor Extended State */
2204 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) || !kvm_enabled()) {
2208 kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX) |
2209 ((uint64_t)kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX) << 32);
2213 for (i = 2; i < ARRAY_SIZE(ext_save_areas); i++) {
2214 const ExtSaveArea *esa = &ext_save_areas[i];
2215 if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2216 (kvm_mask & (1 << i)) != 0) {
2220 *edx |= 1 << (i - 32);
2222 *ecx = MAX(*ecx, esa->offset + esa->size);
2225 *eax |= kvm_mask & (XSTATE_FP | XSTATE_SSE);
2227 } else if (count == 1) {
2228 *eax = kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
2229 } else if (count < ARRAY_SIZE(ext_save_areas)) {
2230 const ExtSaveArea *esa = &ext_save_areas[count];
2231 if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2232 (kvm_mask & (1 << count)) != 0) {
2240 *eax = env->cpuid_xlevel;
2241 *ebx = env->cpuid_vendor1;
2242 *edx = env->cpuid_vendor2;
2243 *ecx = env->cpuid_vendor3;
2246 *eax = env->cpuid_version;
2248 *ecx = env->features[FEAT_8000_0001_ECX];
2249 *edx = env->features[FEAT_8000_0001_EDX];
2251 /* The Linux kernel checks for the CMPLegacy bit and
2252 * discards multiple thread information if it is set.
2253 * So dont set it here for Intel to make Linux guests happy.
2255 if (cs->nr_cores * cs->nr_threads > 1) {
2256 uint32_t tebx, tecx, tedx;
2257 get_cpuid_vendor(env, &tebx, &tecx, &tedx);
2258 if (tebx != CPUID_VENDOR_INTEL_1 ||
2259 tedx != CPUID_VENDOR_INTEL_2 ||
2260 tecx != CPUID_VENDOR_INTEL_3) {
2261 *ecx |= 1 << 1; /* CmpLegacy bit */
2268 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2269 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2270 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2271 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2274 /* cache info (L1 cache) */
2275 if (cpu->cache_info_passthrough) {
2276 host_cpuid(index, 0, eax, ebx, ecx, edx);
2279 *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \
2280 (L1_ITLB_2M_ASSOC << 8) | (L1_ITLB_2M_ENTRIES);
2281 *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
2282 (L1_ITLB_4K_ASSOC << 8) | (L1_ITLB_4K_ENTRIES);
2283 *ecx = (L1D_SIZE_KB_AMD << 24) | (L1D_ASSOCIATIVITY_AMD << 16) | \
2284 (L1D_LINES_PER_TAG << 8) | (L1D_LINE_SIZE);
2285 *edx = (L1I_SIZE_KB_AMD << 24) | (L1I_ASSOCIATIVITY_AMD << 16) | \
2286 (L1I_LINES_PER_TAG << 8) | (L1I_LINE_SIZE);
2289 /* cache info (L2 cache) */
2290 if (cpu->cache_info_passthrough) {
2291 host_cpuid(index, 0, eax, ebx, ecx, edx);
2294 *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \
2295 (L2_DTLB_2M_ENTRIES << 16) | \
2296 (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \
2297 (L2_ITLB_2M_ENTRIES);
2298 *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) | \
2299 (L2_DTLB_4K_ENTRIES << 16) | \
2300 (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
2301 (L2_ITLB_4K_ENTRIES);
2302 *ecx = (L2_SIZE_KB_AMD << 16) | \
2303 (AMD_ENC_ASSOC(L2_ASSOCIATIVITY) << 12) | \
2304 (L2_LINES_PER_TAG << 8) | (L2_LINE_SIZE);
2305 *edx = ((L3_SIZE_KB/512) << 18) | \
2306 (AMD_ENC_ASSOC(L3_ASSOCIATIVITY) << 12) | \
2307 (L3_LINES_PER_TAG << 8) | (L3_LINE_SIZE);
2310 /* virtual & phys address size in low 2 bytes. */
2311 /* XXX: This value must match the one used in the MMU code. */
2312 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
2313 /* 64 bit processor */
2314 /* XXX: The physical address space is limited to 42 bits in exec.c. */
2315 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
2317 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
2318 *eax = 0x00000024; /* 36 bits physical */
2320 *eax = 0x00000020; /* 32 bits physical */
2326 if (cs->nr_cores * cs->nr_threads > 1) {
2327 *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
2331 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
2332 *eax = 0x00000001; /* SVM Revision */
2333 *ebx = 0x00000010; /* nr of ASIDs */
2335 *edx = env->features[FEAT_SVM]; /* optional features */
2344 *eax = env->cpuid_xlevel2;
2350 /* Support for VIA CPU's CPUID instruction */
2351 *eax = env->cpuid_version;
2354 *edx = env->features[FEAT_C000_0001_EDX];
2359 /* Reserved for the future, and now filled with zero */
2366 /* reserved values: zero */
2375 /* CPUClass::reset() */
2376 static void x86_cpu_reset(CPUState *s)
2378 X86CPU *cpu = X86_CPU(s);
2379 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2380 CPUX86State *env = &cpu->env;
2383 xcc->parent_reset(s);
2386 memset(env, 0, offsetof(CPUX86State, breakpoints));
2390 env->old_exception = -1;
2392 /* init to reset state */
2394 #ifdef CONFIG_SOFTMMU
2395 env->hflags |= HF_SOFTMMU_MASK;
2397 env->hflags2 |= HF2_GIF_MASK;
2399 cpu_x86_update_cr0(env, 0x60000010);
2400 env->a20_mask = ~0x0;
2401 env->smbase = 0x30000;
2403 env->idt.limit = 0xffff;
2404 env->gdt.limit = 0xffff;
2405 env->ldt.limit = 0xffff;
2406 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2407 env->tr.limit = 0xffff;
2408 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2410 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2411 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2412 DESC_R_MASK | DESC_A_MASK);
2413 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2414 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2416 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
2417 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2419 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
2420 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2422 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
2423 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2425 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
2426 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2430 env->regs[R_EDX] = env->cpuid_version;
2435 for (i = 0; i < 8; i++) {
2440 env->mxcsr = 0x1f80;
2441 env->xstate_bv = XSTATE_FP | XSTATE_SSE;
2443 env->pat = 0x0007040600070406ULL;
2444 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2446 memset(env->dr, 0, sizeof(env->dr));
2447 env->dr[6] = DR6_FIXED_1;
2448 env->dr[7] = DR7_FIXED_1;
2449 cpu_breakpoint_remove_all(env, BP_CPU);
2450 cpu_watchpoint_remove_all(env, BP_CPU);
2452 env->tsc_adjust = 0;
2455 #if !defined(CONFIG_USER_ONLY)
2456 /* We hard-wire the BSP to the first CPU. */
2457 if (s->cpu_index == 0) {
2458 apic_designate_bsp(cpu->apic_state);
2461 s->halted = !cpu_is_bsp(cpu);
2465 #ifndef CONFIG_USER_ONLY
2466 bool cpu_is_bsp(X86CPU *cpu)
2468 return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
2471 /* TODO: remove me, when reset over QOM tree is implemented */
2472 static void x86_cpu_machine_reset_cb(void *opaque)
2474 X86CPU *cpu = opaque;
2475 cpu_reset(CPU(cpu));
2479 static void mce_init(X86CPU *cpu)
2481 CPUX86State *cenv = &cpu->env;
2484 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
2485 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
2486 (CPUID_MCE | CPUID_MCA)) {
2487 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2488 cenv->mcg_ctl = ~(uint64_t)0;
2489 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2490 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2495 #ifndef CONFIG_USER_ONLY
2496 static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
2498 CPUX86State *env = &cpu->env;
2499 DeviceState *dev = DEVICE(cpu);
2500 APICCommonState *apic;
2501 const char *apic_type = "apic";
2503 if (kvm_irqchip_in_kernel()) {
2504 apic_type = "kvm-apic";
2505 } else if (xen_enabled()) {
2506 apic_type = "xen-apic";
2509 cpu->apic_state = qdev_try_create(qdev_get_parent_bus(dev), apic_type);
2510 if (cpu->apic_state == NULL) {
2511 error_setg(errp, "APIC device '%s' could not be created", apic_type);
2515 object_property_add_child(OBJECT(cpu), "apic",
2516 OBJECT(cpu->apic_state), NULL);
2517 qdev_prop_set_uint8(cpu->apic_state, "id", env->cpuid_apic_id);
2518 /* TODO: convert to link<> */
2519 apic = APIC_COMMON(cpu->apic_state);
2523 static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2525 if (cpu->apic_state == NULL) {
2529 if (qdev_init(cpu->apic_state)) {
2530 error_setg(errp, "APIC device '%s' could not be initialized",
2531 object_get_typename(OBJECT(cpu->apic_state)));
2536 static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2541 static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
2543 CPUState *cs = CPU(dev);
2544 X86CPU *cpu = X86_CPU(dev);
2545 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
2546 CPUX86State *env = &cpu->env;
2547 Error *local_err = NULL;
2549 if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
2550 env->cpuid_level = 7;
2553 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
2556 if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
2557 env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
2558 env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
2559 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
2560 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
2561 & CPUID_EXT2_AMD_ALIASES);
2564 if (!kvm_enabled()) {
2565 env->features[FEAT_1_EDX] &= TCG_FEATURES;
2566 env->features[FEAT_1_ECX] &= TCG_EXT_FEATURES;
2567 env->features[FEAT_8000_0001_EDX] &= (TCG_EXT2_FEATURES
2568 #ifdef TARGET_X86_64
2569 | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
2572 env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES;
2573 env->features[FEAT_SVM] &= TCG_SVM_FEATURES;
2575 if ((cpu->check_cpuid || cpu->enforce_cpuid)
2576 && kvm_check_features_against_host(cpu) && cpu->enforce_cpuid) {
2577 error_setg(&local_err,
2578 "Host's CPU doesn't support requested features");
2582 filter_features_for_kvm(cpu);
2586 #ifndef CONFIG_USER_ONLY
2587 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
2589 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
2590 x86_cpu_apic_create(cpu, &local_err);
2591 if (local_err != NULL) {
2600 x86_cpu_apic_realize(cpu, &local_err);
2601 if (local_err != NULL) {
2606 xcc->parent_realize(dev, &local_err);
2608 if (local_err != NULL) {
2609 error_propagate(errp, local_err);
2614 /* Enables contiguous-apic-ID mode, for compatibility */
2615 static bool compat_apic_id_mode;
2617 void enable_compat_apic_id_mode(void)
2619 compat_apic_id_mode = true;
2622 /* Calculates initial APIC ID for a specific CPU index
2624 * Currently we need to be able to calculate the APIC ID from the CPU index
2625 * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
2626 * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
2627 * all CPUs up to max_cpus.
2629 uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
2631 uint32_t correct_id;
2634 correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
2635 if (compat_apic_id_mode) {
2636 if (cpu_index != correct_id && !warned) {
2637 error_report("APIC IDs set in compatibility mode, "
2638 "CPU topology won't match the configuration");
2647 static void x86_cpu_initfn(Object *obj)
2649 CPUState *cs = CPU(obj);
2650 X86CPU *cpu = X86_CPU(obj);
2651 CPUX86State *env = &cpu->env;
2657 object_property_add(obj, "family", "int",
2658 x86_cpuid_version_get_family,
2659 x86_cpuid_version_set_family, NULL, NULL, NULL);
2660 object_property_add(obj, "model", "int",
2661 x86_cpuid_version_get_model,
2662 x86_cpuid_version_set_model, NULL, NULL, NULL);
2663 object_property_add(obj, "stepping", "int",
2664 x86_cpuid_version_get_stepping,
2665 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
2666 object_property_add(obj, "level", "int",
2667 x86_cpuid_get_level,
2668 x86_cpuid_set_level, NULL, NULL, NULL);
2669 object_property_add(obj, "xlevel", "int",
2670 x86_cpuid_get_xlevel,
2671 x86_cpuid_set_xlevel, NULL, NULL, NULL);
2672 object_property_add_str(obj, "vendor",
2673 x86_cpuid_get_vendor,
2674 x86_cpuid_set_vendor, NULL);
2675 object_property_add_str(obj, "model-id",
2676 x86_cpuid_get_model_id,
2677 x86_cpuid_set_model_id, NULL);
2678 object_property_add(obj, "tsc-frequency", "int",
2679 x86_cpuid_get_tsc_freq,
2680 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
2681 object_property_add(obj, "apic-id", "int",
2682 x86_cpuid_get_apic_id,
2683 x86_cpuid_set_apic_id, NULL, NULL, NULL);
2684 object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
2685 x86_cpu_get_feature_words,
2686 NULL, NULL, (void *)env->features, NULL);
2687 object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
2688 x86_cpu_get_feature_words,
2689 NULL, NULL, (void *)cpu->filtered_features, NULL);
2691 cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
2692 env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
2694 /* init various static tables used in TCG mode */
2695 if (tcg_enabled() && !inited) {
2697 optimize_flags_init();
2698 #ifndef CONFIG_USER_ONLY
2699 cpu_set_debug_excp_handler(breakpoint_handler);
2704 static int64_t x86_cpu_get_arch_id(CPUState *cs)
2706 X86CPU *cpu = X86_CPU(cs);
2707 CPUX86State *env = &cpu->env;
2709 return env->cpuid_apic_id;
2712 static bool x86_cpu_get_paging_enabled(const CPUState *cs)
2714 X86CPU *cpu = X86_CPU(cs);
2716 return cpu->env.cr[0] & CR0_PG_MASK;
2719 static void x86_cpu_set_pc(CPUState *cs, vaddr value)
2721 X86CPU *cpu = X86_CPU(cs);
2723 cpu->env.eip = value;
2726 static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
2728 X86CPU *cpu = X86_CPU(cs);
2730 cpu->env.eip = tb->pc - tb->cs_base;
2733 static Property x86_cpu_properties[] = {
2734 DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
2735 { .name = "hv-spinlocks", .info = &qdev_prop_spinlocks },
2736 DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false),
2737 DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false),
2738 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false),
2739 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
2740 DEFINE_PROP_END_OF_LIST()
2743 static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
2745 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2746 CPUClass *cc = CPU_CLASS(oc);
2747 DeviceClass *dc = DEVICE_CLASS(oc);
2749 xcc->parent_realize = dc->realize;
2750 dc->realize = x86_cpu_realizefn;
2751 dc->bus_type = TYPE_ICC_BUS;
2752 dc->props = x86_cpu_properties;
2754 xcc->parent_reset = cc->reset;
2755 cc->reset = x86_cpu_reset;
2756 cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
2758 cc->do_interrupt = x86_cpu_do_interrupt;
2759 cc->dump_state = x86_cpu_dump_state;
2760 cc->set_pc = x86_cpu_set_pc;
2761 cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
2762 cc->gdb_read_register = x86_cpu_gdb_read_register;
2763 cc->gdb_write_register = x86_cpu_gdb_write_register;
2764 cc->get_arch_id = x86_cpu_get_arch_id;
2765 cc->get_paging_enabled = x86_cpu_get_paging_enabled;
2766 #ifndef CONFIG_USER_ONLY
2767 cc->get_memory_mapping = x86_cpu_get_memory_mapping;
2768 cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
2769 cc->write_elf64_note = x86_cpu_write_elf64_note;
2770 cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
2771 cc->write_elf32_note = x86_cpu_write_elf32_note;
2772 cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
2773 cc->vmsd = &vmstate_x86_cpu;
2775 cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
2778 static const TypeInfo x86_cpu_type_info = {
2779 .name = TYPE_X86_CPU,
2781 .instance_size = sizeof(X86CPU),
2782 .instance_init = x86_cpu_initfn,
2784 .class_size = sizeof(X86CPUClass),
2785 .class_init = x86_cpu_common_class_init,
2788 static void x86_cpu_register_types(void)
2790 type_register_static(&x86_cpu_type_info);
2793 type_init(x86_cpu_register_types)