blob: f3f95cd0c4d2969423a79b5c57dade887a2ca907 [file] [log] [blame]
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001/*
2 * i386 CPUID helper functions
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
Peter Maydell1ef26b12016-02-23 11:58:02 +000019#include "qemu/osdep.h"
Veronia Bahaaf348b6d2016-03-20 19:16:19 +020020#include "qemu/cutils.h"
Andre Przywarac6dc6f62010-03-11 14:38:55 +010021
22#include "cpu.h"
Paolo Bonzini63c91552016-03-15 13:18:37 +010023#include "exec/exec-all.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010024#include "sysemu/kvm.h"
Eduardo Habkost8932cfd2013-01-22 18:25:09 -020025#include "sysemu/cpus.h"
Paolo Bonzini50a2c6e2013-03-20 13:11:56 +010026#include "kvm_i386.h"
Andre Przywarac6dc6f62010-03-11 14:38:55 +010027
Markus Armbrusterd49b6832015-03-17 18:29:20 +010028#include "qemu/error-report.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010029#include "qemu/option.h"
30#include "qemu/config-file.h"
Paolo Bonzini7b1b5d12012-12-17 18:19:43 +010031#include "qapi/qmp/qerror.h"
Andre Przywarac6dc6f62010-03-11 14:38:55 +010032
Eduardo Habkost8e8aba52013-05-06 13:20:07 -030033#include "qapi-types.h"
34#include "qapi-visit.h"
Paolo Bonzini7b1b5d12012-12-17 18:19:43 +010035#include "qapi/visitor.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010036#include "sysemu/arch_init.h"
Andreas Färber71ad61d2012-04-17 12:10:29 +020037
Stefan Weilb834b502012-08-30 22:28:31 +020038#if defined(CONFIG_KVM)
Anthony Liguorief8621b2012-08-29 09:32:41 -050039#include <linux/kvm_para.h>
Stefan Weilb834b502012-08-30 22:28:31 +020040#endif
Igor Mammedov65dee382012-07-23 15:22:28 +020041
Paolo Bonzini9c17d612012-12-17 18:20:04 +010042#include "sysemu/sysemu.h"
Igor Mammedov53a89e22013-04-29 19:03:01 +020043#include "hw/qdev-properties.h"
Radim Krčmář5232d002016-05-12 19:24:26 +020044#include "hw/i386/topology.h"
Igor Mammedovbdeec802012-10-13 22:35:39 +020045#ifndef CONFIG_USER_ONLY
Paolo Bonzini2001d0c2015-03-31 14:11:09 +020046#include "exec/address-spaces.h"
Paolo Bonzini741da0d2014-06-27 08:40:04 +020047#include "hw/hw.h"
Paolo Bonzini0d09e412013-02-05 17:06:20 +010048#include "hw/xen/xen.h"
Paolo Bonzini0d09e412013-02-05 17:06:20 +010049#include "hw/i386/apic_internal.h"
Igor Mammedovbdeec802012-10-13 22:35:39 +020050#endif
51
Eduardo Habkost5e891bf2013-08-27 12:24:37 -030052
53/* Cache topology CPUID constants: */
54
55/* CPUID Leaf 2 Descriptors */
56
57#define CPUID_2_L1D_32KB_8WAY_64B 0x2c
58#define CPUID_2_L1I_32KB_8WAY_64B 0x30
59#define CPUID_2_L2_2MB_8WAY_64B 0x7d
60
61
62/* CPUID Leaf 4 constants: */
63
64/* EAX: */
65#define CPUID_4_TYPE_DCACHE 1
66#define CPUID_4_TYPE_ICACHE 2
67#define CPUID_4_TYPE_UNIFIED 3
68
69#define CPUID_4_LEVEL(l) ((l) << 5)
70
71#define CPUID_4_SELF_INIT_LEVEL (1 << 8)
72#define CPUID_4_FULLY_ASSOC (1 << 9)
73
74/* EDX: */
75#define CPUID_4_NO_INVD_SHARING (1 << 0)
76#define CPUID_4_INCLUSIVE (1 << 1)
77#define CPUID_4_COMPLEX_IDX (1 << 2)
78
79#define ASSOC_FULL 0xFF
80
81/* AMD associativity encoding used on CPUID Leaf 0x80000006: */
82#define AMD_ENC_ASSOC(a) (a <= 1 ? a : \
83 a == 2 ? 0x2 : \
84 a == 4 ? 0x4 : \
85 a == 8 ? 0x6 : \
86 a == 16 ? 0x8 : \
87 a == 32 ? 0xA : \
88 a == 48 ? 0xB : \
89 a == 64 ? 0xC : \
90 a == 96 ? 0xD : \
91 a == 128 ? 0xE : \
92 a == ASSOC_FULL ? 0xF : \
93 0 /* invalid value */)
94
95
96/* Definitions of the hardcoded cache entries we expose: */
97
98/* L1 data cache: */
99#define L1D_LINE_SIZE 64
100#define L1D_ASSOCIATIVITY 8
101#define L1D_SETS 64
102#define L1D_PARTITIONS 1
103/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
104#define L1D_DESCRIPTOR CPUID_2_L1D_32KB_8WAY_64B
105/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
106#define L1D_LINES_PER_TAG 1
107#define L1D_SIZE_KB_AMD 64
108#define L1D_ASSOCIATIVITY_AMD 2
109
110/* L1 instruction cache: */
111#define L1I_LINE_SIZE 64
112#define L1I_ASSOCIATIVITY 8
113#define L1I_SETS 64
114#define L1I_PARTITIONS 1
115/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
116#define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
117/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
118#define L1I_LINES_PER_TAG 1
119#define L1I_SIZE_KB_AMD 64
120#define L1I_ASSOCIATIVITY_AMD 2
121
122/* Level 2 unified cache: */
123#define L2_LINE_SIZE 64
124#define L2_ASSOCIATIVITY 16
125#define L2_SETS 4096
126#define L2_PARTITIONS 1
127/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
128/*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
129#define L2_DESCRIPTOR CPUID_2_L2_2MB_8WAY_64B
130/*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
131#define L2_LINES_PER_TAG 1
132#define L2_SIZE_KB_AMD 512
133
134/* No L3 cache: */
135#define L3_SIZE_KB 0 /* disabled */
136#define L3_ASSOCIATIVITY 0 /* disabled */
137#define L3_LINES_PER_TAG 0 /* disabled */
138#define L3_LINE_SIZE 0 /* disabled */
139
140/* TLB definitions: */
141
142#define L1_DTLB_2M_ASSOC 1
143#define L1_DTLB_2M_ENTRIES 255
144#define L1_DTLB_4K_ASSOC 1
145#define L1_DTLB_4K_ENTRIES 255
146
147#define L1_ITLB_2M_ASSOC 1
148#define L1_ITLB_2M_ENTRIES 255
149#define L1_ITLB_4K_ASSOC 1
150#define L1_ITLB_4K_ENTRIES 255
151
152#define L2_DTLB_2M_ASSOC 0 /* disabled */
153#define L2_DTLB_2M_ENTRIES 0 /* disabled */
154#define L2_DTLB_4K_ASSOC 4
155#define L2_DTLB_4K_ENTRIES 512
156
157#define L2_ITLB_2M_ASSOC 0 /* disabled */
158#define L2_ITLB_2M_ENTRIES 0 /* disabled */
159#define L2_ITLB_4K_ASSOC 4
160#define L2_ITLB_4K_ENTRIES 512
161
162
163
Igor Mammedov99b88a12013-01-21 15:06:36 +0100164static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
165 uint32_t vendor2, uint32_t vendor3)
166{
167 int i;
168 for (i = 0; i < 4; i++) {
169 dst[i] = vendor1 >> (8 * i);
170 dst[i + 4] = vendor2 >> (8 * i);
171 dst[i + 8] = vendor3 >> (8 * i);
172 }
173 dst[CPUID_VENDOR_SZ] = '\0';
174}
175
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100176/* feature flags taken from "Intel Processor Identification and the CPUID
177 * Instruction" and AMD's "CPUID Specification". In cases of disagreement
178 * between feature naming conventions, aliases may be added.
179 */
180static const char *feature_name[] = {
181 "fpu", "vme", "de", "pse",
182 "tsc", "msr", "pae", "mce",
183 "cx8", "apic", NULL, "sep",
184 "mtrr", "pge", "mca", "cmov",
185 "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
186 NULL, "ds" /* Intel dts */, "acpi", "mmx",
187 "fxsr", "sse", "sse2", "ss",
188 "ht" /* Intel htt */, "tm", "ia64", "pbe",
189};
190static const char *ext_feature_name[] = {
Eduardo Habkostf370be32012-02-17 14:41:20 -0200191 "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
Andre Przywarae117f772010-03-11 14:38:59 +0100192 "ds_cpl", "vmx", "smx", "est",
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100193 "tm2", "ssse3", "cid", NULL,
Andre Przywarae117f772010-03-11 14:38:59 +0100194 "fma", "cx16", "xtpr", "pdcm",
Mao, Junjie434acb82012-07-20 07:08:21 +0000195 NULL, "pcid", "dca", "sse4.1|sse4_1",
Andre Przywarae117f772010-03-11 14:38:59 +0100196 "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
Eduardo Habkosteaf3f092012-03-06 15:11:30 -0300197 "tsc-deadline", "aes", "xsave", "osxsave",
Andre Przywarac8acc382012-11-14 16:28:52 -0200198 "avx", "f16c", "rdrand", "hypervisor",
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100199};
Eduardo Habkost3b671a42012-09-06 10:05:38 +0000200/* Feature names that are already defined on feature_name[] but are set on
201 * CPUID[8000_0001].EDX on AMD CPUs don't have their names on
202 * ext2_feature_name[]. They are copied automatically to cpuid_ext2_features
203 * if and only if CPU vendor is AMD.
204 */
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100205static const char *ext2_feature_name[] = {
Eduardo Habkost3b671a42012-09-06 10:05:38 +0000206 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
207 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
208 NULL /* cx8 */ /* AMD CMPXCHG8B */, NULL /* apic */, NULL, "syscall",
209 NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
210 NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
211 "nx|xd", NULL, "mmxext", NULL /* mmx */,
212 NULL /* fxsr */, "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
Eduardo Habkost01f590d2012-10-24 12:10:33 -0200213 NULL, "lm|i64", "3dnowext", "3dnow",
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100214};
215static const char *ext3_feature_name[] = {
216 "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
217 "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
Andre Przywarae117f772010-03-11 14:38:59 +0100218 "3dnowprefetch", "osvw", "ibs", "xop",
Andre Przywarac8acc382012-11-14 16:28:52 -0200219 "skinit", "wdt", NULL, "lwp",
220 "fma4", "tce", NULL, "nodeid_msr",
221 NULL, "tbm", "topoext", "perfctr_core",
222 "perfctr_nb", NULL, NULL, NULL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100223 NULL, NULL, NULL, NULL,
224};
225
Eduardo Habkost89e49c82013-01-07 16:20:47 -0200226static const char *ext4_feature_name[] = {
227 NULL, NULL, "xstore", "xstore-en",
228 NULL, NULL, "xcrypt", "xcrypt-en",
229 "ace2", "ace2-en", "phe", "phe-en",
230 "pmm", "pmm-en", NULL, NULL,
231 NULL, NULL, NULL, NULL,
232 NULL, NULL, NULL, NULL,
233 NULL, NULL, NULL, NULL,
234 NULL, NULL, NULL, NULL,
235};
236
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100237static const char *kvm_feature_name[] = {
Don Slutzc3d39802012-10-12 15:43:23 -0400238 "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock",
Andrew Jonesf010bc62013-09-18 16:41:45 +0200239 "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", "kvm_pv_unhalt",
Don Slutzc3d39802012-10-12 15:43:23 -0400240 NULL, NULL, NULL, NULL,
241 NULL, NULL, NULL, NULL,
242 NULL, NULL, NULL, NULL,
243 NULL, NULL, NULL, NULL,
Eduardo Habkost8248c362014-07-04 16:44:34 -0300244 "kvmclock-stable-bit", NULL, NULL, NULL,
Don Slutzc3d39802012-10-12 15:43:23 -0400245 NULL, NULL, NULL, NULL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100246};
247
Joerg Roedel296acb62010-09-27 15:16:17 +0200248static const char *svm_feature_name[] = {
249 "npt", "lbrv", "svm_lock", "nrip_save",
250 "tsc_scale", "vmcb_clean", "flushbyasid", "decodeassists",
251 NULL, NULL, "pause_filter", NULL,
252 "pfthreshold", NULL, NULL, NULL,
253 NULL, NULL, NULL, NULL,
254 NULL, NULL, NULL, NULL,
255 NULL, NULL, NULL, NULL,
256 NULL, NULL, NULL, NULL,
257};
258
H. Peter Anvina9321a42012-09-26 13:18:43 -0700259static const char *cpuid_7_0_ebx_feature_name[] = {
Eduardo Habkost7b458bf2014-08-25 17:02:13 -0300260 "fsgsbase", "tsc_adjust", NULL, "bmi1", "hle", "avx2", NULL, "smep",
Eduardo Habkost5bd8ff02014-08-25 17:02:12 -0300261 "bmi2", "erms", "invpcid", "rtm", NULL, NULL, "mpx", NULL,
Xiao Guangrongf7fda282015-10-29 15:31:39 +0800262 "avx512f", NULL, "rdseed", "adx", "smap", NULL, "pcommit", "clflushopt",
263 "clwb", NULL, "avx512pf", "avx512er", "avx512cd", NULL, NULL, NULL,
H. Peter Anvina9321a42012-09-26 13:18:43 -0700264};
265
Huaitong Hanf74eefe2015-11-18 10:20:15 +0800266static const char *cpuid_7_0_ecx_feature_name[] = {
267 NULL, NULL, NULL, "pku",
268 "ospke", NULL, NULL, NULL,
269 NULL, NULL, NULL, NULL,
270 NULL, NULL, NULL, NULL,
271 NULL, NULL, NULL, NULL,
272 NULL, NULL, NULL, NULL,
273 NULL, NULL, NULL, NULL,
274 NULL, NULL, NULL, NULL,
275};
276
Marcelo Tosatti303752a2014-04-30 13:48:45 -0300277static const char *cpuid_apm_edx_feature_name[] = {
278 NULL, NULL, NULL, NULL,
279 NULL, NULL, NULL, NULL,
280 "invtsc", NULL, NULL, NULL,
281 NULL, NULL, NULL, NULL,
282 NULL, NULL, NULL, NULL,
283 NULL, NULL, NULL, NULL,
284 NULL, NULL, NULL, NULL,
285 NULL, NULL, NULL, NULL,
286};
287
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +0100288static const char *cpuid_xsave_feature_name[] = {
289 "xsaveopt", "xsavec", "xgetbv1", "xsaves",
290 NULL, NULL, NULL, NULL,
291 NULL, NULL, NULL, NULL,
292 NULL, NULL, NULL, NULL,
293 NULL, NULL, NULL, NULL,
294 NULL, NULL, NULL, NULL,
295 NULL, NULL, NULL, NULL,
296 NULL, NULL, NULL, NULL,
297};
298
Jan Kiszka28b8e4d2015-06-07 11:15:08 +0200299static const char *cpuid_6_feature_name[] = {
300 NULL, NULL, "arat", NULL,
301 NULL, NULL, NULL, NULL,
302 NULL, NULL, NULL, NULL,
303 NULL, NULL, NULL, NULL,
304 NULL, NULL, NULL, NULL,
305 NULL, NULL, NULL, NULL,
306 NULL, NULL, NULL, NULL,
307 NULL, NULL, NULL, NULL,
308};
309
Eduardo Habkost621626c2014-04-30 13:48:36 -0300310#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
311#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
312 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
313#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
314 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
315 CPUID_PSE36 | CPUID_FXSR)
316#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
317#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
318 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
319 CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
320 CPUID_PAE | CPUID_SEP | CPUID_APIC)
321
322#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
323 CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
324 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
325 CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
Eduardo Habkostb6c5a6f2015-10-07 16:39:43 -0300326 CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS | CPUID_DE)
Eduardo Habkost621626c2014-04-30 13:48:36 -0300327 /* partly implemented:
328 CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64) */
329 /* missing:
330 CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
331#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
332 CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
333 CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
Richard Henderson19dc85d2015-07-02 14:53:40 +0100334 CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */ \
Eduardo Habkost621626c2014-04-30 13:48:36 -0300335 CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
336 /* missing:
337 CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
338 CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
339 CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
Richard Henderson19dc85d2015-07-02 14:53:40 +0100340 CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_AVX,
341 CPUID_EXT_F16C, CPUID_EXT_RDRAND */
Eduardo Habkost621626c2014-04-30 13:48:36 -0300342
343#ifdef TARGET_X86_64
344#define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM)
345#else
346#define TCG_EXT2_X86_64_FEATURES 0
347#endif
348
349#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
350 CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
351 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_PDPE1GB | \
352 TCG_EXT2_X86_64_FEATURES)
353#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
354 CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
355#define TCG_EXT4_FEATURES 0
356#define TCG_SVM_FEATURES 0
357#define TCG_KVM_FEATURES 0
358#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
Xiao Guangrong0c472422015-10-29 15:31:39 +0800359 CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
360 CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT | \
Richard Henderson07929f22015-11-18 12:55:47 +0100361 CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE)
Eduardo Habkost621626c2014-04-30 13:48:36 -0300362 /* missing:
Richard Henderson07929f22015-11-18 12:55:47 +0100363 CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
Eduardo Habkost621626c2014-04-30 13:48:36 -0300364 CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
365 CPUID_7_0_EBX_RDSEED */
Paolo Bonzini0f70ed42016-02-09 14:14:28 +0100366#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE)
Marcelo Tosatti303752a2014-04-30 13:48:45 -0300367#define TCG_APM_FEATURES 0
Jan Kiszka28b8e4d2015-06-07 11:15:08 +0200368#define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
Richard Hendersonc9cfe8f2015-07-02 15:21:23 +0100369#define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1)
370 /* missing:
371 CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
Eduardo Habkost621626c2014-04-30 13:48:36 -0300372
Eduardo Habkost5ef57872013-01-07 16:20:45 -0200373typedef struct FeatureWordInfo {
374 const char **feat_names;
Eduardo Habkost04d104b2013-04-22 16:00:16 -0300375 uint32_t cpuid_eax; /* Input EAX for CPUID */
376 bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
377 uint32_t cpuid_ecx; /* Input ECX value for CPUID */
378 int cpuid_reg; /* output register (R_* constant) */
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300379 uint32_t tcg_features; /* Feature flags supported by TCG */
Eduardo Habkost84f1b922014-04-30 13:48:41 -0300380 uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
Eduardo Habkost5ef57872013-01-07 16:20:45 -0200381} FeatureWordInfo;
382
383static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200384 [FEAT_1_EDX] = {
385 .feat_names = feature_name,
386 .cpuid_eax = 1, .cpuid_reg = R_EDX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300387 .tcg_features = TCG_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200388 },
389 [FEAT_1_ECX] = {
390 .feat_names = ext_feature_name,
391 .cpuid_eax = 1, .cpuid_reg = R_ECX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300392 .tcg_features = TCG_EXT_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200393 },
394 [FEAT_8000_0001_EDX] = {
395 .feat_names = ext2_feature_name,
396 .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300397 .tcg_features = TCG_EXT2_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200398 },
399 [FEAT_8000_0001_ECX] = {
400 .feat_names = ext3_feature_name,
401 .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300402 .tcg_features = TCG_EXT3_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200403 },
Eduardo Habkost89e49c82013-01-07 16:20:47 -0200404 [FEAT_C000_0001_EDX] = {
405 .feat_names = ext4_feature_name,
406 .cpuid_eax = 0xC0000001, .cpuid_reg = R_EDX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300407 .tcg_features = TCG_EXT4_FEATURES,
Eduardo Habkost89e49c82013-01-07 16:20:47 -0200408 },
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200409 [FEAT_KVM] = {
410 .feat_names = kvm_feature_name,
411 .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300412 .tcg_features = TCG_KVM_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200413 },
414 [FEAT_SVM] = {
415 .feat_names = svm_feature_name,
416 .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300417 .tcg_features = TCG_SVM_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200418 },
419 [FEAT_7_0_EBX] = {
420 .feat_names = cpuid_7_0_ebx_feature_name,
Eduardo Habkost04d104b2013-04-22 16:00:16 -0300421 .cpuid_eax = 7,
422 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
423 .cpuid_reg = R_EBX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300424 .tcg_features = TCG_7_0_EBX_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200425 },
Huaitong Hanf74eefe2015-11-18 10:20:15 +0800426 [FEAT_7_0_ECX] = {
427 .feat_names = cpuid_7_0_ecx_feature_name,
428 .cpuid_eax = 7,
429 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
430 .cpuid_reg = R_ECX,
431 .tcg_features = TCG_7_0_ECX_FEATURES,
432 },
Marcelo Tosatti303752a2014-04-30 13:48:45 -0300433 [FEAT_8000_0007_EDX] = {
434 .feat_names = cpuid_apm_edx_feature_name,
435 .cpuid_eax = 0x80000007,
436 .cpuid_reg = R_EDX,
437 .tcg_features = TCG_APM_FEATURES,
438 .unmigratable_flags = CPUID_APM_INVTSC,
439 },
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +0100440 [FEAT_XSAVE] = {
441 .feat_names = cpuid_xsave_feature_name,
442 .cpuid_eax = 0xd,
443 .cpuid_needs_ecx = true, .cpuid_ecx = 1,
444 .cpuid_reg = R_EAX,
Richard Hendersonc9cfe8f2015-07-02 15:21:23 +0100445 .tcg_features = TCG_XSAVE_FEATURES,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +0100446 },
Jan Kiszka28b8e4d2015-06-07 11:15:08 +0200447 [FEAT_6_EAX] = {
448 .feat_names = cpuid_6_feature_name,
449 .cpuid_eax = 6, .cpuid_reg = R_EAX,
450 .tcg_features = TCG_6_EAX_FEATURES,
451 },
Eduardo Habkost5ef57872013-01-07 16:20:45 -0200452};
453
Eduardo Habkost8e8aba52013-05-06 13:20:07 -0300454typedef struct X86RegisterInfo32 {
455 /* Name of register */
456 const char *name;
457 /* QAPI enum value register */
458 X86CPURegister32 qapi_enum;
459} X86RegisterInfo32;
460
461#define REGISTER(reg) \
Wenchao Xia5d371f42014-03-04 18:44:40 -0800462 [R_##reg] = { .name = #reg, .qapi_enum = X86_CPU_REGISTER32_##reg }
Stefan Weila443bc32014-03-16 15:03:41 +0100463static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
Eduardo Habkost8e8aba52013-05-06 13:20:07 -0300464 REGISTER(EAX),
465 REGISTER(ECX),
466 REGISTER(EDX),
467 REGISTER(EBX),
468 REGISTER(ESP),
469 REGISTER(EBP),
470 REGISTER(ESI),
471 REGISTER(EDI),
472};
473#undef REGISTER
474
Richard Hendersonf4f11102015-07-02 15:57:14 +0100475const ExtSaveArea x86_ext_save_areas[] = {
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100476 [XSTATE_YMM_BIT] =
477 { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200478 .offset = offsetof(X86XSaveArea, avx_state),
479 .size = sizeof(XSaveAVX) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100480 [XSTATE_BNDREGS_BIT] =
481 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200482 .offset = offsetof(X86XSaveArea, bndreg_state),
483 .size = sizeof(XSaveBNDREG) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100484 [XSTATE_BNDCSR_BIT] =
485 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200486 .offset = offsetof(X86XSaveArea, bndcsr_state),
487 .size = sizeof(XSaveBNDCSR) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100488 [XSTATE_OPMASK_BIT] =
489 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200490 .offset = offsetof(X86XSaveArea, opmask_state),
491 .size = sizeof(XSaveOpmask) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100492 [XSTATE_ZMM_Hi256_BIT] =
493 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200494 .offset = offsetof(X86XSaveArea, zmm_hi256_state),
495 .size = sizeof(XSaveZMM_Hi256) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100496 [XSTATE_Hi16_ZMM_BIT] =
497 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200498 .offset = offsetof(X86XSaveArea, hi16_zmm_state),
499 .size = sizeof(XSaveHi16_ZMM) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100500 [XSTATE_PKRU_BIT] =
501 { .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200502 .offset = offsetof(X86XSaveArea, pkru_state),
503 .size = sizeof(XSavePKRU) },
Paolo Bonzini2560f192013-10-02 17:54:57 +0200504};
Eduardo Habkost8e8aba52013-05-06 13:20:07 -0300505
Eduardo Habkost8b4bedd2013-01-04 20:01:06 -0200506const char *get_register_name_32(unsigned int reg)
507{
Igor Mammedov31ccdde2013-06-03 18:23:27 +0200508 if (reg >= CPU_NB_REGS32) {
Eduardo Habkost8b4bedd2013-01-04 20:01:06 -0200509 return NULL;
510 }
Eduardo Habkost8e8aba52013-05-06 13:20:07 -0300511 return x86_reg_info_32[reg].name;
Eduardo Habkost8b4bedd2013-01-04 20:01:06 -0200512}
513
Eduardo Habkost84f1b922014-04-30 13:48:41 -0300514/*
515 * Returns the set of feature flags that are supported and migratable by
516 * QEMU, for a given FeatureWord.
517 */
518static uint32_t x86_cpu_get_migratable_flags(FeatureWord w)
519{
520 FeatureWordInfo *wi = &feature_word_info[w];
521 uint32_t r = 0;
522 int i;
523
524 for (i = 0; i < 32; i++) {
525 uint32_t f = 1U << i;
526 /* If the feature name is unknown, it is not supported by QEMU yet */
527 if (!wi->feat_names[i]) {
528 continue;
529 }
530 /* Skip features known to QEMU, but explicitly marked as unmigratable */
531 if (wi->unmigratable_flags & f) {
532 continue;
533 }
534 r |= f;
535 }
536 return r;
537}
538
Jan Kiszkabb44e0d2011-01-21 21:48:07 +0100539void host_cpuid(uint32_t function, uint32_t count,
540 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
Andre Przywarabdde4762010-03-11 14:38:58 +0100541{
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600542 uint32_t vec[4];
543
544#ifdef __x86_64__
545 asm volatile("cpuid"
546 : "=a"(vec[0]), "=b"(vec[1]),
547 "=c"(vec[2]), "=d"(vec[3])
548 : "0"(function), "c"(count) : "cc");
Eduardo Habkostc1f41222014-01-30 17:48:53 -0200549#elif defined(__i386__)
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600550 asm volatile("pusha \n\t"
551 "cpuid \n\t"
552 "mov %%eax, 0(%2) \n\t"
553 "mov %%ebx, 4(%2) \n\t"
554 "mov %%ecx, 8(%2) \n\t"
555 "mov %%edx, 12(%2) \n\t"
556 "popa"
557 : : "a"(function), "c"(count), "S"(vec)
558 : "memory", "cc");
Eduardo Habkostc1f41222014-01-30 17:48:53 -0200559#else
560 abort();
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600561#endif
562
Andre Przywarabdde4762010-03-11 14:38:58 +0100563 if (eax)
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600564 *eax = vec[0];
Andre Przywarabdde4762010-03-11 14:38:58 +0100565 if (ebx)
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600566 *ebx = vec[1];
Andre Przywarabdde4762010-03-11 14:38:58 +0100567 if (ecx)
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600568 *ecx = vec[2];
Andre Przywarabdde4762010-03-11 14:38:58 +0100569 if (edx)
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600570 *edx = vec[3];
Andre Przywarabdde4762010-03-11 14:38:58 +0100571}
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100572
573#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
574
575/* general substring compare of *[s1..e1) and *[s2..e2). sx is start of
576 * a substring. ex if !NULL points to the first char after a substring,
577 * otherwise the string is assumed to sized by a terminating nul.
578 * Return lexical ordering of *s1:*s2.
579 */
Chen Fan8f9d9892014-11-05 16:40:33 +0800580static int sstrcmp(const char *s1, const char *e1,
581 const char *s2, const char *e2)
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100582{
583 for (;;) {
584 if (!*s1 || !*s2 || *s1 != *s2)
585 return (*s1 - *s2);
586 ++s1, ++s2;
587 if (s1 == e1 && s2 == e2)
588 return (0);
589 else if (s1 == e1)
590 return (*s2);
591 else if (s2 == e2)
592 return (*s1);
593 }
594}
595
596/* compare *[s..e) to *altstr. *altstr may be a simple string or multiple
597 * '|' delimited (possibly empty) strings in which case search for a match
598 * within the alternatives proceeds left to right. Return 0 for success,
599 * non-zero otherwise.
600 */
601static int altcmp(const char *s, const char *e, const char *altstr)
602{
603 const char *p, *q;
604
605 for (q = p = altstr; ; ) {
606 while (*p && *p != '|')
607 ++p;
608 if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
609 return (0);
610 if (!*p)
611 return (1);
612 else
613 q = ++p;
614 }
615}
616
617/* search featureset for flag *[s..e), if found set corresponding bit in
Jan Kiszkae41e0fc2011-04-19 13:06:06 +0200618 * *pval and return true, otherwise return false
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100619 */
Jan Kiszkae41e0fc2011-04-19 13:06:06 +0200620static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
621 const char **featureset)
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100622{
623 uint32_t mask;
624 const char **ppc;
Jan Kiszkae41e0fc2011-04-19 13:06:06 +0200625 bool found = false;
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100626
Jan Kiszkae41e0fc2011-04-19 13:06:06 +0200627 for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100628 if (*ppc && !altcmp(s, e, *ppc)) {
629 *pval |= mask;
Jan Kiszkae41e0fc2011-04-19 13:06:06 +0200630 found = true;
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100631 }
Jan Kiszkae41e0fc2011-04-19 13:06:06 +0200632 }
633 return found;
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100634}
635
Eduardo Habkost5ef57872013-01-07 16:20:45 -0200636static void add_flagname_to_bitmaps(const char *flagname,
Eduardo Habkostc00c94a2014-08-21 17:22:56 -0300637 FeatureWordArray words,
638 Error **errp)
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100639{
Eduardo Habkost5ef57872013-01-07 16:20:45 -0200640 FeatureWord w;
641 for (w = 0; w < FEATURE_WORDS; w++) {
642 FeatureWordInfo *wi = &feature_word_info[w];
643 if (wi->feat_names &&
644 lookup_feature(&words[w], flagname, NULL, wi->feat_names)) {
645 break;
646 }
647 }
648 if (w == FEATURE_WORDS) {
Eduardo Habkostc00c94a2014-08-21 17:22:56 -0300649 error_setg(errp, "CPU feature %s not found", flagname);
Eduardo Habkost5ef57872013-01-07 16:20:45 -0200650 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100651}
652
Eduardo Habkostd940ee92014-02-10 08:21:30 -0200653/* CPU class name definitions: */
654
655#define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU
656#define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX)
657
658/* Return type name for a given CPU model name
659 * Caller is responsible for freeing the returned string.
660 */
661static char *x86_cpu_type_name(const char *model_name)
662{
663 return g_strdup_printf(X86_CPU_TYPE_NAME("%s"), model_name);
664}
665
Andreas Färber500050d2014-02-10 22:02:44 +0100666static ObjectClass *x86_cpu_class_by_name(const char *cpu_model)
667{
Eduardo Habkostd940ee92014-02-10 08:21:30 -0200668 ObjectClass *oc;
669 char *typename;
670
Andreas Färber500050d2014-02-10 22:02:44 +0100671 if (cpu_model == NULL) {
672 return NULL;
673 }
674
Eduardo Habkostd940ee92014-02-10 08:21:30 -0200675 typename = x86_cpu_type_name(cpu_model);
676 oc = object_class_by_name(typename);
677 g_free(typename);
678 return oc;
Andreas Färber500050d2014-02-10 22:02:44 +0100679}
680
Eduardo Habkostd940ee92014-02-10 08:21:30 -0200681struct X86CPUDefinition {
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100682 const char *name;
683 uint32_t level;
Eduardo Habkost90e4b0c2013-04-22 16:00:12 -0300684 uint32_t xlevel;
685 uint32_t xlevel2;
Igor Mammedov99b88a12013-01-21 15:06:36 +0100686 /* vendor is zero-terminated, 12 character ASCII string */
687 char vendor[CPUID_VENDOR_SZ + 1];
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100688 int family;
689 int model;
690 int stepping;
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300691 FeatureWordArray features;
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100692 char model_id[48];
Eduardo Habkostd940ee92014-02-10 08:21:30 -0200693};
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100694
Eduardo Habkost9576de72014-01-30 17:48:58 -0200695static X86CPUDefinition builtin_x86_defs[] = {
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100696 {
697 .name = "qemu64",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200698 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100699 .vendor = CPUID_VENDOR_AMD,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100700 .family = 6,
Eduardo Habkostf8e6a112013-09-10 17:48:59 -0300701 .model = 6,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100702 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300703 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300704 PPRO_FEATURES |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100705 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100706 CPUID_PSE36,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300707 .features[FEAT_1_ECX] =
Eduardo Habkost6aa91e42015-11-03 17:24:18 -0200708 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300709 .features[FEAT_8000_0001_EDX] =
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100710 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300711 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost71195672015-11-03 17:24:18 -0200712 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100713 .xlevel = 0x8000000A,
Eduardo Habkost9cf2cc32016-04-09 16:44:20 -0300714 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100715 },
716 {
717 .name = "phenom",
718 .level = 5,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100719 .vendor = CPUID_VENDOR_AMD,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100720 .family = 16,
721 .model = 2,
722 .stepping = 3,
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300723 /* Missing: CPUID_HT */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300724 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300725 PPRO_FEATURES |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100726 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300727 CPUID_PSE36 | CPUID_VME,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300728 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300729 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100730 CPUID_EXT_POPCNT,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300731 .features[FEAT_8000_0001_EDX] =
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100732 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
733 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
Aurelien Jarno8560efe2010-03-13 16:43:15 +0100734 CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100735 /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
736 CPUID_EXT3_CR8LEG,
737 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
738 CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300739 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300740 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100741 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300742 /* Missing: CPUID_SVM_LBRV */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300743 .features[FEAT_SVM] =
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300744 CPUID_SVM_NPT,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100745 .xlevel = 0x8000001A,
746 .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
747 },
748 {
749 .name = "core2duo",
750 .level = 10,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100751 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100752 .family = 6,
753 .model = 15,
754 .stepping = 11,
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300755 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300756 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300757 PPRO_FEATURES |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100758 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300759 CPUID_PSE36 | CPUID_VME | CPUID_ACPI | CPUID_SS,
760 /* Missing: CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_EST,
Eduardo Habkoste93abc12014-10-03 16:39:50 -0300761 * CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_VMX */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300762 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300763 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
Eduardo Habkoste93abc12014-10-03 16:39:50 -0300764 CPUID_EXT_CX16,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300765 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300766 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300767 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300768 CPUID_EXT3_LAHF_LM,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100769 .xlevel = 0x80000008,
770 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
771 },
772 {
773 .name = "kvm64",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200774 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100775 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100776 .family = 15,
777 .model = 6,
778 .stepping = 1,
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -0200779 /* Missing: CPUID_HT */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300780 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -0200781 PPRO_FEATURES | CPUID_VME |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100782 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
783 CPUID_PSE36,
784 /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300785 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300786 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100787 /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300788 .features[FEAT_8000_0001_EDX] =
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100789 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
790 /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
791 CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
792 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
793 CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300794 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300795 0,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100796 .xlevel = 0x80000008,
797 .model_id = "Common KVM processor"
798 },
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100799 {
800 .name = "qemu32",
801 .level = 4,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100802 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100803 .family = 6,
Eduardo Habkostf8e6a112013-09-10 17:48:59 -0300804 .model = 6,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100805 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300806 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300807 PPRO_FEATURES,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300808 .features[FEAT_1_ECX] =
Eduardo Habkost6aa91e42015-11-03 17:24:18 -0200809 CPUID_EXT_SSE3,
Andre Przywara58012d62010-03-11 14:39:06 +0100810 .xlevel = 0x80000004,
Eduardo Habkost9cf2cc32016-04-09 16:44:20 -0300811 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100812 },
813 {
Andre Przywaraeafaf1e2010-05-21 09:50:51 +0200814 .name = "kvm32",
815 .level = 5,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100816 .vendor = CPUID_VENDOR_INTEL,
Andre Przywaraeafaf1e2010-05-21 09:50:51 +0200817 .family = 15,
818 .model = 6,
819 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300820 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -0200821 PPRO_FEATURES | CPUID_VME |
Andre Przywaraeafaf1e2010-05-21 09:50:51 +0200822 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300823 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300824 CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300825 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300826 0,
Andre Przywaraeafaf1e2010-05-21 09:50:51 +0200827 .xlevel = 0x80000008,
828 .model_id = "Common 32-bit KVM processor"
829 },
830 {
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100831 .name = "coreduo",
832 .level = 10,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100833 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100834 .family = 6,
835 .model = 14,
836 .stepping = 8,
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300837 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300838 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300839 PPRO_FEATURES | CPUID_VME |
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300840 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_ACPI |
841 CPUID_SS,
842 /* Missing: CPUID_EXT_EST, CPUID_EXT_TM2 , CPUID_EXT_XTPR,
Eduardo Habkoste93abc12014-10-03 16:39:50 -0300843 * CPUID_EXT_PDCM, CPUID_EXT_VMX */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300844 .features[FEAT_1_ECX] =
Eduardo Habkoste93abc12014-10-03 16:39:50 -0300845 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300846 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300847 CPUID_EXT2_NX,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100848 .xlevel = 0x80000008,
849 .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
850 },
851 {
852 .name = "486",
Andre Przywara58012d62010-03-11 14:39:06 +0100853 .level = 1,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100854 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100855 .family = 4,
Andreas Färberb2a856d2013-05-01 17:30:51 +0200856 .model = 8,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100857 .stepping = 0,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300858 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300859 I486_FEATURES,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100860 .xlevel = 0,
861 },
862 {
863 .name = "pentium",
864 .level = 1,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100865 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100866 .family = 5,
867 .model = 4,
868 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300869 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300870 PENTIUM_FEATURES,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100871 .xlevel = 0,
872 },
873 {
874 .name = "pentium2",
875 .level = 2,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100876 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100877 .family = 6,
878 .model = 5,
879 .stepping = 2,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300880 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300881 PENTIUM2_FEATURES,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100882 .xlevel = 0,
883 },
884 {
885 .name = "pentium3",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200886 .level = 3,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100887 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100888 .family = 6,
889 .model = 7,
890 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300891 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300892 PENTIUM3_FEATURES,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100893 .xlevel = 0,
894 },
895 {
896 .name = "athlon",
897 .level = 2,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100898 .vendor = CPUID_VENDOR_AMD,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100899 .family = 6,
900 .model = 2,
901 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300902 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300903 PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
Eduardo Habkost60032ac2012-09-06 10:05:37 +0000904 CPUID_MCA,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300905 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost60032ac2012-09-06 10:05:37 +0000906 CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100907 .xlevel = 0x80000008,
Eduardo Habkost9cf2cc32016-04-09 16:44:20 -0300908 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100909 },
910 {
911 .name = "n270",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200912 .level = 10,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100913 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100914 .family = 6,
915 .model = 28,
916 .stepping = 2,
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300917 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300918 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300919 PPRO_FEATURES |
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300920 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME |
921 CPUID_ACPI | CPUID_SS,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100922 /* Some CPUs got no CPUID_SEP */
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300923 /* Missing: CPUID_EXT_DSCPL, CPUID_EXT_EST, CPUID_EXT_TM2,
924 * CPUID_EXT_XTPR */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300925 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300926 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
Borislav Petkov4458c232013-04-25 15:43:04 -0300927 CPUID_EXT_MOVBE,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300928 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost60032ac2012-09-06 10:05:37 +0000929 CPUID_EXT2_NX,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300930 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300931 CPUID_EXT3_LAHF_LM,
Radim Krčmář3046bb52015-07-09 21:07:39 +0200932 .xlevel = 0x80000008,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100933 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
934 },
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300935 {
936 .name = "Conroe",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200937 .level = 10,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100938 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300939 .family = 6,
Eduardo Habkostffce9eb2013-05-27 17:23:54 -0300940 .model = 15,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300941 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300942 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -0200943 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -0300944 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
945 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
946 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
947 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300948 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300949 CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300950 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300951 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300952 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300953 CPUID_EXT3_LAHF_LM,
Radim Krčmář3046bb52015-07-09 21:07:39 +0200954 .xlevel = 0x80000008,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300955 .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
956 },
957 {
958 .name = "Penryn",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200959 .level = 10,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100960 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300961 .family = 6,
Eduardo Habkostffce9eb2013-05-27 17:23:54 -0300962 .model = 23,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300963 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300964 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -0200965 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -0300966 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
967 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
968 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
969 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300970 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300971 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -0300972 CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300973 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300974 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300975 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300976 CPUID_EXT3_LAHF_LM,
Radim Krčmář3046bb52015-07-09 21:07:39 +0200977 .xlevel = 0x80000008,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300978 .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
979 },
980 {
981 .name = "Nehalem",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200982 .level = 11,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100983 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300984 .family = 6,
Eduardo Habkostffce9eb2013-05-27 17:23:54 -0300985 .model = 26,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300986 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300987 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -0200988 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -0300989 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
990 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
991 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
992 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300993 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300994 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -0300995 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300996 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300997 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300998 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300999 CPUID_EXT3_LAHF_LM,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001000 .xlevel = 0x80000008,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001001 .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
1002 },
1003 {
1004 .name = "Westmere",
1005 .level = 11,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001006 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001007 .family = 6,
1008 .model = 44,
1009 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001010 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001011 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001012 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1013 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1014 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1015 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001016 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001017 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001018 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1019 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001020 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001021 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001022 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001023 CPUID_EXT3_LAHF_LM,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001024 .features[FEAT_6_EAX] =
1025 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001026 .xlevel = 0x80000008,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001027 .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
1028 },
1029 {
1030 .name = "SandyBridge",
1031 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001032 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001033 .family = 6,
1034 .model = 42,
1035 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001036 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001037 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001038 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1039 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1040 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1041 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001042 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001043 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001044 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1045 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1046 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1047 CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001048 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001049 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001050 CPUID_EXT2_SYSCALL,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001051 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001052 CPUID_EXT3_LAHF_LM,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01001053 .features[FEAT_XSAVE] =
1054 CPUID_XSAVE_XSAVEOPT,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001055 .features[FEAT_6_EAX] =
1056 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001057 .xlevel = 0x80000008,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001058 .model_id = "Intel Xeon E312xx (Sandy Bridge)",
1059 },
1060 {
Paolo Bonzini2f9ac422014-12-05 10:55:23 +01001061 .name = "IvyBridge",
1062 .level = 0xd,
1063 .vendor = CPUID_VENDOR_INTEL,
1064 .family = 6,
1065 .model = 58,
1066 .stepping = 9,
1067 .features[FEAT_1_EDX] =
1068 CPUID_VME | 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_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1075 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1076 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1077 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1078 CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1079 .features[FEAT_7_0_EBX] =
1080 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
1081 CPUID_7_0_EBX_ERMS,
1082 .features[FEAT_8000_0001_EDX] =
1083 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1084 CPUID_EXT2_SYSCALL,
1085 .features[FEAT_8000_0001_ECX] =
1086 CPUID_EXT3_LAHF_LM,
1087 .features[FEAT_XSAVE] =
1088 CPUID_XSAVE_XSAVEOPT,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001089 .features[FEAT_6_EAX] =
1090 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001091 .xlevel = 0x80000008,
Paolo Bonzini2f9ac422014-12-05 10:55:23 +01001092 .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
1093 },
1094 {
Eduardo Habkosta3568502015-03-13 15:58:09 -03001095 .name = "Haswell-noTSX",
1096 .level = 0xd,
1097 .vendor = CPUID_VENDOR_INTEL,
1098 .family = 6,
1099 .model = 60,
1100 .stepping = 1,
1101 .features[FEAT_1_EDX] =
1102 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1103 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1104 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1105 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1106 CPUID_DE | CPUID_FP87,
1107 .features[FEAT_1_ECX] =
1108 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1109 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1110 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1111 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1112 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1113 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1114 .features[FEAT_8000_0001_EDX] =
1115 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1116 CPUID_EXT2_SYSCALL,
1117 .features[FEAT_8000_0001_ECX] =
Paolo Bonzinibecb6662015-09-28 14:00:18 +02001118 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
Eduardo Habkosta3568502015-03-13 15:58:09 -03001119 .features[FEAT_7_0_EBX] =
1120 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1121 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1122 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
1123 .features[FEAT_XSAVE] =
1124 CPUID_XSAVE_XSAVEOPT,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001125 .features[FEAT_6_EAX] =
1126 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001127 .xlevel = 0x80000008,
Eduardo Habkosta3568502015-03-13 15:58:09 -03001128 .model_id = "Intel Core Processor (Haswell, no TSX)",
1129 }, {
Eduardo Habkost37507092012-11-14 16:28:54 -02001130 .name = "Haswell",
1131 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001132 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost37507092012-11-14 16:28:54 -02001133 .family = 6,
1134 .model = 60,
1135 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001136 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001137 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001138 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1139 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1140 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1141 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001142 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001143 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001144 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1145 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1146 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1147 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
Paolo Bonzini78a611f2014-12-05 10:52:46 +01001148 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001149 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001150 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001151 CPUID_EXT2_SYSCALL,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001152 .features[FEAT_8000_0001_ECX] =
Paolo Bonzinibecb6662015-09-28 14:00:18 +02001153 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001154 .features[FEAT_7_0_EBX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001155 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
Eduardo Habkost1ee91592015-03-13 15:39:43 -03001156 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1157 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1158 CPUID_7_0_EBX_RTM,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01001159 .features[FEAT_XSAVE] =
1160 CPUID_XSAVE_XSAVEOPT,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001161 .features[FEAT_6_EAX] =
1162 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001163 .xlevel = 0x80000008,
Eduardo Habkost37507092012-11-14 16:28:54 -02001164 .model_id = "Intel Core Processor (Haswell)",
1165 },
1166 {
Eduardo Habkosta3568502015-03-13 15:58:09 -03001167 .name = "Broadwell-noTSX",
1168 .level = 0xd,
1169 .vendor = CPUID_VENDOR_INTEL,
1170 .family = 6,
1171 .model = 61,
1172 .stepping = 2,
1173 .features[FEAT_1_EDX] =
1174 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1175 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1176 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1177 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1178 CPUID_DE | CPUID_FP87,
1179 .features[FEAT_1_ECX] =
1180 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1181 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1182 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1183 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1184 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1185 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1186 .features[FEAT_8000_0001_EDX] =
1187 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1188 CPUID_EXT2_SYSCALL,
1189 .features[FEAT_8000_0001_ECX] =
Paolo Bonzinibecb6662015-09-28 14:00:18 +02001190 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
Eduardo Habkosta3568502015-03-13 15:58:09 -03001191 .features[FEAT_7_0_EBX] =
1192 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1193 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1194 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1195 CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1196 CPUID_7_0_EBX_SMAP,
1197 .features[FEAT_XSAVE] =
1198 CPUID_XSAVE_XSAVEOPT,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001199 .features[FEAT_6_EAX] =
1200 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001201 .xlevel = 0x80000008,
Eduardo Habkosta3568502015-03-13 15:58:09 -03001202 .model_id = "Intel Core Processor (Broadwell, no TSX)",
1203 },
1204 {
Eduardo Habkostece01352014-06-17 17:11:40 -03001205 .name = "Broadwell",
1206 .level = 0xd,
1207 .vendor = CPUID_VENDOR_INTEL,
1208 .family = 6,
1209 .model = 61,
1210 .stepping = 2,
1211 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001212 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostece01352014-06-17 17:11:40 -03001213 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1214 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1215 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1216 CPUID_DE | CPUID_FP87,
1217 .features[FEAT_1_ECX] =
1218 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1219 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1220 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1221 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1222 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
Paolo Bonzini78a611f2014-12-05 10:52:46 +01001223 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
Eduardo Habkostece01352014-06-17 17:11:40 -03001224 .features[FEAT_8000_0001_EDX] =
1225 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1226 CPUID_EXT2_SYSCALL,
1227 .features[FEAT_8000_0001_ECX] =
Paolo Bonzinibecb6662015-09-28 14:00:18 +02001228 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
Eduardo Habkostece01352014-06-17 17:11:40 -03001229 .features[FEAT_7_0_EBX] =
1230 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
Eduardo Habkost1ee91592015-03-13 15:39:43 -03001231 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
Eduardo Habkostece01352014-06-17 17:11:40 -03001232 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
Eduardo Habkost1ee91592015-03-13 15:39:43 -03001233 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
Eduardo Habkostece01352014-06-17 17:11:40 -03001234 CPUID_7_0_EBX_SMAP,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01001235 .features[FEAT_XSAVE] =
1236 CPUID_XSAVE_XSAVEOPT,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001237 .features[FEAT_6_EAX] =
1238 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001239 .xlevel = 0x80000008,
Eduardo Habkostece01352014-06-17 17:11:40 -03001240 .model_id = "Intel Core Processor (Broadwell)",
1241 },
1242 {
Eduardo Habkostf6f949e2016-04-27 16:13:06 +08001243 .name = "Skylake-Client",
1244 .level = 0xd,
1245 .vendor = CPUID_VENDOR_INTEL,
1246 .family = 6,
1247 .model = 94,
1248 .stepping = 3,
1249 .features[FEAT_1_EDX] =
1250 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1251 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1252 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1253 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1254 CPUID_DE | CPUID_FP87,
1255 .features[FEAT_1_ECX] =
1256 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1257 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1258 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1259 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1260 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1261 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1262 .features[FEAT_8000_0001_EDX] =
1263 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1264 CPUID_EXT2_SYSCALL,
1265 .features[FEAT_8000_0001_ECX] =
1266 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
1267 .features[FEAT_7_0_EBX] =
1268 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1269 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1270 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1271 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1272 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
1273 /* Missing: XSAVES (not supported by some Linux versions,
1274 * including v4.1 to v4.6).
1275 * KVM doesn't yet expose any XSAVES state save component,
1276 * and the only one defined in Skylake (processor tracing)
1277 * probably will block migration anyway.
1278 */
1279 .features[FEAT_XSAVE] =
1280 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
1281 CPUID_XSAVE_XGETBV1,
1282 .features[FEAT_6_EAX] =
1283 CPUID_6_EAX_ARAT,
1284 .xlevel = 0x80000008,
1285 .model_id = "Intel Core Processor (Skylake)",
1286 },
1287 {
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001288 .name = "Opteron_G1",
1289 .level = 5,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001290 .vendor = CPUID_VENDOR_AMD,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001291 .family = 15,
1292 .model = 6,
1293 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001294 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001295 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001296 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1297 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1298 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1299 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001300 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001301 CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001302 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001303 CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001304 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1305 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1306 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1307 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1308 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001309 .xlevel = 0x80000008,
1310 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
1311 },
1312 {
1313 .name = "Opteron_G2",
1314 .level = 5,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001315 .vendor = CPUID_VENDOR_AMD,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001316 .family = 15,
1317 .model = 6,
1318 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001319 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001320 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001321 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1322 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1323 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1324 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001325 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001326 CPUID_EXT_CX16 | CPUID_EXT_SSE3,
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001327 /* Missing: CPUID_EXT2_RDTSCP */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001328 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001329 CPUID_EXT2_LM | CPUID_EXT2_FXSR |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001330 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1331 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1332 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1333 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1334 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1335 CPUID_EXT2_DE | CPUID_EXT2_FPU,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001336 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001337 CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001338 .xlevel = 0x80000008,
1339 .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
1340 },
1341 {
1342 .name = "Opteron_G3",
1343 .level = 5,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001344 .vendor = CPUID_VENDOR_AMD,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001345 .family = 15,
1346 .model = 6,
1347 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001348 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001349 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001350 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1351 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1352 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1353 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001354 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001355 CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001356 CPUID_EXT_SSE3,
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001357 /* Missing: CPUID_EXT2_RDTSCP */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001358 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001359 CPUID_EXT2_LM | CPUID_EXT2_FXSR |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001360 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1361 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1362 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1363 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1364 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1365 CPUID_EXT2_DE | CPUID_EXT2_FPU,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001366 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001367 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001368 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001369 .xlevel = 0x80000008,
1370 .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
1371 },
1372 {
1373 .name = "Opteron_G4",
1374 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001375 .vendor = CPUID_VENDOR_AMD,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001376 .family = 21,
1377 .model = 1,
1378 .stepping = 2,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001379 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001380 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001381 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1382 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1383 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1384 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001385 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001386 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001387 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1388 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1389 CPUID_EXT_SSE3,
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001390 /* Missing: CPUID_EXT2_RDTSCP */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001391 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001392 CPUID_EXT2_LM |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001393 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1394 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1395 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1396 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1397 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1398 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001399 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001400 CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001401 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1402 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1403 CPUID_EXT3_LAHF_LM,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01001404 /* no xsaveopt! */
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001405 .xlevel = 0x8000001A,
1406 .model_id = "AMD Opteron 62xx class CPU",
1407 },
Andre Przywara021941b2012-11-14 16:28:53 -02001408 {
1409 .name = "Opteron_G5",
1410 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001411 .vendor = CPUID_VENDOR_AMD,
Andre Przywara021941b2012-11-14 16:28:53 -02001412 .family = 21,
1413 .model = 2,
1414 .stepping = 0,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001415 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001416 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001417 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1418 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1419 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1420 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001421 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001422 CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001423 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1424 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
1425 CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001426 /* Missing: CPUID_EXT2_RDTSCP */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001427 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001428 CPUID_EXT2_LM |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001429 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1430 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1431 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1432 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1433 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1434 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001435 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001436 CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001437 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1438 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1439 CPUID_EXT3_LAHF_LM,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01001440 /* no xsaveopt! */
Andre Przywara021941b2012-11-14 16:28:53 -02001441 .xlevel = 0x8000001A,
1442 .model_id = "AMD Opteron 63xx class CPU",
1443 },
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001444};
1445
Eduardo Habkost5114e842015-09-11 12:40:27 -03001446typedef struct PropValue {
1447 const char *prop, *value;
1448} PropValue;
1449
1450/* KVM-specific features that are automatically added/removed
1451 * from all CPU models when KVM is enabled.
1452 */
1453static PropValue kvm_default_props[] = {
1454 { "kvmclock", "on" },
1455 { "kvm-nopiodelay", "on" },
1456 { "kvm-asyncpf", "on" },
1457 { "kvm-steal-time", "on" },
1458 { "kvm-pv-eoi", "on" },
1459 { "kvmclock-stable-bit", "on" },
1460 { "x2apic", "on" },
1461 { "acpi", "off" },
1462 { "monitor", "off" },
1463 { "svm", "off" },
1464 { NULL, NULL },
1465};
1466
1467void x86_cpu_change_kvm_default(const char *prop, const char *value)
1468{
1469 PropValue *pv;
1470 for (pv = kvm_default_props; pv->prop; pv++) {
1471 if (!strcmp(pv->prop, prop)) {
1472 pv->value = value;
1473 break;
1474 }
1475 }
1476
1477 /* It is valid to call this function only for properties that
1478 * are already present in the kvm_default_props table.
1479 */
1480 assert(pv->prop);
1481}
1482
Eduardo Habkost4d1b2792014-08-20 17:30:12 -03001483static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
1484 bool migratable_only);
1485
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001486#ifdef CONFIG_KVM
1487
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001488static int cpu_x86_fill_model_id(char *str)
1489{
1490 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1491 int i;
1492
1493 for (i = 0; i < 3; i++) {
1494 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
1495 memcpy(str + i * 16 + 0, &eax, 4);
1496 memcpy(str + i * 16 + 4, &ebx, 4);
1497 memcpy(str + i * 16 + 8, &ecx, 4);
1498 memcpy(str + i * 16 + 12, &edx, 4);
1499 }
1500 return 0;
1501}
1502
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001503static X86CPUDefinition host_cpudef;
1504
Eduardo Habkost84f1b922014-04-30 13:48:41 -03001505static Property host_x86_cpu_properties[] = {
Eduardo Habkost120eee72014-06-17 17:31:53 -03001506 DEFINE_PROP_BOOL("migratable", X86CPU, migratable, true),
Eduardo Habkoste265e3e2015-09-02 11:19:11 -03001507 DEFINE_PROP_BOOL("host-cache-info", X86CPU, cache_info_passthrough, false),
Eduardo Habkost84f1b922014-04-30 13:48:41 -03001508 DEFINE_PROP_END_OF_LIST()
1509};
1510
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001511/* class_init for the "host" CPU model
Eduardo Habkost6e746f32012-10-24 19:44:06 -02001512 *
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001513 * This function may be called before KVM is initialized.
Eduardo Habkost6e746f32012-10-24 19:44:06 -02001514 */
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001515static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001516{
Eduardo Habkost84f1b922014-04-30 13:48:41 -03001517 DeviceClass *dc = DEVICE_CLASS(oc);
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001518 X86CPUClass *xcc = X86_CPU_CLASS(oc);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001519 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001520
1521 xcc->kvm_required = true;
1522
1523 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
1524 x86_cpu_vendor_words2str(host_cpudef.vendor, ebx, edx, ecx);
1525
1526 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
1527 host_cpudef.family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1528 host_cpudef.model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1529 host_cpudef.stepping = eax & 0x0F;
1530
1531 cpu_x86_fill_model_id(host_cpudef.model_id);
1532
1533 xcc->cpu_def = &host_cpudef;
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001534
1535 /* level, xlevel, xlevel2, and the feature words are initialized on
1536 * instance_init, because they require KVM to be initialized.
1537 */
Eduardo Habkost84f1b922014-04-30 13:48:41 -03001538
1539 dc->props = host_x86_cpu_properties;
Markus Armbruster4c315c22015-10-01 10:59:58 +02001540 /* Reason: host_x86_cpu_initfn() dies when !kvm_enabled() */
1541 dc->cannot_destroy_with_object_finalize_yet = true;
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001542}
1543
1544static void host_x86_cpu_initfn(Object *obj)
1545{
1546 X86CPU *cpu = X86_CPU(obj);
1547 CPUX86State *env = &cpu->env;
1548 KVMState *s = kvm_state;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001549
Eduardo Habkost6e746f32012-10-24 19:44:06 -02001550 assert(kvm_enabled());
1551
Eduardo Habkost4d1b2792014-08-20 17:30:12 -03001552 /* We can't fill the features array here because we don't know yet if
1553 * "migratable" is true or false.
1554 */
1555 cpu->host_features = true;
1556
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001557 env->cpuid_level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
1558 env->cpuid_xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
1559 env->cpuid_xlevel2 = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
Eduardo Habkost2a573252014-01-20 14:41:12 -02001560
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001561 object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001562}
1563
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001564static const TypeInfo host_x86_cpu_type_info = {
1565 .name = X86_CPU_TYPE_NAME("host"),
1566 .parent = TYPE_X86_CPU,
1567 .instance_init = host_x86_cpu_initfn,
1568 .class_init = host_x86_cpu_class_init,
1569};
1570
1571#endif
1572
Eduardo Habkost8459e392014-04-30 13:48:31 -03001573static void report_unavailable_features(FeatureWord w, uint32_t mask)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001574{
Eduardo Habkost8459e392014-04-30 13:48:31 -03001575 FeatureWordInfo *f = &feature_word_info[w];
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001576 int i;
1577
Eduardo Habkost857aee32014-04-30 13:48:29 -03001578 for (i = 0; i < 32; ++i) {
Eduardo Habkost72370dc2015-09-29 17:34:22 -03001579 if ((1UL << i) & mask) {
Eduardo Habkostbffd67b2013-01-07 16:20:46 -02001580 const char *reg = get_register_name_32(f->cpuid_reg);
Eduardo Habkost8b4bedd2013-01-04 20:01:06 -02001581 assert(reg);
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03001582 fprintf(stderr, "warning: %s doesn't support requested feature: "
Eduardo Habkost8b4bedd2013-01-04 20:01:06 -02001583 "CPUID.%02XH:%s%s%s [bit %d]\n",
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03001584 kvm_enabled() ? "host" : "TCG",
Eduardo Habkostbffd67b2013-01-07 16:20:46 -02001585 f->cpuid_eax, reg,
1586 f->feat_names[i] ? "." : "",
1587 f->feat_names[i] ? f->feat_names[i] : "", i);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001588 }
Eduardo Habkost857aee32014-04-30 13:48:29 -03001589 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001590}
1591
Eric Blaked7bce992016-01-29 06:48:55 -07001592static void x86_cpuid_version_get_family(Object *obj, Visitor *v,
1593 const char *name, void *opaque,
1594 Error **errp)
Andreas Färber95b85192012-04-17 14:42:22 +02001595{
1596 X86CPU *cpu = X86_CPU(obj);
1597 CPUX86State *env = &cpu->env;
1598 int64_t value;
1599
1600 value = (env->cpuid_version >> 8) & 0xf;
1601 if (value == 0xf) {
1602 value += (env->cpuid_version >> 20) & 0xff;
1603 }
Eric Blake51e72bc2016-01-29 06:48:54 -07001604 visit_type_int(v, name, &value, errp);
Andreas Färber95b85192012-04-17 14:42:22 +02001605}
1606
Eric Blaked7bce992016-01-29 06:48:55 -07001607static void x86_cpuid_version_set_family(Object *obj, Visitor *v,
1608 const char *name, void *opaque,
1609 Error **errp)
Andreas Färbered5e1ec2012-02-17 17:46:01 +01001610{
Andreas Färber71ad61d2012-04-17 12:10:29 +02001611 X86CPU *cpu = X86_CPU(obj);
1612 CPUX86State *env = &cpu->env;
1613 const int64_t min = 0;
1614 const int64_t max = 0xff + 0xf;
Markus Armbruster65cd9062014-04-25 12:44:22 +02001615 Error *local_err = NULL;
Andreas Färber71ad61d2012-04-17 12:10:29 +02001616 int64_t value;
1617
Eric Blake51e72bc2016-01-29 06:48:54 -07001618 visit_type_int(v, name, &value, &local_err);
Markus Armbruster65cd9062014-04-25 12:44:22 +02001619 if (local_err) {
1620 error_propagate(errp, local_err);
Andreas Färber71ad61d2012-04-17 12:10:29 +02001621 return;
1622 }
1623 if (value < min || value > max) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001624 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1625 name ? name : "null", value, min, max);
Andreas Färber71ad61d2012-04-17 12:10:29 +02001626 return;
1627 }
1628
Andreas Färbered5e1ec2012-02-17 17:46:01 +01001629 env->cpuid_version &= ~0xff00f00;
Andreas Färber71ad61d2012-04-17 12:10:29 +02001630 if (value > 0x0f) {
1631 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
Andreas Färbered5e1ec2012-02-17 17:46:01 +01001632 } else {
Andreas Färber71ad61d2012-04-17 12:10:29 +02001633 env->cpuid_version |= value << 8;
Andreas Färbered5e1ec2012-02-17 17:46:01 +01001634 }
1635}
1636
Eric Blaked7bce992016-01-29 06:48:55 -07001637static void x86_cpuid_version_get_model(Object *obj, Visitor *v,
1638 const char *name, void *opaque,
1639 Error **errp)
Andreas Färber67e30c82012-04-17 14:48:14 +02001640{
1641 X86CPU *cpu = X86_CPU(obj);
1642 CPUX86State *env = &cpu->env;
1643 int64_t value;
1644
1645 value = (env->cpuid_version >> 4) & 0xf;
1646 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
Eric Blake51e72bc2016-01-29 06:48:54 -07001647 visit_type_int(v, name, &value, errp);
Andreas Färber67e30c82012-04-17 14:48:14 +02001648}
1649
Eric Blaked7bce992016-01-29 06:48:55 -07001650static void x86_cpuid_version_set_model(Object *obj, Visitor *v,
1651 const char *name, void *opaque,
1652 Error **errp)
Andreas Färberb0704cb2012-02-17 17:46:02 +01001653{
Andreas Färberc5291a42012-04-17 12:16:39 +02001654 X86CPU *cpu = X86_CPU(obj);
1655 CPUX86State *env = &cpu->env;
1656 const int64_t min = 0;
1657 const int64_t max = 0xff;
Markus Armbruster65cd9062014-04-25 12:44:22 +02001658 Error *local_err = NULL;
Andreas Färberc5291a42012-04-17 12:16:39 +02001659 int64_t value;
1660
Eric Blake51e72bc2016-01-29 06:48:54 -07001661 visit_type_int(v, name, &value, &local_err);
Markus Armbruster65cd9062014-04-25 12:44:22 +02001662 if (local_err) {
1663 error_propagate(errp, local_err);
Andreas Färberc5291a42012-04-17 12:16:39 +02001664 return;
1665 }
1666 if (value < min || value > max) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001667 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1668 name ? name : "null", value, min, max);
Andreas Färberc5291a42012-04-17 12:16:39 +02001669 return;
1670 }
1671
Andreas Färberb0704cb2012-02-17 17:46:02 +01001672 env->cpuid_version &= ~0xf00f0;
Andreas Färberc5291a42012-04-17 12:16:39 +02001673 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
Andreas Färberb0704cb2012-02-17 17:46:02 +01001674}
1675
Andreas Färber35112e42012-04-17 14:50:53 +02001676static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
Eric Blaked7bce992016-01-29 06:48:55 -07001677 const char *name, void *opaque,
Andreas Färber35112e42012-04-17 14:50:53 +02001678 Error **errp)
1679{
1680 X86CPU *cpu = X86_CPU(obj);
1681 CPUX86State *env = &cpu->env;
1682 int64_t value;
1683
1684 value = env->cpuid_version & 0xf;
Eric Blake51e72bc2016-01-29 06:48:54 -07001685 visit_type_int(v, name, &value, errp);
Andreas Färber35112e42012-04-17 14:50:53 +02001686}
1687
Andreas Färber036e2222012-04-17 14:14:18 +02001688static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
Eric Blaked7bce992016-01-29 06:48:55 -07001689 const char *name, void *opaque,
Andreas Färber036e2222012-04-17 14:14:18 +02001690 Error **errp)
Andreas Färber38c3dc42012-02-17 17:46:03 +01001691{
Andreas Färber036e2222012-04-17 14:14:18 +02001692 X86CPU *cpu = X86_CPU(obj);
1693 CPUX86State *env = &cpu->env;
1694 const int64_t min = 0;
1695 const int64_t max = 0xf;
Markus Armbruster65cd9062014-04-25 12:44:22 +02001696 Error *local_err = NULL;
Andreas Färber036e2222012-04-17 14:14:18 +02001697 int64_t value;
1698
Eric Blake51e72bc2016-01-29 06:48:54 -07001699 visit_type_int(v, name, &value, &local_err);
Markus Armbruster65cd9062014-04-25 12:44:22 +02001700 if (local_err) {
1701 error_propagate(errp, local_err);
Andreas Färber036e2222012-04-17 14:14:18 +02001702 return;
1703 }
1704 if (value < min || value > max) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001705 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1706 name ? name : "null", value, min, max);
Andreas Färber036e2222012-04-17 14:14:18 +02001707 return;
1708 }
1709
Andreas Färber38c3dc42012-02-17 17:46:03 +01001710 env->cpuid_version &= ~0xf;
Andreas Färber036e2222012-04-17 14:14:18 +02001711 env->cpuid_version |= value & 0xf;
Andreas Färber38c3dc42012-02-17 17:46:03 +01001712}
1713
Andreas Färberd480e1a2012-04-17 19:22:58 +02001714static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1715{
1716 X86CPU *cpu = X86_CPU(obj);
1717 CPUX86State *env = &cpu->env;
1718 char *value;
Andreas Färberd480e1a2012-04-17 19:22:58 +02001719
Markus Armbrustere42a92a2014-12-04 14:46:46 +01001720 value = g_malloc(CPUID_VENDOR_SZ + 1);
Igor Mammedov99b88a12013-01-21 15:06:36 +01001721 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
1722 env->cpuid_vendor3);
Andreas Färberd480e1a2012-04-17 19:22:58 +02001723 return value;
1724}
1725
1726static void x86_cpuid_set_vendor(Object *obj, const char *value,
1727 Error **errp)
1728{
1729 X86CPU *cpu = X86_CPU(obj);
1730 CPUX86State *env = &cpu->env;
1731 int i;
1732
Igor Mammedov9df694e2012-10-22 17:03:10 +02001733 if (strlen(value) != CPUID_VENDOR_SZ) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001734 error_setg(errp, QERR_PROPERTY_VALUE_BAD, "", "vendor", value);
Andreas Färberd480e1a2012-04-17 19:22:58 +02001735 return;
1736 }
1737
1738 env->cpuid_vendor1 = 0;
1739 env->cpuid_vendor2 = 0;
1740 env->cpuid_vendor3 = 0;
1741 for (i = 0; i < 4; i++) {
1742 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1743 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1744 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1745 }
Andreas Färberd480e1a2012-04-17 19:22:58 +02001746}
1747
Andreas Färber63e886e2012-04-17 23:02:26 +02001748static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1749{
1750 X86CPU *cpu = X86_CPU(obj);
1751 CPUX86State *env = &cpu->env;
1752 char *value;
1753 int i;
1754
1755 value = g_malloc(48 + 1);
1756 for (i = 0; i < 48; i++) {
1757 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1758 }
1759 value[48] = '\0';
1760 return value;
1761}
1762
Andreas Färber938d4c22012-04-17 15:17:27 +02001763static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1764 Error **errp)
Andreas Färberdcce6672012-02-17 17:46:04 +01001765{
Andreas Färber938d4c22012-04-17 15:17:27 +02001766 X86CPU *cpu = X86_CPU(obj);
1767 CPUX86State *env = &cpu->env;
Andreas Färberdcce6672012-02-17 17:46:04 +01001768 int c, len, i;
1769
1770 if (model_id == NULL) {
1771 model_id = "";
1772 }
1773 len = strlen(model_id);
Andreas Färberd0a6acf2012-04-17 18:21:52 +02001774 memset(env->cpuid_model, 0, 48);
Andreas Färberdcce6672012-02-17 17:46:04 +01001775 for (i = 0; i < 48; i++) {
1776 if (i >= len) {
1777 c = '\0';
1778 } else {
1779 c = (uint8_t)model_id[i];
1780 }
1781 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1782 }
1783}
1784
Eric Blaked7bce992016-01-29 06:48:55 -07001785static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, const char *name,
1786 void *opaque, Error **errp)
Andreas Färber89e48962012-04-18 00:12:23 +02001787{
1788 X86CPU *cpu = X86_CPU(obj);
1789 int64_t value;
1790
1791 value = cpu->env.tsc_khz * 1000;
Eric Blake51e72bc2016-01-29 06:48:54 -07001792 visit_type_int(v, name, &value, errp);
Andreas Färber89e48962012-04-18 00:12:23 +02001793}
1794
Eric Blaked7bce992016-01-29 06:48:55 -07001795static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
1796 void *opaque, Error **errp)
Andreas Färber89e48962012-04-18 00:12:23 +02001797{
1798 X86CPU *cpu = X86_CPU(obj);
1799 const int64_t min = 0;
Don Slutz2e848492012-09-21 20:13:13 -04001800 const int64_t max = INT64_MAX;
Markus Armbruster65cd9062014-04-25 12:44:22 +02001801 Error *local_err = NULL;
Andreas Färber89e48962012-04-18 00:12:23 +02001802 int64_t value;
1803
Eric Blake51e72bc2016-01-29 06:48:54 -07001804 visit_type_int(v, name, &value, &local_err);
Markus Armbruster65cd9062014-04-25 12:44:22 +02001805 if (local_err) {
1806 error_propagate(errp, local_err);
Andreas Färber89e48962012-04-18 00:12:23 +02001807 return;
1808 }
1809 if (value < min || value > max) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001810 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1811 name ? name : "null", value, min, max);
Andreas Färber89e48962012-04-18 00:12:23 +02001812 return;
1813 }
1814
Haozhong Zhang36f96c42015-11-24 11:33:57 +08001815 cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
Andreas Färber89e48962012-04-18 00:12:23 +02001816}
1817
Eric Blaked7bce992016-01-29 06:48:55 -07001818static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, const char *name,
1819 void *opaque, Error **errp)
Igor Mammedov31050932013-04-25 16:05:26 +02001820{
1821 X86CPU *cpu = X86_CPU(obj);
Eduardo Habkost7e72a452014-12-18 23:20:10 -02001822 int64_t value = cpu->apic_id;
Igor Mammedov31050932013-04-25 16:05:26 +02001823
Eric Blake51e72bc2016-01-29 06:48:54 -07001824 visit_type_int(v, name, &value, errp);
Igor Mammedov31050932013-04-25 16:05:26 +02001825}
1826
Eric Blaked7bce992016-01-29 06:48:55 -07001827static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, const char *name,
1828 void *opaque, Error **errp)
Igor Mammedov31050932013-04-25 16:05:26 +02001829{
1830 X86CPU *cpu = X86_CPU(obj);
Igor Mammedov8d6d4982013-04-26 19:51:52 +02001831 DeviceState *dev = DEVICE(obj);
Igor Mammedov31050932013-04-25 16:05:26 +02001832 const int64_t min = 0;
1833 const int64_t max = UINT32_MAX;
1834 Error *error = NULL;
1835 int64_t value;
1836
Igor Mammedov8d6d4982013-04-26 19:51:52 +02001837 if (dev->realized) {
1838 error_setg(errp, "Attempt to set property '%s' on '%s' after "
1839 "it was realized", name, object_get_typename(obj));
1840 return;
1841 }
1842
Eric Blake51e72bc2016-01-29 06:48:54 -07001843 visit_type_int(v, name, &value, &error);
Igor Mammedov31050932013-04-25 16:05:26 +02001844 if (error) {
1845 error_propagate(errp, error);
1846 return;
1847 }
1848 if (value < min || value > max) {
1849 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1850 " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
1851 object_get_typename(obj), name, value, min, max);
1852 return;
1853 }
1854
Eduardo Habkost7e72a452014-12-18 23:20:10 -02001855 if ((value != cpu->apic_id) && cpu_exists(value)) {
Igor Mammedov31050932013-04-25 16:05:26 +02001856 error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
1857 return;
1858 }
Eduardo Habkost7e72a452014-12-18 23:20:10 -02001859 cpu->apic_id = value;
Igor Mammedov31050932013-04-25 16:05:26 +02001860}
1861
Eduardo Habkost7e5292b2013-05-06 13:20:09 -03001862/* Generic getter for "feature-words" and "filtered-features" properties */
Eric Blaked7bce992016-01-29 06:48:55 -07001863static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
1864 const char *name, void *opaque,
1865 Error **errp)
Eduardo Habkost8e8aba52013-05-06 13:20:07 -03001866{
Eduardo Habkost7e5292b2013-05-06 13:20:09 -03001867 uint32_t *array = (uint32_t *)opaque;
Eduardo Habkost8e8aba52013-05-06 13:20:07 -03001868 FeatureWord w;
1869 Error *err = NULL;
1870 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
1871 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
1872 X86CPUFeatureWordInfoList *list = NULL;
1873
1874 for (w = 0; w < FEATURE_WORDS; w++) {
1875 FeatureWordInfo *wi = &feature_word_info[w];
1876 X86CPUFeatureWordInfo *qwi = &word_infos[w];
1877 qwi->cpuid_input_eax = wi->cpuid_eax;
1878 qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
1879 qwi->cpuid_input_ecx = wi->cpuid_ecx;
1880 qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
Eduardo Habkost7e5292b2013-05-06 13:20:09 -03001881 qwi->features = array[w];
Eduardo Habkost8e8aba52013-05-06 13:20:07 -03001882
1883 /* List will be in reverse order, but order shouldn't matter */
1884 list_entries[w].next = list;
1885 list_entries[w].value = &word_infos[w];
1886 list = &list_entries[w];
1887 }
1888
Eric Blake51e72bc2016-01-29 06:48:54 -07001889 visit_type_X86CPUFeatureWordInfoList(v, "feature-words", &list, &err);
Eduardo Habkost8e8aba52013-05-06 13:20:07 -03001890 error_propagate(errp, err);
1891}
1892
Eric Blaked7bce992016-01-29 06:48:55 -07001893static void x86_get_hv_spinlocks(Object *obj, Visitor *v, const char *name,
1894 void *opaque, Error **errp)
Igor Mammedovc8f0f882013-06-04 15:05:25 +02001895{
1896 X86CPU *cpu = X86_CPU(obj);
1897 int64_t value = cpu->hyperv_spinlock_attempts;
1898
Eric Blake51e72bc2016-01-29 06:48:54 -07001899 visit_type_int(v, name, &value, errp);
Igor Mammedovc8f0f882013-06-04 15:05:25 +02001900}
1901
Eric Blaked7bce992016-01-29 06:48:55 -07001902static void x86_set_hv_spinlocks(Object *obj, Visitor *v, const char *name,
1903 void *opaque, Error **errp)
Igor Mammedovc8f0f882013-06-04 15:05:25 +02001904{
1905 const int64_t min = 0xFFF;
1906 const int64_t max = UINT_MAX;
1907 X86CPU *cpu = X86_CPU(obj);
1908 Error *err = NULL;
1909 int64_t value;
1910
Eric Blake51e72bc2016-01-29 06:48:54 -07001911 visit_type_int(v, name, &value, &err);
Igor Mammedovc8f0f882013-06-04 15:05:25 +02001912 if (err) {
1913 error_propagate(errp, err);
1914 return;
1915 }
1916
1917 if (value < min || value > max) {
1918 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
chenfan5bb4c352014-07-28 15:13:06 +08001919 " (minimum: %" PRId64 ", maximum: %" PRId64 ")",
1920 object_get_typename(obj), name ? name : "null",
1921 value, min, max);
Igor Mammedovc8f0f882013-06-04 15:05:25 +02001922 return;
1923 }
1924 cpu->hyperv_spinlock_attempts = value;
1925}
1926
1927static PropertyInfo qdev_prop_spinlocks = {
1928 .name = "int",
1929 .get = x86_get_hv_spinlocks,
1930 .set = x86_set_hv_spinlocks,
1931};
1932
Igor Mammedov72ac2e82013-04-26 18:04:32 +02001933/* Convert all '_' in a feature string option name to '-', to make feature
1934 * name conform to QOM property naming rule, which uses '-' instead of '_'.
1935 */
1936static inline void feat2prop(char *s)
1937{
1938 while ((s = strchr(s, '_'))) {
1939 *s = '-';
1940 }
1941}
1942
Eduardo Habkost8f961352012-12-04 17:34:39 -02001943/* Parse "+feature,-feature,feature=foo" CPU feature string
1944 */
Andreas Färber94a444b2014-03-03 23:19:19 +01001945static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
1946 Error **errp)
Eduardo Habkost8f961352012-12-04 17:34:39 -02001947{
Andreas Färber94a444b2014-03-03 23:19:19 +01001948 X86CPU *cpu = X86_CPU(cs);
Eduardo Habkost8f961352012-12-04 17:34:39 -02001949 char *featurestr; /* Single 'key=value" string being parsed */
Eduardo Habkoste1c224b2014-04-30 13:48:37 -03001950 FeatureWord w;
Eduardo Habkost9f3fb562012-12-04 17:34:38 -02001951 /* Features to be added */
Igor Mammedov077c68c2013-01-11 03:10:15 +01001952 FeatureWordArray plus_features = { 0 };
Joerg Roedel296acb62010-09-27 15:16:17 +02001953 /* Features to be removed */
Eduardo Habkost5ef57872013-01-07 16:20:45 -02001954 FeatureWordArray minus_features = { 0 };
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001955 uint32_t numvalue;
Igor Mammedova91987c2013-01-21 15:06:38 +01001956 CPUX86State *env = &cpu->env;
Andreas Färber94a444b2014-03-03 23:19:19 +01001957 Error *local_err = NULL;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001958
Eduardo Habkost8f961352012-12-04 17:34:39 -02001959 featurestr = features ? strtok(features, ",") : NULL;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001960
1961 while (featurestr) {
1962 char *val;
1963 if (featurestr[0] == '+') {
Eduardo Habkostc00c94a2014-08-21 17:22:56 -03001964 add_flagname_to_bitmaps(featurestr + 1, plus_features, &local_err);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001965 } else if (featurestr[0] == '-') {
Eduardo Habkostc00c94a2014-08-21 17:22:56 -03001966 add_flagname_to_bitmaps(featurestr + 1, minus_features, &local_err);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001967 } else if ((val = strchr(featurestr, '='))) {
1968 *val = 0; val++;
Igor Mammedov72ac2e82013-04-26 18:04:32 +02001969 feat2prop(featurestr);
Igor Mammedovd024d202012-12-14 01:29:56 +01001970 if (!strcmp(featurestr, "xlevel")) {
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001971 char *err;
Igor Mammedova91987c2013-01-21 15:06:38 +01001972 char num[32];
1973
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001974 numvalue = strtoul(val, &err, 0);
1975 if (!*val || *err) {
Paolo Bonzini6b1dd542014-06-06 15:21:25 +02001976 error_setg(errp, "bad numerical value %s", val);
1977 return;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001978 }
1979 if (numvalue < 0x80000000) {
Andreas Färber94a444b2014-03-03 23:19:19 +01001980 error_report("xlevel value shall always be >= 0x80000000"
1981 ", fixup will be removed in future versions");
Aurelien Jarno2f7a21c2010-03-13 16:46:33 +01001982 numvalue += 0x80000000;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001983 }
Igor Mammedova91987c2013-01-21 15:06:38 +01001984 snprintf(num, sizeof(num), "%" PRIu32, numvalue);
Andreas Färber94a444b2014-03-03 23:19:19 +01001985 object_property_parse(OBJECT(cpu), num, featurestr, &local_err);
Igor Mammedov72ac2e82013-04-26 18:04:32 +02001986 } else if (!strcmp(featurestr, "tsc-freq")) {
Joerg Roedelb862d1f2011-07-07 16:13:12 +02001987 int64_t tsc_freq;
1988 char *err;
Igor Mammedova91987c2013-01-21 15:06:38 +01001989 char num[32];
Joerg Roedelb862d1f2011-07-07 16:13:12 +02001990
Marc-André Lureau4677bb42015-09-16 18:02:56 +02001991 tsc_freq = qemu_strtosz_suffix_unit(val, &err,
1992 QEMU_STRTOSZ_DEFSUFFIX_B, 1000);
Markus Armbruster45009a32011-11-22 09:46:04 +01001993 if (tsc_freq < 0 || *err) {
Paolo Bonzini6b1dd542014-06-06 15:21:25 +02001994 error_setg(errp, "bad numerical value %s", val);
1995 return;
Joerg Roedelb862d1f2011-07-07 16:13:12 +02001996 }
Igor Mammedova91987c2013-01-21 15:06:38 +01001997 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
Andreas Färber94a444b2014-03-03 23:19:19 +01001998 object_property_parse(OBJECT(cpu), num, "tsc-frequency",
1999 &local_err);
Igor Mammedov72ac2e82013-04-26 18:04:32 +02002000 } else if (!strcmp(featurestr, "hv-spinlocks")) {
Vadim Rozenfeld28f52cc2011-12-18 22:48:13 +02002001 char *err;
Igor Mammedov92067bf2013-06-05 15:18:40 +02002002 const int min = 0xFFF;
Igor Mammedovc8f0f882013-06-04 15:05:25 +02002003 char num[32];
Vadim Rozenfeld28f52cc2011-12-18 22:48:13 +02002004 numvalue = strtoul(val, &err, 0);
2005 if (!*val || *err) {
Paolo Bonzini6b1dd542014-06-06 15:21:25 +02002006 error_setg(errp, "bad numerical value %s", val);
2007 return;
Vadim Rozenfeld28f52cc2011-12-18 22:48:13 +02002008 }
Igor Mammedov92067bf2013-06-05 15:18:40 +02002009 if (numvalue < min) {
Andreas Färber94a444b2014-03-03 23:19:19 +01002010 error_report("hv-spinlocks value shall always be >= 0x%x"
chenfan5bb4c352014-07-28 15:13:06 +08002011 ", fixup will be removed in future versions",
2012 min);
Igor Mammedov92067bf2013-06-05 15:18:40 +02002013 numvalue = min;
2014 }
Igor Mammedovc8f0f882013-06-04 15:05:25 +02002015 snprintf(num, sizeof(num), "%" PRId32, numvalue);
Andreas Färber94a444b2014-03-03 23:19:19 +01002016 object_property_parse(OBJECT(cpu), num, featurestr, &local_err);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002017 } else {
Andreas Färber94a444b2014-03-03 23:19:19 +01002018 object_property_parse(OBJECT(cpu), val, featurestr, &local_err);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002019 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002020 } else {
Igor Mammedov258f5ab2012-12-14 01:16:00 +01002021 feat2prop(featurestr);
Andreas Färber94a444b2014-03-03 23:19:19 +01002022 object_property_parse(OBJECT(cpu), "on", featurestr, &local_err);
Igor Mammedova91987c2013-01-21 15:06:38 +01002023 }
Andreas Färber94a444b2014-03-03 23:19:19 +01002024 if (local_err) {
2025 error_propagate(errp, local_err);
Paolo Bonzini6b1dd542014-06-06 15:21:25 +02002026 return;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002027 }
2028 featurestr = strtok(NULL, ",");
2029 }
Eduardo Habkoste1c224b2014-04-30 13:48:37 -03002030
Eduardo Habkost4d1b2792014-08-20 17:30:12 -03002031 if (cpu->host_features) {
2032 for (w = 0; w < FEATURE_WORDS; w++) {
2033 env->features[w] =
2034 x86_cpu_get_supported_feature_word(w, cpu->migratable);
2035 }
2036 }
2037
Eduardo Habkoste1c224b2014-04-30 13:48:37 -03002038 for (w = 0; w < FEATURE_WORDS; w++) {
2039 env->features[w] |= plus_features[w];
2040 env->features[w] &= ~minus_features[w];
2041 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002042}
2043
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002044/* Print all cpuid feature names in featureset
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002045 */
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002046static void listflags(FILE *f, fprintf_function print, const char **featureset)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002047{
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002048 int bit;
2049 bool first = true;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002050
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002051 for (bit = 0; bit < 32; bit++) {
2052 if (featureset[bit]) {
2053 print(f, "%s%s", first ? "" : " ", featureset[bit]);
2054 first = false;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002055 }
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002056 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002057}
2058
Peter Maydelle916cbf2012-09-05 17:41:08 -03002059/* generate CPU information. */
2060void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002061{
Eduardo Habkost9576de72014-01-30 17:48:58 -02002062 X86CPUDefinition *def;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002063 char buf[256];
Andreas Färber7fc9b712013-01-21 01:02:28 +01002064 int i;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002065
Andreas Färber7fc9b712013-01-21 01:02:28 +01002066 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
2067 def = &builtin_x86_defs[i];
Eduardo Habkostc04321b2012-09-05 17:41:13 -03002068 snprintf(buf, sizeof(buf), "%s", def->name);
Peter Maydell6cdf8852012-09-05 17:41:07 -03002069 (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002070 }
Jan Kiszka21ad7782013-03-24 17:01:02 +01002071#ifdef CONFIG_KVM
2072 (*cpu_fprintf)(f, "x86 %16s %-48s\n", "host",
2073 "KVM processor with all supported host features "
2074 "(only available in KVM mode)");
2075#endif
2076
Peter Maydell6cdf8852012-09-05 17:41:07 -03002077 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
Jan Kiszka3af60be2013-02-27 10:15:51 +01002078 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
2079 FeatureWordInfo *fw = &feature_word_info[i];
2080
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002081 (*cpu_fprintf)(f, " ");
2082 listflags(f, cpu_fprintf, fw->feat_names);
2083 (*cpu_fprintf)(f, "\n");
Jan Kiszka3af60be2013-02-27 10:15:51 +01002084 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002085}
2086
Anthony Liguori76b64a72012-08-14 22:17:36 -05002087CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
Anthony Liguorie3966122012-08-10 11:04:14 -05002088{
2089 CpuDefinitionInfoList *cpu_list = NULL;
Eduardo Habkost9576de72014-01-30 17:48:58 -02002090 X86CPUDefinition *def;
Andreas Färber7fc9b712013-01-21 01:02:28 +01002091 int i;
Anthony Liguorie3966122012-08-10 11:04:14 -05002092
Andreas Färber7fc9b712013-01-21 01:02:28 +01002093 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
Anthony Liguorie3966122012-08-10 11:04:14 -05002094 CpuDefinitionInfoList *entry;
2095 CpuDefinitionInfo *info;
2096
Andreas Färber7fc9b712013-01-21 01:02:28 +01002097 def = &builtin_x86_defs[i];
Anthony Liguorie3966122012-08-10 11:04:14 -05002098 info = g_malloc0(sizeof(*info));
2099 info->name = g_strdup(def->name);
2100
2101 entry = g_malloc0(sizeof(*entry));
2102 entry->value = info;
2103 entry->next = cpu_list;
2104 cpu_list = entry;
2105 }
2106
2107 return cpu_list;
2108}
2109
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002110static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
2111 bool migratable_only)
Eduardo Habkost27418ad2014-04-30 13:48:32 -03002112{
2113 FeatureWordInfo *wi = &feature_word_info[w];
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002114 uint32_t r;
Eduardo Habkost27418ad2014-04-30 13:48:32 -03002115
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03002116 if (kvm_enabled()) {
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002117 r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid_eax,
2118 wi->cpuid_ecx,
2119 wi->cpuid_reg);
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03002120 } else if (tcg_enabled()) {
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002121 r = wi->tcg_features;
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03002122 } else {
2123 return ~0;
2124 }
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002125 if (migratable_only) {
2126 r &= x86_cpu_get_migratable_flags(w);
2127 }
2128 return r;
Eduardo Habkost27418ad2014-04-30 13:48:32 -03002129}
2130
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002131/*
2132 * Filters CPU feature words based on host availability of each feature.
2133 *
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002134 * Returns: 0 if all flags are supported by the host, non-zero otherwise.
2135 */
Eduardo Habkost27418ad2014-04-30 13:48:32 -03002136static int x86_cpu_filter_features(X86CPU *cpu)
Eduardo Habkostbc74b7d2012-10-04 17:49:05 -03002137{
2138 CPUX86State *env = &cpu->env;
Eduardo Habkostbd87d2a2013-04-22 16:00:18 -03002139 FeatureWord w;
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002140 int rv = 0;
2141
Eduardo Habkostbd87d2a2013-04-22 16:00:18 -03002142 for (w = 0; w < FEATURE_WORDS; w++) {
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002143 uint32_t host_feat =
2144 x86_cpu_get_supported_feature_word(w, cpu->migratable);
Eduardo Habkost034acf42013-05-06 13:20:08 -03002145 uint32_t requested_features = env->features[w];
2146 env->features[w] &= host_feat;
2147 cpu->filtered_features[w] = requested_features & ~env->features[w];
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002148 if (cpu->filtered_features[w]) {
2149 if (cpu->check_cpuid || cpu->enforce_cpuid) {
Eduardo Habkost8459e392014-04-30 13:48:31 -03002150 report_unavailable_features(w, cpu->filtered_features[w]);
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002151 }
2152 rv = 1;
2153 }
Eduardo Habkostbd87d2a2013-04-22 16:00:18 -03002154 }
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002155
2156 return rv;
Eduardo Habkostbc74b7d2012-10-04 17:49:05 -03002157}
Eduardo Habkostbc74b7d2012-10-04 17:49:05 -03002158
Eduardo Habkost5114e842015-09-11 12:40:27 -03002159static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
2160{
2161 PropValue *pv;
2162 for (pv = props; pv->prop; pv++) {
2163 if (!pv->value) {
2164 continue;
2165 }
2166 object_property_parse(OBJECT(cpu), pv->value, pv->prop,
2167 &error_abort);
2168 }
2169}
2170
Eduardo Habkostd940ee92014-02-10 08:21:30 -02002171/* Load data from X86CPUDefinition
Eduardo Habkostc080e302014-01-30 17:48:56 -02002172 */
Eduardo Habkostd940ee92014-02-10 08:21:30 -02002173static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002174{
Andreas Färber61dcd772012-04-17 12:00:51 +02002175 CPUX86State *env = &cpu->env;
Eduardo Habkost74f54bc2014-02-19 16:39:21 -03002176 const char *vendor;
2177 char host_vendor[CPUID_VENDOR_SZ + 1];
Eduardo Habkoste1c224b2014-04-30 13:48:37 -03002178 FeatureWord w;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002179
Andreas Färber2d642552013-02-15 14:06:56 +01002180 object_property_set_int(OBJECT(cpu), def->level, "level", errp);
2181 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
2182 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
2183 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
Andreas Färber2d642552013-02-15 14:06:56 +01002184 object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
Eduardo Habkost01431f32015-04-02 17:22:27 -03002185 object_property_set_int(OBJECT(cpu), def->xlevel2, "xlevel2", errp);
Andreas Färber2d642552013-02-15 14:06:56 +01002186 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
Eduardo Habkoste1c224b2014-04-30 13:48:37 -03002187 for (w = 0; w < FEATURE_WORDS; w++) {
2188 env->features[w] = def->features[w];
2189 }
Eduardo Habkost82beb532014-01-30 17:48:54 -02002190
Eduardo Habkost9576de72014-01-30 17:48:58 -02002191 /* Special cases not set in the X86CPUDefinition structs: */
Eduardo Habkost82beb532014-01-30 17:48:54 -02002192 if (kvm_enabled()) {
Lan Tianyu492a4c92016-02-25 23:15:12 +08002193 if (!kvm_irqchip_in_kernel()) {
2194 x86_cpu_change_kvm_default("x2apic", "off");
2195 }
2196
Eduardo Habkost5114e842015-09-11 12:40:27 -03002197 x86_cpu_apply_props(cpu, kvm_default_props);
Eduardo Habkost82beb532014-01-30 17:48:54 -02002198 }
Eduardo Habkost5fcca9f2014-02-19 11:58:10 -03002199
Eduardo Habkost82beb532014-01-30 17:48:54 -02002200 env->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
Eduardo Habkost7c08db32014-01-30 17:48:55 -02002201
2202 /* sysenter isn't supported in compatibility mode on AMD,
2203 * syscall isn't supported in compatibility mode on Intel.
2204 * Normally we advertise the actual CPU vendor, but you can
2205 * override this using the 'vendor' property if you want to use
2206 * KVM's sysenter/syscall emulation in compatibility mode and
2207 * when doing cross vendor migration
2208 */
Eduardo Habkost74f54bc2014-02-19 16:39:21 -03002209 vendor = def->vendor;
Eduardo Habkost7c08db32014-01-30 17:48:55 -02002210 if (kvm_enabled()) {
2211 uint32_t ebx = 0, ecx = 0, edx = 0;
2212 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
2213 x86_cpu_vendor_words2str(host_vendor, ebx, edx, ecx);
2214 vendor = host_vendor;
2215 }
2216
2217 object_property_set_str(OBJECT(cpu), vendor, "vendor", errp);
2218
Andreas Färber2d642552013-02-15 14:06:56 +01002219}
2220
Eduardo Habkoste1570d02015-03-05 14:26:51 -03002221X86CPU *cpu_x86_create(const char *cpu_model, Error **errp)
Andreas Färber2d642552013-02-15 14:06:56 +01002222{
2223 X86CPU *cpu = NULL;
Eduardo Habkostd940ee92014-02-10 08:21:30 -02002224 X86CPUClass *xcc;
Andreas Färber500050d2014-02-10 22:02:44 +01002225 ObjectClass *oc;
Andreas Färber2d642552013-02-15 14:06:56 +01002226 gchar **model_pieces;
2227 char *name, *features;
2228 Error *error = NULL;
2229
Eduardo Habkost8f961352012-12-04 17:34:39 -02002230 model_pieces = g_strsplit(cpu_model, ",", 2);
2231 if (!model_pieces[0]) {
Igor Mammedovfa2db3c2013-01-11 03:10:16 +01002232 error_setg(&error, "Invalid/empty CPU model name");
2233 goto out;
Eduardo Habkost8f961352012-12-04 17:34:39 -02002234 }
2235 name = model_pieces[0];
2236 features = model_pieces[1];
2237
Andreas Färber500050d2014-02-10 22:02:44 +01002238 oc = x86_cpu_class_by_name(name);
2239 if (oc == NULL) {
2240 error_setg(&error, "Unable to find CPU definition: %s", name);
2241 goto out;
2242 }
Eduardo Habkostd940ee92014-02-10 08:21:30 -02002243 xcc = X86_CPU_CLASS(oc);
2244
2245 if (xcc->kvm_required && !kvm_enabled()) {
2246 error_setg(&error, "CPU model '%s' requires KVM", name);
Eduardo Habkost285f0252014-01-30 17:48:57 -02002247 goto out;
2248 }
2249
Eduardo Habkostd940ee92014-02-10 08:21:30 -02002250 cpu = X86_CPU(object_new(object_class_get_name(oc)));
2251
Andreas Färber94a444b2014-03-03 23:19:19 +01002252 x86_cpu_parse_featurestr(CPU(cpu), features, &error);
Andreas Färber2d642552013-02-15 14:06:56 +01002253 if (error) {
2254 goto out;
2255 }
2256
Igor Mammedov7f833242013-04-11 16:51:40 +02002257out:
Andreas Färbercd7b87f2013-08-02 18:56:05 +02002258 if (error != NULL) {
2259 error_propagate(errp, error);
Andreas Färber500050d2014-02-10 22:02:44 +01002260 if (cpu) {
2261 object_unref(OBJECT(cpu));
2262 cpu = NULL;
2263 }
Andreas Färbercd7b87f2013-08-02 18:56:05 +02002264 }
Igor Mammedov7f833242013-04-11 16:51:40 +02002265 g_strfreev(model_pieces);
2266 return cpu;
2267}
2268
Peter Maydell08565792015-03-03 00:29:17 +00002269X86CPU *cpu_x86_init(const char *cpu_model)
Igor Mammedov7f833242013-04-11 16:51:40 +02002270{
2271 Error *error = NULL;
2272 X86CPU *cpu;
2273
Eduardo Habkoste1570d02015-03-05 14:26:51 -03002274 cpu = cpu_x86_create(cpu_model, &error);
Andreas Färber2d642552013-02-15 14:06:56 +01002275 if (error) {
Peter Maydell08565792015-03-03 00:29:17 +00002276 goto out;
Andreas Färber2d642552013-02-15 14:06:56 +01002277 }
2278
Igor Mammedov7f833242013-04-11 16:51:40 +02002279 object_property_set_bool(OBJECT(cpu), true, "realized", &error);
Peter Maydell08565792015-03-03 00:29:17 +00002280
2281out:
Igor Mammedov18eb4732012-10-02 17:36:54 +02002282 if (error) {
Peter Maydell08565792015-03-03 00:29:17 +00002283 error_report_err(error);
2284 if (cpu != NULL) {
2285 object_unref(OBJECT(cpu));
2286 cpu = NULL;
2287 }
Andreas Färber5c3c6a62013-02-01 15:12:13 +01002288 }
Peter Maydell08565792015-03-03 00:29:17 +00002289 return cpu;
Andreas Färber5c3c6a62013-02-01 15:12:13 +01002290}
2291
Eduardo Habkostd940ee92014-02-10 08:21:30 -02002292static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
2293{
2294 X86CPUDefinition *cpudef = data;
2295 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2296
2297 xcc->cpu_def = cpudef;
2298}
2299
2300static void x86_register_cpudef_type(X86CPUDefinition *def)
2301{
2302 char *typename = x86_cpu_type_name(def->name);
2303 TypeInfo ti = {
2304 .name = typename,
2305 .parent = TYPE_X86_CPU,
2306 .class_init = x86_cpu_cpudef_class_init,
2307 .class_data = def,
2308 };
2309
2310 type_register(&ti);
2311 g_free(typename);
2312}
2313
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002314#if !defined(CONFIG_USER_ONLY)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002315
Blue Swirl0e26b7b2010-06-19 10:42:34 +03002316void cpu_clear_apic_feature(CPUX86State *env)
2317{
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002318 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
Blue Swirl0e26b7b2010-06-19 10:42:34 +03002319}
2320
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002321#endif /* !CONFIG_USER_ONLY */
2322
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002323void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
2324 uint32_t *eax, uint32_t *ebx,
2325 uint32_t *ecx, uint32_t *edx)
2326{
Andreas Färbera60f24b2012-12-01 05:35:08 +01002327 X86CPU *cpu = x86_env_get_cpu(env);
2328 CPUState *cs = CPU(cpu);
2329
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002330 /* test if maximum index reached */
2331 if (index & 0x80000000) {
brillywu@viatech.com.cnb3baa152011-06-01 09:59:52 +08002332 if (index > env->cpuid_xlevel) {
2333 if (env->cpuid_xlevel2 > 0) {
2334 /* Handle the Centaur's CPUID instruction. */
2335 if (index > env->cpuid_xlevel2) {
2336 index = env->cpuid_xlevel2;
2337 } else if (index < 0xC0000000) {
2338 index = env->cpuid_xlevel;
2339 }
2340 } else {
Eduardo Habkost57f26ae2012-12-20 16:43:48 -02002341 /* Intel documentation states that invalid EAX input will
2342 * return the same information as EAX=cpuid_level
2343 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
2344 */
2345 index = env->cpuid_level;
brillywu@viatech.com.cnb3baa152011-06-01 09:59:52 +08002346 }
2347 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002348 } else {
2349 if (index > env->cpuid_level)
2350 index = env->cpuid_level;
2351 }
2352
2353 switch(index) {
2354 case 0:
2355 *eax = env->cpuid_level;
Eduardo Habkost5eb2f7a2015-02-03 15:57:50 -02002356 *ebx = env->cpuid_vendor1;
2357 *edx = env->cpuid_vendor2;
2358 *ecx = env->cpuid_vendor3;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002359 break;
2360 case 1:
2361 *eax = env->cpuid_version;
Eduardo Habkost7e72a452014-12-18 23:20:10 -02002362 *ebx = (cpu->apic_id << 24) |
2363 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002364 *ecx = env->features[FEAT_1_ECX];
Richard Henderson19dc85d2015-07-02 14:53:40 +01002365 if ((*ecx & CPUID_EXT_XSAVE) && (env->cr[4] & CR4_OSXSAVE_MASK)) {
2366 *ecx |= CPUID_EXT_OSXSAVE;
2367 }
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002368 *edx = env->features[FEAT_1_EDX];
Andreas Färberce3960e2012-12-17 03:27:07 +01002369 if (cs->nr_cores * cs->nr_threads > 1) {
2370 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
Richard Henderson19dc85d2015-07-02 14:53:40 +01002371 *edx |= CPUID_HT;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002372 }
2373 break;
2374 case 2:
2375 /* cache info: needed for Pentium Pro compatibility */
Benoît Canet787aaf52013-09-02 17:06:37 +02002376 if (cpu->cache_info_passthrough) {
2377 host_cpuid(index, 0, eax, ebx, ecx, edx);
2378 break;
2379 }
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002380 *eax = 1; /* Number of CPUID[EAX=2] calls required */
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002381 *ebx = 0;
2382 *ecx = 0;
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002383 *edx = (L1D_DESCRIPTOR << 16) | \
2384 (L1I_DESCRIPTOR << 8) | \
2385 (L2_DESCRIPTOR);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002386 break;
2387 case 4:
2388 /* cache info: needed for Core compatibility */
Benoît Canet787aaf52013-09-02 17:06:37 +02002389 if (cpu->cache_info_passthrough) {
2390 host_cpuid(index, count, eax, ebx, ecx, edx);
Paolo Bonzini76c29752013-11-19 17:49:46 +01002391 *eax &= ~0xFC000000;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002392 } else {
Aurelien Jarno2f7a21c2010-03-13 16:46:33 +01002393 *eax = 0;
Paolo Bonzini76c29752013-11-19 17:49:46 +01002394 switch (count) {
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002395 case 0: /* L1 dcache info */
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002396 *eax |= CPUID_4_TYPE_DCACHE | \
2397 CPUID_4_LEVEL(1) | \
2398 CPUID_4_SELF_INIT_LEVEL;
2399 *ebx = (L1D_LINE_SIZE - 1) | \
2400 ((L1D_PARTITIONS - 1) << 12) | \
2401 ((L1D_ASSOCIATIVITY - 1) << 22);
2402 *ecx = L1D_SETS - 1;
2403 *edx = CPUID_4_NO_INVD_SHARING;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002404 break;
2405 case 1: /* L1 icache info */
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002406 *eax |= CPUID_4_TYPE_ICACHE | \
2407 CPUID_4_LEVEL(1) | \
2408 CPUID_4_SELF_INIT_LEVEL;
2409 *ebx = (L1I_LINE_SIZE - 1) | \
2410 ((L1I_PARTITIONS - 1) << 12) | \
2411 ((L1I_ASSOCIATIVITY - 1) << 22);
2412 *ecx = L1I_SETS - 1;
2413 *edx = CPUID_4_NO_INVD_SHARING;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002414 break;
2415 case 2: /* L2 cache info */
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002416 *eax |= CPUID_4_TYPE_UNIFIED | \
2417 CPUID_4_LEVEL(2) | \
2418 CPUID_4_SELF_INIT_LEVEL;
Andreas Färberce3960e2012-12-17 03:27:07 +01002419 if (cs->nr_threads > 1) {
2420 *eax |= (cs->nr_threads - 1) << 14;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002421 }
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002422 *ebx = (L2_LINE_SIZE - 1) | \
2423 ((L2_PARTITIONS - 1) << 12) | \
2424 ((L2_ASSOCIATIVITY - 1) << 22);
2425 *ecx = L2_SETS - 1;
2426 *edx = CPUID_4_NO_INVD_SHARING;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002427 break;
2428 default: /* end of info */
2429 *eax = 0;
2430 *ebx = 0;
2431 *ecx = 0;
2432 *edx = 0;
2433 break;
Paolo Bonzini76c29752013-11-19 17:49:46 +01002434 }
2435 }
2436
2437 /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
2438 if ((*eax & 31) && cs->nr_cores > 1) {
2439 *eax |= (cs->nr_cores - 1) << 26;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002440 }
2441 break;
2442 case 5:
2443 /* mwait info: needed for Core compatibility */
2444 *eax = 0; /* Smallest monitor-line size in bytes */
2445 *ebx = 0; /* Largest monitor-line size in bytes */
2446 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
2447 *edx = 0;
2448 break;
2449 case 6:
2450 /* Thermal and Power Leaf */
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02002451 *eax = env->features[FEAT_6_EAX];
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002452 *ebx = 0;
2453 *ecx = 0;
2454 *edx = 0;
2455 break;
Yang, Wei Yf7911682011-05-30 23:17:42 +08002456 case 7:
Eduardo Habkost13526722012-05-21 11:27:02 -03002457 /* Structured Extended Feature Flags Enumeration Leaf */
2458 if (count == 0) {
2459 *eax = 0; /* Maximum ECX value for sub-leaves */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002460 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
Huaitong Hanf74eefe2015-11-18 10:20:15 +08002461 *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */
Paolo Bonzini0f70ed42016-02-09 14:14:28 +01002462 if ((*ecx & CPUID_7_0_ECX_PKU) && env->cr[4] & CR4_PKE_MASK) {
2463 *ecx |= CPUID_7_0_ECX_OSPKE;
2464 }
Eduardo Habkost13526722012-05-21 11:27:02 -03002465 *edx = 0; /* Reserved */
Yang, Wei Yf7911682011-05-30 23:17:42 +08002466 } else {
2467 *eax = 0;
2468 *ebx = 0;
2469 *ecx = 0;
2470 *edx = 0;
2471 }
2472 break;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002473 case 9:
2474 /* Direct Cache Access Information Leaf */
2475 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2476 *ebx = 0;
2477 *ecx = 0;
2478 *edx = 0;
2479 break;
2480 case 0xA:
2481 /* Architectural Performance Monitoring Leaf */
Eduardo Habkost9337e3b2013-07-26 17:09:36 -03002482 if (kvm_enabled() && cpu->enable_pmu) {
Andreas Färbera60f24b2012-12-01 05:35:08 +01002483 KVMState *s = cs->kvm_state;
Gleb Natapova0fa8202011-12-15 12:44:05 +02002484
2485 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
2486 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
2487 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
2488 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
2489 } else {
2490 *eax = 0;
2491 *ebx = 0;
2492 *ecx = 0;
2493 *edx = 0;
2494 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002495 break;
Radim Krčmář5232d002016-05-12 19:24:26 +02002496 case 0xB:
2497 /* Extended Topology Enumeration Leaf */
2498 if (!cpu->enable_cpuid_0xb) {
2499 *eax = *ebx = *ecx = *edx = 0;
2500 break;
2501 }
2502
2503 *ecx = count & 0xff;
2504 *edx = cpu->apic_id;
2505
2506 switch (count) {
2507 case 0:
2508 *eax = apicid_core_offset(smp_cores, smp_threads);
2509 *ebx = smp_threads;
2510 *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
2511 break;
2512 case 1:
2513 *eax = apicid_pkg_offset(smp_cores, smp_threads);
2514 *ebx = smp_cores * smp_threads;
2515 *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
2516 break;
2517 default:
2518 *eax = 0;
2519 *ebx = 0;
2520 *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
2521 }
2522
2523 assert(!(*eax & ~0x1f));
2524 *ebx &= 0xffff; /* The count doesn't need to be reliable. */
2525 break;
Paolo Bonzini2560f192013-10-02 17:54:57 +02002526 case 0xD: {
2527 KVMState *s = cs->kvm_state;
Richard Henderson19dc85d2015-07-02 14:53:40 +01002528 uint64_t ena_mask;
Paolo Bonzini2560f192013-10-02 17:54:57 +02002529 int i;
2530
Sheng Yang51e49432010-06-17 15:18:14 +08002531 /* Processor Extended State */
Paolo Bonzini2560f192013-10-02 17:54:57 +02002532 *eax = 0;
2533 *ebx = 0;
2534 *ecx = 0;
2535 *edx = 0;
Richard Henderson19dc85d2015-07-02 14:53:40 +01002536 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
Sheng Yang51e49432010-06-17 15:18:14 +08002537 break;
2538 }
Richard Henderson19dc85d2015-07-02 14:53:40 +01002539 if (kvm_enabled()) {
2540 ena_mask = kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX);
2541 ena_mask <<= 32;
2542 ena_mask |= kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX);
2543 } else {
2544 ena_mask = -1;
2545 }
Jan Kiszkaba9bc592011-06-08 16:11:05 +02002546
Paolo Bonzini2560f192013-10-02 17:54:57 +02002547 if (count == 0) {
2548 *ecx = 0x240;
Richard Hendersonf4f11102015-07-02 15:57:14 +01002549 for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
2550 const ExtSaveArea *esa = &x86_ext_save_areas[i];
Richard Henderson19dc85d2015-07-02 14:53:40 +01002551 if ((env->features[esa->feature] & esa->bits) == esa->bits
2552 && ((ena_mask >> i) & 1) != 0) {
Paolo Bonzini2560f192013-10-02 17:54:57 +02002553 if (i < 32) {
Richard Henderson19dc85d2015-07-02 14:53:40 +01002554 *eax |= 1u << i;
Paolo Bonzini2560f192013-10-02 17:54:57 +02002555 } else {
Richard Henderson19dc85d2015-07-02 14:53:40 +01002556 *edx |= 1u << (i - 32);
Paolo Bonzini2560f192013-10-02 17:54:57 +02002557 }
2558 *ecx = MAX(*ecx, esa->offset + esa->size);
2559 }
2560 }
Paolo Bonzinicfc3b072016-02-17 10:54:53 +01002561 *eax |= ena_mask & (XSTATE_FP_MASK | XSTATE_SSE_MASK);
Paolo Bonzini2560f192013-10-02 17:54:57 +02002562 *ebx = *ecx;
2563 } else if (count == 1) {
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01002564 *eax = env->features[FEAT_XSAVE];
Richard Hendersonf4f11102015-07-02 15:57:14 +01002565 } else if (count < ARRAY_SIZE(x86_ext_save_areas)) {
2566 const ExtSaveArea *esa = &x86_ext_save_areas[count];
Richard Henderson19dc85d2015-07-02 14:53:40 +01002567 if ((env->features[esa->feature] & esa->bits) == esa->bits
2568 && ((ena_mask >> count) & 1) != 0) {
Liu Jinsong33f373d2013-12-03 04:17:50 +08002569 *eax = esa->size;
2570 *ebx = esa->offset;
Paolo Bonzini2560f192013-10-02 17:54:57 +02002571 }
Sheng Yang51e49432010-06-17 15:18:14 +08002572 }
2573 break;
Paolo Bonzini2560f192013-10-02 17:54:57 +02002574 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002575 case 0x80000000:
2576 *eax = env->cpuid_xlevel;
2577 *ebx = env->cpuid_vendor1;
2578 *edx = env->cpuid_vendor2;
2579 *ecx = env->cpuid_vendor3;
2580 break;
2581 case 0x80000001:
2582 *eax = env->cpuid_version;
2583 *ebx = 0;
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002584 *ecx = env->features[FEAT_8000_0001_ECX];
2585 *edx = env->features[FEAT_8000_0001_EDX];
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002586
2587 /* The Linux kernel checks for the CMPLegacy bit and
2588 * discards multiple thread information if it is set.
Stefan Weilcb8d4c82016-03-23 15:59:57 +01002589 * So don't set it here for Intel to make Linux guests happy.
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002590 */
Andreas Färberce3960e2012-12-17 03:27:07 +01002591 if (cs->nr_cores * cs->nr_threads > 1) {
Eduardo Habkost5eb2f7a2015-02-03 15:57:50 -02002592 if (env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1 ||
2593 env->cpuid_vendor2 != CPUID_VENDOR_INTEL_2 ||
2594 env->cpuid_vendor3 != CPUID_VENDOR_INTEL_3) {
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002595 *ecx |= 1 << 1; /* CmpLegacy bit */
2596 }
2597 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002598 break;
2599 case 0x80000002:
2600 case 0x80000003:
2601 case 0x80000004:
2602 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2603 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2604 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2605 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2606 break;
2607 case 0x80000005:
2608 /* cache info (L1 cache) */
Benoît Canet787aaf52013-09-02 17:06:37 +02002609 if (cpu->cache_info_passthrough) {
2610 host_cpuid(index, 0, eax, ebx, ecx, edx);
2611 break;
2612 }
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002613 *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \
2614 (L1_ITLB_2M_ASSOC << 8) | (L1_ITLB_2M_ENTRIES);
2615 *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
2616 (L1_ITLB_4K_ASSOC << 8) | (L1_ITLB_4K_ENTRIES);
2617 *ecx = (L1D_SIZE_KB_AMD << 24) | (L1D_ASSOCIATIVITY_AMD << 16) | \
2618 (L1D_LINES_PER_TAG << 8) | (L1D_LINE_SIZE);
2619 *edx = (L1I_SIZE_KB_AMD << 24) | (L1I_ASSOCIATIVITY_AMD << 16) | \
2620 (L1I_LINES_PER_TAG << 8) | (L1I_LINE_SIZE);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002621 break;
2622 case 0x80000006:
2623 /* cache info (L2 cache) */
Benoît Canet787aaf52013-09-02 17:06:37 +02002624 if (cpu->cache_info_passthrough) {
2625 host_cpuid(index, 0, eax, ebx, ecx, edx);
2626 break;
2627 }
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002628 *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \
2629 (L2_DTLB_2M_ENTRIES << 16) | \
2630 (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \
2631 (L2_ITLB_2M_ENTRIES);
2632 *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) | \
2633 (L2_DTLB_4K_ENTRIES << 16) | \
2634 (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
2635 (L2_ITLB_4K_ENTRIES);
2636 *ecx = (L2_SIZE_KB_AMD << 16) | \
2637 (AMD_ENC_ASSOC(L2_ASSOCIATIVITY) << 12) | \
2638 (L2_LINES_PER_TAG << 8) | (L2_LINE_SIZE);
2639 *edx = ((L3_SIZE_KB/512) << 18) | \
2640 (AMD_ENC_ASSOC(L3_ASSOCIATIVITY) << 12) | \
2641 (L3_LINES_PER_TAG << 8) | (L3_LINE_SIZE);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002642 break;
Marcelo Tosatti303752a2014-04-30 13:48:45 -03002643 case 0x80000007:
2644 *eax = 0;
2645 *ebx = 0;
2646 *ecx = 0;
2647 *edx = env->features[FEAT_8000_0007_EDX];
2648 break;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002649 case 0x80000008:
2650 /* virtual & phys address size in low 2 bytes. */
2651/* XXX: This value must match the one used in the MMU code. */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002652 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002653 /* 64 bit processor */
2654/* XXX: The physical address space is limited to 42 bits in exec.c. */
Eduardo Habkostdd13e082013-04-11 17:07:23 -03002655 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002656 } else {
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002657 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002658 *eax = 0x00000024; /* 36 bits physical */
Eduardo Habkostdd13e082013-04-11 17:07:23 -03002659 } else {
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002660 *eax = 0x00000020; /* 32 bits physical */
Eduardo Habkostdd13e082013-04-11 17:07:23 -03002661 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002662 }
2663 *ebx = 0;
2664 *ecx = 0;
2665 *edx = 0;
Andreas Färberce3960e2012-12-17 03:27:07 +01002666 if (cs->nr_cores * cs->nr_threads > 1) {
2667 *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002668 }
2669 break;
2670 case 0x8000000A:
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002671 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
Eduardo Habkost9f3fb562012-12-04 17:34:38 -02002672 *eax = 0x00000001; /* SVM Revision */
2673 *ebx = 0x00000010; /* nr of ASIDs */
2674 *ecx = 0;
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002675 *edx = env->features[FEAT_SVM]; /* optional features */
Eduardo Habkost9f3fb562012-12-04 17:34:38 -02002676 } else {
2677 *eax = 0;
2678 *ebx = 0;
2679 *ecx = 0;
2680 *edx = 0;
2681 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002682 break;
brillywu@viatech.com.cnb3baa152011-06-01 09:59:52 +08002683 case 0xC0000000:
2684 *eax = env->cpuid_xlevel2;
2685 *ebx = 0;
2686 *ecx = 0;
2687 *edx = 0;
2688 break;
2689 case 0xC0000001:
2690 /* Support for VIA CPU's CPUID instruction */
2691 *eax = env->cpuid_version;
2692 *ebx = 0;
2693 *ecx = 0;
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002694 *edx = env->features[FEAT_C000_0001_EDX];
brillywu@viatech.com.cnb3baa152011-06-01 09:59:52 +08002695 break;
2696 case 0xC0000002:
2697 case 0xC0000003:
2698 case 0xC0000004:
2699 /* Reserved for the future, and now filled with zero */
2700 *eax = 0;
2701 *ebx = 0;
2702 *ecx = 0;
2703 *edx = 0;
2704 break;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002705 default:
2706 /* reserved values: zero */
2707 *eax = 0;
2708 *ebx = 0;
2709 *ecx = 0;
2710 *edx = 0;
2711 break;
2712 }
2713}
Andreas Färber5fd20872012-04-02 23:20:08 +02002714
2715/* CPUClass::reset() */
2716static void x86_cpu_reset(CPUState *s)
2717{
2718 X86CPU *cpu = X86_CPU(s);
2719 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2720 CPUX86State *env = &cpu->env;
Richard Hendersona114d252015-07-07 16:13:10 +01002721 target_ulong cr4;
2722 uint64_t xcr0;
Andreas Färberc1958ae2012-04-03 00:16:24 +02002723 int i;
2724
Andreas Färber5fd20872012-04-02 23:20:08 +02002725 xcc->parent_reset(s);
2726
Paolo Bonzini43175fa2013-03-12 13:16:28 +01002727 memset(env, 0, offsetof(CPUX86State, cpuid_level));
Andreas Färberc1958ae2012-04-03 00:16:24 +02002728
Andreas Färber00c8cb02013-09-04 02:19:44 +02002729 tlb_flush(s, 1);
Andreas Färberc1958ae2012-04-03 00:16:24 +02002730
2731 env->old_exception = -1;
2732
2733 /* init to reset state */
2734
2735#ifdef CONFIG_SOFTMMU
2736 env->hflags |= HF_SOFTMMU_MASK;
2737#endif
2738 env->hflags2 |= HF2_GIF_MASK;
2739
2740 cpu_x86_update_cr0(env, 0x60000010);
2741 env->a20_mask = ~0x0;
2742 env->smbase = 0x30000;
2743
2744 env->idt.limit = 0xffff;
2745 env->gdt.limit = 0xffff;
2746 env->ldt.limit = 0xffff;
2747 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2748 env->tr.limit = 0xffff;
2749 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2750
2751 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2752 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2753 DESC_R_MASK | DESC_A_MASK);
2754 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2755 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2756 DESC_A_MASK);
2757 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
2758 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2759 DESC_A_MASK);
2760 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
2761 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2762 DESC_A_MASK);
2763 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
2764 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2765 DESC_A_MASK);
2766 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
2767 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2768 DESC_A_MASK);
2769
2770 env->eip = 0xfff0;
2771 env->regs[R_EDX] = env->cpuid_version;
2772
2773 env->eflags = 0x2;
2774
2775 /* FPU init */
2776 for (i = 0; i < 8; i++) {
2777 env->fptags[i] = 1;
2778 }
Pavel Dovgalyuk5bde1402014-09-17 12:05:19 +04002779 cpu_set_fpuc(env, 0x37f);
Andreas Färberc1958ae2012-04-03 00:16:24 +02002780
2781 env->mxcsr = 0x1f80;
Richard Hendersona114d252015-07-07 16:13:10 +01002782 /* All units are in INIT state. */
2783 env->xstate_bv = 0;
Andreas Färberc1958ae2012-04-03 00:16:24 +02002784
2785 env->pat = 0x0007040600070406ULL;
2786 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2787
2788 memset(env->dr, 0, sizeof(env->dr));
2789 env->dr[6] = DR6_FIXED_1;
2790 env->dr[7] = DR7_FIXED_1;
Andreas Färberb3310ab2013-09-02 17:26:20 +02002791 cpu_breakpoint_remove_all(s, BP_CPU);
Andreas Färber75a34032013-09-02 16:57:02 +02002792 cpu_watchpoint_remove_all(s, BP_CPU);
Igor Mammedovdd673282012-07-23 15:22:27 +02002793
Richard Hendersona114d252015-07-07 16:13:10 +01002794 cr4 = 0;
Paolo Bonzinicfc3b072016-02-17 10:54:53 +01002795 xcr0 = XSTATE_FP_MASK;
Richard Hendersona114d252015-07-07 16:13:10 +01002796
2797#ifdef CONFIG_USER_ONLY
2798 /* Enable all the features for user-mode. */
2799 if (env->features[FEAT_1_EDX] & CPUID_SSE) {
Paolo Bonzinicfc3b072016-02-17 10:54:53 +01002800 xcr0 |= XSTATE_SSE_MASK;
Richard Hendersona114d252015-07-07 16:13:10 +01002801 }
Paolo Bonzini0f70ed42016-02-09 14:14:28 +01002802 for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
2803 const ExtSaveArea *esa = &x86_ext_save_areas[i];
2804 if ((env->features[esa->feature] & esa->bits) == esa->bits) {
2805 xcr0 |= 1ull << i;
2806 }
Richard Hendersona114d252015-07-07 16:13:10 +01002807 }
Paolo Bonzini0f70ed42016-02-09 14:14:28 +01002808
Richard Hendersona114d252015-07-07 16:13:10 +01002809 if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) {
2810 cr4 |= CR4_OSFXSR_MASK | CR4_OSXSAVE_MASK;
2811 }
Richard Henderson07929f22015-11-18 12:55:47 +01002812 if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_FSGSBASE) {
2813 cr4 |= CR4_FSGSBASE_MASK;
2814 }
Richard Hendersona114d252015-07-07 16:13:10 +01002815#endif
2816
2817 env->xcr0 = xcr0;
2818 cpu_x86_update_cr4(env, cr4);
Fernando Luis Vázquez Cao05226042013-12-06 17:33:01 +09002819
Alex Williamson9db2efd2014-08-14 15:39:39 -06002820 /*
2821 * SDM 11.11.5 requires:
2822 * - IA32_MTRR_DEF_TYPE MSR.E = 0
2823 * - IA32_MTRR_PHYSMASKn.V = 0
2824 * All other bits are undefined. For simplification, zero it all.
2825 */
2826 env->mtrr_deftype = 0;
2827 memset(env->mtrr_var, 0, sizeof(env->mtrr_var));
2828 memset(env->mtrr_fixed, 0, sizeof(env->mtrr_fixed));
2829
Igor Mammedovdd673282012-07-23 15:22:27 +02002830#if !defined(CONFIG_USER_ONLY)
2831 /* We hard-wire the BSP to the first CPU. */
Nadav Amit9cb11fd2015-04-02 02:58:36 +03002832 apic_designate_bsp(cpu->apic_state, s->cpu_index == 0);
Igor Mammedovdd673282012-07-23 15:22:27 +02002833
Andreas Färber259186a2013-01-17 18:51:17 +01002834 s->halted = !cpu_is_bsp(cpu);
Paolo Bonzini50a2c6e2013-03-20 13:11:56 +01002835
2836 if (kvm_enabled()) {
2837 kvm_arch_reset_vcpu(cpu);
2838 }
Igor Mammedovdd673282012-07-23 15:22:27 +02002839#endif
Andreas Färber5fd20872012-04-02 23:20:08 +02002840}
2841
Igor Mammedovdd673282012-07-23 15:22:27 +02002842#ifndef CONFIG_USER_ONLY
2843bool cpu_is_bsp(X86CPU *cpu)
2844{
Chen Fan02e51482013-12-23 17:04:02 +08002845 return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
Igor Mammedovdd673282012-07-23 15:22:27 +02002846}
Igor Mammedov65dee382012-07-23 15:22:28 +02002847
2848/* TODO: remove me, when reset over QOM tree is implemented */
2849static void x86_cpu_machine_reset_cb(void *opaque)
2850{
2851 X86CPU *cpu = opaque;
2852 cpu_reset(CPU(cpu));
2853}
Igor Mammedovdd673282012-07-23 15:22:27 +02002854#endif
2855
Andreas Färberde024812012-04-03 00:00:17 +02002856static void mce_init(X86CPU *cpu)
2857{
2858 CPUX86State *cenv = &cpu->env;
2859 unsigned int bank;
2860
2861 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002862 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
Andreas Färberde024812012-04-03 00:00:17 +02002863 (CPUID_MCE | CPUID_MCA)) {
2864 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2865 cenv->mcg_ctl = ~(uint64_t)0;
2866 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2867 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2868 }
2869 }
2870}
2871
Igor Mammedovbdeec802012-10-13 22:35:39 +02002872#ifndef CONFIG_USER_ONLY
Igor Mammedovd3c64d62013-04-05 16:36:54 +02002873static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
Igor Mammedovbdeec802012-10-13 22:35:39 +02002874{
Andreas Färber449994e2012-10-10 12:18:02 +02002875 APICCommonState *apic;
Igor Mammedovbdeec802012-10-13 22:35:39 +02002876 const char *apic_type = "apic";
2877
Paolo Bonzini15eafc22015-12-17 17:16:08 +01002878 if (kvm_apic_in_kernel()) {
Igor Mammedovbdeec802012-10-13 22:35:39 +02002879 apic_type = "kvm-apic";
2880 } else if (xen_enabled()) {
2881 apic_type = "xen-apic";
2882 }
2883
Chen Fan46232aa2015-09-16 17:19:14 +08002884 cpu->apic_state = DEVICE(object_new(apic_type));
Igor Mammedovbdeec802012-10-13 22:35:39 +02002885
2886 object_property_add_child(OBJECT(cpu), "apic",
Chen Fan02e51482013-12-23 17:04:02 +08002887 OBJECT(cpu->apic_state), NULL);
Eduardo Habkost7e72a452014-12-18 23:20:10 -02002888 qdev_prop_set_uint8(cpu->apic_state, "id", cpu->apic_id);
Igor Mammedovbdeec802012-10-13 22:35:39 +02002889 /* TODO: convert to link<> */
Chen Fan02e51482013-12-23 17:04:02 +08002890 apic = APIC_COMMON(cpu->apic_state);
Andreas Färber60671e52012-10-10 14:10:07 +02002891 apic->cpu = cpu;
Chen Fan8d42d2d2015-09-16 17:19:11 +08002892 apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE;
Igor Mammedovd3c64d62013-04-05 16:36:54 +02002893}
2894
2895static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2896{
Chen Fan8d42d2d2015-09-16 17:19:11 +08002897 APICCommonState *apic;
2898 static bool apic_mmio_map_once;
2899
Chen Fan02e51482013-12-23 17:04:02 +08002900 if (cpu->apic_state == NULL) {
Igor Mammedovd3c64d62013-04-05 16:36:54 +02002901 return;
2902 }
Markus Armbruster6e8e2652015-02-05 10:29:15 +01002903 object_property_set_bool(OBJECT(cpu->apic_state), true, "realized",
2904 errp);
Chen Fan8d42d2d2015-09-16 17:19:11 +08002905
2906 /* Map APIC MMIO area */
2907 apic = APIC_COMMON(cpu->apic_state);
2908 if (!apic_mmio_map_once) {
2909 memory_region_add_subregion_overlap(get_system_memory(),
2910 apic->apicbase &
2911 MSR_IA32_APICBASE_BASE,
2912 &apic->io_memory,
2913 0x1000);
2914 apic_mmio_map_once = true;
2915 }
Igor Mammedovbdeec802012-10-13 22:35:39 +02002916}
Paolo Bonzinif809c602015-03-31 14:12:25 +02002917
2918static void x86_cpu_machine_done(Notifier *n, void *unused)
2919{
2920 X86CPU *cpu = container_of(n, X86CPU, machine_done);
2921 MemoryRegion *smram =
2922 (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
2923
2924 if (smram) {
2925 cpu->smram = g_new(MemoryRegion, 1);
2926 memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
2927 smram, 0, 1ull << 32);
2928 memory_region_set_enabled(cpu->smram, false);
2929 memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->smram, 1);
2930 }
2931}
Igor Mammedovd3c64d62013-04-05 16:36:54 +02002932#else
2933static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2934{
2935}
Igor Mammedovbdeec802012-10-13 22:35:39 +02002936#endif
2937
Wei Huange48638f2014-10-21 11:00:45 -04002938
2939#define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \
2940 (env)->cpuid_vendor2 == CPUID_VENDOR_INTEL_2 && \
2941 (env)->cpuid_vendor3 == CPUID_VENDOR_INTEL_3)
2942#define IS_AMD_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && \
2943 (env)->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && \
2944 (env)->cpuid_vendor3 == CPUID_VENDOR_AMD_3)
Andreas Färber2b6f2942013-01-16 03:41:47 +01002945static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
Andreas Färber7a059952012-05-09 23:15:32 +02002946{
Andreas Färber14a10fc2013-07-27 02:53:25 +02002947 CPUState *cs = CPU(dev);
Andreas Färber2b6f2942013-01-16 03:41:47 +01002948 X86CPU *cpu = X86_CPU(dev);
2949 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
Igor Mammedovb34d12d2012-10-22 17:03:00 +02002950 CPUX86State *env = &cpu->env;
Andreas Färber2b6f2942013-01-16 03:41:47 +01002951 Error *local_err = NULL;
Wei Huange48638f2014-10-21 11:00:45 -04002952 static bool ht_warned;
Igor Mammedovb34d12d2012-10-22 17:03:00 +02002953
Eduardo Habkost9886e832014-12-18 23:31:11 -02002954 if (cpu->apic_id < 0) {
2955 error_setg(errp, "apic-id property was not initialized properly");
2956 return;
2957 }
2958
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002959 if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
Igor Mammedovb34d12d2012-10-22 17:03:00 +02002960 env->cpuid_level = 7;
2961 }
Andreas Färber7a059952012-05-09 23:15:32 +02002962
Eduardo Habkost9997cf72016-04-15 14:54:26 -03002963 if (x86_cpu_filter_features(cpu) && cpu->enforce_cpuid) {
2964 error_setg(&local_err,
2965 kvm_enabled() ?
2966 "Host doesn't support requested features" :
2967 "TCG doesn't support requested features");
2968 goto out;
2969 }
2970
Igor Mammedov9b15cd92012-12-28 21:01:17 +01002971 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
2972 * CPUID[1].EDX.
2973 */
Wei Huange48638f2014-10-21 11:00:45 -04002974 if (IS_AMD_CPU(env)) {
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002975 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
2976 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
Igor Mammedov9b15cd92012-12-28 21:01:17 +01002977 & CPUID_EXT2_AMD_ALIASES);
2978 }
2979
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03002980
Eduardo Habkost42ecaba2015-02-12 23:04:50 -02002981 cpu_exec_init(cs, &error_abort);
2982
Eduardo Habkost57f24532015-02-12 22:57:44 -02002983 if (tcg_enabled()) {
2984 tcg_x86_init();
2985 }
2986
Igor Mammedov65dee382012-07-23 15:22:28 +02002987#ifndef CONFIG_USER_ONLY
2988 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
Igor Mammedovbdeec802012-10-13 22:35:39 +02002989
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002990 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
Igor Mammedovd3c64d62013-04-05 16:36:54 +02002991 x86_cpu_apic_create(cpu, &local_err);
Andreas Färber2b6f2942013-01-16 03:41:47 +01002992 if (local_err != NULL) {
Igor Mammedov4dc1f442013-04-05 16:36:53 +02002993 goto out;
Igor Mammedovbdeec802012-10-13 22:35:39 +02002994 }
2995 }
Igor Mammedov65dee382012-07-23 15:22:28 +02002996#endif
2997
Andreas Färber7a059952012-05-09 23:15:32 +02002998 mce_init(cpu);
Paolo Bonzini2001d0c2015-03-31 14:11:09 +02002999
3000#ifndef CONFIG_USER_ONLY
3001 if (tcg_enabled()) {
Peter Maydell56943e82016-01-21 14:15:04 +00003002 AddressSpace *newas = g_new(AddressSpace, 1);
3003
Paolo Bonzinif809c602015-03-31 14:12:25 +02003004 cpu->cpu_as_mem = g_new(MemoryRegion, 1);
Paolo Bonzini2001d0c2015-03-31 14:11:09 +02003005 cpu->cpu_as_root = g_new(MemoryRegion, 1);
Paolo Bonzinif809c602015-03-31 14:12:25 +02003006
3007 /* Outer container... */
3008 memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
Paolo Bonzini2001d0c2015-03-31 14:11:09 +02003009 memory_region_set_enabled(cpu->cpu_as_root, true);
Paolo Bonzinif809c602015-03-31 14:12:25 +02003010
3011 /* ... with two regions inside: normal system memory with low
3012 * priority, and...
3013 */
3014 memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
3015 get_system_memory(), 0, ~0ull);
3016 memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
3017 memory_region_set_enabled(cpu->cpu_as_mem, true);
Peter Maydell56943e82016-01-21 14:15:04 +00003018 address_space_init(newas, cpu->cpu_as_root, "CPU");
Peter Maydell12ebc9a2016-01-21 14:15:04 +00003019 cs->num_ases = 1;
Peter Maydell56943e82016-01-21 14:15:04 +00003020 cpu_address_space_init(cs, newas, 0);
Paolo Bonzinif809c602015-03-31 14:12:25 +02003021
3022 /* ... SMRAM with higher priority, linked from /machine/smram. */
3023 cpu->machine_done.notify = x86_cpu_machine_done;
3024 qemu_add_machine_init_done_notifier(&cpu->machine_done);
Paolo Bonzini2001d0c2015-03-31 14:11:09 +02003025 }
3026#endif
3027
Andreas Färber14a10fc2013-07-27 02:53:25 +02003028 qemu_init_vcpu(cs);
Igor Mammedovd3c64d62013-04-05 16:36:54 +02003029
Wei Huange48638f2014-10-21 11:00:45 -04003030 /* Only Intel CPUs support hyperthreading. Even though QEMU fixes this
3031 * issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX
3032 * based on inputs (sockets,cores,threads), it is still better to gives
3033 * users a warning.
3034 *
3035 * NOTE: the following code has to follow qemu_init_vcpu(). Otherwise
3036 * cs->nr_threads hasn't be populated yet and the checking is incorrect.
3037 */
3038 if (!IS_INTEL_CPU(env) && cs->nr_threads > 1 && !ht_warned) {
3039 error_report("AMD CPU doesn't support hyperthreading. Please configure"
3040 " -smp options properly.");
3041 ht_warned = true;
3042 }
3043
Igor Mammedovd3c64d62013-04-05 16:36:54 +02003044 x86_cpu_apic_realize(cpu, &local_err);
3045 if (local_err != NULL) {
3046 goto out;
3047 }
Andreas Färber14a10fc2013-07-27 02:53:25 +02003048 cpu_reset(cs);
Andreas Färber2b6f2942013-01-16 03:41:47 +01003049
Igor Mammedov4dc1f442013-04-05 16:36:53 +02003050 xcc->parent_realize(dev, &local_err);
Paolo Bonzini2001d0c2015-03-31 14:11:09 +02003051
Igor Mammedov4dc1f442013-04-05 16:36:53 +02003052out:
3053 if (local_err != NULL) {
3054 error_propagate(errp, local_err);
3055 return;
3056 }
Andreas Färber7a059952012-05-09 23:15:32 +02003057}
3058
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003059typedef struct BitProperty {
3060 uint32_t *ptr;
3061 uint32_t mask;
3062} BitProperty;
3063
Eric Blaked7bce992016-01-29 06:48:55 -07003064static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
3065 void *opaque, Error **errp)
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003066{
3067 BitProperty *fp = opaque;
3068 bool value = (*fp->ptr & fp->mask) == fp->mask;
Eric Blake51e72bc2016-01-29 06:48:54 -07003069 visit_type_bool(v, name, &value, errp);
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003070}
3071
Eric Blaked7bce992016-01-29 06:48:55 -07003072static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
3073 void *opaque, Error **errp)
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003074{
3075 DeviceState *dev = DEVICE(obj);
3076 BitProperty *fp = opaque;
3077 Error *local_err = NULL;
3078 bool value;
3079
3080 if (dev->realized) {
3081 qdev_prop_set_after_realize(dev, name, errp);
3082 return;
3083 }
3084
Eric Blake51e72bc2016-01-29 06:48:54 -07003085 visit_type_bool(v, name, &value, &local_err);
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003086 if (local_err) {
3087 error_propagate(errp, local_err);
3088 return;
3089 }
3090
3091 if (value) {
3092 *fp->ptr |= fp->mask;
3093 } else {
3094 *fp->ptr &= ~fp->mask;
3095 }
3096}
3097
3098static void x86_cpu_release_bit_prop(Object *obj, const char *name,
3099 void *opaque)
3100{
3101 BitProperty *prop = opaque;
3102 g_free(prop);
3103}
3104
3105/* Register a boolean property to get/set a single bit in a uint32_t field.
3106 *
3107 * The same property name can be registered multiple times to make it affect
3108 * multiple bits in the same FeatureWord. In that case, the getter will return
3109 * true only if all bits are set.
3110 */
3111static void x86_cpu_register_bit_prop(X86CPU *cpu,
3112 const char *prop_name,
3113 uint32_t *field,
3114 int bitnr)
3115{
3116 BitProperty *fp;
3117 ObjectProperty *op;
3118 uint32_t mask = (1UL << bitnr);
3119
3120 op = object_property_find(OBJECT(cpu), prop_name, NULL);
3121 if (op) {
3122 fp = op->opaque;
3123 assert(fp->ptr == field);
3124 fp->mask |= mask;
3125 } else {
3126 fp = g_new0(BitProperty, 1);
3127 fp->ptr = field;
3128 fp->mask = mask;
3129 object_property_add(OBJECT(cpu), prop_name, "bool",
3130 x86_cpu_get_bit_prop,
3131 x86_cpu_set_bit_prop,
3132 x86_cpu_release_bit_prop, fp, &error_abort);
3133 }
3134}
3135
3136static void x86_cpu_register_feature_bit_props(X86CPU *cpu,
3137 FeatureWord w,
3138 int bitnr)
3139{
3140 Object *obj = OBJECT(cpu);
3141 int i;
3142 char **names;
3143 FeatureWordInfo *fi = &feature_word_info[w];
3144
3145 if (!fi->feat_names) {
3146 return;
3147 }
3148 if (!fi->feat_names[bitnr]) {
3149 return;
3150 }
3151
3152 names = g_strsplit(fi->feat_names[bitnr], "|", 0);
3153
3154 feat2prop(names[0]);
3155 x86_cpu_register_bit_prop(cpu, names[0], &cpu->env.features[w], bitnr);
3156
3157 for (i = 1; names[i]; i++) {
3158 feat2prop(names[i]);
Eduardo Habkostd461a442015-07-09 12:24:43 -03003159 object_property_add_alias(obj, names[i], obj, names[0],
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003160 &error_abort);
3161 }
3162
3163 g_strfreev(names);
3164}
3165
Andreas Färberde024812012-04-03 00:00:17 +02003166static void x86_cpu_initfn(Object *obj)
3167{
Andreas Färber55e5c282012-12-17 06:18:02 +01003168 CPUState *cs = CPU(obj);
Andreas Färberde024812012-04-03 00:00:17 +02003169 X86CPU *cpu = X86_CPU(obj);
Eduardo Habkostd940ee92014-02-10 08:21:30 -02003170 X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
Andreas Färberde024812012-04-03 00:00:17 +02003171 CPUX86State *env = &cpu->env;
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003172 FeatureWord w;
Andreas Färberde024812012-04-03 00:00:17 +02003173
Andreas Färberc05efcb2013-01-17 12:13:41 +01003174 cs->env_ptr = env;
Andreas Färber71ad61d2012-04-17 12:10:29 +02003175
3176 object_property_add(obj, "family", "int",
Andreas Färber95b85192012-04-17 14:42:22 +02003177 x86_cpuid_version_get_family,
Andreas Färber71ad61d2012-04-17 12:10:29 +02003178 x86_cpuid_version_set_family, NULL, NULL, NULL);
Andreas Färberc5291a42012-04-17 12:16:39 +02003179 object_property_add(obj, "model", "int",
Andreas Färber67e30c82012-04-17 14:48:14 +02003180 x86_cpuid_version_get_model,
Andreas Färberc5291a42012-04-17 12:16:39 +02003181 x86_cpuid_version_set_model, NULL, NULL, NULL);
Andreas Färber036e2222012-04-17 14:14:18 +02003182 object_property_add(obj, "stepping", "int",
Andreas Färber35112e42012-04-17 14:50:53 +02003183 x86_cpuid_version_get_stepping,
Andreas Färber036e2222012-04-17 14:14:18 +02003184 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
Andreas Färberd480e1a2012-04-17 19:22:58 +02003185 object_property_add_str(obj, "vendor",
3186 x86_cpuid_get_vendor,
3187 x86_cpuid_set_vendor, NULL);
Andreas Färber938d4c22012-04-17 15:17:27 +02003188 object_property_add_str(obj, "model-id",
Andreas Färber63e886e2012-04-17 23:02:26 +02003189 x86_cpuid_get_model_id,
Andreas Färber938d4c22012-04-17 15:17:27 +02003190 x86_cpuid_set_model_id, NULL);
Andreas Färber89e48962012-04-18 00:12:23 +02003191 object_property_add(obj, "tsc-frequency", "int",
3192 x86_cpuid_get_tsc_freq,
3193 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
Igor Mammedov31050932013-04-25 16:05:26 +02003194 object_property_add(obj, "apic-id", "int",
3195 x86_cpuid_get_apic_id,
3196 x86_cpuid_set_apic_id, NULL, NULL, NULL);
Eduardo Habkost8e8aba52013-05-06 13:20:07 -03003197 object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
3198 x86_cpu_get_feature_words,
Eduardo Habkost7e5292b2013-05-06 13:20:09 -03003199 NULL, NULL, (void *)env->features, NULL);
3200 object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
3201 x86_cpu_get_feature_words,
3202 NULL, NULL, (void *)cpu->filtered_features, NULL);
Andreas Färber71ad61d2012-04-17 12:10:29 +02003203
Igor Mammedov92067bf2013-06-05 15:18:40 +02003204 cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
Igor Mammedovd65e9812012-06-19 15:39:46 +02003205
Eduardo Habkost9886e832014-12-18 23:31:11 -02003206#ifndef CONFIG_USER_ONLY
3207 /* Any code creating new X86CPU objects have to set apic-id explicitly */
3208 cpu->apic_id = -1;
3209#endif
3210
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003211 for (w = 0; w < FEATURE_WORDS; w++) {
3212 int bitnr;
3213
3214 for (bitnr = 0; bitnr < 32; bitnr++) {
3215 x86_cpu_register_feature_bit_props(cpu, w, bitnr);
3216 }
3217 }
3218
Eduardo Habkostd940ee92014-02-10 08:21:30 -02003219 x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
Andreas Färberde024812012-04-03 00:00:17 +02003220}
3221
Igor Mammedov997395d2013-04-23 10:29:41 +02003222static int64_t x86_cpu_get_arch_id(CPUState *cs)
3223{
3224 X86CPU *cpu = X86_CPU(cs);
Igor Mammedov997395d2013-04-23 10:29:41 +02003225
Eduardo Habkost7e72a452014-12-18 23:20:10 -02003226 return cpu->apic_id;
Igor Mammedov997395d2013-04-23 10:29:41 +02003227}
3228
Andreas Färber444d5592013-05-28 13:28:38 +02003229static bool x86_cpu_get_paging_enabled(const CPUState *cs)
3230{
3231 X86CPU *cpu = X86_CPU(cs);
3232
3233 return cpu->env.cr[0] & CR0_PG_MASK;
3234}
3235
Andreas Färberf45748f2013-06-21 19:09:18 +02003236static void x86_cpu_set_pc(CPUState *cs, vaddr value)
3237{
3238 X86CPU *cpu = X86_CPU(cs);
3239
3240 cpu->env.eip = value;
3241}
3242
Andreas Färberbdf7ae52013-06-28 19:31:32 +02003243static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
3244{
3245 X86CPU *cpu = X86_CPU(cs);
3246
3247 cpu->env.eip = tb->pc - tb->cs_base;
3248}
3249
Andreas Färber8c2e1b02013-08-25 18:53:55 +02003250static bool x86_cpu_has_work(CPUState *cs)
3251{
3252 X86CPU *cpu = X86_CPU(cs);
3253 CPUX86State *env = &cpu->env;
3254
Pavel Dovgalyuk6220e902015-09-17 19:23:31 +03003255 return ((cs->interrupt_request & (CPU_INTERRUPT_HARD |
3256 CPU_INTERRUPT_POLL)) &&
Andreas Färber8c2e1b02013-08-25 18:53:55 +02003257 (env->eflags & IF_MASK)) ||
3258 (cs->interrupt_request & (CPU_INTERRUPT_NMI |
3259 CPU_INTERRUPT_INIT |
3260 CPU_INTERRUPT_SIPI |
Paolo Bonzinia9bad652015-05-19 13:46:47 +02003261 CPU_INTERRUPT_MCE)) ||
3262 ((cs->interrupt_request & CPU_INTERRUPT_SMI) &&
3263 !(env->hflags & HF_SMM_MASK));
Andreas Färber8c2e1b02013-08-25 18:53:55 +02003264}
3265
Eduardo Habkost9337e3b2013-07-26 17:09:36 -03003266static Property x86_cpu_properties[] = {
3267 DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
Igor Mammedovc8f0f882013-06-04 15:05:25 +02003268 { .name = "hv-spinlocks", .info = &qdev_prop_spinlocks },
Igor Mammedov89314502012-08-08 13:52:51 +02003269 DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false),
Igor Mammedov0f466852012-08-08 13:54:27 +02003270 DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false),
Vadim Rozenfeld48a5f3b2014-01-24 00:40:49 +11003271 DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false),
Andrey Smetaninf2a53c92015-09-09 14:41:30 +02003272 DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false),
Andrey Smetanin744b8a92015-09-16 12:59:42 +03003273 DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false),
Andrey Smetanin8c145d72015-09-16 12:59:43 +03003274 DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false),
Andrey Smetanin46eb8f92015-09-16 12:59:44 +03003275 DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
Andrey Smetanin866eea92015-11-11 13:18:38 +03003276 DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
Andrey Smetaninff99aa62015-11-25 18:21:25 +03003277 DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
Eduardo Habkost15e41342015-08-26 13:25:44 -03003278 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
Igor Mammedov912ffc42013-06-04 15:13:14 +02003279 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
Alex Williamsonf522d2a2014-06-02 11:28:50 -06003280 DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
Eduardo Habkostb9472b72015-04-02 17:21:53 -03003281 DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, 0),
3282 DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, 0),
Eduardo Habkost01431f32015-04-02 17:22:27 -03003283 DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0),
Alex Williamson1c4a55d2015-10-16 09:38:22 -06003284 DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
Radim Krčmář5232d002016-05-12 19:24:26 +02003285 DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
Eduardo Habkost9337e3b2013-07-26 17:09:36 -03003286 DEFINE_PROP_END_OF_LIST()
3287};
3288
Andreas Färber5fd20872012-04-02 23:20:08 +02003289static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
3290{
3291 X86CPUClass *xcc = X86_CPU_CLASS(oc);
3292 CPUClass *cc = CPU_CLASS(oc);
Andreas Färber2b6f2942013-01-16 03:41:47 +01003293 DeviceClass *dc = DEVICE_CLASS(oc);
3294
3295 xcc->parent_realize = dc->realize;
3296 dc->realize = x86_cpu_realizefn;
Eduardo Habkost9337e3b2013-07-26 17:09:36 -03003297 dc->props = x86_cpu_properties;
Andreas Färber5fd20872012-04-02 23:20:08 +02003298
3299 xcc->parent_reset = cc->reset;
3300 cc->reset = x86_cpu_reset;
Andreas Färber91b1df82013-06-16 07:49:48 +02003301 cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
Andreas Färberf56e3a12013-02-02 13:38:08 +01003302
Andreas Färber500050d2014-02-10 22:02:44 +01003303 cc->class_by_name = x86_cpu_class_by_name;
Andreas Färber94a444b2014-03-03 23:19:19 +01003304 cc->parse_features = x86_cpu_parse_featurestr;
Andreas Färber8c2e1b02013-08-25 18:53:55 +02003305 cc->has_work = x86_cpu_has_work;
Andreas Färber97a8ea52013-02-02 10:57:51 +01003306 cc->do_interrupt = x86_cpu_do_interrupt;
Richard Henderson42f53fe2014-09-13 09:45:33 -07003307 cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
Andreas Färber878096e2013-05-27 01:33:50 +02003308 cc->dump_state = x86_cpu_dump_state;
Andreas Färberf45748f2013-06-21 19:09:18 +02003309 cc->set_pc = x86_cpu_set_pc;
Andreas Färberbdf7ae52013-06-28 19:31:32 +02003310 cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
Andreas Färber5b50e792013-06-29 04:18:45 +02003311 cc->gdb_read_register = x86_cpu_gdb_read_register;
3312 cc->gdb_write_register = x86_cpu_gdb_write_register;
Andreas Färber444d5592013-05-28 13:28:38 +02003313 cc->get_arch_id = x86_cpu_get_arch_id;
3314 cc->get_paging_enabled = x86_cpu_get_paging_enabled;
Andreas Färber75104542013-08-26 03:01:33 +02003315#ifdef CONFIG_USER_ONLY
3316 cc->handle_mmu_fault = x86_cpu_handle_mmu_fault;
3317#else
Andreas Färbera23bbfd2013-05-28 13:52:01 +02003318 cc->get_memory_mapping = x86_cpu_get_memory_mapping;
Andreas Färber00b941e2013-06-29 18:55:54 +02003319 cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
Jens Freimannc72bf462013-04-19 16:45:06 +02003320 cc->write_elf64_note = x86_cpu_write_elf64_note;
3321 cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
3322 cc->write_elf32_note = x86_cpu_write_elf32_note;
3323 cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
Andreas Färber00b941e2013-06-29 18:55:54 +02003324 cc->vmsd = &vmstate_x86_cpu;
Jens Freimannc72bf462013-04-19 16:45:06 +02003325#endif
Andreas Färbera0e372f2013-06-28 23:18:47 +02003326 cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
Peter Maydell86025ee2014-09-12 14:06:48 +01003327#ifndef CONFIG_USER_ONLY
3328 cc->debug_excp_handler = breakpoint_handler;
3329#endif
Richard Henderson374e0cd2014-09-13 09:45:14 -07003330 cc->cpu_exec_enter = x86_cpu_exec_enter;
3331 cc->cpu_exec_exit = x86_cpu_exec_exit;
Markus Armbruster4c315c22015-10-01 10:59:58 +02003332
3333 /*
3334 * Reason: x86_cpu_initfn() calls cpu_exec_init(), which saves the
3335 * object in cpus -> dangling pointer after final object_unref().
3336 */
3337 dc->cannot_destroy_with_object_finalize_yet = true;
Andreas Färber5fd20872012-04-02 23:20:08 +02003338}
3339
3340static const TypeInfo x86_cpu_type_info = {
3341 .name = TYPE_X86_CPU,
3342 .parent = TYPE_CPU,
3343 .instance_size = sizeof(X86CPU),
Andreas Färberde024812012-04-03 00:00:17 +02003344 .instance_init = x86_cpu_initfn,
Eduardo Habkostd940ee92014-02-10 08:21:30 -02003345 .abstract = true,
Andreas Färber5fd20872012-04-02 23:20:08 +02003346 .class_size = sizeof(X86CPUClass),
3347 .class_init = x86_cpu_common_class_init,
3348};
3349
3350static void x86_cpu_register_types(void)
3351{
Eduardo Habkostd940ee92014-02-10 08:21:30 -02003352 int i;
3353
Andreas Färber5fd20872012-04-02 23:20:08 +02003354 type_register_static(&x86_cpu_type_info);
Eduardo Habkostd940ee92014-02-10 08:21:30 -02003355 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
3356 x86_register_cpudef_type(&builtin_x86_defs[i]);
3357 }
3358#ifdef CONFIG_KVM
3359 type_register_static(&host_x86_cpu_type_info);
3360#endif
Andreas Färber5fd20872012-04-02 23:20:08 +02003361}
3362
3363type_init(x86_cpu_register_types)