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 = 0x100, .size = 0x240 },
341
const char *get_register_name_32(unsigned int reg)
343
if (reg >= CPU_NB_REGS32) {
346
return x86_reg_info_32[reg].name;
349
/* collects per-function cpuid data
351
typedef struct model_features_t {
352
uint32_t *guest_feat;
354
FeatureWord feat_word;
358
int enforce_cpuid = 0;
360
static uint32_t kvm_default_features = (1 << KVM_FEATURE_CLOCKSOURCE) |
361
(1 << KVM_FEATURE_NOP_IO_DELAY) |
362
(1 << KVM_FEATURE_CLOCKSOURCE2) |
363
(1 << KVM_FEATURE_ASYNC_PF) |
364
(1 << KVM_FEATURE_STEAL_TIME) |
365
(1 << KVM_FEATURE_PV_EOI) |
366
(1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
368
void disable_kvm_pv_eoi(void)
370
kvm_default_features &= ~(1UL << KVM_FEATURE_PV_EOI);
373
void host_cpuid(uint32_t function, uint32_t count,
374
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
376
#if defined(CONFIG_KVM)
381
: "=a"(vec[0]), "=b"(vec[1]),
382
"=c"(vec[2]), "=d"(vec[3])
383
: "0"(function), "c"(count) : "cc");
385
asm volatile("pusha \n\t"
387
"mov %%eax, 0(%2) \n\t"
388
"mov %%ebx, 4(%2) \n\t"
389
"mov %%ecx, 8(%2) \n\t"
390
"mov %%edx, 12(%2) \n\t"
392
: : "a"(function), "c"(count), "S"(vec)
407
#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
409
/* general substring compare of *[s1..e1) and *[s2..e2). sx is start of
410
* a substring. ex if !NULL points to the first char after a substring,
411
* otherwise the string is assumed to sized by a terminating nul.
412
* Return lexical ordering of *s1:*s2.
414
static int sstrcmp(const char *s1, const char *e1, const char *s2,
418
if (!*s1 || !*s2 || *s1 != *s2)
421
if (s1 == e1 && s2 == e2)
430
/* compare *[s..e) to *altstr. *altstr may be a simple string or multiple
431
* '|' delimited (possibly empty) strings in which case search for a match
432
* within the alternatives proceeds left to right. Return 0 for success,
433
* non-zero otherwise.
435
static int altcmp(const char *s, const char *e, const char *altstr)
439
for (q = p = altstr; ; ) {
440
while (*p && *p != '|')
442
if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
451
/* search featureset for flag *[s..e), if found set corresponding bit in
452
* *pval and return true, otherwise return false
454
static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
455
const char **featureset)
461
for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
462
if (*ppc && !altcmp(s, e, *ppc)) {
470
static void add_flagname_to_bitmaps(const char *flagname,
471
FeatureWordArray words)
474
for (w = 0; w < FEATURE_WORDS; w++) {
475
FeatureWordInfo *wi = &feature_word_info[w];
476
if (wi->feat_names &&
477
lookup_feature(&words[w], flagname, NULL, wi->feat_names)) {
481
if (w == FEATURE_WORDS) {
482
fprintf(stderr, "CPU feature %s not found\n", flagname);
486
typedef struct x86_def_t {
491
/* vendor is zero-terminated, 12 character ASCII string */
492
char vendor[CPUID_VENDOR_SZ + 1];
496
FeatureWordArray features;
498
bool cache_info_passthrough;
501
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
502
#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
503
CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
504
#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
505
CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
506
CPUID_PSE36 | CPUID_FXSR)
507
#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
508
#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
509
CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
510
CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
511
CPUID_PAE | CPUID_SEP | CPUID_APIC)
513
#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
514
CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
515
CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
516
CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
517
CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
518
/* partly implemented:
519
CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
520
CPUID_PSE36 (needed for Solaris) */
522
CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
523
#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
524
CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
525
CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
526
CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
528
CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
529
CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
530
CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
531
CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_XSAVE,
532
CPUID_EXT_OSXSAVE, CPUID_EXT_AVX, CPUID_EXT_F16C,
534
#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
535
CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
536
CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
538
CPUID_EXT2_PDPE1GB */
539
#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
540
CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
541
#define TCG_SVM_FEATURES 0
542
#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP \
543
CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX)
545
CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
546
CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
547
CPUID_7_0_EBX_RDSEED */
549
/* built-in CPU model definitions
551
static x86_def_t builtin_x86_defs[] = {
555
.vendor = CPUID_VENDOR_AMD,
559
.features[FEAT_1_EDX] =
561
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
563
.features[FEAT_1_ECX] =
564
CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
565
.features[FEAT_8000_0001_EDX] =
566
(PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
567
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
568
.features[FEAT_8000_0001_ECX] =
569
CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
570
CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
571
.xlevel = 0x8000000A,
576
.vendor = CPUID_VENDOR_AMD,
580
.features[FEAT_1_EDX] =
582
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
583
CPUID_PSE36 | CPUID_VME | CPUID_HT,
584
.features[FEAT_1_ECX] =
585
CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
587
.features[FEAT_8000_0001_EDX] =
588
(PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
589
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
590
CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
591
CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
592
/* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
594
CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
595
CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
596
.features[FEAT_8000_0001_ECX] =
597
CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
598
CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
599
.features[FEAT_SVM] =
600
CPUID_SVM_NPT | CPUID_SVM_LBRV,
601
.xlevel = 0x8000001A,
602
.model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
607
.vendor = CPUID_VENDOR_INTEL,
611
.features[FEAT_1_EDX] =
613
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
614
CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
615
CPUID_HT | CPUID_TM | CPUID_PBE,
616
.features[FEAT_1_ECX] =
617
CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
618
CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
619
CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
620
.features[FEAT_8000_0001_EDX] =
621
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
622
.features[FEAT_8000_0001_ECX] =
624
.xlevel = 0x80000008,
625
.model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
630
.vendor = CPUID_VENDOR_INTEL,
634
/* Missing: CPUID_VME, CPUID_HT */
635
.features[FEAT_1_EDX] =
637
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
639
/* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
640
.features[FEAT_1_ECX] =
641
CPUID_EXT_SSE3 | CPUID_EXT_CX16,
642
/* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
643
.features[FEAT_8000_0001_EDX] =
644
(PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
645
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
646
/* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
647
CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
648
CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
649
CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
650
.features[FEAT_8000_0001_ECX] =
652
.xlevel = 0x80000008,
653
.model_id = "Common KVM processor"
658
.vendor = CPUID_VENDOR_INTEL,
662
.features[FEAT_1_EDX] =
664
.features[FEAT_1_ECX] =
665
CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
666
.xlevel = 0x80000004,
671
.vendor = CPUID_VENDOR_INTEL,
675
.features[FEAT_1_EDX] =
677
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
678
.features[FEAT_1_ECX] =
680
.features[FEAT_8000_0001_EDX] =
681
PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES,
682
.features[FEAT_8000_0001_ECX] =
684
.xlevel = 0x80000008,
685
.model_id = "Common 32-bit KVM processor"
690
.vendor = CPUID_VENDOR_INTEL,
694
.features[FEAT_1_EDX] =
695
PPRO_FEATURES | CPUID_VME |
696
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
697
CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
698
.features[FEAT_1_ECX] =
699
CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
700
CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
701
.features[FEAT_8000_0001_EDX] =
703
.xlevel = 0x80000008,
704
.model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
709
.vendor = CPUID_VENDOR_INTEL,
713
.features[FEAT_1_EDX] =
720
.vendor = CPUID_VENDOR_INTEL,
724
.features[FEAT_1_EDX] =
731
.vendor = CPUID_VENDOR_INTEL,
735
.features[FEAT_1_EDX] =
742
.vendor = CPUID_VENDOR_INTEL,
746
.features[FEAT_1_EDX] =
753
.vendor = CPUID_VENDOR_AMD,
757
.features[FEAT_1_EDX] =
758
PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
760
.features[FEAT_8000_0001_EDX] =
761
(PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
762
CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
763
.xlevel = 0x80000008,
767
/* original is on level 10 */
769
.vendor = CPUID_VENDOR_INTEL,
773
.features[FEAT_1_EDX] =
775
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
776
CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
777
/* Some CPUs got no CPUID_SEP */
778
.features[FEAT_1_ECX] =
779
CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
780
CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR |
782
.features[FEAT_8000_0001_EDX] =
783
(PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
785
.features[FEAT_8000_0001_ECX] =
787
.xlevel = 0x8000000A,
788
.model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
793
.vendor = CPUID_VENDOR_INTEL,
797
.features[FEAT_1_EDX] =
798
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
799
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
800
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
801
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
802
CPUID_DE | CPUID_FP87,
803
.features[FEAT_1_ECX] =
804
CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
805
.features[FEAT_8000_0001_EDX] =
806
CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
807
.features[FEAT_8000_0001_ECX] =
809
.xlevel = 0x8000000A,
810
.model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
815
.vendor = CPUID_VENDOR_INTEL,
819
.features[FEAT_1_EDX] =
820
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
821
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
822
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
823
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
824
CPUID_DE | CPUID_FP87,
825
.features[FEAT_1_ECX] =
826
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
828
.features[FEAT_8000_0001_EDX] =
829
CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
830
.features[FEAT_8000_0001_ECX] =
832
.xlevel = 0x8000000A,
833
.model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
838
.vendor = CPUID_VENDOR_INTEL,
842
.features[FEAT_1_EDX] =
843
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
844
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
845
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
846
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
847
CPUID_DE | CPUID_FP87,
848
.features[FEAT_1_ECX] =
849
CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
850
CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
851
.features[FEAT_8000_0001_EDX] =
852
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
853
.features[FEAT_8000_0001_ECX] =
855
.xlevel = 0x8000000A,
856
.model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
861
.vendor = CPUID_VENDOR_INTEL,
865
.features[FEAT_1_EDX] =
866
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
867
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
868
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
869
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
870
CPUID_DE | CPUID_FP87,
871
.features[FEAT_1_ECX] =
872
CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
873
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
874
CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
875
.features[FEAT_8000_0001_EDX] =
876
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
877
.features[FEAT_8000_0001_ECX] =
879
.xlevel = 0x8000000A,
880
.model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
883
.name = "SandyBridge",
885
.vendor = CPUID_VENDOR_INTEL,
889
.features[FEAT_1_EDX] =
890
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
891
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
892
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
893
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
894
CPUID_DE | CPUID_FP87,
895
.features[FEAT_1_ECX] =
896
CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
897
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
898
CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
899
CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
901
.features[FEAT_8000_0001_EDX] =
902
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
904
.features[FEAT_8000_0001_ECX] =
906
.xlevel = 0x8000000A,
907
.model_id = "Intel Xeon E312xx (Sandy Bridge)",
912
.vendor = CPUID_VENDOR_INTEL,
916
.features[FEAT_1_EDX] =
917
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
918
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
919
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
920
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
921
CPUID_DE | CPUID_FP87,
922
.features[FEAT_1_ECX] =
923
CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
924
CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
925
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
926
CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
927
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
929
.features[FEAT_8000_0001_EDX] =
930
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
932
.features[FEAT_8000_0001_ECX] =
934
.features[FEAT_7_0_EBX] =
935
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
936
CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
937
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
939
.xlevel = 0x8000000A,
940
.model_id = "Intel Core Processor (Haswell)",
943
.name = "Opteron_G1",
945
.vendor = CPUID_VENDOR_AMD,
949
.features[FEAT_1_EDX] =
950
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
951
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
952
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
953
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
954
CPUID_DE | CPUID_FP87,
955
.features[FEAT_1_ECX] =
957
.features[FEAT_8000_0001_EDX] =
958
CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
959
CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
960
CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
961
CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
962
CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
963
CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
964
.xlevel = 0x80000008,
965
.model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
968
.name = "Opteron_G2",
970
.vendor = CPUID_VENDOR_AMD,
974
.features[FEAT_1_EDX] =
975
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
976
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
977
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
978
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
979
CPUID_DE | CPUID_FP87,
980
.features[FEAT_1_ECX] =
981
CPUID_EXT_CX16 | CPUID_EXT_SSE3,
982
.features[FEAT_8000_0001_EDX] =
983
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
984
CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
985
CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
986
CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
987
CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
988
CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
989
CPUID_EXT2_DE | CPUID_EXT2_FPU,
990
.features[FEAT_8000_0001_ECX] =
991
CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
992
.xlevel = 0x80000008,
993
.model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
996
.name = "Opteron_G3",
998
.vendor = CPUID_VENDOR_AMD,
1002
.features[FEAT_1_EDX] =
1003
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1004
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1005
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1006
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1007
CPUID_DE | CPUID_FP87,
1008
.features[FEAT_1_ECX] =
1009
CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
1011
.features[FEAT_8000_0001_EDX] =
1012
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
1013
CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1014
CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1015
CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1016
CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1017
CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1018
CPUID_EXT2_DE | CPUID_EXT2_FPU,
1019
.features[FEAT_8000_0001_ECX] =
1020
CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
1021
CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
1022
.xlevel = 0x80000008,
1023
.model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
1026
.name = "Opteron_G4",
1028
.vendor = CPUID_VENDOR_AMD,
1032
.features[FEAT_1_EDX] =
1033
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1034
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1035
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1036
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1037
CPUID_DE | CPUID_FP87,
1038
.features[FEAT_1_ECX] =
1039
CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1040
CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1041
CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1043
.features[FEAT_8000_0001_EDX] =
1044
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
1045
CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1046
CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1047
CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1048
CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1049
CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1050
CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
1051
.features[FEAT_8000_0001_ECX] =
1052
CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1053
CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1054
CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1056
.xlevel = 0x8000001A,
1057
.model_id = "AMD Opteron 62xx class CPU",
1060
.name = "Opteron_G5",
1062
.vendor = CPUID_VENDOR_AMD,
1066
.features[FEAT_1_EDX] =
1067
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1068
CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1069
CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1070
CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1071
CPUID_DE | CPUID_FP87,
1072
.features[FEAT_1_ECX] =
1073
CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
1074
CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1075
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
1076
CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1077
.features[FEAT_8000_0001_EDX] =
1078
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
1079
CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1080
CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1081
CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1082
CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1083
CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1084
CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
1085
.features[FEAT_8000_0001_ECX] =
1086
CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1087
CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1088
CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1090
.xlevel = 0x8000001A,
1091
.model_id = "AMD Opteron 63xx class CPU",
1096
* x86_cpu_compat_set_features:
1097
* @cpu_model: CPU model name to be changed. If NULL, all CPU models are changed
1098
* @w: Identifies the feature word to be changed.
1099
* @feat_add: Feature bits to be added to feature word
1100
* @feat_remove: Feature bits to be removed from feature word
1102
* Change CPU model feature bits for compatibility.
1104
* This function may be used by machine-type compatibility functions
1105
* to enable or disable feature bits on specific CPU models.
1107
void x86_cpu_compat_set_features(const char *cpu_model, FeatureWord w,
1108
uint32_t feat_add, uint32_t feat_remove)
1112
for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1113
def = &builtin_x86_defs[i];
1114
if (!cpu_model || !strcmp(cpu_model, def->name)) {
1115
def->features[w] |= feat_add;
1116
def->features[w] &= ~feat_remove;
1122
static int cpu_x86_fill_model_id(char *str)
1124
uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1127
for (i = 0; i < 3; i++) {
1128
host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
1129
memcpy(str + i * 16 + 0, &eax, 4);
1130
memcpy(str + i * 16 + 4, &ebx, 4);
1131
memcpy(str + i * 16 + 8, &ecx, 4);
1132
memcpy(str + i * 16 + 12, &edx, 4);
1138
/* Fill a x86_def_t struct with information about the host CPU, and
1139
* the CPU features supported by the host hardware + host kernel
1141
* This function may be called only if KVM is enabled.
1143
static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
1146
KVMState *s = kvm_state;
1147
uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1149
assert(kvm_enabled());
1151
x86_cpu_def->name = "host";
1152
x86_cpu_def->cache_info_passthrough = true;
1153
host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
1154
x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1156
host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
1157
x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1158
x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1159
x86_cpu_def->stepping = eax & 0x0F;
1161
x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
1162
x86_cpu_def->features[FEAT_1_EDX] =
1163
kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX);
1164
x86_cpu_def->features[FEAT_1_ECX] =
1165
kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX);
1167
if (x86_cpu_def->level >= 7) {
1168
x86_cpu_def->features[FEAT_7_0_EBX] =
1169
kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX);
1171
x86_cpu_def->features[FEAT_7_0_EBX] = 0;
1174
x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
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);
1180
cpu_x86_fill_model_id(x86_cpu_def->model_id);
1182
/* Call Centaur's CPUID instruction. */
1183
if (!strcmp(x86_cpu_def->vendor, CPUID_VENDOR_VIA)) {
1184
host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
1185
eax = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
1186
if (eax >= 0xC0000001) {
1187
/* Support VIA max extended level */
1188
x86_cpu_def->xlevel2 = eax;
1189
host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
1190
x86_cpu_def->features[FEAT_C000_0001_EDX] =
1191
kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
1195
/* Other KVM-specific feature fields: */
1196
x86_cpu_def->features[FEAT_SVM] =
1197
kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
1198
x86_cpu_def->features[FEAT_KVM] =
1199
kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
1201
#endif /* CONFIG_KVM */
1204
static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask)
1208
for (i = 0; i < 32; ++i)
1209
if (1 << i & mask) {
1210
const char *reg = get_register_name_32(f->cpuid_reg);
1212
fprintf(stderr, "warning: host doesn't support requested feature: "
1213
"CPUID.%02XH:%s%s%s [bit %d]\n",
1215
f->feat_names[i] ? "." : "",
1216
f->feat_names[i] ? f->feat_names[i] : "", i);
1222
/* Check if all requested cpu flags are making their way to the guest
1224
* Returns 0 if all flags are supported by the host, non-zero otherwise.
1226
* This function may be called only if KVM is enabled.
1228
static int kvm_check_features_against_host(X86CPU *cpu)
1230
CPUX86State *env = &cpu->env;
1234
struct model_features_t ft[] = {
1235
{&env->features[FEAT_1_EDX],
1236
&host_def.features[FEAT_1_EDX],
1238
{&env->features[FEAT_1_ECX],
1239
&host_def.features[FEAT_1_ECX],
1241
{&env->features[FEAT_8000_0001_EDX],
1242
&host_def.features[FEAT_8000_0001_EDX],
1243
FEAT_8000_0001_EDX },
1244
{&env->features[FEAT_8000_0001_ECX],
1245
&host_def.features[FEAT_8000_0001_ECX],
1246
FEAT_8000_0001_ECX },
1247
{&env->features[FEAT_C000_0001_EDX],
1248
&host_def.features[FEAT_C000_0001_EDX],
1249
FEAT_C000_0001_EDX },
1250
{&env->features[FEAT_7_0_EBX],
1251
&host_def.features[FEAT_7_0_EBX],
1253
{&env->features[FEAT_SVM],
1254
&host_def.features[FEAT_SVM],
1256
{&env->features[FEAT_KVM],
1257
&host_def.features[FEAT_KVM],
1261
assert(kvm_enabled());
1263
kvm_cpu_fill_host(&host_def);
1264
for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i) {
1265
FeatureWord w = ft[i].feat_word;
1266
FeatureWordInfo *wi = &feature_word_info[w];
1267
for (mask = 1; mask; mask <<= 1) {
1268
if (*ft[i].guest_feat & mask &&
1269
!(*ft[i].host_feat & mask)) {
1270
unavailable_host_feature(wi, mask);
1278
static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
1279
const char *name, Error **errp)
1281
X86CPU *cpu = X86_CPU(obj);
1282
CPUX86State *env = &cpu->env;
1285
value = (env->cpuid_version >> 8) & 0xf;
1287
value += (env->cpuid_version >> 20) & 0xff;
1289
visit_type_int(v, &value, name, errp);
1292
static void x86_cpuid_version_set_family(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 + 0xf;
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 &= ~0xff00f00;
1313
env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
1315
env->cpuid_version |= value << 8;
1319
static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
1320
const char *name, Error **errp)
1322
X86CPU *cpu = X86_CPU(obj);
1323
CPUX86State *env = &cpu->env;
1326
value = (env->cpuid_version >> 4) & 0xf;
1327
value |= ((env->cpuid_version >> 16) & 0xf) << 4;
1328
visit_type_int(v, &value, name, errp);
1331
static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
1332
const char *name, Error **errp)
1334
X86CPU *cpu = X86_CPU(obj);
1335
CPUX86State *env = &cpu->env;
1336
const int64_t min = 0;
1337
const int64_t max = 0xff;
1340
visit_type_int(v, &value, name, errp);
1341
if (error_is_set(errp)) {
1344
if (value < min || value > max) {
1345
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1346
name ? name : "null", value, min, max);
1350
env->cpuid_version &= ~0xf00f0;
1351
env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
1354
static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
1355
void *opaque, const char *name,
1358
X86CPU *cpu = X86_CPU(obj);
1359
CPUX86State *env = &cpu->env;
1362
value = env->cpuid_version & 0xf;
1363
visit_type_int(v, &value, name, errp);
1366
static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
1367
void *opaque, const char *name,
1370
X86CPU *cpu = X86_CPU(obj);
1371
CPUX86State *env = &cpu->env;
1372
const int64_t min = 0;
1373
const int64_t max = 0xf;
1376
visit_type_int(v, &value, name, errp);
1377
if (error_is_set(errp)) {
1380
if (value < min || value > max) {
1381
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1382
name ? name : "null", value, min, max);
1386
env->cpuid_version &= ~0xf;
1387
env->cpuid_version |= value & 0xf;
1390
static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
1391
const char *name, Error **errp)
1393
X86CPU *cpu = X86_CPU(obj);
1395
visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
1398
static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
1399
const char *name, Error **errp)
1401
X86CPU *cpu = X86_CPU(obj);
1403
visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
1406
static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
1407
const char *name, Error **errp)
1409
X86CPU *cpu = X86_CPU(obj);
1411
visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1414
static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
1415
const char *name, Error **errp)
1417
X86CPU *cpu = X86_CPU(obj);
1419
visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1422
static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1424
X86CPU *cpu = X86_CPU(obj);
1425
CPUX86State *env = &cpu->env;
1428
value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
1429
x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
1430
env->cpuid_vendor3);
1434
static void x86_cpuid_set_vendor(Object *obj, const char *value,
1437
X86CPU *cpu = X86_CPU(obj);
1438
CPUX86State *env = &cpu->env;
1441
if (strlen(value) != CPUID_VENDOR_SZ) {
1442
error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
1447
env->cpuid_vendor1 = 0;
1448
env->cpuid_vendor2 = 0;
1449
env->cpuid_vendor3 = 0;
1450
for (i = 0; i < 4; i++) {
1451
env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1452
env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1453
env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1457
static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1459
X86CPU *cpu = X86_CPU(obj);
1460
CPUX86State *env = &cpu->env;
1464
value = g_malloc(48 + 1);
1465
for (i = 0; i < 48; i++) {
1466
value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1472
static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1475
X86CPU *cpu = X86_CPU(obj);
1476
CPUX86State *env = &cpu->env;
1479
if (model_id == NULL) {
1482
len = strlen(model_id);
1483
memset(env->cpuid_model, 0, 48);
1484
for (i = 0; i < 48; i++) {
1488
c = (uint8_t)model_id[i];
1490
env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1494
static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
1495
const char *name, Error **errp)
1497
X86CPU *cpu = X86_CPU(obj);
1500
value = cpu->env.tsc_khz * 1000;
1501
visit_type_int(v, &value, name, errp);
1504
static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
1505
const char *name, Error **errp)
1507
X86CPU *cpu = X86_CPU(obj);
1508
const int64_t min = 0;
1509
const int64_t max = INT64_MAX;
1512
visit_type_int(v, &value, name, errp);
1513
if (error_is_set(errp)) {
1516
if (value < min || value > max) {
1517
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1518
name ? name : "null", value, min, max);
1522
cpu->env.tsc_khz = value / 1000;
1525
static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, void *opaque,
1526
const char *name, Error **errp)
1528
X86CPU *cpu = X86_CPU(obj);
1529
int64_t value = cpu->env.cpuid_apic_id;
1531
visit_type_int(v, &value, name, errp);
1534
static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque,
1535
const char *name, Error **errp)
1537
X86CPU *cpu = X86_CPU(obj);
1538
DeviceState *dev = DEVICE(obj);
1539
const int64_t min = 0;
1540
const int64_t max = UINT32_MAX;
1541
Error *error = NULL;
1544
if (dev->realized) {
1545
error_setg(errp, "Attempt to set property '%s' on '%s' after "
1546
"it was realized", name, object_get_typename(obj));
1550
visit_type_int(v, &value, name, &error);
1552
error_propagate(errp, error);
1555
if (value < min || value > max) {
1556
error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1557
" (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
1558
object_get_typename(obj), name, value, min, max);
1562
if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
1563
error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
1566
cpu->env.cpuid_apic_id = value;
1569
/* Generic getter for "feature-words" and "filtered-features" properties */
1570
static void x86_cpu_get_feature_words(Object *obj, Visitor *v, void *opaque,
1571
const char *name, Error **errp)
1573
uint32_t *array = (uint32_t *)opaque;
1576
X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
1577
X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
1578
X86CPUFeatureWordInfoList *list = NULL;
1580
for (w = 0; w < FEATURE_WORDS; w++) {
1581
FeatureWordInfo *wi = &feature_word_info[w];
1582
X86CPUFeatureWordInfo *qwi = &word_infos[w];
1583
qwi->cpuid_input_eax = wi->cpuid_eax;
1584
qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
1585
qwi->cpuid_input_ecx = wi->cpuid_ecx;
1586
qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
1587
qwi->features = array[w];
1589
/* List will be in reverse order, but order shouldn't matter */
1590
list_entries[w].next = list;
1591
list_entries[w].value = &word_infos[w];
1592
list = &list_entries[w];
1595
visit_type_X86CPUFeatureWordInfoList(v, &list, "feature-words", &err);
1596
error_propagate(errp, err);
1599
static int cpu_x86_find_by_name(X86CPU *cpu, x86_def_t *x86_cpu_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", &err);
1612
assert_no_error(err);
1616
for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1617
def = &builtin_x86_defs[i];
1618
if (strcmp(name, def->name) == 0) {
1619
memcpy(x86_cpu_def, def, sizeof(*def));
1620
/* sysenter isn't supported in compatibility mode on AMD,
1621
* syscall isn't supported in compatibility mode on Intel.
1622
* Normally we advertise the actual CPU vendor, but you can
1623
* override this using the 'vendor' property if you want to use
1624
* KVM's sysenter/syscall emulation in compatibility mode and
1625
* when doing cross vendor migration
1627
if (kvm_enabled()) {
1628
uint32_t ebx = 0, ecx = 0, edx = 0;
1629
host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
1630
x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1639
/* Convert all '_' in a feature string option name to '-', to make feature
1640
* name conform to QOM property naming rule, which uses '-' instead of '_'.
1642
static inline void feat2prop(char *s)
1644
while ((s = strchr(s, '_'))) {
1649
/* Parse "+feature,-feature,feature=foo" CPU feature string
1651
static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
1653
char *featurestr; /* Single 'key=value" string being parsed */
1654
/* Features to be added */
1655
FeatureWordArray plus_features = { 0 };
1656
/* Features to be removed */
1657
FeatureWordArray minus_features = { 0 };
1659
CPUX86State *env = &cpu->env;
1661
featurestr = features ? strtok(features, ",") : NULL;
1663
while (featurestr) {
1665
if (featurestr[0] == '+') {
1666
add_flagname_to_bitmaps(featurestr + 1, plus_features);
1667
} else if (featurestr[0] == '-') {
1668
add_flagname_to_bitmaps(featurestr + 1, minus_features);
1669
} else if ((val = strchr(featurestr, '='))) {
1671
feat2prop(featurestr);
1672
if (!strcmp(featurestr, "family")) {
1673
object_property_parse(OBJECT(cpu), val, featurestr, errp);
1674
} else if (!strcmp(featurestr, "model")) {
1675
object_property_parse(OBJECT(cpu), val, featurestr, errp);
1676
} else if (!strcmp(featurestr, "stepping")) {
1677
object_property_parse(OBJECT(cpu), val, featurestr, errp);
1678
} else if (!strcmp(featurestr, "level")) {
1679
object_property_parse(OBJECT(cpu), val, featurestr, errp);
1680
} else if (!strcmp(featurestr, "xlevel")) {
1684
numvalue = strtoul(val, &err, 0);
1685
if (!*val || *err) {
1686
error_setg(errp, "bad numerical value %s", val);
1689
if (numvalue < 0x80000000) {
1690
fprintf(stderr, "xlevel value shall always be >= 0x80000000"
1691
", fixup will be removed in future versions\n");
1692
numvalue += 0x80000000;
1694
snprintf(num, sizeof(num), "%" PRIu32, numvalue);
1695
object_property_parse(OBJECT(cpu), num, featurestr, errp);
1696
} else if (!strcmp(featurestr, "vendor")) {
1697
object_property_parse(OBJECT(cpu), val, featurestr, errp);
1698
} else if (!strcmp(featurestr, "model-id")) {
1699
object_property_parse(OBJECT(cpu), val, featurestr, errp);
1700
} else if (!strcmp(featurestr, "tsc-freq")) {
1705
tsc_freq = strtosz_suffix_unit(val, &err,
1706
STRTOSZ_DEFSUFFIX_B, 1000);
1707
if (tsc_freq < 0 || *err) {
1708
error_setg(errp, "bad numerical value %s", val);
1711
snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
1712
object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
1713
} else if (!strcmp(featurestr, "hv-spinlocks")) {
1715
const int min = 0xFFF;
1716
numvalue = strtoul(val, &err, 0);
1717
if (!*val || *err) {
1718
error_setg(errp, "bad numerical value %s", val);
1721
if (numvalue < min) {
1722
fprintf(stderr, "hv-spinlocks value shall always be >= 0x%x"
1723
", fixup will be removed in future versions\n",
1727
cpu->hyperv_spinlock_attempts = numvalue;
1729
error_setg(errp, "unrecognized feature %s", featurestr);
1732
} else if (!strcmp(featurestr, "check")) {
1734
} else if (!strcmp(featurestr, "enforce")) {
1735
check_cpuid = enforce_cpuid = 1;
1736
} else if (!strcmp(featurestr, "hv_relaxed")) {
1737
cpu->hyperv_relaxed_timing = true;
1738
} else if (!strcmp(featurestr, "hv_vapic")) {
1739
cpu->hyperv_vapic = true;
1741
error_setg(errp, "feature string `%s' not in format (+feature|"
1742
"-feature|feature=xyz)", featurestr);
1745
if (error_is_set(errp)) {
1748
featurestr = strtok(NULL, ",");
1750
env->features[FEAT_1_EDX] |= plus_features[FEAT_1_EDX];
1751
env->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX];
1752
env->features[FEAT_8000_0001_EDX] |= plus_features[FEAT_8000_0001_EDX];
1753
env->features[FEAT_8000_0001_ECX] |= plus_features[FEAT_8000_0001_ECX];
1754
env->features[FEAT_C000_0001_EDX] |= plus_features[FEAT_C000_0001_EDX];
1755
env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
1756
env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
1757
env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
1758
env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
1759
env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
1760
env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX];
1761
env->features[FEAT_8000_0001_ECX] &= ~minus_features[FEAT_8000_0001_ECX];
1762
env->features[FEAT_C000_0001_EDX] &= ~minus_features[FEAT_C000_0001_EDX];
1763
env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
1764
env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
1765
env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
1771
/* generate a composite string into buf of all cpuid names in featureset
1772
* selected by fbits. indicate truncation at bufsize in the event of overflow.
1773
* if flags, suppress names undefined in featureset.
1775
static void listflags(char *buf, int bufsize, uint32_t fbits,
1776
const char **featureset, uint32_t flags)
1778
const char **p = &featureset[31];
1782
b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1784
for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1785
if (fbits & 1 << bit && (*p || !flags)) {
1787
nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1789
nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1790
if (bufsize <= nc) {
1792
memcpy(b, "...", sizeof("..."));
1801
/* generate CPU information. */
1802
void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
1808
for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1809
def = &builtin_x86_defs[i];
1810
snprintf(buf, sizeof(buf), "%s", def->name);
1811
(*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
1814
(*cpu_fprintf)(f, "x86 %16s %-48s\n", "host",
1815
"KVM processor with all supported host features "
1816
"(only available in KVM mode)");
1819
(*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
1820
for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
1821
FeatureWordInfo *fw = &feature_word_info[i];
1823
listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
1824
(*cpu_fprintf)(f, " %s\n", buf);
1828
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
1830
CpuDefinitionInfoList *cpu_list = NULL;
1834
for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1835
CpuDefinitionInfoList *entry;
1836
CpuDefinitionInfo *info;
1838
def = &builtin_x86_defs[i];
1839
info = g_malloc0(sizeof(*info));
1840
info->name = g_strdup(def->name);
1842
entry = g_malloc0(sizeof(*entry));
1843
entry->value = info;
1844
entry->next = cpu_list;
1852
static void filter_features_for_kvm(X86CPU *cpu)
1854
CPUX86State *env = &cpu->env;
1855
KVMState *s = kvm_state;
1858
for (w = 0; w < FEATURE_WORDS; w++) {
1859
FeatureWordInfo *wi = &feature_word_info[w];
1860
uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax,
1863
uint32_t requested_features = env->features[w];
1864
env->features[w] &= host_feat;
1865
cpu->filtered_features[w] = requested_features & ~env->features[w];
1870
static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
1872
CPUX86State *env = &cpu->env;
1873
x86_def_t def1, *def = &def1;
1875
memset(def, 0, sizeof(*def));
1877
if (cpu_x86_find_by_name(cpu, def, name) < 0) {
1878
error_setg(errp, "Unable to find CPU definition: %s", name);
1882
if (kvm_enabled()) {
1883
def->features[FEAT_KVM] |= kvm_default_features;
1885
def->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
1887
object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp);
1888
object_property_set_int(OBJECT(cpu), def->level, "level", errp);
1889
object_property_set_int(OBJECT(cpu), def->family, "family", errp);
1890
object_property_set_int(OBJECT(cpu), def->model, "model", errp);
1891
object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
1892
env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX];
1893
env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX];
1894
env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX];
1895
env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX];
1896
object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
1897
env->features[FEAT_KVM] = def->features[FEAT_KVM];
1898
env->features[FEAT_SVM] = def->features[FEAT_SVM];
1899
env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
1900
env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
1901
env->cpuid_xlevel2 = def->xlevel2;
1902
cpu->cache_info_passthrough = def->cache_info_passthrough;
1904
object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
1907
X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
1911
gchar **model_pieces;
1912
char *name, *features;
1914
Error *error = NULL;
1916
model_pieces = g_strsplit(cpu_model, ",", 2);
1917
if (!model_pieces[0]) {
1918
error_setg(&error, "Invalid/empty CPU model name");
1921
name = model_pieces[0];
1922
features = model_pieces[1];
1924
cpu = X86_CPU(object_new(TYPE_X86_CPU));
1925
#ifndef CONFIG_USER_ONLY
1926
if (icc_bridge == NULL) {
1927
error_setg(&error, "Invalid icc-bridge value");
1930
qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
1931
object_unref(OBJECT(cpu));
1934
cpu_x86_register(cpu, name, &error);
1939
/* Emulate per-model subclasses for global properties */
1940
typename = g_strdup_printf("%s-" TYPE_X86_CPU, name);
1941
qdev_prop_set_globals_for_type(DEVICE(cpu), typename, &error);
1947
cpu_x86_parse_featurestr(cpu, features, &error);
1953
if (error != NULL) {
1954
error_propagate(errp, error);
1955
object_unref(OBJECT(cpu));
1958
g_strfreev(model_pieces);
1962
X86CPU *cpu_x86_init(const char *cpu_model)
1964
Error *error = NULL;
1967
cpu = cpu_x86_create(cpu_model, NULL, &error);
1972
object_property_set_bool(OBJECT(cpu), true, "realized", &error);
1976
error_report("%s", error_get_pretty(error));
1979
object_unref(OBJECT(cpu));
1986
#if !defined(CONFIG_USER_ONLY)
1988
void cpu_clear_apic_feature(CPUX86State *env)
1990
env->features[FEAT_1_EDX] &= ~CPUID_APIC;
1993
#endif /* !CONFIG_USER_ONLY */
1995
/* Initialize list of CPU models, filling some non-static fields if necessary
1997
void x86_cpudef_setup(void)
2000
static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
2002
for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
2003
x86_def_t *def = &builtin_x86_defs[i];
2005
/* Look for specific "cpudef" models that */
2006
/* have the QEMU version in .model_id */
2007
for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
2008
if (strcmp(model_with_versions[j], def->name) == 0) {
2009
pstrcpy(def->model_id, sizeof(def->model_id),
2010
"QEMU Virtual CPU version ");
2011
pstrcat(def->model_id, sizeof(def->model_id),
2012
qemu_get_version());
2019
static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
2020
uint32_t *ecx, uint32_t *edx)
2022
*ebx = env->cpuid_vendor1;
2023
*edx = env->cpuid_vendor2;
2024
*ecx = env->cpuid_vendor3;
2027
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
2028
uint32_t *eax, uint32_t *ebx,
2029
uint32_t *ecx, uint32_t *edx)
2031
X86CPU *cpu = x86_env_get_cpu(env);
2032
CPUState *cs = CPU(cpu);
2034
/* test if maximum index reached */
2035
if (index & 0x80000000) {
2036
if (index > env->cpuid_xlevel) {
2037
if (env->cpuid_xlevel2 > 0) {
2038
/* Handle the Centaur's CPUID instruction. */
2039
if (index > env->cpuid_xlevel2) {
2040
index = env->cpuid_xlevel2;
2041
} else if (index < 0xC0000000) {
2042
index = env->cpuid_xlevel;
2045
/* Intel documentation states that invalid EAX input will
2046
* return the same information as EAX=cpuid_level
2047
* (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
2049
index = env->cpuid_level;
2053
if (index > env->cpuid_level)
2054
index = env->cpuid_level;
2059
*eax = env->cpuid_level;
2060
get_cpuid_vendor(env, ebx, ecx, edx);
2063
*eax = env->cpuid_version;
2064
*ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
2065
*ecx = env->features[FEAT_1_ECX];
2066
*edx = env->features[FEAT_1_EDX];
2067
if (cs->nr_cores * cs->nr_threads > 1) {
2068
*ebx |= (cs->nr_cores * cs->nr_threads) << 16;
2069
*edx |= 1 << 28; /* HTT bit */
2073
/* cache info: needed for Pentium Pro compatibility */
2074
if (cpu->cache_info_passthrough) {
2075
host_cpuid(index, 0, eax, ebx, ecx, edx);
2078
*eax = 1; /* Number of CPUID[EAX=2] calls required */
2081
*edx = (L1D_DESCRIPTOR << 16) | \
2082
(L1I_DESCRIPTOR << 8) | \
2086
/* cache info: needed for Core compatibility */
2087
if (cpu->cache_info_passthrough) {
2088
host_cpuid(index, count, eax, ebx, ecx, edx);
2089
*eax &= ~0xFC000000;
2093
case 0: /* L1 dcache info */
2094
*eax |= CPUID_4_TYPE_DCACHE | \
2095
CPUID_4_LEVEL(1) | \
2096
CPUID_4_SELF_INIT_LEVEL;
2097
*ebx = (L1D_LINE_SIZE - 1) | \
2098
((L1D_PARTITIONS - 1) << 12) | \
2099
((L1D_ASSOCIATIVITY - 1) << 22);
2100
*ecx = L1D_SETS - 1;
2101
*edx = CPUID_4_NO_INVD_SHARING;
2103
case 1: /* L1 icache info */
2104
*eax |= CPUID_4_TYPE_ICACHE | \
2105
CPUID_4_LEVEL(1) | \
2106
CPUID_4_SELF_INIT_LEVEL;
2107
*ebx = (L1I_LINE_SIZE - 1) | \
2108
((L1I_PARTITIONS - 1) << 12) | \
2109
((L1I_ASSOCIATIVITY - 1) << 22);
2110
*ecx = L1I_SETS - 1;
2111
*edx = CPUID_4_NO_INVD_SHARING;
2113
case 2: /* L2 cache info */
2114
*eax |= CPUID_4_TYPE_UNIFIED | \
2115
CPUID_4_LEVEL(2) | \
2116
CPUID_4_SELF_INIT_LEVEL;
2117
if (cs->nr_threads > 1) {
2118
*eax |= (cs->nr_threads - 1) << 14;
2120
*ebx = (L2_LINE_SIZE - 1) | \
2121
((L2_PARTITIONS - 1) << 12) | \
2122
((L2_ASSOCIATIVITY - 1) << 22);
2124
*edx = CPUID_4_NO_INVD_SHARING;
2126
default: /* end of info */
2135
/* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
2136
if ((*eax & 31) && cs->nr_cores > 1) {
2137
*eax |= (cs->nr_cores - 1) << 26;
2141
/* mwait info: needed for Core compatibility */
2142
*eax = 0; /* Smallest monitor-line size in bytes */
2143
*ebx = 0; /* Largest monitor-line size in bytes */
2144
*ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
2148
/* Thermal and Power Leaf */
2155
/* Structured Extended Feature Flags Enumeration Leaf */
2157
*eax = 0; /* Maximum ECX value for sub-leaves */
2158
*ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
2159
*ecx = 0; /* Reserved */
2160
*edx = 0; /* Reserved */
2169
/* Direct Cache Access Information Leaf */
2170
*eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2176
/* Architectural Performance Monitoring Leaf */
2177
if (kvm_enabled() && cpu->enable_pmu) {
2178
KVMState *s = cs->kvm_state;
2180
*eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
2181
*ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
2182
*ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
2183
*edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
2192
KVMState *s = cs->kvm_state;
2196
/* Processor Extended State */
2201
if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) || !kvm_enabled()) {
2205
kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX) |
2206
((uint64_t)kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX) << 32);
2210
for (i = 2; i < ARRAY_SIZE(ext_save_areas); i++) {
2211
const ExtSaveArea *esa = &ext_save_areas[i];
2212
if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2213
(kvm_mask & (1 << i)) != 0) {
2217
*edx |= 1 << (i - 32);
2219
*ecx = MAX(*ecx, esa->offset + esa->size);
2222
*eax |= kvm_mask & (XSTATE_FP | XSTATE_SSE);
2224
} else if (count == 1) {
2225
*eax = kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
2226
} else if (count < ARRAY_SIZE(ext_save_areas)) {
2227
const ExtSaveArea *esa = &ext_save_areas[count];
2228
if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2229
(kvm_mask & (1 << count)) != 0) {
2237
*eax = env->cpuid_xlevel;
2238
*ebx = env->cpuid_vendor1;
2239
*edx = env->cpuid_vendor2;
2240
*ecx = env->cpuid_vendor3;
2243
*eax = env->cpuid_version;
2245
*ecx = env->features[FEAT_8000_0001_ECX];
2246
*edx = env->features[FEAT_8000_0001_EDX];
2248
/* The Linux kernel checks for the CMPLegacy bit and
2249
* discards multiple thread information if it is set.
2250
* So dont set it here for Intel to make Linux guests happy.
2252
if (cs->nr_cores * cs->nr_threads > 1) {
2253
uint32_t tebx, tecx, tedx;
2254
get_cpuid_vendor(env, &tebx, &tecx, &tedx);
2255
if (tebx != CPUID_VENDOR_INTEL_1 ||
2256
tedx != CPUID_VENDOR_INTEL_2 ||
2257
tecx != CPUID_VENDOR_INTEL_3) {
2258
*ecx |= 1 << 1; /* CmpLegacy bit */
2265
*eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2266
*ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2267
*ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2268
*edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2271
/* cache info (L1 cache) */
2272
if (cpu->cache_info_passthrough) {
2273
host_cpuid(index, 0, eax, ebx, ecx, edx);
2276
*eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \
2277
(L1_ITLB_2M_ASSOC << 8) | (L1_ITLB_2M_ENTRIES);
2278
*ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
2279
(L1_ITLB_4K_ASSOC << 8) | (L1_ITLB_4K_ENTRIES);
2280
*ecx = (L1D_SIZE_KB_AMD << 24) | (L1D_ASSOCIATIVITY_AMD << 16) | \
2281
(L1D_LINES_PER_TAG << 8) | (L1D_LINE_SIZE);
2282
*edx = (L1I_SIZE_KB_AMD << 24) | (L1I_ASSOCIATIVITY_AMD << 16) | \
2283
(L1I_LINES_PER_TAG << 8) | (L1I_LINE_SIZE);
2286
/* cache info (L2 cache) */
2287
if (cpu->cache_info_passthrough) {
2288
host_cpuid(index, 0, eax, ebx, ecx, edx);
2291
*eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \
2292
(L2_DTLB_2M_ENTRIES << 16) | \
2293
(AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \
2294
(L2_ITLB_2M_ENTRIES);
2295
*ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) | \
2296
(L2_DTLB_4K_ENTRIES << 16) | \
2297
(AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
2298
(L2_ITLB_4K_ENTRIES);
2299
*ecx = (L2_SIZE_KB_AMD << 16) | \
2300
(AMD_ENC_ASSOC(L2_ASSOCIATIVITY) << 12) | \
2301
(L2_LINES_PER_TAG << 8) | (L2_LINE_SIZE);
2302
*edx = ((L3_SIZE_KB/512) << 18) | \
2303
(AMD_ENC_ASSOC(L3_ASSOCIATIVITY) << 12) | \
2304
(L3_LINES_PER_TAG << 8) | (L3_LINE_SIZE);
2307
/* virtual & phys address size in low 2 bytes. */
2308
/* XXX: This value must match the one used in the MMU code. */
2309
if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
2310
/* 64 bit processor */
2311
/* XXX: The physical address space is limited to 42 bits in exec.c. */
2312
*eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
2314
if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
2315
*eax = 0x00000024; /* 36 bits physical */
2317
*eax = 0x00000020; /* 32 bits physical */
2323
if (cs->nr_cores * cs->nr_threads > 1) {
2324
*ecx |= (cs->nr_cores * cs->nr_threads) - 1;
2328
if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
2329
*eax = 0x00000001; /* SVM Revision */
2330
*ebx = 0x00000010; /* nr of ASIDs */
2332
*edx = env->features[FEAT_SVM]; /* optional features */
2341
*eax = env->cpuid_xlevel2;
2347
/* Support for VIA CPU's CPUID instruction */
2348
*eax = env->cpuid_version;
2351
*edx = env->features[FEAT_C000_0001_EDX];
2356
/* Reserved for the future, and now filled with zero */
2363
/* reserved values: zero */
2372
/* CPUClass::reset() */
2373
static void x86_cpu_reset(CPUState *s)
2375
X86CPU *cpu = X86_CPU(s);
2376
X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2377
CPUX86State *env = &cpu->env;
2380
xcc->parent_reset(s);
2383
memset(env, 0, offsetof(CPUX86State, breakpoints));
2387
env->old_exception = -1;
2389
/* init to reset state */
2391
#ifdef CONFIG_SOFTMMU
2392
env->hflags |= HF_SOFTMMU_MASK;
2394
env->hflags2 |= HF2_GIF_MASK;
2396
cpu_x86_update_cr0(env, 0x60000010);
2397
env->a20_mask = ~0x0;
2398
env->smbase = 0x30000;
2400
env->idt.limit = 0xffff;
2401
env->gdt.limit = 0xffff;
2402
env->ldt.limit = 0xffff;
2403
env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2404
env->tr.limit = 0xffff;
2405
env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2407
cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2408
DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2409
DESC_R_MASK | DESC_A_MASK);
2410
cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2411
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2413
cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
2414
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2416
cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
2417
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2419
cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
2420
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2422
cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
2423
DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2427
env->regs[R_EDX] = env->cpuid_version;
2432
for (i = 0; i < 8; i++) {
2437
env->mxcsr = 0x1f80;
2438
env->xstate_bv = XSTATE_FP | XSTATE_SSE;
2440
env->pat = 0x0007040600070406ULL;
2441
env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2443
memset(env->dr, 0, sizeof(env->dr));
2444
env->dr[6] = DR6_FIXED_1;
2445
env->dr[7] = DR7_FIXED_1;
2446
cpu_breakpoint_remove_all(env, BP_CPU);
2447
cpu_watchpoint_remove_all(env, BP_CPU);
2449
#if !defined(CONFIG_USER_ONLY)
2450
/* We hard-wire the BSP to the first CPU. */
2451
if (s->cpu_index == 0) {
2452
apic_designate_bsp(env->apic_state);
2455
s->halted = !cpu_is_bsp(cpu);
2459
#ifndef CONFIG_USER_ONLY
2460
bool cpu_is_bsp(X86CPU *cpu)
2462
return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP;
2465
/* TODO: remove me, when reset over QOM tree is implemented */
2466
static void x86_cpu_machine_reset_cb(void *opaque)
2468
X86CPU *cpu = opaque;
2469
cpu_reset(CPU(cpu));
2473
static void mce_init(X86CPU *cpu)
2475
CPUX86State *cenv = &cpu->env;
2478
if (((cenv->cpuid_version >> 8) & 0xf) >= 6
2479
&& (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
2480
(CPUID_MCE | CPUID_MCA)) {
2481
cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2482
cenv->mcg_ctl = ~(uint64_t)0;
2483
for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2484
cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2489
#ifndef CONFIG_USER_ONLY
2490
static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
2492
CPUX86State *env = &cpu->env;
2493
DeviceState *dev = DEVICE(cpu);
2494
APICCommonState *apic;
2495
const char *apic_type = "apic";
2497
if (kvm_irqchip_in_kernel()) {
2498
apic_type = "kvm-apic";
2499
} else if (xen_enabled()) {
2500
apic_type = "xen-apic";
2503
env->apic_state = qdev_try_create(qdev_get_parent_bus(dev), apic_type);
2504
if (env->apic_state == NULL) {
2505
error_setg(errp, "APIC device '%s' could not be created", apic_type);
2509
object_property_add_child(OBJECT(cpu), "apic",
2510
OBJECT(env->apic_state), NULL);
2511
qdev_prop_set_uint8(env->apic_state, "id", env->cpuid_apic_id);
2512
/* TODO: convert to link<> */
2513
apic = APIC_COMMON(env->apic_state);
2517
static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2519
CPUX86State *env = &cpu->env;
2521
if (env->apic_state == NULL) {
2525
if (qdev_init(env->apic_state)) {
2526
error_setg(errp, "APIC device '%s' could not be initialized",
2527
object_get_typename(OBJECT(env->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
if (check_cpuid && kvm_check_features_against_host(cpu)
2573
error_setg(&local_err,
2574
"Host's CPU doesn't support requested features");
2578
filter_features_for_kvm(cpu);
2582
#ifndef CONFIG_USER_ONLY
2583
qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
2585
if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
2586
x86_cpu_apic_create(cpu, &local_err);
2587
if (local_err != NULL) {
2596
x86_cpu_apic_realize(cpu, &local_err);
2597
if (local_err != NULL) {
2602
xcc->parent_realize(dev, &local_err);
2604
if (local_err != NULL) {
2605
error_propagate(errp, local_err);
2610
/* Enables contiguous-apic-ID mode, for compatibility */
2611
static bool compat_apic_id_mode;
2613
void enable_compat_apic_id_mode(void)
2615
compat_apic_id_mode = true;
2618
/* Calculates initial APIC ID for a specific CPU index
2620
* Currently we need to be able to calculate the APIC ID from the CPU index
2621
* alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
2622
* no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
2623
* all CPUs up to max_cpus.
2625
uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
2627
uint32_t correct_id;
2630
correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
2631
if (compat_apic_id_mode) {
2632
if (cpu_index != correct_id && !warned) {
2633
error_report("APIC IDs set in compatibility mode, "
2634
"CPU topology won't match the configuration");
2643
static void x86_cpu_initfn(Object *obj)
2645
CPUState *cs = CPU(obj);
2646
X86CPU *cpu = X86_CPU(obj);
2647
CPUX86State *env = &cpu->env;
2653
object_property_add(obj, "family", "int",
2654
x86_cpuid_version_get_family,
2655
x86_cpuid_version_set_family, NULL, NULL, NULL);
2656
object_property_add(obj, "model", "int",
2657
x86_cpuid_version_get_model,
2658
x86_cpuid_version_set_model, NULL, NULL, NULL);
2659
object_property_add(obj, "stepping", "int",
2660
x86_cpuid_version_get_stepping,
2661
x86_cpuid_version_set_stepping, NULL, NULL, NULL);
2662
object_property_add(obj, "level", "int",
2663
x86_cpuid_get_level,
2664
x86_cpuid_set_level, NULL, NULL, NULL);
2665
object_property_add(obj, "xlevel", "int",
2666
x86_cpuid_get_xlevel,
2667
x86_cpuid_set_xlevel, NULL, NULL, NULL);
2668
object_property_add_str(obj, "vendor",
2669
x86_cpuid_get_vendor,
2670
x86_cpuid_set_vendor, NULL);
2671
object_property_add_str(obj, "model-id",
2672
x86_cpuid_get_model_id,
2673
x86_cpuid_set_model_id, NULL);
2674
object_property_add(obj, "tsc-frequency", "int",
2675
x86_cpuid_get_tsc_freq,
2676
x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
2677
object_property_add(obj, "apic-id", "int",
2678
x86_cpuid_get_apic_id,
2679
x86_cpuid_set_apic_id, NULL, NULL, NULL);
2680
object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
2681
x86_cpu_get_feature_words,
2682
NULL, NULL, (void *)env->features, NULL);
2683
object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
2684
x86_cpu_get_feature_words,
2685
NULL, NULL, (void *)cpu->filtered_features, NULL);
2687
cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
2688
env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
2690
/* init various static tables used in TCG mode */
2691
if (tcg_enabled() && !inited) {
2693
optimize_flags_init();
2694
#ifndef CONFIG_USER_ONLY
2695
cpu_set_debug_excp_handler(breakpoint_handler);
2700
static int64_t x86_cpu_get_arch_id(CPUState *cs)
2702
X86CPU *cpu = X86_CPU(cs);
2703
CPUX86State *env = &cpu->env;
2705
return env->cpuid_apic_id;
2708
static bool x86_cpu_get_paging_enabled(const CPUState *cs)
2710
X86CPU *cpu = X86_CPU(cs);
2712
return cpu->env.cr[0] & CR0_PG_MASK;
2715
static void x86_cpu_set_pc(CPUState *cs, vaddr value)
2717
X86CPU *cpu = X86_CPU(cs);
2719
cpu->env.eip = value;
2722
static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
2724
X86CPU *cpu = X86_CPU(cs);
2726
cpu->env.eip = tb->pc - tb->cs_base;
2729
static Property x86_cpu_properties[] = {
2730
DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
2731
DEFINE_PROP_END_OF_LIST()
2734
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
2736
X86CPUClass *xcc = X86_CPU_CLASS(oc);
2737
CPUClass *cc = CPU_CLASS(oc);
2738
DeviceClass *dc = DEVICE_CLASS(oc);
2740
xcc->parent_realize = dc->realize;
2741
dc->realize = x86_cpu_realizefn;
2742
dc->bus_type = TYPE_ICC_BUS;
2743
dc->props = x86_cpu_properties;
2745
xcc->parent_reset = cc->reset;
2746
cc->reset = x86_cpu_reset;
2747
cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
2749
cc->do_interrupt = x86_cpu_do_interrupt;
2750
cc->dump_state = x86_cpu_dump_state;
2751
cc->set_pc = x86_cpu_set_pc;
2752
cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
2753
cc->gdb_read_register = x86_cpu_gdb_read_register;
2754
cc->gdb_write_register = x86_cpu_gdb_write_register;
2755
cc->get_arch_id = x86_cpu_get_arch_id;
2756
cc->get_paging_enabled = x86_cpu_get_paging_enabled;
2757
#ifndef CONFIG_USER_ONLY
2758
cc->get_memory_mapping = x86_cpu_get_memory_mapping;
2759
cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
2760
cc->write_elf64_note = x86_cpu_write_elf64_note;
2761
cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
2762
cc->write_elf32_note = x86_cpu_write_elf32_note;
2763
cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
2764
cc->vmsd = &vmstate_x86_cpu;
2766
cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
2769
static const TypeInfo x86_cpu_type_info = {
2770
.name = TYPE_X86_CPU,
2772
.instance_size = sizeof(X86CPU),
2773
.instance_init = x86_cpu_initfn,
2775
.class_size = sizeof(X86CPUClass),
2776
.class_init = x86_cpu_common_class_init,
2779
static void x86_cpu_register_types(void)
2781
type_register_static(&x86_cpu_type_info);
2784
type_init(x86_cpu_register_types)