blob: 14c5186fe75a252264aba136b8bcd1785aa5db1c [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
Longpeng(Mike)14c985c2016-09-07 13:21:13 +080060#define CPUID_2_L3_16MB_16WAY_64B 0x4d
Eduardo Habkost5e891bf2013-08-27 12:24:37 -030061
62
63/* CPUID Leaf 4 constants: */
64
65/* EAX: */
66#define CPUID_4_TYPE_DCACHE 1
67#define CPUID_4_TYPE_ICACHE 2
68#define CPUID_4_TYPE_UNIFIED 3
69
70#define CPUID_4_LEVEL(l) ((l) << 5)
71
72#define CPUID_4_SELF_INIT_LEVEL (1 << 8)
73#define CPUID_4_FULLY_ASSOC (1 << 9)
74
75/* EDX: */
76#define CPUID_4_NO_INVD_SHARING (1 << 0)
77#define CPUID_4_INCLUSIVE (1 << 1)
78#define CPUID_4_COMPLEX_IDX (1 << 2)
79
80#define ASSOC_FULL 0xFF
81
82/* AMD associativity encoding used on CPUID Leaf 0x80000006: */
83#define AMD_ENC_ASSOC(a) (a <= 1 ? a : \
84 a == 2 ? 0x2 : \
85 a == 4 ? 0x4 : \
86 a == 8 ? 0x6 : \
87 a == 16 ? 0x8 : \
88 a == 32 ? 0xA : \
89 a == 48 ? 0xB : \
90 a == 64 ? 0xC : \
91 a == 96 ? 0xD : \
92 a == 128 ? 0xE : \
93 a == ASSOC_FULL ? 0xF : \
94 0 /* invalid value */)
95
96
97/* Definitions of the hardcoded cache entries we expose: */
98
99/* L1 data cache: */
100#define L1D_LINE_SIZE 64
101#define L1D_ASSOCIATIVITY 8
102#define L1D_SETS 64
103#define L1D_PARTITIONS 1
104/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
105#define L1D_DESCRIPTOR CPUID_2_L1D_32KB_8WAY_64B
106/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
107#define L1D_LINES_PER_TAG 1
108#define L1D_SIZE_KB_AMD 64
109#define L1D_ASSOCIATIVITY_AMD 2
110
111/* L1 instruction cache: */
112#define L1I_LINE_SIZE 64
113#define L1I_ASSOCIATIVITY 8
114#define L1I_SETS 64
115#define L1I_PARTITIONS 1
116/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
117#define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
118/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
119#define L1I_LINES_PER_TAG 1
120#define L1I_SIZE_KB_AMD 64
121#define L1I_ASSOCIATIVITY_AMD 2
122
123/* Level 2 unified cache: */
124#define L2_LINE_SIZE 64
125#define L2_ASSOCIATIVITY 16
126#define L2_SETS 4096
127#define L2_PARTITIONS 1
128/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
129/*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
130#define L2_DESCRIPTOR CPUID_2_L2_2MB_8WAY_64B
131/*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
132#define L2_LINES_PER_TAG 1
133#define L2_SIZE_KB_AMD 512
134
Longpeng(Mike)14c985c2016-09-07 13:21:13 +0800135/* Level 3 unified cache: */
Eduardo Habkost5e891bf2013-08-27 12:24:37 -0300136#define L3_SIZE_KB 0 /* disabled */
137#define L3_ASSOCIATIVITY 0 /* disabled */
138#define L3_LINES_PER_TAG 0 /* disabled */
139#define L3_LINE_SIZE 0 /* disabled */
Longpeng(Mike)14c985c2016-09-07 13:21:13 +0800140#define L3_N_LINE_SIZE 64
141#define L3_N_ASSOCIATIVITY 16
142#define L3_N_SETS 16384
143#define L3_N_PARTITIONS 1
144#define L3_N_DESCRIPTOR CPUID_2_L3_16MB_16WAY_64B
145#define L3_N_LINES_PER_TAG 1
146#define L3_N_SIZE_KB_AMD 16384
Eduardo Habkost5e891bf2013-08-27 12:24:37 -0300147
148/* TLB definitions: */
149
150#define L1_DTLB_2M_ASSOC 1
151#define L1_DTLB_2M_ENTRIES 255
152#define L1_DTLB_4K_ASSOC 1
153#define L1_DTLB_4K_ENTRIES 255
154
155#define L1_ITLB_2M_ASSOC 1
156#define L1_ITLB_2M_ENTRIES 255
157#define L1_ITLB_4K_ASSOC 1
158#define L1_ITLB_4K_ENTRIES 255
159
160#define L2_DTLB_2M_ASSOC 0 /* disabled */
161#define L2_DTLB_2M_ENTRIES 0 /* disabled */
162#define L2_DTLB_4K_ASSOC 4
163#define L2_DTLB_4K_ENTRIES 512
164
165#define L2_ITLB_2M_ASSOC 0 /* disabled */
166#define L2_ITLB_2M_ENTRIES 0 /* disabled */
167#define L2_ITLB_4K_ASSOC 4
168#define L2_ITLB_4K_ENTRIES 512
169
170
171
Igor Mammedov99b88a12013-01-21 15:06:36 +0100172static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
173 uint32_t vendor2, uint32_t vendor3)
174{
175 int i;
176 for (i = 0; i < 4; i++) {
177 dst[i] = vendor1 >> (8 * i);
178 dst[i + 4] = vendor2 >> (8 * i);
179 dst[i + 8] = vendor3 >> (8 * i);
180 }
181 dst[CPUID_VENDOR_SZ] = '\0';
182}
183
Eduardo Habkost621626c2014-04-30 13:48:36 -0300184#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
185#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
186 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
187#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
188 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
189 CPUID_PSE36 | CPUID_FXSR)
190#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
191#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
192 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
193 CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
194 CPUID_PAE | CPUID_SEP | CPUID_APIC)
195
196#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
197 CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
198 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
199 CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
Eduardo Habkostb6c5a6f2015-10-07 16:39:43 -0300200 CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS | CPUID_DE)
Eduardo Habkost621626c2014-04-30 13:48:36 -0300201 /* partly implemented:
202 CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64) */
203 /* missing:
204 CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
205#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
206 CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
207 CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
Richard Henderson19dc85d2015-07-02 14:53:40 +0100208 CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */ \
Eduardo Habkost621626c2014-04-30 13:48:36 -0300209 CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
210 /* missing:
211 CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
212 CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
213 CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
Richard Henderson19dc85d2015-07-02 14:53:40 +0100214 CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_AVX,
215 CPUID_EXT_F16C, CPUID_EXT_RDRAND */
Eduardo Habkost621626c2014-04-30 13:48:36 -0300216
217#ifdef TARGET_X86_64
218#define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM)
219#else
220#define TCG_EXT2_X86_64_FEATURES 0
221#endif
222
223#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
224 CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
225 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_PDPE1GB | \
226 TCG_EXT2_X86_64_FEATURES)
227#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
228 CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
229#define TCG_EXT4_FEATURES 0
230#define TCG_SVM_FEATURES 0
231#define TCG_KVM_FEATURES 0
232#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
Xiao Guangrong0c472422015-10-29 15:31:39 +0800233 CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
234 CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT | \
Paolo Bonzini7eb24382016-06-17 17:47:13 +0200235 CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE | \
236 CPUID_7_0_EBX_ERMS)
Eduardo Habkost621626c2014-04-30 13:48:36 -0300237 /* missing:
Richard Henderson07929f22015-11-18 12:55:47 +0100238 CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
Paolo Bonzini7eb24382016-06-17 17:47:13 +0200239 CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
Eduardo Habkost621626c2014-04-30 13:48:36 -0300240 CPUID_7_0_EBX_RDSEED */
Paolo Bonzini0f70ed42016-02-09 14:14:28 +0100241#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE)
Luwei Kang95ea69f2016-10-31 16:27:26 +0800242#define TCG_7_0_EDX_FEATURES 0
Marcelo Tosatti303752a2014-04-30 13:48:45 -0300243#define TCG_APM_FEATURES 0
Jan Kiszka28b8e4d2015-06-07 11:15:08 +0200244#define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
Richard Hendersonc9cfe8f2015-07-02 15:21:23 +0100245#define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1)
246 /* missing:
247 CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
Eduardo Habkost621626c2014-04-30 13:48:36 -0300248
Eduardo Habkost5ef57872013-01-07 16:20:45 -0200249typedef struct FeatureWordInfo {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300250 /* feature flags names are taken from "Intel Processor Identification and
251 * the CPUID Instruction" and AMD's "CPUID Specification".
252 * In cases of disagreement between feature naming conventions,
253 * aliases may be added.
254 */
255 const char *feat_names[32];
Eduardo Habkost04d104b2013-04-22 16:00:16 -0300256 uint32_t cpuid_eax; /* Input EAX for CPUID */
257 bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
258 uint32_t cpuid_ecx; /* Input ECX value for CPUID */
259 int cpuid_reg; /* output register (R_* constant) */
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300260 uint32_t tcg_features; /* Feature flags supported by TCG */
Eduardo Habkost84f1b922014-04-30 13:48:41 -0300261 uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
Eduardo Habkost6fb2fff2016-09-28 12:00:29 -0300262 uint32_t migratable_flags; /* Feature flags known to be migratable */
Eduardo Habkost5ef57872013-01-07 16:20:45 -0200263} FeatureWordInfo;
264
265static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200266 [FEAT_1_EDX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300267 .feat_names = {
268 "fpu", "vme", "de", "pse",
269 "tsc", "msr", "pae", "mce",
270 "cx8", "apic", NULL, "sep",
271 "mtrr", "pge", "mca", "cmov",
272 "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
273 NULL, "ds" /* Intel dts */, "acpi", "mmx",
274 "fxsr", "sse", "sse2", "ss",
275 "ht" /* Intel htt */, "tm", "ia64", "pbe",
276 },
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200277 .cpuid_eax = 1, .cpuid_reg = R_EDX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300278 .tcg_features = TCG_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200279 },
280 [FEAT_1_ECX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300281 .feat_names = {
Eduardo Habkost16d2fca2016-09-30 15:49:41 -0300282 "pni" /* Intel,AMD sse3 */, "pclmulqdq", "dtes64", "monitor",
Eduardo Habkostfc7dfd22016-09-30 15:49:40 -0300283 "ds-cpl", "vmx", "smx", "est",
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300284 "tm2", "ssse3", "cid", NULL,
285 "fma", "cx16", "xtpr", "pdcm",
Eduardo Habkost16d2fca2016-09-30 15:49:41 -0300286 NULL, "pcid", "dca", "sse4.1",
287 "sse4.2", "x2apic", "movbe", "popcnt",
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300288 "tsc-deadline", "aes", "xsave", "osxsave",
289 "avx", "f16c", "rdrand", "hypervisor",
290 },
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200291 .cpuid_eax = 1, .cpuid_reg = R_ECX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300292 .tcg_features = TCG_EXT_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200293 },
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300294 /* Feature names that are already defined on feature_name[] but
295 * are set on CPUID[8000_0001].EDX on AMD CPUs don't have their
296 * names on feat_names below. They are copied automatically
297 * to features[FEAT_8000_0001_EDX] if and only if CPU vendor is AMD.
298 */
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200299 [FEAT_8000_0001_EDX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300300 .feat_names = {
301 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
302 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
303 NULL /* cx8 */, NULL /* apic */, NULL, "syscall",
304 NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
305 NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
Eduardo Habkost16d2fca2016-09-30 15:49:41 -0300306 "nx", NULL, "mmxext", NULL /* mmx */,
307 NULL /* fxsr */, "fxsr-opt", "pdpe1gb", "rdtscp",
308 NULL, "lm", "3dnowext", "3dnow",
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300309 },
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200310 .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300311 .tcg_features = TCG_EXT2_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200312 },
313 [FEAT_8000_0001_ECX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300314 .feat_names = {
Eduardo Habkostfc7dfd22016-09-30 15:49:40 -0300315 "lahf-lm", "cmp-legacy", "svm", "extapic",
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300316 "cr8legacy", "abm", "sse4a", "misalignsse",
317 "3dnowprefetch", "osvw", "ibs", "xop",
318 "skinit", "wdt", NULL, "lwp",
Eduardo Habkostfc7dfd22016-09-30 15:49:40 -0300319 "fma4", "tce", NULL, "nodeid-msr",
320 NULL, "tbm", "topoext", "perfctr-core",
321 "perfctr-nb", NULL, NULL, NULL,
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300322 NULL, NULL, NULL, NULL,
323 },
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200324 .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300325 .tcg_features = TCG_EXT3_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200326 },
Eduardo Habkost89e49c82013-01-07 16:20:47 -0200327 [FEAT_C000_0001_EDX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300328 .feat_names = {
329 NULL, NULL, "xstore", "xstore-en",
330 NULL, NULL, "xcrypt", "xcrypt-en",
331 "ace2", "ace2-en", "phe", "phe-en",
332 "pmm", "pmm-en", NULL, NULL,
333 NULL, NULL, NULL, NULL,
334 NULL, NULL, NULL, NULL,
335 NULL, NULL, NULL, NULL,
336 NULL, NULL, NULL, NULL,
337 },
Eduardo Habkost89e49c82013-01-07 16:20:47 -0200338 .cpuid_eax = 0xC0000001, .cpuid_reg = R_EDX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300339 .tcg_features = TCG_EXT4_FEATURES,
Eduardo Habkost89e49c82013-01-07 16:20:47 -0200340 },
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200341 [FEAT_KVM] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300342 .feat_names = {
Eduardo Habkostfc7dfd22016-09-30 15:49:40 -0300343 "kvmclock", "kvm-nopiodelay", "kvm-mmu", "kvmclock",
344 "kvm-asyncpf", "kvm-steal-time", "kvm-pv-eoi", "kvm-pv-unhalt",
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300345 NULL, NULL, NULL, NULL,
346 NULL, NULL, NULL, NULL,
347 NULL, NULL, NULL, NULL,
348 NULL, NULL, NULL, NULL,
349 "kvmclock-stable-bit", NULL, NULL, NULL,
350 NULL, NULL, NULL, NULL,
351 },
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200352 .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300353 .tcg_features = TCG_KVM_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200354 },
Evgeny Yakovlevc35bd192016-06-24 13:49:36 +0300355 [FEAT_HYPERV_EAX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300356 .feat_names = {
357 NULL /* hv_msr_vp_runtime_access */, NULL /* hv_msr_time_refcount_access */,
358 NULL /* hv_msr_synic_access */, NULL /* hv_msr_stimer_access */,
359 NULL /* hv_msr_apic_access */, NULL /* hv_msr_hypercall_access */,
360 NULL /* hv_vpindex_access */, NULL /* hv_msr_reset_access */,
361 NULL /* hv_msr_stats_access */, NULL /* hv_reftsc_access */,
362 NULL /* hv_msr_idle_access */, NULL /* hv_msr_frequency_access */,
363 NULL, NULL, NULL, NULL,
364 NULL, NULL, NULL, NULL,
365 NULL, NULL, NULL, NULL,
366 NULL, NULL, NULL, NULL,
367 NULL, NULL, NULL, NULL,
368 },
Evgeny Yakovlevc35bd192016-06-24 13:49:36 +0300369 .cpuid_eax = 0x40000003, .cpuid_reg = R_EAX,
370 },
371 [FEAT_HYPERV_EBX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300372 .feat_names = {
373 NULL /* hv_create_partitions */, NULL /* hv_access_partition_id */,
374 NULL /* hv_access_memory_pool */, NULL /* hv_adjust_message_buffers */,
375 NULL /* hv_post_messages */, NULL /* hv_signal_events */,
376 NULL /* hv_create_port */, NULL /* hv_connect_port */,
377 NULL /* hv_access_stats */, NULL, NULL, NULL /* hv_debugging */,
378 NULL /* hv_cpu_power_management */, NULL /* hv_configure_profiler */,
379 NULL, NULL,
380 NULL, NULL, NULL, NULL,
381 NULL, NULL, NULL, NULL,
382 NULL, NULL, NULL, NULL,
383 NULL, NULL, NULL, NULL,
384 },
Evgeny Yakovlevc35bd192016-06-24 13:49:36 +0300385 .cpuid_eax = 0x40000003, .cpuid_reg = R_EBX,
386 },
387 [FEAT_HYPERV_EDX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300388 .feat_names = {
389 NULL /* hv_mwait */, NULL /* hv_guest_debugging */,
390 NULL /* hv_perf_monitor */, NULL /* hv_cpu_dynamic_part */,
391 NULL /* hv_hypercall_params_xmm */, NULL /* hv_guest_idle_state */,
392 NULL, NULL,
393 NULL, NULL, NULL /* hv_guest_crash_msr */, NULL,
394 NULL, NULL, NULL, NULL,
395 NULL, NULL, NULL, NULL,
396 NULL, NULL, NULL, NULL,
397 NULL, NULL, NULL, NULL,
398 NULL, NULL, NULL, NULL,
399 },
Evgeny Yakovlevc35bd192016-06-24 13:49:36 +0300400 .cpuid_eax = 0x40000003, .cpuid_reg = R_EDX,
401 },
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200402 [FEAT_SVM] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300403 .feat_names = {
Eduardo Habkostfc7dfd22016-09-30 15:49:40 -0300404 "npt", "lbrv", "svm-lock", "nrip-save",
405 "tsc-scale", "vmcb-clean", "flushbyasid", "decodeassists",
406 NULL, NULL, "pause-filter", NULL,
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300407 "pfthreshold", NULL, NULL, NULL,
408 NULL, NULL, NULL, NULL,
409 NULL, NULL, NULL, NULL,
410 NULL, NULL, NULL, NULL,
411 NULL, NULL, NULL, NULL,
412 },
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200413 .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300414 .tcg_features = TCG_SVM_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200415 },
416 [FEAT_7_0_EBX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300417 .feat_names = {
Eduardo Habkostfc7dfd22016-09-30 15:49:40 -0300418 "fsgsbase", "tsc-adjust", NULL, "bmi1",
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300419 "hle", "avx2", NULL, "smep",
420 "bmi2", "erms", "invpcid", "rtm",
421 NULL, NULL, "mpx", NULL,
422 "avx512f", "avx512dq", "rdseed", "adx",
423 "smap", "avx512ifma", "pcommit", "clflushopt",
424 "clwb", NULL, "avx512pf", "avx512er",
425 "avx512cd", NULL, "avx512bw", "avx512vl",
426 },
Eduardo Habkost04d104b2013-04-22 16:00:16 -0300427 .cpuid_eax = 7,
428 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
429 .cpuid_reg = R_EBX,
Eduardo Habkost37ce3522014-04-30 13:48:38 -0300430 .tcg_features = TCG_7_0_EBX_FEATURES,
Eduardo Habkostbffd67b2013-01-07 16:20:46 -0200431 },
Huaitong Hanf74eefe2015-11-18 10:20:15 +0800432 [FEAT_7_0_ECX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300433 .feat_names = {
434 NULL, "avx512vbmi", "umip", "pku",
435 "ospke", NULL, NULL, NULL,
436 NULL, NULL, NULL, NULL,
437 NULL, NULL, NULL, NULL,
438 NULL, NULL, NULL, NULL,
439 NULL, NULL, "rdpid", NULL,
440 NULL, NULL, NULL, NULL,
441 NULL, NULL, NULL, NULL,
442 },
Huaitong Hanf74eefe2015-11-18 10:20:15 +0800443 .cpuid_eax = 7,
444 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
445 .cpuid_reg = R_ECX,
446 .tcg_features = TCG_7_0_ECX_FEATURES,
447 },
Luwei Kang95ea69f2016-10-31 16:27:26 +0800448 [FEAT_7_0_EDX] = {
449 .feat_names = {
450 NULL, NULL, "avx512-4vnniw", "avx512-4fmaps",
451 NULL, NULL, NULL, NULL,
452 NULL, NULL, NULL, NULL,
453 NULL, NULL, NULL, NULL,
454 NULL, NULL, NULL, NULL,
455 NULL, NULL, NULL, NULL,
456 NULL, NULL, NULL, NULL,
457 NULL, NULL, NULL, NULL,
458 },
459 .cpuid_eax = 7,
460 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
461 .cpuid_reg = R_EDX,
462 .tcg_features = TCG_7_0_EDX_FEATURES,
463 },
Marcelo Tosatti303752a2014-04-30 13:48:45 -0300464 [FEAT_8000_0007_EDX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300465 .feat_names = {
466 NULL, NULL, NULL, NULL,
467 NULL, NULL, NULL, NULL,
468 "invtsc", NULL, NULL, NULL,
469 NULL, NULL, NULL, NULL,
470 NULL, NULL, NULL, NULL,
471 NULL, NULL, NULL, NULL,
472 NULL, NULL, NULL, NULL,
473 NULL, NULL, NULL, NULL,
474 },
Marcelo Tosatti303752a2014-04-30 13:48:45 -0300475 .cpuid_eax = 0x80000007,
476 .cpuid_reg = R_EDX,
477 .tcg_features = TCG_APM_FEATURES,
478 .unmigratable_flags = CPUID_APM_INVTSC,
479 },
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +0100480 [FEAT_XSAVE] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300481 .feat_names = {
482 "xsaveopt", "xsavec", "xgetbv1", "xsaves",
483 NULL, NULL, NULL, NULL,
484 NULL, NULL, NULL, NULL,
485 NULL, NULL, NULL, NULL,
486 NULL, NULL, NULL, NULL,
487 NULL, NULL, NULL, NULL,
488 NULL, NULL, NULL, NULL,
489 NULL, NULL, NULL, NULL,
490 },
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +0100491 .cpuid_eax = 0xd,
492 .cpuid_needs_ecx = true, .cpuid_ecx = 1,
493 .cpuid_reg = R_EAX,
Richard Hendersonc9cfe8f2015-07-02 15:21:23 +0100494 .tcg_features = TCG_XSAVE_FEATURES,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +0100495 },
Jan Kiszka28b8e4d2015-06-07 11:15:08 +0200496 [FEAT_6_EAX] = {
Eduardo Habkost2d5312d2016-05-12 11:24:04 -0300497 .feat_names = {
498 NULL, NULL, "arat", NULL,
499 NULL, NULL, NULL, NULL,
500 NULL, NULL, NULL, NULL,
501 NULL, NULL, NULL, NULL,
502 NULL, NULL, NULL, NULL,
503 NULL, NULL, NULL, NULL,
504 NULL, NULL, NULL, NULL,
505 NULL, NULL, NULL, NULL,
506 },
Jan Kiszka28b8e4d2015-06-07 11:15:08 +0200507 .cpuid_eax = 6, .cpuid_reg = R_EAX,
508 .tcg_features = TCG_6_EAX_FEATURES,
509 },
Eduardo Habkost96193c22016-09-22 17:41:35 -0300510 [FEAT_XSAVE_COMP_LO] = {
511 .cpuid_eax = 0xD,
512 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
513 .cpuid_reg = R_EAX,
514 .tcg_features = ~0U,
Eduardo Habkost6fb2fff2016-09-28 12:00:29 -0300515 .migratable_flags = XSTATE_FP_MASK | XSTATE_SSE_MASK |
516 XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK |
517 XSTATE_OPMASK_MASK | XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_MASK |
518 XSTATE_PKRU_MASK,
Eduardo Habkost96193c22016-09-22 17:41:35 -0300519 },
520 [FEAT_XSAVE_COMP_HI] = {
521 .cpuid_eax = 0xD,
522 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
523 .cpuid_reg = R_EDX,
524 .tcg_features = ~0U,
525 },
Eduardo Habkost5ef57872013-01-07 16:20:45 -0200526};
527
Eduardo Habkost8e8aba52013-05-06 13:20:07 -0300528typedef struct X86RegisterInfo32 {
529 /* Name of register */
530 const char *name;
531 /* QAPI enum value register */
532 X86CPURegister32 qapi_enum;
533} X86RegisterInfo32;
534
535#define REGISTER(reg) \
Wenchao Xia5d371f42014-03-04 18:44:40 -0800536 [R_##reg] = { .name = #reg, .qapi_enum = X86_CPU_REGISTER32_##reg }
Stefan Weila443bc32014-03-16 15:03:41 +0100537static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
Eduardo Habkost8e8aba52013-05-06 13:20:07 -0300538 REGISTER(EAX),
539 REGISTER(ECX),
540 REGISTER(EDX),
541 REGISTER(EBX),
542 REGISTER(ESP),
543 REGISTER(EBP),
544 REGISTER(ESI),
545 REGISTER(EDI),
546};
547#undef REGISTER
548
Richard Henderson3f32bd22016-07-06 13:35:00 -0700549typedef struct ExtSaveArea {
550 uint32_t feature, bits;
551 uint32_t offset, size;
552} ExtSaveArea;
553
554static const ExtSaveArea x86_ext_save_areas[] = {
Eduardo Habkoste3c90222016-09-30 15:49:42 -0300555 [XSTATE_FP_BIT] = {
556 /* x87 FP state component is always enabled if XSAVE is supported */
557 .feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
558 /* x87 state is in the legacy region of the XSAVE area */
559 .offset = 0,
560 .size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
561 },
562 [XSTATE_SSE_BIT] = {
563 /* SSE state component is always enabled if XSAVE is supported */
564 .feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
565 /* SSE state is in the legacy region of the XSAVE area */
566 .offset = 0,
567 .size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
568 },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100569 [XSTATE_YMM_BIT] =
570 { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200571 .offset = offsetof(X86XSaveArea, avx_state),
572 .size = sizeof(XSaveAVX) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100573 [XSTATE_BNDREGS_BIT] =
574 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200575 .offset = offsetof(X86XSaveArea, bndreg_state),
576 .size = sizeof(XSaveBNDREG) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100577 [XSTATE_BNDCSR_BIT] =
578 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200579 .offset = offsetof(X86XSaveArea, bndcsr_state),
580 .size = sizeof(XSaveBNDCSR) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100581 [XSTATE_OPMASK_BIT] =
582 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200583 .offset = offsetof(X86XSaveArea, opmask_state),
584 .size = sizeof(XSaveOpmask) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100585 [XSTATE_ZMM_Hi256_BIT] =
586 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200587 .offset = offsetof(X86XSaveArea, zmm_hi256_state),
588 .size = sizeof(XSaveZMM_Hi256) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100589 [XSTATE_Hi16_ZMM_BIT] =
590 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200591 .offset = offsetof(X86XSaveArea, hi16_zmm_state),
592 .size = sizeof(XSaveHi16_ZMM) },
Paolo Bonzinicfc3b072016-02-17 10:54:53 +0100593 [XSTATE_PKRU_BIT] =
594 { .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU,
Eduardo Habkostee1b09f2015-11-28 14:32:26 -0200595 .offset = offsetof(X86XSaveArea, pkru_state),
596 .size = sizeof(XSavePKRU) },
Paolo Bonzini2560f192013-10-02 17:54:57 +0200597};
Eduardo Habkost8e8aba52013-05-06 13:20:07 -0300598
Eduardo Habkost1fda6192016-09-22 17:14:07 -0300599static uint32_t xsave_area_size(uint64_t mask)
600{
601 int i;
Eduardo Habkoste3c90222016-09-30 15:49:42 -0300602 uint64_t ret = 0;
Eduardo Habkost1fda6192016-09-22 17:14:07 -0300603
Eduardo Habkoste3c90222016-09-30 15:49:42 -0300604 for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
Eduardo Habkost1fda6192016-09-22 17:14:07 -0300605 const ExtSaveArea *esa = &x86_ext_save_areas[i];
606 if ((mask >> i) & 1) {
607 ret = MAX(ret, esa->offset + esa->size);
608 }
609 }
610 return ret;
611}
612
Eduardo Habkost96193c22016-09-22 17:41:35 -0300613static inline uint64_t x86_cpu_xsave_components(X86CPU *cpu)
614{
615 return ((uint64_t)cpu->env.features[FEAT_XSAVE_COMP_HI]) << 32 |
616 cpu->env.features[FEAT_XSAVE_COMP_LO];
617}
618
Eduardo Habkost8b4bedd2013-01-04 20:01:06 -0200619const char *get_register_name_32(unsigned int reg)
620{
Igor Mammedov31ccdde2013-06-03 18:23:27 +0200621 if (reg >= CPU_NB_REGS32) {
Eduardo Habkost8b4bedd2013-01-04 20:01:06 -0200622 return NULL;
623 }
Eduardo Habkost8e8aba52013-05-06 13:20:07 -0300624 return x86_reg_info_32[reg].name;
Eduardo Habkost8b4bedd2013-01-04 20:01:06 -0200625}
626
Eduardo Habkost84f1b922014-04-30 13:48:41 -0300627/*
628 * Returns the set of feature flags that are supported and migratable by
629 * QEMU, for a given FeatureWord.
630 */
631static uint32_t x86_cpu_get_migratable_flags(FeatureWord w)
632{
633 FeatureWordInfo *wi = &feature_word_info[w];
634 uint32_t r = 0;
635 int i;
636
637 for (i = 0; i < 32; i++) {
638 uint32_t f = 1U << i;
Eduardo Habkost6fb2fff2016-09-28 12:00:29 -0300639
640 /* If the feature name is known, it is implicitly considered migratable,
641 * unless it is explicitly set in unmigratable_flags */
642 if ((wi->migratable_flags & f) ||
643 (wi->feat_names[i] && !(wi->unmigratable_flags & f))) {
644 r |= f;
Eduardo Habkost84f1b922014-04-30 13:48:41 -0300645 }
Eduardo Habkost84f1b922014-04-30 13:48:41 -0300646 }
647 return r;
648}
649
Jan Kiszkabb44e0d2011-01-21 21:48:07 +0100650void host_cpuid(uint32_t function, uint32_t count,
651 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
Andre Przywarabdde4762010-03-11 14:38:58 +0100652{
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600653 uint32_t vec[4];
654
655#ifdef __x86_64__
656 asm volatile("cpuid"
657 : "=a"(vec[0]), "=b"(vec[1]),
658 "=c"(vec[2]), "=d"(vec[3])
659 : "0"(function), "c"(count) : "cc");
Eduardo Habkostc1f41222014-01-30 17:48:53 -0200660#elif defined(__i386__)
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600661 asm volatile("pusha \n\t"
662 "cpuid \n\t"
663 "mov %%eax, 0(%2) \n\t"
664 "mov %%ebx, 4(%2) \n\t"
665 "mov %%ecx, 8(%2) \n\t"
666 "mov %%edx, 12(%2) \n\t"
667 "popa"
668 : : "a"(function), "c"(count), "S"(vec)
669 : "memory", "cc");
Eduardo Habkostc1f41222014-01-30 17:48:53 -0200670#else
671 abort();
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600672#endif
673
Andre Przywarabdde4762010-03-11 14:38:58 +0100674 if (eax)
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600675 *eax = vec[0];
Andre Przywarabdde4762010-03-11 14:38:58 +0100676 if (ebx)
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600677 *ebx = vec[1];
Andre Przywarabdde4762010-03-11 14:38:58 +0100678 if (ecx)
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600679 *ecx = vec[2];
Andre Przywarabdde4762010-03-11 14:38:58 +0100680 if (edx)
Anthony Liguoria1fd24a2011-11-27 11:13:01 -0600681 *edx = vec[3];
Andre Przywarabdde4762010-03-11 14:38:58 +0100682}
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100683
Eduardo Habkostd940ee92014-02-10 08:21:30 -0200684/* CPU class name definitions: */
685
686#define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU
687#define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX)
688
689/* Return type name for a given CPU model name
690 * Caller is responsible for freeing the returned string.
691 */
692static char *x86_cpu_type_name(const char *model_name)
693{
694 return g_strdup_printf(X86_CPU_TYPE_NAME("%s"), model_name);
695}
696
Andreas Färber500050d2014-02-10 22:02:44 +0100697static ObjectClass *x86_cpu_class_by_name(const char *cpu_model)
698{
Eduardo Habkostd940ee92014-02-10 08:21:30 -0200699 ObjectClass *oc;
700 char *typename;
701
Andreas Färber500050d2014-02-10 22:02:44 +0100702 if (cpu_model == NULL) {
703 return NULL;
704 }
705
Eduardo Habkostd940ee92014-02-10 08:21:30 -0200706 typename = x86_cpu_type_name(cpu_model);
707 oc = object_class_by_name(typename);
708 g_free(typename);
709 return oc;
Andreas Färber500050d2014-02-10 22:02:44 +0100710}
711
Igor Mammedov104494e2016-06-06 17:16:45 +0200712static char *x86_cpu_class_get_model_name(X86CPUClass *cc)
713{
714 const char *class_name = object_class_get_name(OBJECT_CLASS(cc));
715 assert(g_str_has_suffix(class_name, X86_CPU_TYPE_SUFFIX));
716 return g_strndup(class_name,
717 strlen(class_name) - strlen(X86_CPU_TYPE_SUFFIX));
718}
719
Eduardo Habkostd940ee92014-02-10 08:21:30 -0200720struct X86CPUDefinition {
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100721 const char *name;
722 uint32_t level;
Eduardo Habkost90e4b0c2013-04-22 16:00:12 -0300723 uint32_t xlevel;
Igor Mammedov99b88a12013-01-21 15:06:36 +0100724 /* vendor is zero-terminated, 12 character ASCII string */
725 char vendor[CPUID_VENDOR_SZ + 1];
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100726 int family;
727 int model;
728 int stepping;
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300729 FeatureWordArray features;
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100730 char model_id[48];
Eduardo Habkostd940ee92014-02-10 08:21:30 -0200731};
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100732
Eduardo Habkost9576de72014-01-30 17:48:58 -0200733static X86CPUDefinition builtin_x86_defs[] = {
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100734 {
735 .name = "qemu64",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200736 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100737 .vendor = CPUID_VENDOR_AMD,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100738 .family = 6,
Eduardo Habkostf8e6a112013-09-10 17:48:59 -0300739 .model = 6,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100740 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300741 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300742 PPRO_FEATURES |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100743 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100744 CPUID_PSE36,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300745 .features[FEAT_1_ECX] =
Eduardo Habkost6aa91e42015-11-03 17:24:18 -0200746 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300747 .features[FEAT_8000_0001_EDX] =
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100748 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300749 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost71195672015-11-03 17:24:18 -0200750 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100751 .xlevel = 0x8000000A,
Eduardo Habkost9cf2cc32016-04-09 16:44:20 -0300752 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100753 },
754 {
755 .name = "phenom",
756 .level = 5,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100757 .vendor = CPUID_VENDOR_AMD,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100758 .family = 16,
759 .model = 2,
760 .stepping = 3,
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300761 /* Missing: CPUID_HT */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300762 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300763 PPRO_FEATURES |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100764 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300765 CPUID_PSE36 | CPUID_VME,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300766 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300767 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100768 CPUID_EXT_POPCNT,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300769 .features[FEAT_8000_0001_EDX] =
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100770 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
771 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
Aurelien Jarno8560efe2010-03-13 16:43:15 +0100772 CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100773 /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
774 CPUID_EXT3_CR8LEG,
775 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
776 CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300777 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300778 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100779 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300780 /* Missing: CPUID_SVM_LBRV */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300781 .features[FEAT_SVM] =
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300782 CPUID_SVM_NPT,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100783 .xlevel = 0x8000001A,
784 .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
785 },
786 {
787 .name = "core2duo",
788 .level = 10,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100789 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100790 .family = 6,
791 .model = 15,
792 .stepping = 11,
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300793 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300794 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300795 PPRO_FEATURES |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100796 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300797 CPUID_PSE36 | CPUID_VME | CPUID_ACPI | CPUID_SS,
798 /* Missing: CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_EST,
Eduardo Habkoste93abc12014-10-03 16:39:50 -0300799 * CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_VMX */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300800 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300801 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
Eduardo Habkoste93abc12014-10-03 16:39:50 -0300802 CPUID_EXT_CX16,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300803 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300804 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300805 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300806 CPUID_EXT3_LAHF_LM,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100807 .xlevel = 0x80000008,
808 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
809 },
810 {
811 .name = "kvm64",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200812 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100813 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100814 .family = 15,
815 .model = 6,
816 .stepping = 1,
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -0200817 /* Missing: CPUID_HT */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300818 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -0200819 PPRO_FEATURES | CPUID_VME |
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100820 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
821 CPUID_PSE36,
822 /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300823 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300824 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100825 /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300826 .features[FEAT_8000_0001_EDX] =
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100827 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
828 /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
829 CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
830 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
831 CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300832 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300833 0,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100834 .xlevel = 0x80000008,
835 .model_id = "Common KVM processor"
836 },
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100837 {
838 .name = "qemu32",
839 .level = 4,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100840 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100841 .family = 6,
Eduardo Habkostf8e6a112013-09-10 17:48:59 -0300842 .model = 6,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100843 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300844 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300845 PPRO_FEATURES,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300846 .features[FEAT_1_ECX] =
Eduardo Habkost6aa91e42015-11-03 17:24:18 -0200847 CPUID_EXT_SSE3,
Andre Przywara58012d62010-03-11 14:39:06 +0100848 .xlevel = 0x80000004,
Eduardo Habkost9cf2cc32016-04-09 16:44:20 -0300849 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100850 },
851 {
Andre Przywaraeafaf1e2010-05-21 09:50:51 +0200852 .name = "kvm32",
853 .level = 5,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100854 .vendor = CPUID_VENDOR_INTEL,
Andre Przywaraeafaf1e2010-05-21 09:50:51 +0200855 .family = 15,
856 .model = 6,
857 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300858 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -0200859 PPRO_FEATURES | CPUID_VME |
Andre Przywaraeafaf1e2010-05-21 09:50:51 +0200860 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300861 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300862 CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300863 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300864 0,
Andre Przywaraeafaf1e2010-05-21 09:50:51 +0200865 .xlevel = 0x80000008,
866 .model_id = "Common 32-bit KVM processor"
867 },
868 {
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100869 .name = "coreduo",
870 .level = 10,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100871 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100872 .family = 6,
873 .model = 14,
874 .stepping = 8,
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300875 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300876 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300877 PPRO_FEATURES | CPUID_VME |
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300878 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_ACPI |
879 CPUID_SS,
880 /* Missing: CPUID_EXT_EST, CPUID_EXT_TM2 , CPUID_EXT_XTPR,
Eduardo Habkoste93abc12014-10-03 16:39:50 -0300881 * CPUID_EXT_PDCM, CPUID_EXT_VMX */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300882 .features[FEAT_1_ECX] =
Eduardo Habkoste93abc12014-10-03 16:39:50 -0300883 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300884 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300885 CPUID_EXT2_NX,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100886 .xlevel = 0x80000008,
887 .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
888 },
889 {
890 .name = "486",
Andre Przywara58012d62010-03-11 14:39:06 +0100891 .level = 1,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100892 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100893 .family = 4,
Andreas Färberb2a856d2013-05-01 17:30:51 +0200894 .model = 8,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100895 .stepping = 0,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300896 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300897 I486_FEATURES,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100898 .xlevel = 0,
899 },
900 {
901 .name = "pentium",
902 .level = 1,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100903 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100904 .family = 5,
905 .model = 4,
906 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300907 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300908 PENTIUM_FEATURES,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100909 .xlevel = 0,
910 },
911 {
912 .name = "pentium2",
913 .level = 2,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100914 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100915 .family = 6,
916 .model = 5,
917 .stepping = 2,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300918 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300919 PENTIUM2_FEATURES,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100920 .xlevel = 0,
921 },
922 {
923 .name = "pentium3",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200924 .level = 3,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100925 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100926 .family = 6,
927 .model = 7,
928 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300929 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300930 PENTIUM3_FEATURES,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100931 .xlevel = 0,
932 },
933 {
934 .name = "athlon",
935 .level = 2,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100936 .vendor = CPUID_VENDOR_AMD,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100937 .family = 6,
938 .model = 2,
939 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300940 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300941 PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
Eduardo Habkost60032ac2012-09-06 10:05:37 +0000942 CPUID_MCA,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300943 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost60032ac2012-09-06 10:05:37 +0000944 CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100945 .xlevel = 0x80000008,
Eduardo Habkost9cf2cc32016-04-09 16:44:20 -0300946 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100947 },
948 {
949 .name = "n270",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200950 .level = 10,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100951 .vendor = CPUID_VENDOR_INTEL,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100952 .family = 6,
953 .model = 28,
954 .stepping = 2,
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300955 /* Missing: CPUID_DTS, CPUID_HT, CPUID_TM, CPUID_PBE */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300956 .features[FEAT_1_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300957 PPRO_FEATURES |
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300958 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME |
959 CPUID_ACPI | CPUID_SS,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100960 /* Some CPUs got no CPUID_SEP */
Eduardo Habkostb9fc20b2014-10-03 16:39:49 -0300961 /* Missing: CPUID_EXT_DSCPL, CPUID_EXT_EST, CPUID_EXT_TM2,
962 * CPUID_EXT_XTPR */
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300963 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300964 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
Borislav Petkov4458c232013-04-25 15:43:04 -0300965 CPUID_EXT_MOVBE,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300966 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost60032ac2012-09-06 10:05:37 +0000967 CPUID_EXT2_NX,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300968 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300969 CPUID_EXT3_LAHF_LM,
Radim Krčmář3046bb52015-07-09 21:07:39 +0200970 .xlevel = 0x80000008,
Andre Przywarac6dc6f62010-03-11 14:38:55 +0100971 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
972 },
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300973 {
974 .name = "Conroe",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200975 .level = 10,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100976 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300977 .family = 6,
Eduardo Habkostffce9eb2013-05-27 17:23:54 -0300978 .model = 15,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300979 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300980 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -0200981 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -0300982 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
983 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
984 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
985 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300986 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300987 CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300988 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300989 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
Eduardo Habkost0514ef22013-04-22 16:00:15 -0300990 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -0300991 CPUID_EXT3_LAHF_LM,
Radim Krčmář3046bb52015-07-09 21:07:39 +0200992 .xlevel = 0x80000008,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300993 .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
994 },
995 {
996 .name = "Penryn",
Radim Krčmář3046bb52015-07-09 21:07:39 +0200997 .level = 10,
Igor Mammedov99b88a12013-01-21 15:06:36 +0100998 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost3eca4642012-09-05 17:41:10 -0300999 .family = 6,
Eduardo Habkostffce9eb2013-05-27 17:23:54 -03001000 .model = 23,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001001 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001002 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001003 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001004 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1005 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1006 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1007 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001008 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001009 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001010 CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001011 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001012 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001013 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001014 CPUID_EXT3_LAHF_LM,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001015 .xlevel = 0x80000008,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001016 .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
1017 },
1018 {
1019 .name = "Nehalem",
Radim Krčmář3046bb52015-07-09 21:07:39 +02001020 .level = 11,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001021 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001022 .family = 6,
Eduardo Habkostffce9eb2013-05-27 17:23:54 -03001023 .model = 26,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001024 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001025 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001026 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001027 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1028 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1029 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1030 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001031 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001032 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001033 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001034 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001035 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001036 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001037 CPUID_EXT3_LAHF_LM,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001038 .xlevel = 0x80000008,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001039 .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
1040 },
1041 {
1042 .name = "Westmere",
1043 .level = 11,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001044 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001045 .family = 6,
1046 .model = 44,
1047 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001048 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001049 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001050 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1051 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1052 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1053 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001054 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001055 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001056 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1057 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001058 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001059 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001060 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001061 CPUID_EXT3_LAHF_LM,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001062 .features[FEAT_6_EAX] =
1063 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001064 .xlevel = 0x80000008,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001065 .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
1066 },
1067 {
1068 .name = "SandyBridge",
1069 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001070 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001071 .family = 6,
1072 .model = 42,
1073 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001074 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001075 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001076 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1077 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1078 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1079 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001080 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001081 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001082 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1083 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1084 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1085 CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001086 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001087 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001088 CPUID_EXT2_SYSCALL,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001089 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001090 CPUID_EXT3_LAHF_LM,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01001091 .features[FEAT_XSAVE] =
1092 CPUID_XSAVE_XSAVEOPT,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001093 .features[FEAT_6_EAX] =
1094 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001095 .xlevel = 0x80000008,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001096 .model_id = "Intel Xeon E312xx (Sandy Bridge)",
1097 },
1098 {
Paolo Bonzini2f9ac422014-12-05 10:55:23 +01001099 .name = "IvyBridge",
1100 .level = 0xd,
1101 .vendor = CPUID_VENDOR_INTEL,
1102 .family = 6,
1103 .model = 58,
1104 .stepping = 9,
1105 .features[FEAT_1_EDX] =
1106 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1107 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1108 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1109 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1110 CPUID_DE | CPUID_FP87,
1111 .features[FEAT_1_ECX] =
1112 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1113 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1114 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1115 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1116 CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1117 .features[FEAT_7_0_EBX] =
1118 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
1119 CPUID_7_0_EBX_ERMS,
1120 .features[FEAT_8000_0001_EDX] =
1121 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1122 CPUID_EXT2_SYSCALL,
1123 .features[FEAT_8000_0001_ECX] =
1124 CPUID_EXT3_LAHF_LM,
1125 .features[FEAT_XSAVE] =
1126 CPUID_XSAVE_XSAVEOPT,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001127 .features[FEAT_6_EAX] =
1128 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001129 .xlevel = 0x80000008,
Paolo Bonzini2f9ac422014-12-05 10:55:23 +01001130 .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
1131 },
1132 {
Eduardo Habkosta3568502015-03-13 15:58:09 -03001133 .name = "Haswell-noTSX",
1134 .level = 0xd,
1135 .vendor = CPUID_VENDOR_INTEL,
1136 .family = 6,
1137 .model = 60,
1138 .stepping = 1,
1139 .features[FEAT_1_EDX] =
1140 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1141 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1142 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1143 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1144 CPUID_DE | CPUID_FP87,
1145 .features[FEAT_1_ECX] =
1146 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1147 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1148 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1149 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1150 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1151 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1152 .features[FEAT_8000_0001_EDX] =
1153 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1154 CPUID_EXT2_SYSCALL,
1155 .features[FEAT_8000_0001_ECX] =
Paolo Bonzinibecb6662015-09-28 14:00:18 +02001156 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
Eduardo Habkosta3568502015-03-13 15:58:09 -03001157 .features[FEAT_7_0_EBX] =
1158 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1159 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1160 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
1161 .features[FEAT_XSAVE] =
1162 CPUID_XSAVE_XSAVEOPT,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001163 .features[FEAT_6_EAX] =
1164 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001165 .xlevel = 0x80000008,
Eduardo Habkosta3568502015-03-13 15:58:09 -03001166 .model_id = "Intel Core Processor (Haswell, no TSX)",
1167 }, {
Eduardo Habkost37507092012-11-14 16:28:54 -02001168 .name = "Haswell",
1169 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001170 .vendor = CPUID_VENDOR_INTEL,
Eduardo Habkost37507092012-11-14 16:28:54 -02001171 .family = 6,
1172 .model = 60,
1173 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001174 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001175 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001176 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1177 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1178 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1179 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001180 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001181 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001182 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1183 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1184 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1185 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
Paolo Bonzini78a611f2014-12-05 10:52:46 +01001186 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001187 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001188 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001189 CPUID_EXT2_SYSCALL,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001190 .features[FEAT_8000_0001_ECX] =
Paolo Bonzinibecb6662015-09-28 14:00:18 +02001191 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001192 .features[FEAT_7_0_EBX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001193 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
Eduardo Habkost1ee91592015-03-13 15:39:43 -03001194 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1195 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1196 CPUID_7_0_EBX_RTM,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01001197 .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 Habkost37507092012-11-14 16:28:54 -02001202 .model_id = "Intel Core Processor (Haswell)",
1203 },
1204 {
Eduardo Habkosta3568502015-03-13 15:58:09 -03001205 .name = "Broadwell-noTSX",
1206 .level = 0xd,
1207 .vendor = CPUID_VENDOR_INTEL,
1208 .family = 6,
1209 .model = 61,
1210 .stepping = 2,
1211 .features[FEAT_1_EDX] =
1212 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1213 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 |
1223 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1224 .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 Habkosta3568502015-03-13 15:58:09 -03001229 .features[FEAT_7_0_EBX] =
1230 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1231 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1232 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1233 CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1234 CPUID_7_0_EBX_SMAP,
1235 .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 Habkosta3568502015-03-13 15:58:09 -03001240 .model_id = "Intel Core Processor (Broadwell, no TSX)",
1241 },
1242 {
Eduardo Habkostece01352014-06-17 17:11:40 -03001243 .name = "Broadwell",
1244 .level = 0xd,
1245 .vendor = CPUID_VENDOR_INTEL,
1246 .family = 6,
1247 .model = 61,
1248 .stepping = 2,
1249 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001250 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostece01352014-06-17 17:11:40 -03001251 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 |
Paolo Bonzini78a611f2014-12-05 10:52:46 +01001261 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
Eduardo Habkostece01352014-06-17 17:11:40 -03001262 .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] =
Paolo Bonzinibecb6662015-09-28 14:00:18 +02001266 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
Eduardo Habkostece01352014-06-17 17:11:40 -03001267 .features[FEAT_7_0_EBX] =
1268 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
Eduardo Habkost1ee91592015-03-13 15:39:43 -03001269 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
Eduardo Habkostece01352014-06-17 17:11:40 -03001270 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
Eduardo Habkost1ee91592015-03-13 15:39:43 -03001271 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
Eduardo Habkostece01352014-06-17 17:11:40 -03001272 CPUID_7_0_EBX_SMAP,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01001273 .features[FEAT_XSAVE] =
1274 CPUID_XSAVE_XSAVEOPT,
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02001275 .features[FEAT_6_EAX] =
1276 CPUID_6_EAX_ARAT,
Radim Krčmář3046bb52015-07-09 21:07:39 +02001277 .xlevel = 0x80000008,
Eduardo Habkostece01352014-06-17 17:11:40 -03001278 .model_id = "Intel Core Processor (Broadwell)",
1279 },
1280 {
Eduardo Habkostf6f949e2016-04-27 16:13:06 +08001281 .name = "Skylake-Client",
1282 .level = 0xd,
1283 .vendor = CPUID_VENDOR_INTEL,
1284 .family = 6,
1285 .model = 94,
1286 .stepping = 3,
1287 .features[FEAT_1_EDX] =
1288 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1289 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1290 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1291 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1292 CPUID_DE | CPUID_FP87,
1293 .features[FEAT_1_ECX] =
1294 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1295 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1296 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1297 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1298 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1299 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1300 .features[FEAT_8000_0001_EDX] =
1301 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1302 CPUID_EXT2_SYSCALL,
1303 .features[FEAT_8000_0001_ECX] =
1304 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
1305 .features[FEAT_7_0_EBX] =
1306 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1307 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1308 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
1309 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
1310 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
1311 /* Missing: XSAVES (not supported by some Linux versions,
1312 * including v4.1 to v4.6).
1313 * KVM doesn't yet expose any XSAVES state save component,
1314 * and the only one defined in Skylake (processor tracing)
1315 * probably will block migration anyway.
1316 */
1317 .features[FEAT_XSAVE] =
1318 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
1319 CPUID_XSAVE_XGETBV1,
1320 .features[FEAT_6_EAX] =
1321 CPUID_6_EAX_ARAT,
1322 .xlevel = 0x80000008,
1323 .model_id = "Intel Core Processor (Skylake)",
1324 },
1325 {
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001326 .name = "Opteron_G1",
1327 .level = 5,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001328 .vendor = CPUID_VENDOR_AMD,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001329 .family = 15,
1330 .model = 6,
1331 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001332 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001333 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001334 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1335 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1336 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1337 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001338 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001339 CPUID_EXT_SSE3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001340 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001341 CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001342 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1343 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1344 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1345 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1346 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001347 .xlevel = 0x80000008,
1348 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
1349 },
1350 {
1351 .name = "Opteron_G2",
1352 .level = 5,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001353 .vendor = CPUID_VENDOR_AMD,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001354 .family = 15,
1355 .model = 6,
1356 .stepping = 1,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001357 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001358 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001359 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1360 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1361 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1362 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001363 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001364 CPUID_EXT_CX16 | CPUID_EXT_SSE3,
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001365 /* Missing: CPUID_EXT2_RDTSCP */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001366 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001367 CPUID_EXT2_LM | CPUID_EXT2_FXSR |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001368 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1369 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1370 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1371 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1372 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1373 CPUID_EXT2_DE | CPUID_EXT2_FPU,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001374 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001375 CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001376 .xlevel = 0x80000008,
1377 .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
1378 },
1379 {
1380 .name = "Opteron_G3",
1381 .level = 5,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001382 .vendor = CPUID_VENDOR_AMD,
Evgeny Yakovlev339892d2016-10-03 14:50:02 +03001383 .family = 16,
1384 .model = 2,
1385 .stepping = 3,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001386 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001387 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001388 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1389 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1390 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1391 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001392 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001393 CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001394 CPUID_EXT_SSE3,
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001395 /* Missing: CPUID_EXT2_RDTSCP */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001396 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001397 CPUID_EXT2_LM | CPUID_EXT2_FXSR |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001398 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1399 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1400 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1401 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1402 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1403 CPUID_EXT2_DE | CPUID_EXT2_FPU,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001404 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001405 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001406 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001407 .xlevel = 0x80000008,
1408 .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
1409 },
1410 {
1411 .name = "Opteron_G4",
1412 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001413 .vendor = CPUID_VENDOR_AMD,
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001414 .family = 21,
1415 .model = 1,
1416 .stepping = 2,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001417 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001418 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001419 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1420 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1421 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1422 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001423 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001424 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001425 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1426 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1427 CPUID_EXT_SSE3,
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001428 /* Missing: CPUID_EXT2_RDTSCP */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001429 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001430 CPUID_EXT2_LM |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001431 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1432 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1433 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1434 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1435 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1436 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001437 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001438 CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001439 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1440 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1441 CPUID_EXT3_LAHF_LM,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01001442 /* no xsaveopt! */
Eduardo Habkost3eca4642012-09-05 17:41:10 -03001443 .xlevel = 0x8000001A,
1444 .model_id = "AMD Opteron 62xx class CPU",
1445 },
Andre Przywara021941b2012-11-14 16:28:53 -02001446 {
1447 .name = "Opteron_G5",
1448 .level = 0xd,
Igor Mammedov99b88a12013-01-21 15:06:36 +01001449 .vendor = CPUID_VENDOR_AMD,
Andre Przywara021941b2012-11-14 16:28:53 -02001450 .family = 21,
1451 .model = 2,
1452 .stepping = 0,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001453 .features[FEAT_1_EDX] =
Paolo Bonzinib3a4f0b2014-12-10 14:12:41 -02001454 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001455 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1456 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1457 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1458 CPUID_DE | CPUID_FP87,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001459 .features[FEAT_1_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001460 CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001461 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1462 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
1463 CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001464 /* Missing: CPUID_EXT2_RDTSCP */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001465 .features[FEAT_8000_0001_EDX] =
Eduardo Habkost33b5e8c2015-11-13 17:07:13 -02001466 CPUID_EXT2_LM |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001467 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1468 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1469 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1470 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1471 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1472 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
Eduardo Habkost0514ef22013-04-22 16:00:15 -03001473 .features[FEAT_8000_0001_ECX] =
Eduardo Habkost27861ec2013-04-22 16:00:14 -03001474 CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
Eduardo Habkostb3fb3a22014-06-17 20:05:29 -03001475 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1476 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1477 CPUID_EXT3_LAHF_LM,
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01001478 /* no xsaveopt! */
Andre Przywara021941b2012-11-14 16:28:53 -02001479 .xlevel = 0x8000001A,
1480 .model_id = "AMD Opteron 63xx class CPU",
1481 },
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001482};
1483
Eduardo Habkost5114e842015-09-11 12:40:27 -03001484typedef struct PropValue {
1485 const char *prop, *value;
1486} PropValue;
1487
1488/* KVM-specific features that are automatically added/removed
1489 * from all CPU models when KVM is enabled.
1490 */
1491static PropValue kvm_default_props[] = {
1492 { "kvmclock", "on" },
1493 { "kvm-nopiodelay", "on" },
1494 { "kvm-asyncpf", "on" },
1495 { "kvm-steal-time", "on" },
1496 { "kvm-pv-eoi", "on" },
1497 { "kvmclock-stable-bit", "on" },
1498 { "x2apic", "on" },
1499 { "acpi", "off" },
1500 { "monitor", "off" },
1501 { "svm", "off" },
1502 { NULL, NULL },
1503};
1504
Eduardo Habkost04d99c32016-09-30 15:49:37 -03001505/* TCG-specific defaults that override all CPU models when using TCG
1506 */
1507static PropValue tcg_default_props[] = {
1508 { "vme", "off" },
1509 { NULL, NULL },
1510};
1511
1512
Eduardo Habkost5114e842015-09-11 12:40:27 -03001513void x86_cpu_change_kvm_default(const char *prop, const char *value)
1514{
1515 PropValue *pv;
1516 for (pv = kvm_default_props; pv->prop; pv++) {
1517 if (!strcmp(pv->prop, prop)) {
1518 pv->value = value;
1519 break;
1520 }
1521 }
1522
1523 /* It is valid to call this function only for properties that
1524 * are already present in the kvm_default_props table.
1525 */
1526 assert(pv->prop);
1527}
1528
Eduardo Habkost4d1b2792014-08-20 17:30:12 -03001529static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
1530 bool migratable_only);
1531
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001532#ifdef CONFIG_KVM
1533
Haozhong Zhang40bfe482016-06-22 14:56:23 +08001534static bool lmce_supported(void)
1535{
1536 uint64_t mce_cap;
1537
1538 if (kvm_ioctl(kvm_state, KVM_X86_GET_MCE_CAP_SUPPORTED, &mce_cap) < 0) {
1539 return false;
1540 }
1541
1542 return !!(mce_cap & MCG_LMCE_P);
1543}
1544
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001545static int cpu_x86_fill_model_id(char *str)
1546{
1547 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1548 int i;
1549
1550 for (i = 0; i < 3; i++) {
1551 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
1552 memcpy(str + i * 16 + 0, &eax, 4);
1553 memcpy(str + i * 16 + 4, &ebx, 4);
1554 memcpy(str + i * 16 + 8, &ecx, 4);
1555 memcpy(str + i * 16 + 12, &edx, 4);
1556 }
1557 return 0;
1558}
1559
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001560static X86CPUDefinition host_cpudef;
1561
Eduardo Habkost84f1b922014-04-30 13:48:41 -03001562static Property host_x86_cpu_properties[] = {
Eduardo Habkost120eee72014-06-17 17:31:53 -03001563 DEFINE_PROP_BOOL("migratable", X86CPU, migratable, true),
Eduardo Habkoste265e3e2015-09-02 11:19:11 -03001564 DEFINE_PROP_BOOL("host-cache-info", X86CPU, cache_info_passthrough, false),
Eduardo Habkost84f1b922014-04-30 13:48:41 -03001565 DEFINE_PROP_END_OF_LIST()
1566};
1567
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001568/* class_init for the "host" CPU model
Eduardo Habkost6e746f32012-10-24 19:44:06 -02001569 *
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001570 * This function may be called before KVM is initialized.
Eduardo Habkost6e746f32012-10-24 19:44:06 -02001571 */
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001572static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001573{
Eduardo Habkost84f1b922014-04-30 13:48:41 -03001574 DeviceClass *dc = DEVICE_CLASS(oc);
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001575 X86CPUClass *xcc = X86_CPU_CLASS(oc);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001576 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001577
1578 xcc->kvm_required = true;
1579
1580 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
1581 x86_cpu_vendor_words2str(host_cpudef.vendor, ebx, edx, ecx);
1582
1583 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
1584 host_cpudef.family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1585 host_cpudef.model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1586 host_cpudef.stepping = eax & 0x0F;
1587
1588 cpu_x86_fill_model_id(host_cpudef.model_id);
1589
1590 xcc->cpu_def = &host_cpudef;
Eduardo Habkostee465a32016-09-30 15:49:36 -03001591 xcc->model_description =
1592 "KVM processor with all supported host features "
1593 "(only available in KVM mode)";
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001594
1595 /* level, xlevel, xlevel2, and the feature words are initialized on
1596 * instance_init, because they require KVM to be initialized.
1597 */
Eduardo Habkost84f1b922014-04-30 13:48:41 -03001598
1599 dc->props = host_x86_cpu_properties;
Markus Armbruster4c315c22015-10-01 10:59:58 +02001600 /* Reason: host_x86_cpu_initfn() dies when !kvm_enabled() */
1601 dc->cannot_destroy_with_object_finalize_yet = true;
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001602}
1603
1604static void host_x86_cpu_initfn(Object *obj)
1605{
1606 X86CPU *cpu = X86_CPU(obj);
1607 CPUX86State *env = &cpu->env;
1608 KVMState *s = kvm_state;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001609
Eduardo Habkost4d1b2792014-08-20 17:30:12 -03001610 /* We can't fill the features array here because we don't know yet if
1611 * "migratable" is true or false.
1612 */
1613 cpu->host_features = true;
1614
Igor Mammedov104494e2016-06-06 17:16:45 +02001615 /* If KVM is disabled, x86_cpu_realizefn() will report an error later */
Eduardo Habkoste4356012016-06-10 08:42:08 -03001616 if (kvm_enabled()) {
Eduardo Habkostc39c0ed2016-09-21 13:30:12 -03001617 env->cpuid_min_level =
1618 kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
1619 env->cpuid_min_xlevel =
1620 kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
1621 env->cpuid_min_xlevel2 =
1622 kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
Haozhong Zhang40bfe482016-06-22 14:56:23 +08001623
1624 if (lmce_supported()) {
1625 object_property_set_bool(OBJECT(cpu), true, "lmce", &error_abort);
1626 }
Eduardo Habkoste4356012016-06-10 08:42:08 -03001627 }
Eduardo Habkost2a573252014-01-20 14:41:12 -02001628
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001629 object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001630}
1631
Eduardo Habkostd940ee92014-02-10 08:21:30 -02001632static const TypeInfo host_x86_cpu_type_info = {
1633 .name = X86_CPU_TYPE_NAME("host"),
1634 .parent = TYPE_X86_CPU,
1635 .instance_init = host_x86_cpu_initfn,
1636 .class_init = host_x86_cpu_class_init,
1637};
1638
1639#endif
1640
Eduardo Habkost8459e392014-04-30 13:48:31 -03001641static void report_unavailable_features(FeatureWord w, uint32_t mask)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001642{
Eduardo Habkost8459e392014-04-30 13:48:31 -03001643 FeatureWordInfo *f = &feature_word_info[w];
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001644 int i;
1645
Eduardo Habkost857aee32014-04-30 13:48:29 -03001646 for (i = 0; i < 32; ++i) {
Eduardo Habkost72370dc2015-09-29 17:34:22 -03001647 if ((1UL << i) & mask) {
Eduardo Habkostbffd67b2013-01-07 16:20:46 -02001648 const char *reg = get_register_name_32(f->cpuid_reg);
Eduardo Habkost8b4bedd2013-01-04 20:01:06 -02001649 assert(reg);
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03001650 fprintf(stderr, "warning: %s doesn't support requested feature: "
Eduardo Habkost8b4bedd2013-01-04 20:01:06 -02001651 "CPUID.%02XH:%s%s%s [bit %d]\n",
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03001652 kvm_enabled() ? "host" : "TCG",
Eduardo Habkostbffd67b2013-01-07 16:20:46 -02001653 f->cpuid_eax, reg,
1654 f->feat_names[i] ? "." : "",
1655 f->feat_names[i] ? f->feat_names[i] : "", i);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001656 }
Eduardo Habkost857aee32014-04-30 13:48:29 -03001657 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01001658}
1659
Eric Blaked7bce992016-01-29 06:48:55 -07001660static void x86_cpuid_version_get_family(Object *obj, Visitor *v,
1661 const char *name, void *opaque,
1662 Error **errp)
Andreas Färber95b85192012-04-17 14:42:22 +02001663{
1664 X86CPU *cpu = X86_CPU(obj);
1665 CPUX86State *env = &cpu->env;
1666 int64_t value;
1667
1668 value = (env->cpuid_version >> 8) & 0xf;
1669 if (value == 0xf) {
1670 value += (env->cpuid_version >> 20) & 0xff;
1671 }
Eric Blake51e72bc2016-01-29 06:48:54 -07001672 visit_type_int(v, name, &value, errp);
Andreas Färber95b85192012-04-17 14:42:22 +02001673}
1674
Eric Blaked7bce992016-01-29 06:48:55 -07001675static void x86_cpuid_version_set_family(Object *obj, Visitor *v,
1676 const char *name, void *opaque,
1677 Error **errp)
Andreas Färbered5e1ec2012-02-17 17:46:01 +01001678{
Andreas Färber71ad61d2012-04-17 12:10:29 +02001679 X86CPU *cpu = X86_CPU(obj);
1680 CPUX86State *env = &cpu->env;
1681 const int64_t min = 0;
1682 const int64_t max = 0xff + 0xf;
Markus Armbruster65cd9062014-04-25 12:44:22 +02001683 Error *local_err = NULL;
Andreas Färber71ad61d2012-04-17 12:10:29 +02001684 int64_t value;
1685
Eric Blake51e72bc2016-01-29 06:48:54 -07001686 visit_type_int(v, name, &value, &local_err);
Markus Armbruster65cd9062014-04-25 12:44:22 +02001687 if (local_err) {
1688 error_propagate(errp, local_err);
Andreas Färber71ad61d2012-04-17 12:10:29 +02001689 return;
1690 }
1691 if (value < min || value > max) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001692 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1693 name ? name : "null", value, min, max);
Andreas Färber71ad61d2012-04-17 12:10:29 +02001694 return;
1695 }
1696
Andreas Färbered5e1ec2012-02-17 17:46:01 +01001697 env->cpuid_version &= ~0xff00f00;
Andreas Färber71ad61d2012-04-17 12:10:29 +02001698 if (value > 0x0f) {
1699 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
Andreas Färbered5e1ec2012-02-17 17:46:01 +01001700 } else {
Andreas Färber71ad61d2012-04-17 12:10:29 +02001701 env->cpuid_version |= value << 8;
Andreas Färbered5e1ec2012-02-17 17:46:01 +01001702 }
1703}
1704
Eric Blaked7bce992016-01-29 06:48:55 -07001705static void x86_cpuid_version_get_model(Object *obj, Visitor *v,
1706 const char *name, void *opaque,
1707 Error **errp)
Andreas Färber67e30c82012-04-17 14:48:14 +02001708{
1709 X86CPU *cpu = X86_CPU(obj);
1710 CPUX86State *env = &cpu->env;
1711 int64_t value;
1712
1713 value = (env->cpuid_version >> 4) & 0xf;
1714 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
Eric Blake51e72bc2016-01-29 06:48:54 -07001715 visit_type_int(v, name, &value, errp);
Andreas Färber67e30c82012-04-17 14:48:14 +02001716}
1717
Eric Blaked7bce992016-01-29 06:48:55 -07001718static void x86_cpuid_version_set_model(Object *obj, Visitor *v,
1719 const char *name, void *opaque,
1720 Error **errp)
Andreas Färberb0704cb2012-02-17 17:46:02 +01001721{
Andreas Färberc5291a42012-04-17 12:16:39 +02001722 X86CPU *cpu = X86_CPU(obj);
1723 CPUX86State *env = &cpu->env;
1724 const int64_t min = 0;
1725 const int64_t max = 0xff;
Markus Armbruster65cd9062014-04-25 12:44:22 +02001726 Error *local_err = NULL;
Andreas Färberc5291a42012-04-17 12:16:39 +02001727 int64_t value;
1728
Eric Blake51e72bc2016-01-29 06:48:54 -07001729 visit_type_int(v, name, &value, &local_err);
Markus Armbruster65cd9062014-04-25 12:44:22 +02001730 if (local_err) {
1731 error_propagate(errp, local_err);
Andreas Färberc5291a42012-04-17 12:16:39 +02001732 return;
1733 }
1734 if (value < min || value > max) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001735 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1736 name ? name : "null", value, min, max);
Andreas Färberc5291a42012-04-17 12:16:39 +02001737 return;
1738 }
1739
Andreas Färberb0704cb2012-02-17 17:46:02 +01001740 env->cpuid_version &= ~0xf00f0;
Andreas Färberc5291a42012-04-17 12:16:39 +02001741 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
Andreas Färberb0704cb2012-02-17 17:46:02 +01001742}
1743
Andreas Färber35112e42012-04-17 14:50:53 +02001744static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
Eric Blaked7bce992016-01-29 06:48:55 -07001745 const char *name, void *opaque,
Andreas Färber35112e42012-04-17 14:50:53 +02001746 Error **errp)
1747{
1748 X86CPU *cpu = X86_CPU(obj);
1749 CPUX86State *env = &cpu->env;
1750 int64_t value;
1751
1752 value = env->cpuid_version & 0xf;
Eric Blake51e72bc2016-01-29 06:48:54 -07001753 visit_type_int(v, name, &value, errp);
Andreas Färber35112e42012-04-17 14:50:53 +02001754}
1755
Andreas Färber036e2222012-04-17 14:14:18 +02001756static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
Eric Blaked7bce992016-01-29 06:48:55 -07001757 const char *name, void *opaque,
Andreas Färber036e2222012-04-17 14:14:18 +02001758 Error **errp)
Andreas Färber38c3dc42012-02-17 17:46:03 +01001759{
Andreas Färber036e2222012-04-17 14:14:18 +02001760 X86CPU *cpu = X86_CPU(obj);
1761 CPUX86State *env = &cpu->env;
1762 const int64_t min = 0;
1763 const int64_t max = 0xf;
Markus Armbruster65cd9062014-04-25 12:44:22 +02001764 Error *local_err = NULL;
Andreas Färber036e2222012-04-17 14:14:18 +02001765 int64_t value;
1766
Eric Blake51e72bc2016-01-29 06:48:54 -07001767 visit_type_int(v, name, &value, &local_err);
Markus Armbruster65cd9062014-04-25 12:44:22 +02001768 if (local_err) {
1769 error_propagate(errp, local_err);
Andreas Färber036e2222012-04-17 14:14:18 +02001770 return;
1771 }
1772 if (value < min || value > max) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001773 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1774 name ? name : "null", value, min, max);
Andreas Färber036e2222012-04-17 14:14:18 +02001775 return;
1776 }
1777
Andreas Färber38c3dc42012-02-17 17:46:03 +01001778 env->cpuid_version &= ~0xf;
Andreas Färber036e2222012-04-17 14:14:18 +02001779 env->cpuid_version |= value & 0xf;
Andreas Färber38c3dc42012-02-17 17:46:03 +01001780}
1781
Andreas Färberd480e1a2012-04-17 19:22:58 +02001782static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1783{
1784 X86CPU *cpu = X86_CPU(obj);
1785 CPUX86State *env = &cpu->env;
1786 char *value;
Andreas Färberd480e1a2012-04-17 19:22:58 +02001787
Markus Armbrustere42a92a2014-12-04 14:46:46 +01001788 value = g_malloc(CPUID_VENDOR_SZ + 1);
Igor Mammedov99b88a12013-01-21 15:06:36 +01001789 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
1790 env->cpuid_vendor3);
Andreas Färberd480e1a2012-04-17 19:22:58 +02001791 return value;
1792}
1793
1794static void x86_cpuid_set_vendor(Object *obj, const char *value,
1795 Error **errp)
1796{
1797 X86CPU *cpu = X86_CPU(obj);
1798 CPUX86State *env = &cpu->env;
1799 int i;
1800
Igor Mammedov9df694e2012-10-22 17:03:10 +02001801 if (strlen(value) != CPUID_VENDOR_SZ) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001802 error_setg(errp, QERR_PROPERTY_VALUE_BAD, "", "vendor", value);
Andreas Färberd480e1a2012-04-17 19:22:58 +02001803 return;
1804 }
1805
1806 env->cpuid_vendor1 = 0;
1807 env->cpuid_vendor2 = 0;
1808 env->cpuid_vendor3 = 0;
1809 for (i = 0; i < 4; i++) {
1810 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1811 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1812 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1813 }
Andreas Färberd480e1a2012-04-17 19:22:58 +02001814}
1815
Andreas Färber63e886e2012-04-17 23:02:26 +02001816static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1817{
1818 X86CPU *cpu = X86_CPU(obj);
1819 CPUX86State *env = &cpu->env;
1820 char *value;
1821 int i;
1822
1823 value = g_malloc(48 + 1);
1824 for (i = 0; i < 48; i++) {
1825 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1826 }
1827 value[48] = '\0';
1828 return value;
1829}
1830
Andreas Färber938d4c22012-04-17 15:17:27 +02001831static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1832 Error **errp)
Andreas Färberdcce6672012-02-17 17:46:04 +01001833{
Andreas Färber938d4c22012-04-17 15:17:27 +02001834 X86CPU *cpu = X86_CPU(obj);
1835 CPUX86State *env = &cpu->env;
Andreas Färberdcce6672012-02-17 17:46:04 +01001836 int c, len, i;
1837
1838 if (model_id == NULL) {
1839 model_id = "";
1840 }
1841 len = strlen(model_id);
Andreas Färberd0a6acf2012-04-17 18:21:52 +02001842 memset(env->cpuid_model, 0, 48);
Andreas Färberdcce6672012-02-17 17:46:04 +01001843 for (i = 0; i < 48; i++) {
1844 if (i >= len) {
1845 c = '\0';
1846 } else {
1847 c = (uint8_t)model_id[i];
1848 }
1849 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1850 }
1851}
1852
Eric Blaked7bce992016-01-29 06:48:55 -07001853static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, const char *name,
1854 void *opaque, Error **errp)
Andreas Färber89e48962012-04-18 00:12:23 +02001855{
1856 X86CPU *cpu = X86_CPU(obj);
1857 int64_t value;
1858
1859 value = cpu->env.tsc_khz * 1000;
Eric Blake51e72bc2016-01-29 06:48:54 -07001860 visit_type_int(v, name, &value, errp);
Andreas Färber89e48962012-04-18 00:12:23 +02001861}
1862
Eric Blaked7bce992016-01-29 06:48:55 -07001863static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
1864 void *opaque, Error **errp)
Andreas Färber89e48962012-04-18 00:12:23 +02001865{
1866 X86CPU *cpu = X86_CPU(obj);
1867 const int64_t min = 0;
Don Slutz2e848492012-09-21 20:13:13 -04001868 const int64_t max = INT64_MAX;
Markus Armbruster65cd9062014-04-25 12:44:22 +02001869 Error *local_err = NULL;
Andreas Färber89e48962012-04-18 00:12:23 +02001870 int64_t value;
1871
Eric Blake51e72bc2016-01-29 06:48:54 -07001872 visit_type_int(v, name, &value, &local_err);
Markus Armbruster65cd9062014-04-25 12:44:22 +02001873 if (local_err) {
1874 error_propagate(errp, local_err);
Andreas Färber89e48962012-04-18 00:12:23 +02001875 return;
1876 }
1877 if (value < min || value > max) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +01001878 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1879 name ? name : "null", value, min, max);
Andreas Färber89e48962012-04-18 00:12:23 +02001880 return;
1881 }
1882
Haozhong Zhang36f96c42015-11-24 11:33:57 +08001883 cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
Andreas Färber89e48962012-04-18 00:12:23 +02001884}
1885
Eduardo Habkost7e5292b2013-05-06 13:20:09 -03001886/* Generic getter for "feature-words" and "filtered-features" properties */
Eric Blaked7bce992016-01-29 06:48:55 -07001887static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
1888 const char *name, void *opaque,
1889 Error **errp)
Eduardo Habkost8e8aba52013-05-06 13:20:07 -03001890{
Eduardo Habkost7e5292b2013-05-06 13:20:09 -03001891 uint32_t *array = (uint32_t *)opaque;
Eduardo Habkost8e8aba52013-05-06 13:20:07 -03001892 FeatureWord w;
Eduardo Habkost8e8aba52013-05-06 13:20:07 -03001893 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
1894 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
1895 X86CPUFeatureWordInfoList *list = NULL;
1896
1897 for (w = 0; w < FEATURE_WORDS; w++) {
1898 FeatureWordInfo *wi = &feature_word_info[w];
1899 X86CPUFeatureWordInfo *qwi = &word_infos[w];
1900 qwi->cpuid_input_eax = wi->cpuid_eax;
1901 qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
1902 qwi->cpuid_input_ecx = wi->cpuid_ecx;
1903 qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
Eduardo Habkost7e5292b2013-05-06 13:20:09 -03001904 qwi->features = array[w];
Eduardo Habkost8e8aba52013-05-06 13:20:07 -03001905
1906 /* List will be in reverse order, but order shouldn't matter */
1907 list_entries[w].next = list;
1908 list_entries[w].value = &word_infos[w];
1909 list = &list_entries[w];
1910 }
1911
Eduardo Habkost6b62d962016-06-13 18:57:57 -03001912 visit_type_X86CPUFeatureWordInfoList(v, "feature-words", &list, errp);
Eduardo Habkost8e8aba52013-05-06 13:20:07 -03001913}
1914
Eric Blaked7bce992016-01-29 06:48:55 -07001915static void x86_get_hv_spinlocks(Object *obj, Visitor *v, const char *name,
1916 void *opaque, Error **errp)
Igor Mammedovc8f0f882013-06-04 15:05:25 +02001917{
1918 X86CPU *cpu = X86_CPU(obj);
1919 int64_t value = cpu->hyperv_spinlock_attempts;
1920
Eric Blake51e72bc2016-01-29 06:48:54 -07001921 visit_type_int(v, name, &value, errp);
Igor Mammedovc8f0f882013-06-04 15:05:25 +02001922}
1923
Eric Blaked7bce992016-01-29 06:48:55 -07001924static void x86_set_hv_spinlocks(Object *obj, Visitor *v, const char *name,
1925 void *opaque, Error **errp)
Igor Mammedovc8f0f882013-06-04 15:05:25 +02001926{
1927 const int64_t min = 0xFFF;
1928 const int64_t max = UINT_MAX;
1929 X86CPU *cpu = X86_CPU(obj);
1930 Error *err = NULL;
1931 int64_t value;
1932
Eric Blake51e72bc2016-01-29 06:48:54 -07001933 visit_type_int(v, name, &value, &err);
Igor Mammedovc8f0f882013-06-04 15:05:25 +02001934 if (err) {
1935 error_propagate(errp, err);
1936 return;
1937 }
1938
1939 if (value < min || value > max) {
1940 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
chenfan5bb4c352014-07-28 15:13:06 +08001941 " (minimum: %" PRId64 ", maximum: %" PRId64 ")",
1942 object_get_typename(obj), name ? name : "null",
1943 value, min, max);
Igor Mammedovc8f0f882013-06-04 15:05:25 +02001944 return;
1945 }
1946 cpu->hyperv_spinlock_attempts = value;
1947}
1948
1949static PropertyInfo qdev_prop_spinlocks = {
1950 .name = "int",
1951 .get = x86_get_hv_spinlocks,
1952 .set = x86_set_hv_spinlocks,
1953};
1954
Igor Mammedov72ac2e82013-04-26 18:04:32 +02001955/* Convert all '_' in a feature string option name to '-', to make feature
1956 * name conform to QOM property naming rule, which uses '-' instead of '_'.
1957 */
1958static inline void feat2prop(char *s)
1959{
1960 while ((s = strchr(s, '_'))) {
1961 *s = '-';
1962 }
1963}
1964
Eduardo Habkostb54c9372016-05-03 13:48:13 -03001965/* Return the feature property name for a feature flag bit */
1966static const char *x86_cpu_feature_name(FeatureWord w, int bitnr)
1967{
1968 /* XSAVE components are automatically enabled by other features,
1969 * so return the original feature name instead
1970 */
1971 if (w == FEAT_XSAVE_COMP_LO || w == FEAT_XSAVE_COMP_HI) {
1972 int comp = (w == FEAT_XSAVE_COMP_HI) ? bitnr + 32 : bitnr;
1973
1974 if (comp < ARRAY_SIZE(x86_ext_save_areas) &&
1975 x86_ext_save_areas[comp].bits) {
1976 w = x86_ext_save_areas[comp].feature;
1977 bitnr = ctz32(x86_ext_save_areas[comp].bits);
1978 }
1979 }
1980
1981 assert(bitnr < 32);
1982 assert(w < FEATURE_WORDS);
1983 return feature_word_info[w].feat_names[bitnr];
1984}
1985
Igor Mammedovdc15c052016-06-06 17:16:44 +02001986/* Compatibily hack to maintain legacy +-feat semantic,
1987 * where +-feat overwrites any feature set by
1988 * feat=on|feat even if the later is parsed after +-feat
1989 * (i.e. "-x2apic,x2apic=on" will result in x2apic disabled)
1990 */
Eduardo Habkost2fae0d92016-09-30 15:49:39 -03001991static GList *plus_features, *minus_features;
Igor Mammedovdc15c052016-06-06 17:16:44 +02001992
Eduardo Habkost83a00f62016-10-24 17:53:52 -02001993static gint compare_string(gconstpointer a, gconstpointer b)
1994{
1995 return g_strcmp0(a, b);
1996}
1997
Eduardo Habkost8f961352012-12-04 17:34:39 -02001998/* Parse "+feature,-feature,feature=foo" CPU feature string
1999 */
Igor Mammedov62a48a22016-06-09 19:11:01 +02002000static void x86_cpu_parse_featurestr(const char *typename, char *features,
Andreas Färber94a444b2014-03-03 23:19:19 +01002001 Error **errp)
Eduardo Habkost8f961352012-12-04 17:34:39 -02002002{
Eduardo Habkost8f961352012-12-04 17:34:39 -02002003 char *featurestr; /* Single 'key=value" string being parsed */
Andreas Färber94a444b2014-03-03 23:19:19 +01002004 Error *local_err = NULL;
Igor Mammedov62a48a22016-06-09 19:11:01 +02002005 static bool cpu_globals_initialized;
Eduardo Habkost83a00f62016-10-24 17:53:52 -02002006 bool ambiguous = false;
Igor Mammedov62a48a22016-06-09 19:11:01 +02002007
2008 if (cpu_globals_initialized) {
2009 return;
2010 }
2011 cpu_globals_initialized = true;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002012
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002013 if (!features) {
2014 return;
2015 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002016
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002017 for (featurestr = strtok(features, ",");
2018 featurestr && !local_err;
2019 featurestr = strtok(NULL, ",")) {
2020 const char *name;
2021 const char *val = NULL;
2022 char *eq = NULL;
Paolo Bonzinicf2887c2016-06-21 14:04:40 +02002023 char num[32];
Igor Mammedov62a48a22016-06-09 19:11:01 +02002024 GlobalProperty *prop;
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002025
2026 /* Compatibility syntax: */
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002027 if (featurestr[0] == '+') {
Eduardo Habkost2fae0d92016-09-30 15:49:39 -03002028 plus_features = g_list_append(plus_features,
2029 g_strdup(featurestr + 1));
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002030 continue;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002031 } else if (featurestr[0] == '-') {
Eduardo Habkost2fae0d92016-09-30 15:49:39 -03002032 minus_features = g_list_append(minus_features,
2033 g_strdup(featurestr + 1));
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002034 continue;
2035 }
Joerg Roedelb862d1f2011-07-07 16:13:12 +02002036
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002037 eq = strchr(featurestr, '=');
2038 if (eq) {
2039 *eq++ = 0;
2040 val = eq;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002041 } else {
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002042 val = "on";
Igor Mammedova91987c2013-01-21 15:06:38 +01002043 }
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002044
2045 feat2prop(featurestr);
2046 name = featurestr;
2047
Eduardo Habkost83a00f62016-10-24 17:53:52 -02002048 if (g_list_find_custom(plus_features, name, compare_string)) {
2049 error_report("warning: Ambiguous CPU model string. "
2050 "Don't mix both \"+%s\" and \"%s=%s\"",
2051 name, name, val);
2052 ambiguous = true;
2053 }
2054 if (g_list_find_custom(minus_features, name, compare_string)) {
2055 error_report("warning: Ambiguous CPU model string. "
2056 "Don't mix both \"-%s\" and \"%s=%s\"",
2057 name, name, val);
2058 ambiguous = true;
2059 }
2060
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002061 /* Special case: */
2062 if (!strcmp(name, "tsc-freq")) {
2063 int64_t tsc_freq;
2064 char *err;
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002065
2066 tsc_freq = qemu_strtosz_suffix_unit(val, &err,
2067 QEMU_STRTOSZ_DEFSUFFIX_B, 1000);
2068 if (tsc_freq < 0 || *err) {
2069 error_setg(errp, "bad numerical value %s", val);
2070 return;
2071 }
2072 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
2073 val = num;
2074 name = "tsc-frequency";
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002075 }
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002076
Igor Mammedov62a48a22016-06-09 19:11:01 +02002077 prop = g_new0(typeof(*prop), 1);
2078 prop->driver = typename;
2079 prop->property = g_strdup(name);
2080 prop->value = g_strdup(val);
2081 prop->errp = &error_fatal;
2082 qdev_prop_register_global(prop);
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002083 }
2084
Eduardo Habkost83a00f62016-10-24 17:53:52 -02002085 if (ambiguous) {
2086 error_report("warning: Compatibility of ambiguous CPU model "
2087 "strings won't be kept on future QEMU versions");
2088 }
2089
Eduardo Habkostf6750e92016-06-09 19:10:58 +02002090 if (local_err) {
2091 error_propagate(errp, local_err);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002092 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002093}
2094
Eduardo Habkostb54c9372016-05-03 13:48:13 -03002095static void x86_cpu_load_features(X86CPU *cpu, Error **errp);
2096static int x86_cpu_filter_features(X86CPU *cpu);
2097
2098/* Check for missing features that may prevent the CPU class from
2099 * running using the current machine and accelerator.
2100 */
2101static void x86_cpu_class_check_missing_features(X86CPUClass *xcc,
2102 strList **missing_feats)
2103{
2104 X86CPU *xc;
2105 FeatureWord w;
2106 Error *err = NULL;
2107 strList **next = missing_feats;
2108
2109 if (xcc->kvm_required && !kvm_enabled()) {
2110 strList *new = g_new0(strList, 1);
2111 new->value = g_strdup("kvm");;
2112 *missing_feats = new;
2113 return;
2114 }
2115
2116 xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc))));
2117
2118 x86_cpu_load_features(xc, &err);
2119 if (err) {
2120 /* Errors at x86_cpu_load_features should never happen,
2121 * but in case it does, just report the model as not
2122 * runnable at all using the "type" property.
2123 */
2124 strList *new = g_new0(strList, 1);
2125 new->value = g_strdup("type");
2126 *next = new;
2127 next = &new->next;
2128 }
2129
2130 x86_cpu_filter_features(xc);
2131
2132 for (w = 0; w < FEATURE_WORDS; w++) {
2133 uint32_t filtered = xc->filtered_features[w];
2134 int i;
2135 for (i = 0; i < 32; i++) {
2136 if (filtered & (1UL << i)) {
2137 strList *new = g_new0(strList, 1);
2138 new->value = g_strdup(x86_cpu_feature_name(w, i));
2139 *next = new;
2140 next = &new->next;
2141 }
2142 }
2143 }
2144
2145 object_unref(OBJECT(xc));
2146}
2147
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002148/* Print all cpuid feature names in featureset
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002149 */
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002150static void listflags(FILE *f, fprintf_function print, const char **featureset)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002151{
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002152 int bit;
2153 bool first = true;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002154
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002155 for (bit = 0; bit < 32; bit++) {
2156 if (featureset[bit]) {
2157 print(f, "%s%s", first ? "" : " ", featureset[bit]);
2158 first = false;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002159 }
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002160 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002161}
2162
Eduardo Habkostee465a32016-09-30 15:49:36 -03002163/* Sort alphabetically by type name, listing kvm_required models last. */
2164static gint x86_cpu_list_compare(gconstpointer a, gconstpointer b)
2165{
2166 ObjectClass *class_a = (ObjectClass *)a;
2167 ObjectClass *class_b = (ObjectClass *)b;
2168 X86CPUClass *cc_a = X86_CPU_CLASS(class_a);
2169 X86CPUClass *cc_b = X86_CPU_CLASS(class_b);
2170 const char *name_a, *name_b;
2171
2172 if (cc_a->kvm_required != cc_b->kvm_required) {
2173 /* kvm_required items go last */
2174 return cc_a->kvm_required ? 1 : -1;
2175 } else {
2176 name_a = object_class_get_name(class_a);
2177 name_b = object_class_get_name(class_b);
2178 return strcmp(name_a, name_b);
2179 }
2180}
2181
2182static GSList *get_sorted_cpu_model_list(void)
2183{
2184 GSList *list = object_class_get_list(TYPE_X86_CPU, false);
2185 list = g_slist_sort(list, x86_cpu_list_compare);
2186 return list;
2187}
2188
2189static void x86_cpu_list_entry(gpointer data, gpointer user_data)
2190{
2191 ObjectClass *oc = data;
2192 X86CPUClass *cc = X86_CPU_CLASS(oc);
2193 CPUListState *s = user_data;
2194 char *name = x86_cpu_class_get_model_name(cc);
2195 const char *desc = cc->model_description;
2196 if (!desc) {
2197 desc = cc->cpu_def->model_id;
2198 }
2199
2200 (*s->cpu_fprintf)(s->file, "x86 %16s %-48s\n",
2201 name, desc);
2202 g_free(name);
2203}
2204
2205/* list available CPU models and flags */
Peter Maydelle916cbf2012-09-05 17:41:08 -03002206void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002207{
Andreas Färber7fc9b712013-01-21 01:02:28 +01002208 int i;
Eduardo Habkostee465a32016-09-30 15:49:36 -03002209 CPUListState s = {
2210 .file = f,
2211 .cpu_fprintf = cpu_fprintf,
2212 };
2213 GSList *list;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002214
Eduardo Habkostee465a32016-09-30 15:49:36 -03002215 (*cpu_fprintf)(f, "Available CPUs:\n");
2216 list = get_sorted_cpu_model_list();
2217 g_slist_foreach(list, x86_cpu_list_entry, &s);
2218 g_slist_free(list);
Jan Kiszka21ad7782013-03-24 17:01:02 +01002219
Peter Maydell6cdf8852012-09-05 17:41:07 -03002220 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
Jan Kiszka3af60be2013-02-27 10:15:51 +01002221 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
2222 FeatureWordInfo *fw = &feature_word_info[i];
2223
Eduardo Habkost8c3329e2015-02-03 15:48:55 -02002224 (*cpu_fprintf)(f, " ");
2225 listflags(f, cpu_fprintf, fw->feat_names);
2226 (*cpu_fprintf)(f, "\n");
Jan Kiszka3af60be2013-02-27 10:15:51 +01002227 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002228}
2229
Eduardo Habkostee465a32016-09-30 15:49:36 -03002230static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
2231{
2232 ObjectClass *oc = data;
2233 X86CPUClass *cc = X86_CPU_CLASS(oc);
2234 CpuDefinitionInfoList **cpu_list = user_data;
2235 CpuDefinitionInfoList *entry;
2236 CpuDefinitionInfo *info;
2237
2238 info = g_malloc0(sizeof(*info));
2239 info->name = x86_cpu_class_get_model_name(cc);
Eduardo Habkostb54c9372016-05-03 13:48:13 -03002240 x86_cpu_class_check_missing_features(cc, &info->unavailable_features);
2241 info->has_unavailable_features = true;
Eduardo Habkostee465a32016-09-30 15:49:36 -03002242
2243 entry = g_malloc0(sizeof(*entry));
2244 entry->value = info;
2245 entry->next = *cpu_list;
2246 *cpu_list = entry;
2247}
2248
Anthony Liguori76b64a72012-08-14 22:17:36 -05002249CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
Anthony Liguorie3966122012-08-10 11:04:14 -05002250{
2251 CpuDefinitionInfoList *cpu_list = NULL;
Eduardo Habkostee465a32016-09-30 15:49:36 -03002252 GSList *list = get_sorted_cpu_model_list();
2253 g_slist_foreach(list, x86_cpu_definition_entry, &cpu_list);
2254 g_slist_free(list);
Anthony Liguorie3966122012-08-10 11:04:14 -05002255 return cpu_list;
2256}
2257
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002258static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
2259 bool migratable_only)
Eduardo Habkost27418ad2014-04-30 13:48:32 -03002260{
2261 FeatureWordInfo *wi = &feature_word_info[w];
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002262 uint32_t r;
Eduardo Habkost27418ad2014-04-30 13:48:32 -03002263
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03002264 if (kvm_enabled()) {
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002265 r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid_eax,
2266 wi->cpuid_ecx,
2267 wi->cpuid_reg);
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03002268 } else if (tcg_enabled()) {
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002269 r = wi->tcg_features;
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03002270 } else {
2271 return ~0;
2272 }
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002273 if (migratable_only) {
2274 r &= x86_cpu_get_migratable_flags(w);
2275 }
2276 return r;
Eduardo Habkost27418ad2014-04-30 13:48:32 -03002277}
2278
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002279/*
2280 * Filters CPU feature words based on host availability of each feature.
2281 *
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002282 * Returns: 0 if all flags are supported by the host, non-zero otherwise.
2283 */
Eduardo Habkost27418ad2014-04-30 13:48:32 -03002284static int x86_cpu_filter_features(X86CPU *cpu)
Eduardo Habkostbc74b7d2012-10-04 17:49:05 -03002285{
2286 CPUX86State *env = &cpu->env;
Eduardo Habkostbd87d2a2013-04-22 16:00:18 -03002287 FeatureWord w;
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002288 int rv = 0;
2289
Eduardo Habkostbd87d2a2013-04-22 16:00:18 -03002290 for (w = 0; w < FEATURE_WORDS; w++) {
Eduardo Habkost84f1b922014-04-30 13:48:41 -03002291 uint32_t host_feat =
Eduardo Habkost46c032f2016-10-14 15:42:45 -03002292 x86_cpu_get_supported_feature_word(w, false);
Eduardo Habkost034acf42013-05-06 13:20:08 -03002293 uint32_t requested_features = env->features[w];
2294 env->features[w] &= host_feat;
2295 cpu->filtered_features[w] = requested_features & ~env->features[w];
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002296 if (cpu->filtered_features[w]) {
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002297 rv = 1;
2298 }
Eduardo Habkostbd87d2a2013-04-22 16:00:18 -03002299 }
Eduardo Habkost51f63ae2014-04-30 13:48:30 -03002300
2301 return rv;
Eduardo Habkostbc74b7d2012-10-04 17:49:05 -03002302}
Eduardo Habkostbc74b7d2012-10-04 17:49:05 -03002303
Eduardo Habkost8ca30e82016-05-04 14:50:46 -03002304static void x86_cpu_report_filtered_features(X86CPU *cpu)
2305{
2306 FeatureWord w;
2307
2308 for (w = 0; w < FEATURE_WORDS; w++) {
2309 report_unavailable_features(w, cpu->filtered_features[w]);
2310 }
2311}
2312
Eduardo Habkost5114e842015-09-11 12:40:27 -03002313static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
2314{
2315 PropValue *pv;
2316 for (pv = props; pv->prop; pv++) {
2317 if (!pv->value) {
2318 continue;
2319 }
2320 object_property_parse(OBJECT(cpu), pv->value, pv->prop,
2321 &error_abort);
2322 }
2323}
2324
Eduardo Habkostd940ee92014-02-10 08:21:30 -02002325/* Load data from X86CPUDefinition
Eduardo Habkostc080e302014-01-30 17:48:56 -02002326 */
Eduardo Habkostd940ee92014-02-10 08:21:30 -02002327static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002328{
Andreas Färber61dcd772012-04-17 12:00:51 +02002329 CPUX86State *env = &cpu->env;
Eduardo Habkost74f54bc2014-02-19 16:39:21 -03002330 const char *vendor;
2331 char host_vendor[CPUID_VENDOR_SZ + 1];
Eduardo Habkoste1c224b2014-04-30 13:48:37 -03002332 FeatureWord w;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002333
Eduardo Habkostc39c0ed2016-09-21 13:30:12 -03002334 /* CPU models only set _minimum_ values for level/xlevel: */
2335 object_property_set_int(OBJECT(cpu), def->level, "min-level", errp);
2336 object_property_set_int(OBJECT(cpu), def->xlevel, "min-xlevel", errp);
2337
Andreas Färber2d642552013-02-15 14:06:56 +01002338 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
2339 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
2340 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
Andreas Färber2d642552013-02-15 14:06:56 +01002341 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
Eduardo Habkoste1c224b2014-04-30 13:48:37 -03002342 for (w = 0; w < FEATURE_WORDS; w++) {
2343 env->features[w] = def->features[w];
2344 }
Eduardo Habkost82beb532014-01-30 17:48:54 -02002345
Eduardo Habkost9576de72014-01-30 17:48:58 -02002346 /* Special cases not set in the X86CPUDefinition structs: */
Eduardo Habkost82beb532014-01-30 17:48:54 -02002347 if (kvm_enabled()) {
Lan Tianyu492a4c92016-02-25 23:15:12 +08002348 if (!kvm_irqchip_in_kernel()) {
2349 x86_cpu_change_kvm_default("x2apic", "off");
2350 }
2351
Eduardo Habkost5114e842015-09-11 12:40:27 -03002352 x86_cpu_apply_props(cpu, kvm_default_props);
Eduardo Habkost04d99c32016-09-30 15:49:37 -03002353 } else if (tcg_enabled()) {
2354 x86_cpu_apply_props(cpu, tcg_default_props);
Eduardo Habkost82beb532014-01-30 17:48:54 -02002355 }
Eduardo Habkost5fcca9f2014-02-19 11:58:10 -03002356
Eduardo Habkost82beb532014-01-30 17:48:54 -02002357 env->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
Eduardo Habkost7c08db32014-01-30 17:48:55 -02002358
2359 /* sysenter isn't supported in compatibility mode on AMD,
2360 * syscall isn't supported in compatibility mode on Intel.
2361 * Normally we advertise the actual CPU vendor, but you can
2362 * override this using the 'vendor' property if you want to use
2363 * KVM's sysenter/syscall emulation in compatibility mode and
2364 * when doing cross vendor migration
2365 */
Eduardo Habkost74f54bc2014-02-19 16:39:21 -03002366 vendor = def->vendor;
Eduardo Habkost7c08db32014-01-30 17:48:55 -02002367 if (kvm_enabled()) {
2368 uint32_t ebx = 0, ecx = 0, edx = 0;
2369 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
2370 x86_cpu_vendor_words2str(host_vendor, ebx, edx, ecx);
2371 vendor = host_vendor;
2372 }
2373
2374 object_property_set_str(OBJECT(cpu), vendor, "vendor", errp);
2375
Andreas Färber2d642552013-02-15 14:06:56 +01002376}
2377
Peter Maydell08565792015-03-03 00:29:17 +00002378X86CPU *cpu_x86_init(const char *cpu_model)
Igor Mammedov7f833242013-04-11 16:51:40 +02002379{
Igor Mammedova57d0162016-06-06 17:16:46 +02002380 return X86_CPU(cpu_generic_init(TYPE_X86_CPU, cpu_model));
Andreas Färber5c3c6a62013-02-01 15:12:13 +01002381}
2382
Eduardo Habkostd940ee92014-02-10 08:21:30 -02002383static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
2384{
2385 X86CPUDefinition *cpudef = data;
2386 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2387
2388 xcc->cpu_def = cpudef;
2389}
2390
2391static void x86_register_cpudef_type(X86CPUDefinition *def)
2392{
2393 char *typename = x86_cpu_type_name(def->name);
2394 TypeInfo ti = {
2395 .name = typename,
2396 .parent = TYPE_X86_CPU,
2397 .class_init = x86_cpu_cpudef_class_init,
2398 .class_data = def,
2399 };
2400
2401 type_register(&ti);
2402 g_free(typename);
2403}
2404
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002405#if !defined(CONFIG_USER_ONLY)
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002406
Blue Swirl0e26b7b2010-06-19 10:42:34 +03002407void cpu_clear_apic_feature(CPUX86State *env)
2408{
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002409 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
Blue Swirl0e26b7b2010-06-19 10:42:34 +03002410}
2411
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002412#endif /* !CONFIG_USER_ONLY */
2413
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002414void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
2415 uint32_t *eax, uint32_t *ebx,
2416 uint32_t *ecx, uint32_t *edx)
2417{
Andreas Färbera60f24b2012-12-01 05:35:08 +01002418 X86CPU *cpu = x86_env_get_cpu(env);
2419 CPUState *cs = CPU(cpu);
Longpeng(Mike)14c985c2016-09-07 13:21:13 +08002420 uint32_t pkg_offset;
Andreas Färbera60f24b2012-12-01 05:35:08 +01002421
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002422 /* test if maximum index reached */
2423 if (index & 0x80000000) {
brillywu@viatech.com.cnb3baa152011-06-01 09:59:52 +08002424 if (index > env->cpuid_xlevel) {
2425 if (env->cpuid_xlevel2 > 0) {
2426 /* Handle the Centaur's CPUID instruction. */
2427 if (index > env->cpuid_xlevel2) {
2428 index = env->cpuid_xlevel2;
2429 } else if (index < 0xC0000000) {
2430 index = env->cpuid_xlevel;
2431 }
2432 } else {
Eduardo Habkost57f26ae2012-12-20 16:43:48 -02002433 /* Intel documentation states that invalid EAX input will
2434 * return the same information as EAX=cpuid_level
2435 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
2436 */
2437 index = env->cpuid_level;
brillywu@viatech.com.cnb3baa152011-06-01 09:59:52 +08002438 }
2439 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002440 } else {
2441 if (index > env->cpuid_level)
2442 index = env->cpuid_level;
2443 }
2444
2445 switch(index) {
2446 case 0:
2447 *eax = env->cpuid_level;
Eduardo Habkost5eb2f7a2015-02-03 15:57:50 -02002448 *ebx = env->cpuid_vendor1;
2449 *edx = env->cpuid_vendor2;
2450 *ecx = env->cpuid_vendor3;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002451 break;
2452 case 1:
2453 *eax = env->cpuid_version;
Eduardo Habkost7e72a452014-12-18 23:20:10 -02002454 *ebx = (cpu->apic_id << 24) |
2455 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002456 *ecx = env->features[FEAT_1_ECX];
Richard Henderson19dc85d2015-07-02 14:53:40 +01002457 if ((*ecx & CPUID_EXT_XSAVE) && (env->cr[4] & CR4_OSXSAVE_MASK)) {
2458 *ecx |= CPUID_EXT_OSXSAVE;
2459 }
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002460 *edx = env->features[FEAT_1_EDX];
Andreas Färberce3960e2012-12-17 03:27:07 +01002461 if (cs->nr_cores * cs->nr_threads > 1) {
2462 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
Richard Henderson19dc85d2015-07-02 14:53:40 +01002463 *edx |= CPUID_HT;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002464 }
2465 break;
2466 case 2:
2467 /* cache info: needed for Pentium Pro compatibility */
Benoît Canet787aaf52013-09-02 17:06:37 +02002468 if (cpu->cache_info_passthrough) {
2469 host_cpuid(index, 0, eax, ebx, ecx, edx);
2470 break;
2471 }
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002472 *eax = 1; /* Number of CPUID[EAX=2] calls required */
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002473 *ebx = 0;
Longpeng(Mike)14c985c2016-09-07 13:21:13 +08002474 if (!cpu->enable_l3_cache) {
2475 *ecx = 0;
2476 } else {
2477 *ecx = L3_N_DESCRIPTOR;
2478 }
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002479 *edx = (L1D_DESCRIPTOR << 16) | \
2480 (L1I_DESCRIPTOR << 8) | \
2481 (L2_DESCRIPTOR);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002482 break;
2483 case 4:
2484 /* cache info: needed for Core compatibility */
Benoît Canet787aaf52013-09-02 17:06:37 +02002485 if (cpu->cache_info_passthrough) {
2486 host_cpuid(index, count, eax, ebx, ecx, edx);
Paolo Bonzini76c29752013-11-19 17:49:46 +01002487 *eax &= ~0xFC000000;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002488 } else {
Aurelien Jarno2f7a21c2010-03-13 16:46:33 +01002489 *eax = 0;
Paolo Bonzini76c29752013-11-19 17:49:46 +01002490 switch (count) {
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002491 case 0: /* L1 dcache info */
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002492 *eax |= CPUID_4_TYPE_DCACHE | \
2493 CPUID_4_LEVEL(1) | \
2494 CPUID_4_SELF_INIT_LEVEL;
2495 *ebx = (L1D_LINE_SIZE - 1) | \
2496 ((L1D_PARTITIONS - 1) << 12) | \
2497 ((L1D_ASSOCIATIVITY - 1) << 22);
2498 *ecx = L1D_SETS - 1;
2499 *edx = CPUID_4_NO_INVD_SHARING;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002500 break;
2501 case 1: /* L1 icache info */
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002502 *eax |= CPUID_4_TYPE_ICACHE | \
2503 CPUID_4_LEVEL(1) | \
2504 CPUID_4_SELF_INIT_LEVEL;
2505 *ebx = (L1I_LINE_SIZE - 1) | \
2506 ((L1I_PARTITIONS - 1) << 12) | \
2507 ((L1I_ASSOCIATIVITY - 1) << 22);
2508 *ecx = L1I_SETS - 1;
2509 *edx = CPUID_4_NO_INVD_SHARING;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002510 break;
2511 case 2: /* L2 cache info */
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002512 *eax |= CPUID_4_TYPE_UNIFIED | \
2513 CPUID_4_LEVEL(2) | \
2514 CPUID_4_SELF_INIT_LEVEL;
Andreas Färberce3960e2012-12-17 03:27:07 +01002515 if (cs->nr_threads > 1) {
2516 *eax |= (cs->nr_threads - 1) << 14;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002517 }
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002518 *ebx = (L2_LINE_SIZE - 1) | \
2519 ((L2_PARTITIONS - 1) << 12) | \
2520 ((L2_ASSOCIATIVITY - 1) << 22);
2521 *ecx = L2_SETS - 1;
2522 *edx = CPUID_4_NO_INVD_SHARING;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002523 break;
Longpeng(Mike)14c985c2016-09-07 13:21:13 +08002524 case 3: /* L3 cache info */
2525 if (!cpu->enable_l3_cache) {
2526 *eax = 0;
2527 *ebx = 0;
2528 *ecx = 0;
2529 *edx = 0;
2530 break;
2531 }
2532 *eax |= CPUID_4_TYPE_UNIFIED | \
2533 CPUID_4_LEVEL(3) | \
2534 CPUID_4_SELF_INIT_LEVEL;
2535 pkg_offset = apicid_pkg_offset(cs->nr_cores, cs->nr_threads);
2536 *eax |= ((1 << pkg_offset) - 1) << 14;
2537 *ebx = (L3_N_LINE_SIZE - 1) | \
2538 ((L3_N_PARTITIONS - 1) << 12) | \
2539 ((L3_N_ASSOCIATIVITY - 1) << 22);
2540 *ecx = L3_N_SETS - 1;
2541 *edx = CPUID_4_INCLUSIVE | CPUID_4_COMPLEX_IDX;
2542 break;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002543 default: /* end of info */
2544 *eax = 0;
2545 *ebx = 0;
2546 *ecx = 0;
2547 *edx = 0;
2548 break;
Paolo Bonzini76c29752013-11-19 17:49:46 +01002549 }
2550 }
2551
2552 /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
2553 if ((*eax & 31) && cs->nr_cores > 1) {
2554 *eax |= (cs->nr_cores - 1) << 26;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002555 }
2556 break;
2557 case 5:
2558 /* mwait info: needed for Core compatibility */
2559 *eax = 0; /* Smallest monitor-line size in bytes */
2560 *ebx = 0; /* Largest monitor-line size in bytes */
2561 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
2562 *edx = 0;
2563 break;
2564 case 6:
2565 /* Thermal and Power Leaf */
Jan Kiszka28b8e4d2015-06-07 11:15:08 +02002566 *eax = env->features[FEAT_6_EAX];
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002567 *ebx = 0;
2568 *ecx = 0;
2569 *edx = 0;
2570 break;
Yang, Wei Yf7911682011-05-30 23:17:42 +08002571 case 7:
Eduardo Habkost13526722012-05-21 11:27:02 -03002572 /* Structured Extended Feature Flags Enumeration Leaf */
2573 if (count == 0) {
2574 *eax = 0; /* Maximum ECX value for sub-leaves */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002575 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
Huaitong Hanf74eefe2015-11-18 10:20:15 +08002576 *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */
Paolo Bonzini0f70ed42016-02-09 14:14:28 +01002577 if ((*ecx & CPUID_7_0_ECX_PKU) && env->cr[4] & CR4_PKE_MASK) {
2578 *ecx |= CPUID_7_0_ECX_OSPKE;
2579 }
Luwei Kang95ea69f2016-10-31 16:27:26 +08002580 *edx = env->features[FEAT_7_0_EDX]; /* Feature flags */
Yang, Wei Yf7911682011-05-30 23:17:42 +08002581 } else {
2582 *eax = 0;
2583 *ebx = 0;
2584 *ecx = 0;
2585 *edx = 0;
2586 }
2587 break;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002588 case 9:
2589 /* Direct Cache Access Information Leaf */
2590 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2591 *ebx = 0;
2592 *ecx = 0;
2593 *edx = 0;
2594 break;
2595 case 0xA:
2596 /* Architectural Performance Monitoring Leaf */
Eduardo Habkost9337e3b2013-07-26 17:09:36 -03002597 if (kvm_enabled() && cpu->enable_pmu) {
Andreas Färbera60f24b2012-12-01 05:35:08 +01002598 KVMState *s = cs->kvm_state;
Gleb Natapova0fa8202011-12-15 12:44:05 +02002599
2600 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
2601 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
2602 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
2603 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
2604 } else {
2605 *eax = 0;
2606 *ebx = 0;
2607 *ecx = 0;
2608 *edx = 0;
2609 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002610 break;
Radim Krčmář5232d002016-05-12 19:24:26 +02002611 case 0xB:
2612 /* Extended Topology Enumeration Leaf */
2613 if (!cpu->enable_cpuid_0xb) {
2614 *eax = *ebx = *ecx = *edx = 0;
2615 break;
2616 }
2617
2618 *ecx = count & 0xff;
2619 *edx = cpu->apic_id;
2620
2621 switch (count) {
2622 case 0:
Marc-André Lureaueab60fb2016-09-16 19:50:24 +04002623 *eax = apicid_core_offset(cs->nr_cores, cs->nr_threads);
2624 *ebx = cs->nr_threads;
Radim Krčmář5232d002016-05-12 19:24:26 +02002625 *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
2626 break;
2627 case 1:
Marc-André Lureaueab60fb2016-09-16 19:50:24 +04002628 *eax = apicid_pkg_offset(cs->nr_cores, cs->nr_threads);
2629 *ebx = cs->nr_cores * cs->nr_threads;
Radim Krčmář5232d002016-05-12 19:24:26 +02002630 *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
2631 break;
2632 default:
2633 *eax = 0;
2634 *ebx = 0;
2635 *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
2636 }
2637
2638 assert(!(*eax & ~0x1f));
2639 *ebx &= 0xffff; /* The count doesn't need to be reliable. */
2640 break;
Paolo Bonzini2560f192013-10-02 17:54:57 +02002641 case 0xD: {
Sheng Yang51e49432010-06-17 15:18:14 +08002642 /* Processor Extended State */
Paolo Bonzini2560f192013-10-02 17:54:57 +02002643 *eax = 0;
2644 *ebx = 0;
2645 *ecx = 0;
2646 *edx = 0;
Richard Henderson19dc85d2015-07-02 14:53:40 +01002647 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
Sheng Yang51e49432010-06-17 15:18:14 +08002648 break;
2649 }
Eduardo Habkost4928cd62016-09-22 14:33:01 -03002650
Paolo Bonzini2560f192013-10-02 17:54:57 +02002651 if (count == 0) {
Eduardo Habkost96193c22016-09-22 17:41:35 -03002652 *ecx = xsave_area_size(x86_cpu_xsave_components(cpu));
2653 *eax = env->features[FEAT_XSAVE_COMP_LO];
2654 *edx = env->features[FEAT_XSAVE_COMP_HI];
Paolo Bonzini2560f192013-10-02 17:54:57 +02002655 *ebx = *ecx;
2656 } else if (count == 1) {
Paolo Bonzini0bb0b2d2014-11-24 15:54:43 +01002657 *eax = env->features[FEAT_XSAVE];
Richard Hendersonf4f11102015-07-02 15:57:14 +01002658 } else if (count < ARRAY_SIZE(x86_ext_save_areas)) {
Eduardo Habkost96193c22016-09-22 17:41:35 -03002659 if ((x86_cpu_xsave_components(cpu) >> count) & 1) {
2660 const ExtSaveArea *esa = &x86_ext_save_areas[count];
Liu Jinsong33f373d2013-12-03 04:17:50 +08002661 *eax = esa->size;
2662 *ebx = esa->offset;
Paolo Bonzini2560f192013-10-02 17:54:57 +02002663 }
Sheng Yang51e49432010-06-17 15:18:14 +08002664 }
2665 break;
Paolo Bonzini2560f192013-10-02 17:54:57 +02002666 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002667 case 0x80000000:
2668 *eax = env->cpuid_xlevel;
2669 *ebx = env->cpuid_vendor1;
2670 *edx = env->cpuid_vendor2;
2671 *ecx = env->cpuid_vendor3;
2672 break;
2673 case 0x80000001:
2674 *eax = env->cpuid_version;
2675 *ebx = 0;
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002676 *ecx = env->features[FEAT_8000_0001_ECX];
2677 *edx = env->features[FEAT_8000_0001_EDX];
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002678
2679 /* The Linux kernel checks for the CMPLegacy bit and
2680 * discards multiple thread information if it is set.
Stefan Weilcb8d4c82016-03-23 15:59:57 +01002681 * So don't set it here for Intel to make Linux guests happy.
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002682 */
Andreas Färberce3960e2012-12-17 03:27:07 +01002683 if (cs->nr_cores * cs->nr_threads > 1) {
Eduardo Habkost5eb2f7a2015-02-03 15:57:50 -02002684 if (env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1 ||
2685 env->cpuid_vendor2 != CPUID_VENDOR_INTEL_2 ||
2686 env->cpuid_vendor3 != CPUID_VENDOR_INTEL_3) {
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002687 *ecx |= 1 << 1; /* CmpLegacy bit */
2688 }
2689 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002690 break;
2691 case 0x80000002:
2692 case 0x80000003:
2693 case 0x80000004:
2694 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2695 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2696 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2697 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2698 break;
2699 case 0x80000005:
2700 /* cache info (L1 cache) */
Benoît Canet787aaf52013-09-02 17:06:37 +02002701 if (cpu->cache_info_passthrough) {
2702 host_cpuid(index, 0, eax, ebx, ecx, edx);
2703 break;
2704 }
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002705 *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \
2706 (L1_ITLB_2M_ASSOC << 8) | (L1_ITLB_2M_ENTRIES);
2707 *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
2708 (L1_ITLB_4K_ASSOC << 8) | (L1_ITLB_4K_ENTRIES);
2709 *ecx = (L1D_SIZE_KB_AMD << 24) | (L1D_ASSOCIATIVITY_AMD << 16) | \
2710 (L1D_LINES_PER_TAG << 8) | (L1D_LINE_SIZE);
2711 *edx = (L1I_SIZE_KB_AMD << 24) | (L1I_ASSOCIATIVITY_AMD << 16) | \
2712 (L1I_LINES_PER_TAG << 8) | (L1I_LINE_SIZE);
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002713 break;
2714 case 0x80000006:
2715 /* cache info (L2 cache) */
Benoît Canet787aaf52013-09-02 17:06:37 +02002716 if (cpu->cache_info_passthrough) {
2717 host_cpuid(index, 0, eax, ebx, ecx, edx);
2718 break;
2719 }
Eduardo Habkost5e891bf2013-08-27 12:24:37 -03002720 *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \
2721 (L2_DTLB_2M_ENTRIES << 16) | \
2722 (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \
2723 (L2_ITLB_2M_ENTRIES);
2724 *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) | \
2725 (L2_DTLB_4K_ENTRIES << 16) | \
2726 (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
2727 (L2_ITLB_4K_ENTRIES);
2728 *ecx = (L2_SIZE_KB_AMD << 16) | \
2729 (AMD_ENC_ASSOC(L2_ASSOCIATIVITY) << 12) | \
2730 (L2_LINES_PER_TAG << 8) | (L2_LINE_SIZE);
Longpeng(Mike)14c985c2016-09-07 13:21:13 +08002731 if (!cpu->enable_l3_cache) {
2732 *edx = ((L3_SIZE_KB / 512) << 18) | \
2733 (AMD_ENC_ASSOC(L3_ASSOCIATIVITY) << 12) | \
2734 (L3_LINES_PER_TAG << 8) | (L3_LINE_SIZE);
2735 } else {
2736 *edx = ((L3_N_SIZE_KB_AMD / 512) << 18) | \
2737 (AMD_ENC_ASSOC(L3_N_ASSOCIATIVITY) << 12) | \
2738 (L3_N_LINES_PER_TAG << 8) | (L3_N_LINE_SIZE);
2739 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002740 break;
Marcelo Tosatti303752a2014-04-30 13:48:45 -03002741 case 0x80000007:
2742 *eax = 0;
2743 *ebx = 0;
2744 *ecx = 0;
2745 *edx = env->features[FEAT_8000_0007_EDX];
2746 break;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002747 case 0x80000008:
2748 /* virtual & phys address size in low 2 bytes. */
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002749 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
Dr. David Alan Gilbertaf459072016-07-08 16:01:36 +01002750 /* 64 bit processor, 48 bits virtual, configurable
2751 * physical bits.
2752 */
2753 *eax = 0x00003000 + cpu->phys_bits;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002754 } else {
Dr. David Alan Gilbertaf459072016-07-08 16:01:36 +01002755 *eax = cpu->phys_bits;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002756 }
2757 *ebx = 0;
2758 *ecx = 0;
2759 *edx = 0;
Andreas Färberce3960e2012-12-17 03:27:07 +01002760 if (cs->nr_cores * cs->nr_threads > 1) {
2761 *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002762 }
2763 break;
2764 case 0x8000000A:
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002765 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
Eduardo Habkost9f3fb562012-12-04 17:34:38 -02002766 *eax = 0x00000001; /* SVM Revision */
2767 *ebx = 0x00000010; /* nr of ASIDs */
2768 *ecx = 0;
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002769 *edx = env->features[FEAT_SVM]; /* optional features */
Eduardo Habkost9f3fb562012-12-04 17:34:38 -02002770 } else {
2771 *eax = 0;
2772 *ebx = 0;
2773 *ecx = 0;
2774 *edx = 0;
2775 }
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002776 break;
brillywu@viatech.com.cnb3baa152011-06-01 09:59:52 +08002777 case 0xC0000000:
2778 *eax = env->cpuid_xlevel2;
2779 *ebx = 0;
2780 *ecx = 0;
2781 *edx = 0;
2782 break;
2783 case 0xC0000001:
2784 /* Support for VIA CPU's CPUID instruction */
2785 *eax = env->cpuid_version;
2786 *ebx = 0;
2787 *ecx = 0;
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002788 *edx = env->features[FEAT_C000_0001_EDX];
brillywu@viatech.com.cnb3baa152011-06-01 09:59:52 +08002789 break;
2790 case 0xC0000002:
2791 case 0xC0000003:
2792 case 0xC0000004:
2793 /* Reserved for the future, and now filled with zero */
2794 *eax = 0;
2795 *ebx = 0;
2796 *ecx = 0;
2797 *edx = 0;
2798 break;
Andre Przywarac6dc6f62010-03-11 14:38:55 +01002799 default:
2800 /* reserved values: zero */
2801 *eax = 0;
2802 *ebx = 0;
2803 *ecx = 0;
2804 *edx = 0;
2805 break;
2806 }
2807}
Andreas Färber5fd20872012-04-02 23:20:08 +02002808
2809/* CPUClass::reset() */
2810static void x86_cpu_reset(CPUState *s)
2811{
2812 X86CPU *cpu = X86_CPU(s);
2813 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2814 CPUX86State *env = &cpu->env;
Richard Hendersona114d252015-07-07 16:13:10 +01002815 target_ulong cr4;
2816 uint64_t xcr0;
Andreas Färberc1958ae2012-04-03 00:16:24 +02002817 int i;
2818
Andreas Färber5fd20872012-04-02 23:20:08 +02002819 xcc->parent_reset(s);
2820
Eduardo Habkost5e992a82015-04-24 15:49:15 -03002821 memset(env, 0, offsetof(CPUX86State, end_reset_fields));
Andreas Färberc1958ae2012-04-03 00:16:24 +02002822
Andreas Färber00c8cb02013-09-04 02:19:44 +02002823 tlb_flush(s, 1);
Andreas Färberc1958ae2012-04-03 00:16:24 +02002824
2825 env->old_exception = -1;
2826
2827 /* init to reset state */
2828
Andreas Färberc1958ae2012-04-03 00:16:24 +02002829 env->hflags2 |= HF2_GIF_MASK;
2830
2831 cpu_x86_update_cr0(env, 0x60000010);
2832 env->a20_mask = ~0x0;
2833 env->smbase = 0x30000;
2834
2835 env->idt.limit = 0xffff;
2836 env->gdt.limit = 0xffff;
2837 env->ldt.limit = 0xffff;
2838 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2839 env->tr.limit = 0xffff;
2840 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2841
2842 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2843 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2844 DESC_R_MASK | DESC_A_MASK);
2845 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2846 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2847 DESC_A_MASK);
2848 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
2849 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2850 DESC_A_MASK);
2851 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
2852 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2853 DESC_A_MASK);
2854 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
2855 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2856 DESC_A_MASK);
2857 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
2858 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2859 DESC_A_MASK);
2860
2861 env->eip = 0xfff0;
2862 env->regs[R_EDX] = env->cpuid_version;
2863
2864 env->eflags = 0x2;
2865
2866 /* FPU init */
2867 for (i = 0; i < 8; i++) {
2868 env->fptags[i] = 1;
2869 }
Pavel Dovgalyuk5bde1402014-09-17 12:05:19 +04002870 cpu_set_fpuc(env, 0x37f);
Andreas Färberc1958ae2012-04-03 00:16:24 +02002871
2872 env->mxcsr = 0x1f80;
Richard Hendersona114d252015-07-07 16:13:10 +01002873 /* All units are in INIT state. */
2874 env->xstate_bv = 0;
Andreas Färberc1958ae2012-04-03 00:16:24 +02002875
2876 env->pat = 0x0007040600070406ULL;
2877 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2878
2879 memset(env->dr, 0, sizeof(env->dr));
2880 env->dr[6] = DR6_FIXED_1;
2881 env->dr[7] = DR7_FIXED_1;
Andreas Färberb3310ab2013-09-02 17:26:20 +02002882 cpu_breakpoint_remove_all(s, BP_CPU);
Andreas Färber75a34032013-09-02 16:57:02 +02002883 cpu_watchpoint_remove_all(s, BP_CPU);
Igor Mammedovdd673282012-07-23 15:22:27 +02002884
Richard Hendersona114d252015-07-07 16:13:10 +01002885 cr4 = 0;
Paolo Bonzinicfc3b072016-02-17 10:54:53 +01002886 xcr0 = XSTATE_FP_MASK;
Richard Hendersona114d252015-07-07 16:13:10 +01002887
2888#ifdef CONFIG_USER_ONLY
2889 /* Enable all the features for user-mode. */
2890 if (env->features[FEAT_1_EDX] & CPUID_SSE) {
Paolo Bonzinicfc3b072016-02-17 10:54:53 +01002891 xcr0 |= XSTATE_SSE_MASK;
Richard Hendersona114d252015-07-07 16:13:10 +01002892 }
Paolo Bonzini0f70ed42016-02-09 14:14:28 +01002893 for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
2894 const ExtSaveArea *esa = &x86_ext_save_areas[i];
Eduardo Habkost9646f492016-09-22 18:58:39 -03002895 if (env->features[esa->feature] & esa->bits) {
Paolo Bonzini0f70ed42016-02-09 14:14:28 +01002896 xcr0 |= 1ull << i;
2897 }
Richard Hendersona114d252015-07-07 16:13:10 +01002898 }
Paolo Bonzini0f70ed42016-02-09 14:14:28 +01002899
Richard Hendersona114d252015-07-07 16:13:10 +01002900 if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) {
2901 cr4 |= CR4_OSFXSR_MASK | CR4_OSXSAVE_MASK;
2902 }
Richard Henderson07929f22015-11-18 12:55:47 +01002903 if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_FSGSBASE) {
2904 cr4 |= CR4_FSGSBASE_MASK;
2905 }
Richard Hendersona114d252015-07-07 16:13:10 +01002906#endif
2907
2908 env->xcr0 = xcr0;
2909 cpu_x86_update_cr4(env, cr4);
Fernando Luis Vázquez Cao05226042013-12-06 17:33:01 +09002910
Alex Williamson9db2efd2014-08-14 15:39:39 -06002911 /*
2912 * SDM 11.11.5 requires:
2913 * - IA32_MTRR_DEF_TYPE MSR.E = 0
2914 * - IA32_MTRR_PHYSMASKn.V = 0
2915 * All other bits are undefined. For simplification, zero it all.
2916 */
2917 env->mtrr_deftype = 0;
2918 memset(env->mtrr_var, 0, sizeof(env->mtrr_var));
2919 memset(env->mtrr_fixed, 0, sizeof(env->mtrr_fixed));
2920
Igor Mammedovdd673282012-07-23 15:22:27 +02002921#if !defined(CONFIG_USER_ONLY)
2922 /* We hard-wire the BSP to the first CPU. */
Nadav Amit9cb11fd2015-04-02 02:58:36 +03002923 apic_designate_bsp(cpu->apic_state, s->cpu_index == 0);
Igor Mammedovdd673282012-07-23 15:22:27 +02002924
Andreas Färber259186a2013-01-17 18:51:17 +01002925 s->halted = !cpu_is_bsp(cpu);
Paolo Bonzini50a2c6e2013-03-20 13:11:56 +01002926
2927 if (kvm_enabled()) {
2928 kvm_arch_reset_vcpu(cpu);
2929 }
Igor Mammedovdd673282012-07-23 15:22:27 +02002930#endif
Andreas Färber5fd20872012-04-02 23:20:08 +02002931}
2932
Igor Mammedovdd673282012-07-23 15:22:27 +02002933#ifndef CONFIG_USER_ONLY
2934bool cpu_is_bsp(X86CPU *cpu)
2935{
Chen Fan02e51482013-12-23 17:04:02 +08002936 return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
Igor Mammedovdd673282012-07-23 15:22:27 +02002937}
Igor Mammedov65dee382012-07-23 15:22:28 +02002938
2939/* TODO: remove me, when reset over QOM tree is implemented */
2940static void x86_cpu_machine_reset_cb(void *opaque)
2941{
2942 X86CPU *cpu = opaque;
2943 cpu_reset(CPU(cpu));
2944}
Igor Mammedovdd673282012-07-23 15:22:27 +02002945#endif
2946
Andreas Färberde024812012-04-03 00:00:17 +02002947static void mce_init(X86CPU *cpu)
2948{
2949 CPUX86State *cenv = &cpu->env;
2950 unsigned int bank;
2951
2952 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
Eduardo Habkost0514ef22013-04-22 16:00:15 -03002953 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
Andreas Färberde024812012-04-03 00:00:17 +02002954 (CPUID_MCE | CPUID_MCA)) {
Ashok Raj87f8b622016-06-22 14:56:21 +08002955 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF |
2956 (cpu->enable_lmce ? MCG_LMCE_P : 0);
Andreas Färberde024812012-04-03 00:00:17 +02002957 cenv->mcg_ctl = ~(uint64_t)0;
2958 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2959 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2960 }
2961 }
2962}
2963
Igor Mammedovbdeec802012-10-13 22:35:39 +02002964#ifndef CONFIG_USER_ONLY
Radim Krčmář2f114312016-10-10 17:28:42 +02002965APICCommonClass *apic_get_class(void)
Igor Mammedovbdeec802012-10-13 22:35:39 +02002966{
Igor Mammedovbdeec802012-10-13 22:35:39 +02002967 const char *apic_type = "apic";
2968
Paolo Bonzini15eafc22015-12-17 17:16:08 +01002969 if (kvm_apic_in_kernel()) {
Igor Mammedovbdeec802012-10-13 22:35:39 +02002970 apic_type = "kvm-apic";
2971 } else if (xen_enabled()) {
2972 apic_type = "xen-apic";
2973 }
2974
Radim Krčmář2f114312016-10-10 17:28:42 +02002975 return APIC_COMMON_CLASS(object_class_by_name(apic_type));
2976}
2977
2978static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
2979{
2980 APICCommonState *apic;
2981 ObjectClass *apic_class = OBJECT_CLASS(apic_get_class());
2982
2983 cpu->apic_state = DEVICE(object_new(object_class_get_name(apic_class)));
Igor Mammedovbdeec802012-10-13 22:35:39 +02002984
Igor Mammedov6816b1b2016-07-06 08:20:52 +02002985 object_property_add_child(OBJECT(cpu), "lapic",
2986 OBJECT(cpu->apic_state), &error_abort);
Igor Mammedov67e55ca2016-07-06 08:20:53 +02002987 object_unref(OBJECT(cpu->apic_state));
Igor Mammedov6816b1b2016-07-06 08:20:52 +02002988
Igor Mammedov33d7a282016-10-19 14:05:35 +02002989 qdev_prop_set_uint32(cpu->apic_state, "id", cpu->apic_id);
Igor Mammedovbdeec802012-10-13 22:35:39 +02002990 /* TODO: convert to link<> */
Chen Fan02e51482013-12-23 17:04:02 +08002991 apic = APIC_COMMON(cpu->apic_state);
Andreas Färber60671e52012-10-10 14:10:07 +02002992 apic->cpu = cpu;
Chen Fan8d42d2d2015-09-16 17:19:11 +08002993 apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE;
Igor Mammedovd3c64d62013-04-05 16:36:54 +02002994}
2995
2996static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2997{
Chen Fan8d42d2d2015-09-16 17:19:11 +08002998 APICCommonState *apic;
2999 static bool apic_mmio_map_once;
3000
Chen Fan02e51482013-12-23 17:04:02 +08003001 if (cpu->apic_state == NULL) {
Igor Mammedovd3c64d62013-04-05 16:36:54 +02003002 return;
3003 }
Markus Armbruster6e8e2652015-02-05 10:29:15 +01003004 object_property_set_bool(OBJECT(cpu->apic_state), true, "realized",
3005 errp);
Chen Fan8d42d2d2015-09-16 17:19:11 +08003006
3007 /* Map APIC MMIO area */
3008 apic = APIC_COMMON(cpu->apic_state);
3009 if (!apic_mmio_map_once) {
3010 memory_region_add_subregion_overlap(get_system_memory(),
3011 apic->apicbase &
3012 MSR_IA32_APICBASE_BASE,
3013 &apic->io_memory,
3014 0x1000);
3015 apic_mmio_map_once = true;
3016 }
Igor Mammedovbdeec802012-10-13 22:35:39 +02003017}
Paolo Bonzinif809c602015-03-31 14:12:25 +02003018
3019static void x86_cpu_machine_done(Notifier *n, void *unused)
3020{
3021 X86CPU *cpu = container_of(n, X86CPU, machine_done);
3022 MemoryRegion *smram =
3023 (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
3024
3025 if (smram) {
3026 cpu->smram = g_new(MemoryRegion, 1);
3027 memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
3028 smram, 0, 1ull << 32);
3029 memory_region_set_enabled(cpu->smram, false);
3030 memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->smram, 1);
3031 }
3032}
Igor Mammedovd3c64d62013-04-05 16:36:54 +02003033#else
3034static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
3035{
3036}
Igor Mammedovbdeec802012-10-13 22:35:39 +02003037#endif
3038
Dr. David Alan Gilbert11f6fee2016-07-11 20:28:46 +01003039/* Note: Only safe for use on x86(-64) hosts */
3040static uint32_t x86_host_phys_bits(void)
3041{
3042 uint32_t eax;
3043 uint32_t host_phys_bits;
3044
3045 host_cpuid(0x80000000, 0, &eax, NULL, NULL, NULL);
3046 if (eax >= 0x80000008) {
3047 host_cpuid(0x80000008, 0, &eax, NULL, NULL, NULL);
3048 /* Note: According to AMD doc 25481 rev 2.34 they have a field
3049 * at 23:16 that can specify a maximum physical address bits for
3050 * the guest that can override this value; but I've not seen
3051 * anything with that set.
3052 */
3053 host_phys_bits = eax & 0xff;
3054 } else {
3055 /* It's an odd 64 bit machine that doesn't have the leaf for
3056 * physical address bits; fall back to 36 that's most older
3057 * Intel.
3058 */
3059 host_phys_bits = 36;
3060 }
3061
3062 return host_phys_bits;
3063}
Wei Huange48638f2014-10-21 11:00:45 -04003064
Eduardo Habkostc39c0ed2016-09-21 13:30:12 -03003065static void x86_cpu_adjust_level(X86CPU *cpu, uint32_t *min, uint32_t value)
3066{
3067 if (*min < value) {
3068 *min = value;
3069 }
3070}
3071
3072/* Increase cpuid_min_{level,xlevel,xlevel2} automatically, if appropriate */
3073static void x86_cpu_adjust_feat_level(X86CPU *cpu, FeatureWord w)
3074{
3075 CPUX86State *env = &cpu->env;
3076 FeatureWordInfo *fi = &feature_word_info[w];
3077 uint32_t eax = fi->cpuid_eax;
3078 uint32_t region = eax & 0xF0000000;
3079
3080 if (!env->features[w]) {
3081 return;
3082 }
3083
3084 switch (region) {
3085 case 0x00000000:
3086 x86_cpu_adjust_level(cpu, &env->cpuid_min_level, eax);
3087 break;
3088 case 0x80000000:
3089 x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, eax);
3090 break;
3091 case 0xC0000000:
3092 x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel2, eax);
3093 break;
3094 }
3095}
3096
Eduardo Habkost2ca8a8b2016-09-22 17:27:56 -03003097/* Calculate XSAVE components based on the configured CPU feature flags */
3098static void x86_cpu_enable_xsave_components(X86CPU *cpu)
3099{
3100 CPUX86State *env = &cpu->env;
3101 int i;
Eduardo Habkost96193c22016-09-22 17:41:35 -03003102 uint64_t mask;
Eduardo Habkost2ca8a8b2016-09-22 17:27:56 -03003103
3104 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
3105 return;
3106 }
3107
Eduardo Habkoste3c90222016-09-30 15:49:42 -03003108 mask = 0;
3109 for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
Eduardo Habkost2ca8a8b2016-09-22 17:27:56 -03003110 const ExtSaveArea *esa = &x86_ext_save_areas[i];
3111 if (env->features[esa->feature] & esa->bits) {
Eduardo Habkost96193c22016-09-22 17:41:35 -03003112 mask |= (1ULL << i);
Eduardo Habkost2ca8a8b2016-09-22 17:27:56 -03003113 }
3114 }
3115
Eduardo Habkost96193c22016-09-22 17:41:35 -03003116 env->features[FEAT_XSAVE_COMP_LO] = mask;
3117 env->features[FEAT_XSAVE_COMP_HI] = mask >> 32;
Eduardo Habkost2ca8a8b2016-09-22 17:27:56 -03003118}
3119
Eduardo Habkost41f3d4d2016-09-28 15:03:26 -03003120/* Load CPUID data based on configured features */
3121static void x86_cpu_load_features(X86CPU *cpu, Error **errp)
Andreas Färber7a059952012-05-09 23:15:32 +02003122{
Igor Mammedovb34d12d2012-10-22 17:03:00 +02003123 CPUX86State *env = &cpu->env;
Igor Mammedovdc15c052016-06-06 17:16:44 +02003124 FeatureWord w;
Eduardo Habkost2fae0d92016-09-30 15:49:39 -03003125 GList *l;
Eduardo Habkost41f3d4d2016-09-28 15:03:26 -03003126 Error *local_err = NULL;
Eduardo Habkost9886e832014-12-18 23:31:11 -02003127
Igor Mammedovdc15c052016-06-06 17:16:44 +02003128 /*TODO: cpu->host_features incorrectly overwrites features
3129 * set using "feat=on|off". Once we fix this, we can convert
3130 * plus_features & minus_features to global properties
3131 * inside x86_cpu_parse_featurestr() too.
3132 */
3133 if (cpu->host_features) {
3134 for (w = 0; w < FEATURE_WORDS; w++) {
3135 env->features[w] =
3136 x86_cpu_get_supported_feature_word(w, cpu->migratable);
3137 }
3138 }
3139
Eduardo Habkost2fae0d92016-09-30 15:49:39 -03003140 for (l = plus_features; l; l = l->next) {
3141 const char *prop = l->data;
3142 object_property_set_bool(OBJECT(cpu), true, prop, &local_err);
3143 if (local_err) {
3144 goto out;
3145 }
3146 }
3147
3148 for (l = minus_features; l; l = l->next) {
3149 const char *prop = l->data;
3150 object_property_set_bool(OBJECT(cpu), false, prop, &local_err);
3151 if (local_err) {
3152 goto out;
3153 }
Igor Mammedovdc15c052016-06-06 17:16:44 +02003154 }
3155
Eduardo Habkostaec661d2016-09-26 19:11:14 -03003156 if (!kvm_enabled() || !cpu->expose_kvm) {
3157 env->features[FEAT_KVM] = 0;
3158 }
3159
Eduardo Habkost2ca8a8b2016-09-22 17:27:56 -03003160 x86_cpu_enable_xsave_components(cpu);
Eduardo Habkostc39c0ed2016-09-21 13:30:12 -03003161
3162 /* CPUID[EAX=7,ECX=0].EBX always increased level automatically: */
3163 x86_cpu_adjust_feat_level(cpu, FEAT_7_0_EBX);
3164 if (cpu->full_cpuid_auto_level) {
3165 x86_cpu_adjust_feat_level(cpu, FEAT_1_EDX);
3166 x86_cpu_adjust_feat_level(cpu, FEAT_1_ECX);
3167 x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX);
3168 x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX);
3169 x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX);
3170 x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX);
3171 x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX);
3172 x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX);
3173 x86_cpu_adjust_feat_level(cpu, FEAT_SVM);
3174 x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);
Eduardo Habkost0c3d7c02016-09-21 15:01:35 -03003175 /* SVM requires CPUID[0x8000000A] */
3176 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
3177 x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);
3178 }
Eduardo Habkostc39c0ed2016-09-21 13:30:12 -03003179 }
3180
3181 /* Set cpuid_*level* based on cpuid_min_*level, if not explicitly set */
3182 if (env->cpuid_level == UINT32_MAX) {
3183 env->cpuid_level = env->cpuid_min_level;
3184 }
3185 if (env->cpuid_xlevel == UINT32_MAX) {
3186 env->cpuid_xlevel = env->cpuid_min_xlevel;
3187 }
3188 if (env->cpuid_xlevel2 == UINT32_MAX) {
3189 env->cpuid_xlevel2 = env->cpuid_min_xlevel2;
Igor Mammedovb34d12d2012-10-22 17:03:00 +02003190 }
Andreas Färber7a059952012-05-09 23:15:32 +02003191
Eduardo Habkost41f3d4d2016-09-28 15:03:26 -03003192out:
3193 if (local_err != NULL) {
3194 error_propagate(errp, local_err);
3195 }
3196}
3197
3198#define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \
3199 (env)->cpuid_vendor2 == CPUID_VENDOR_INTEL_2 && \
3200 (env)->cpuid_vendor3 == CPUID_VENDOR_INTEL_3)
3201#define IS_AMD_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && \
3202 (env)->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && \
3203 (env)->cpuid_vendor3 == CPUID_VENDOR_AMD_3)
3204static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
3205{
3206 CPUState *cs = CPU(dev);
3207 X86CPU *cpu = X86_CPU(dev);
3208 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
3209 CPUX86State *env = &cpu->env;
3210 Error *local_err = NULL;
3211 static bool ht_warned;
3212
3213 if (xcc->kvm_required && !kvm_enabled()) {
3214 char *name = x86_cpu_class_get_model_name(xcc);
3215 error_setg(&local_err, "CPU model '%s' requires KVM", name);
3216 g_free(name);
3217 goto out;
3218 }
3219
3220 if (cpu->apic_id == UNASSIGNED_APIC_ID) {
3221 error_setg(errp, "apic-id property was not initialized properly");
3222 return;
3223 }
3224
3225 x86_cpu_load_features(cpu, &local_err);
3226 if (local_err) {
3227 goto out;
3228 }
3229
Eduardo Habkost8ca30e82016-05-04 14:50:46 -03003230 if (x86_cpu_filter_features(cpu) &&
3231 (cpu->check_cpuid || cpu->enforce_cpuid)) {
3232 x86_cpu_report_filtered_features(cpu);
3233 if (cpu->enforce_cpuid) {
3234 error_setg(&local_err,
3235 kvm_enabled() ?
3236 "Host doesn't support requested features" :
3237 "TCG doesn't support requested features");
3238 goto out;
3239 }
Eduardo Habkost9997cf72016-04-15 14:54:26 -03003240 }
3241
Igor Mammedov9b15cd92012-12-28 21:01:17 +01003242 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
3243 * CPUID[1].EDX.
3244 */
Wei Huange48638f2014-10-21 11:00:45 -04003245 if (IS_AMD_CPU(env)) {
Eduardo Habkost0514ef22013-04-22 16:00:15 -03003246 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
3247 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
Igor Mammedov9b15cd92012-12-28 21:01:17 +01003248 & CPUID_EXT2_AMD_ALIASES);
3249 }
3250
Dr. David Alan Gilbert11f6fee2016-07-11 20:28:46 +01003251 /* For 64bit systems think about the number of physical bits to present.
3252 * ideally this should be the same as the host; anything other than matching
3253 * the host can cause incorrect guest behaviour.
3254 * QEMU used to pick the magic value of 40 bits that corresponds to
3255 * consumer AMD devices but nothing else.
3256 */
Dr. David Alan Gilbertaf459072016-07-08 16:01:36 +01003257 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
Dr. David Alan Gilbertaf459072016-07-08 16:01:36 +01003258 if (kvm_enabled()) {
Dr. David Alan Gilbert11f6fee2016-07-11 20:28:46 +01003259 uint32_t host_phys_bits = x86_host_phys_bits();
3260 static bool warned;
3261
3262 if (cpu->host_phys_bits) {
3263 /* The user asked for us to use the host physical bits */
3264 cpu->phys_bits = host_phys_bits;
3265 }
3266
3267 /* Print a warning if the user set it to a value that's not the
3268 * host value.
3269 */
3270 if (cpu->phys_bits != host_phys_bits && cpu->phys_bits != 0 &&
3271 !warned) {
3272 error_report("Warning: Host physical bits (%u)"
3273 " does not match phys-bits property (%u)",
3274 host_phys_bits, cpu->phys_bits);
3275 warned = true;
3276 }
3277
3278 if (cpu->phys_bits &&
3279 (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
3280 cpu->phys_bits < 32)) {
Dr. David Alan Gilbertaf459072016-07-08 16:01:36 +01003281 error_setg(errp, "phys-bits should be between 32 and %u "
3282 " (but is %u)",
3283 TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bits);
3284 return;
3285 }
3286 } else {
Dr. David Alan Gilbert11f6fee2016-07-11 20:28:46 +01003287 if (cpu->phys_bits && cpu->phys_bits != TCG_PHYS_ADDR_BITS) {
Dr. David Alan Gilbertaf459072016-07-08 16:01:36 +01003288 error_setg(errp, "TCG only supports phys-bits=%u",
3289 TCG_PHYS_ADDR_BITS);
3290 return;
3291 }
3292 }
Dr. David Alan Gilbert11f6fee2016-07-11 20:28:46 +01003293 /* 0 means it was not explicitly set by the user (or by machine
3294 * compat_props or by the host code above). In this case, the default
3295 * is the value used by TCG (40).
3296 */
3297 if (cpu->phys_bits == 0) {
3298 cpu->phys_bits = TCG_PHYS_ADDR_BITS;
3299 }
Dr. David Alan Gilbertaf459072016-07-08 16:01:36 +01003300 } else {
3301 /* For 32 bit systems don't use the user set value, but keep
3302 * phys_bits consistent with what we tell the guest.
3303 */
3304 if (cpu->phys_bits != 0) {
3305 error_setg(errp, "phys-bits is not user-configurable in 32 bit");
3306 return;
3307 }
Eduardo Habkostfefb41b2014-04-30 13:48:39 -03003308
Dr. David Alan Gilbertaf459072016-07-08 16:01:36 +01003309 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
3310 cpu->phys_bits = 36;
3311 } else {
3312 cpu->phys_bits = 32;
3313 }
3314 }
Laurent Vivierce5b1bb2016-10-20 13:26:03 +02003315 cpu_exec_realizefn(cs, &local_err);
3316 if (local_err != NULL) {
3317 error_propagate(errp, local_err);
3318 return;
3319 }
Eduardo Habkost42ecaba2015-02-12 23:04:50 -02003320
Eduardo Habkost57f24532015-02-12 22:57:44 -02003321 if (tcg_enabled()) {
3322 tcg_x86_init();
3323 }
3324
Igor Mammedov65dee382012-07-23 15:22:28 +02003325#ifndef CONFIG_USER_ONLY
3326 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
Igor Mammedovbdeec802012-10-13 22:35:39 +02003327
Eduardo Habkost0514ef22013-04-22 16:00:15 -03003328 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
Igor Mammedovd3c64d62013-04-05 16:36:54 +02003329 x86_cpu_apic_create(cpu, &local_err);
Andreas Färber2b6f2942013-01-16 03:41:47 +01003330 if (local_err != NULL) {
Igor Mammedov4dc1f442013-04-05 16:36:53 +02003331 goto out;
Igor Mammedovbdeec802012-10-13 22:35:39 +02003332 }
3333 }
Igor Mammedov65dee382012-07-23 15:22:28 +02003334#endif
3335
Andreas Färber7a059952012-05-09 23:15:32 +02003336 mce_init(cpu);
Paolo Bonzini2001d0c2015-03-31 14:11:09 +02003337
3338#ifndef CONFIG_USER_ONLY
3339 if (tcg_enabled()) {
Peter Maydell56943e82016-01-21 14:15:04 +00003340 AddressSpace *newas = g_new(AddressSpace, 1);
3341
Paolo Bonzinif809c602015-03-31 14:12:25 +02003342 cpu->cpu_as_mem = g_new(MemoryRegion, 1);
Paolo Bonzini2001d0c2015-03-31 14:11:09 +02003343 cpu->cpu_as_root = g_new(MemoryRegion, 1);
Paolo Bonzinif809c602015-03-31 14:12:25 +02003344
3345 /* Outer container... */
3346 memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
Paolo Bonzini2001d0c2015-03-31 14:11:09 +02003347 memory_region_set_enabled(cpu->cpu_as_root, true);
Paolo Bonzinif809c602015-03-31 14:12:25 +02003348
3349 /* ... with two regions inside: normal system memory with low
3350 * priority, and...
3351 */
3352 memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
3353 get_system_memory(), 0, ~0ull);
3354 memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
3355 memory_region_set_enabled(cpu->cpu_as_mem, true);
Peter Maydell56943e82016-01-21 14:15:04 +00003356 address_space_init(newas, cpu->cpu_as_root, "CPU");
Peter Maydell12ebc9a2016-01-21 14:15:04 +00003357 cs->num_ases = 1;
Peter Maydell56943e82016-01-21 14:15:04 +00003358 cpu_address_space_init(cs, newas, 0);
Paolo Bonzinif809c602015-03-31 14:12:25 +02003359
3360 /* ... SMRAM with higher priority, linked from /machine/smram. */
3361 cpu->machine_done.notify = x86_cpu_machine_done;
3362 qemu_add_machine_init_done_notifier(&cpu->machine_done);
Paolo Bonzini2001d0c2015-03-31 14:11:09 +02003363 }
3364#endif
3365
Andreas Färber14a10fc2013-07-27 02:53:25 +02003366 qemu_init_vcpu(cs);
Igor Mammedovd3c64d62013-04-05 16:36:54 +02003367
Wei Huange48638f2014-10-21 11:00:45 -04003368 /* Only Intel CPUs support hyperthreading. Even though QEMU fixes this
3369 * issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX
3370 * based on inputs (sockets,cores,threads), it is still better to gives
3371 * users a warning.
3372 *
3373 * NOTE: the following code has to follow qemu_init_vcpu(). Otherwise
3374 * cs->nr_threads hasn't be populated yet and the checking is incorrect.
3375 */
3376 if (!IS_INTEL_CPU(env) && cs->nr_threads > 1 && !ht_warned) {
3377 error_report("AMD CPU doesn't support hyperthreading. Please configure"
3378 " -smp options properly.");
3379 ht_warned = true;
3380 }
3381
Igor Mammedovd3c64d62013-04-05 16:36:54 +02003382 x86_cpu_apic_realize(cpu, &local_err);
3383 if (local_err != NULL) {
3384 goto out;
3385 }
Andreas Färber14a10fc2013-07-27 02:53:25 +02003386 cpu_reset(cs);
Andreas Färber2b6f2942013-01-16 03:41:47 +01003387
Igor Mammedov4dc1f442013-04-05 16:36:53 +02003388 xcc->parent_realize(dev, &local_err);
Paolo Bonzini2001d0c2015-03-31 14:11:09 +02003389
Igor Mammedov4dc1f442013-04-05 16:36:53 +02003390out:
3391 if (local_err != NULL) {
3392 error_propagate(errp, local_err);
3393 return;
3394 }
Andreas Färber7a059952012-05-09 23:15:32 +02003395}
3396
Igor Mammedovc8847762016-06-24 16:01:02 +02003397static void x86_cpu_unrealizefn(DeviceState *dev, Error **errp)
3398{
3399 X86CPU *cpu = X86_CPU(dev);
Laurent Vivier7bbc1242016-10-20 13:26:04 +02003400 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
3401 Error *local_err = NULL;
Igor Mammedovc8847762016-06-24 16:01:02 +02003402
3403#ifndef CONFIG_USER_ONLY
3404 cpu_remove_sync(CPU(dev));
3405 qemu_unregister_reset(x86_cpu_machine_reset_cb, dev);
3406#endif
3407
3408 if (cpu->apic_state) {
3409 object_unparent(OBJECT(cpu->apic_state));
3410 cpu->apic_state = NULL;
3411 }
Laurent Vivier7bbc1242016-10-20 13:26:04 +02003412
3413 xcc->parent_unrealize(dev, &local_err);
3414 if (local_err != NULL) {
3415 error_propagate(errp, local_err);
3416 return;
3417 }
Igor Mammedovc8847762016-06-24 16:01:02 +02003418}
3419
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003420typedef struct BitProperty {
3421 uint32_t *ptr;
3422 uint32_t mask;
3423} BitProperty;
3424
Eric Blaked7bce992016-01-29 06:48:55 -07003425static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
3426 void *opaque, Error **errp)
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003427{
3428 BitProperty *fp = opaque;
3429 bool value = (*fp->ptr & fp->mask) == fp->mask;
Eric Blake51e72bc2016-01-29 06:48:54 -07003430 visit_type_bool(v, name, &value, errp);
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003431}
3432
Eric Blaked7bce992016-01-29 06:48:55 -07003433static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
3434 void *opaque, Error **errp)
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003435{
3436 DeviceState *dev = DEVICE(obj);
3437 BitProperty *fp = opaque;
3438 Error *local_err = NULL;
3439 bool value;
3440
3441 if (dev->realized) {
3442 qdev_prop_set_after_realize(dev, name, errp);
3443 return;
3444 }
3445
Eric Blake51e72bc2016-01-29 06:48:54 -07003446 visit_type_bool(v, name, &value, &local_err);
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003447 if (local_err) {
3448 error_propagate(errp, local_err);
3449 return;
3450 }
3451
3452 if (value) {
3453 *fp->ptr |= fp->mask;
3454 } else {
3455 *fp->ptr &= ~fp->mask;
3456 }
3457}
3458
3459static void x86_cpu_release_bit_prop(Object *obj, const char *name,
3460 void *opaque)
3461{
3462 BitProperty *prop = opaque;
3463 g_free(prop);
3464}
3465
3466/* Register a boolean property to get/set a single bit in a uint32_t field.
3467 *
3468 * The same property name can be registered multiple times to make it affect
3469 * multiple bits in the same FeatureWord. In that case, the getter will return
3470 * true only if all bits are set.
3471 */
3472static void x86_cpu_register_bit_prop(X86CPU *cpu,
3473 const char *prop_name,
3474 uint32_t *field,
3475 int bitnr)
3476{
3477 BitProperty *fp;
3478 ObjectProperty *op;
3479 uint32_t mask = (1UL << bitnr);
3480
3481 op = object_property_find(OBJECT(cpu), prop_name, NULL);
3482 if (op) {
3483 fp = op->opaque;
3484 assert(fp->ptr == field);
3485 fp->mask |= mask;
3486 } else {
3487 fp = g_new0(BitProperty, 1);
3488 fp->ptr = field;
3489 fp->mask = mask;
3490 object_property_add(OBJECT(cpu), prop_name, "bool",
3491 x86_cpu_get_bit_prop,
3492 x86_cpu_set_bit_prop,
3493 x86_cpu_release_bit_prop, fp, &error_abort);
3494 }
3495}
3496
3497static void x86_cpu_register_feature_bit_props(X86CPU *cpu,
3498 FeatureWord w,
3499 int bitnr)
3500{
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003501 FeatureWordInfo *fi = &feature_word_info[w];
Eduardo Habkost16d2fca2016-09-30 15:49:41 -03003502 const char *name = fi->feat_names[bitnr];
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003503
Eduardo Habkost16d2fca2016-09-30 15:49:41 -03003504 if (!name) {
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003505 return;
3506 }
3507
Eduardo Habkostfc7dfd22016-09-30 15:49:40 -03003508 /* Property names should use "-" instead of "_".
3509 * Old names containing underscores are registered as aliases
3510 * using object_property_add_alias()
3511 */
Eduardo Habkost16d2fca2016-09-30 15:49:41 -03003512 assert(!strchr(name, '_'));
3513 /* aliases don't use "|" delimiters anymore, they are registered
3514 * manually using object_property_add_alias() */
3515 assert(!strchr(name, '|'));
3516 x86_cpu_register_bit_prop(cpu, name, &cpu->env.features[w], bitnr);
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003517}
3518
Andreas Färberde024812012-04-03 00:00:17 +02003519static void x86_cpu_initfn(Object *obj)
3520{
Andreas Färber55e5c282012-12-17 06:18:02 +01003521 CPUState *cs = CPU(obj);
Andreas Färberde024812012-04-03 00:00:17 +02003522 X86CPU *cpu = X86_CPU(obj);
Eduardo Habkostd940ee92014-02-10 08:21:30 -02003523 X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
Andreas Färberde024812012-04-03 00:00:17 +02003524 CPUX86State *env = &cpu->env;
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003525 FeatureWord w;
Andreas Färberde024812012-04-03 00:00:17 +02003526
Andreas Färberc05efcb2013-01-17 12:13:41 +01003527 cs->env_ptr = env;
Andreas Färber71ad61d2012-04-17 12:10:29 +02003528
3529 object_property_add(obj, "family", "int",
Andreas Färber95b85192012-04-17 14:42:22 +02003530 x86_cpuid_version_get_family,
Andreas Färber71ad61d2012-04-17 12:10:29 +02003531 x86_cpuid_version_set_family, NULL, NULL, NULL);
Andreas Färberc5291a42012-04-17 12:16:39 +02003532 object_property_add(obj, "model", "int",
Andreas Färber67e30c82012-04-17 14:48:14 +02003533 x86_cpuid_version_get_model,
Andreas Färberc5291a42012-04-17 12:16:39 +02003534 x86_cpuid_version_set_model, NULL, NULL, NULL);
Andreas Färber036e2222012-04-17 14:14:18 +02003535 object_property_add(obj, "stepping", "int",
Andreas Färber35112e42012-04-17 14:50:53 +02003536 x86_cpuid_version_get_stepping,
Andreas Färber036e2222012-04-17 14:14:18 +02003537 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
Andreas Färberd480e1a2012-04-17 19:22:58 +02003538 object_property_add_str(obj, "vendor",
3539 x86_cpuid_get_vendor,
3540 x86_cpuid_set_vendor, NULL);
Andreas Färber938d4c22012-04-17 15:17:27 +02003541 object_property_add_str(obj, "model-id",
Andreas Färber63e886e2012-04-17 23:02:26 +02003542 x86_cpuid_get_model_id,
Andreas Färber938d4c22012-04-17 15:17:27 +02003543 x86_cpuid_set_model_id, NULL);
Andreas Färber89e48962012-04-18 00:12:23 +02003544 object_property_add(obj, "tsc-frequency", "int",
3545 x86_cpuid_get_tsc_freq,
3546 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
Eduardo Habkost8e8aba52013-05-06 13:20:07 -03003547 object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
3548 x86_cpu_get_feature_words,
Eduardo Habkost7e5292b2013-05-06 13:20:09 -03003549 NULL, NULL, (void *)env->features, NULL);
3550 object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
3551 x86_cpu_get_feature_words,
3552 NULL, NULL, (void *)cpu->filtered_features, NULL);
Andreas Färber71ad61d2012-04-17 12:10:29 +02003553
Igor Mammedov92067bf2013-06-05 15:18:40 +02003554 cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
Igor Mammedovd65e9812012-06-19 15:39:46 +02003555
Eduardo Habkost38e5c112015-03-23 17:29:32 -03003556 for (w = 0; w < FEATURE_WORDS; w++) {
3557 int bitnr;
3558
3559 for (bitnr = 0; bitnr < 32; bitnr++) {
3560 x86_cpu_register_feature_bit_props(cpu, w, bitnr);
3561 }
3562 }
3563
Eduardo Habkost16d2fca2016-09-30 15:49:41 -03003564 object_property_add_alias(obj, "sse3", obj, "pni", &error_abort);
3565 object_property_add_alias(obj, "pclmuldq", obj, "pclmulqdq", &error_abort);
3566 object_property_add_alias(obj, "sse4-1", obj, "sse4.1", &error_abort);
3567 object_property_add_alias(obj, "sse4-2", obj, "sse4.2", &error_abort);
3568 object_property_add_alias(obj, "xd", obj, "nx", &error_abort);
3569 object_property_add_alias(obj, "ffxsr", obj, "fxsr-opt", &error_abort);
3570 object_property_add_alias(obj, "i64", obj, "lm", &error_abort);
3571
Eduardo Habkost54b8dc72016-09-30 15:49:38 -03003572 object_property_add_alias(obj, "ds_cpl", obj, "ds-cpl", &error_abort);
3573 object_property_add_alias(obj, "tsc_adjust", obj, "tsc-adjust", &error_abort);
3574 object_property_add_alias(obj, "fxsr_opt", obj, "fxsr-opt", &error_abort);
3575 object_property_add_alias(obj, "lahf_lm", obj, "lahf-lm", &error_abort);
3576 object_property_add_alias(obj, "cmp_legacy", obj, "cmp-legacy", &error_abort);
3577 object_property_add_alias(obj, "nodeid_msr", obj, "nodeid-msr", &error_abort);
3578 object_property_add_alias(obj, "perfctr_core", obj, "perfctr-core", &error_abort);
3579 object_property_add_alias(obj, "perfctr_nb", obj, "perfctr-nb", &error_abort);
3580 object_property_add_alias(obj, "kvm_nopiodelay", obj, "kvm-nopiodelay", &error_abort);
3581 object_property_add_alias(obj, "kvm_mmu", obj, "kvm-mmu", &error_abort);
3582 object_property_add_alias(obj, "kvm_asyncpf", obj, "kvm-asyncpf", &error_abort);
3583 object_property_add_alias(obj, "kvm_steal_time", obj, "kvm-steal-time", &error_abort);
3584 object_property_add_alias(obj, "kvm_pv_eoi", obj, "kvm-pv-eoi", &error_abort);
3585 object_property_add_alias(obj, "kvm_pv_unhalt", obj, "kvm-pv-unhalt", &error_abort);
3586 object_property_add_alias(obj, "svm_lock", obj, "svm-lock", &error_abort);
3587 object_property_add_alias(obj, "nrip_save", obj, "nrip-save", &error_abort);
3588 object_property_add_alias(obj, "tsc_scale", obj, "tsc-scale", &error_abort);
3589 object_property_add_alias(obj, "vmcb_clean", obj, "vmcb-clean", &error_abort);
3590 object_property_add_alias(obj, "pause_filter", obj, "pause-filter", &error_abort);
3591 object_property_add_alias(obj, "sse4_1", obj, "sse4.1", &error_abort);
3592 object_property_add_alias(obj, "sse4_2", obj, "sse4.2", &error_abort);
3593
Eduardo Habkostd940ee92014-02-10 08:21:30 -02003594 x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
Andreas Färberde024812012-04-03 00:00:17 +02003595}
3596
Igor Mammedov997395d2013-04-23 10:29:41 +02003597static int64_t x86_cpu_get_arch_id(CPUState *cs)
3598{
3599 X86CPU *cpu = X86_CPU(cs);
Igor Mammedov997395d2013-04-23 10:29:41 +02003600
Eduardo Habkost7e72a452014-12-18 23:20:10 -02003601 return cpu->apic_id;
Igor Mammedov997395d2013-04-23 10:29:41 +02003602}
3603
Andreas Färber444d5592013-05-28 13:28:38 +02003604static bool x86_cpu_get_paging_enabled(const CPUState *cs)
3605{
3606 X86CPU *cpu = X86_CPU(cs);
3607
3608 return cpu->env.cr[0] & CR0_PG_MASK;
3609}
3610
Andreas Färberf45748f2013-06-21 19:09:18 +02003611static void x86_cpu_set_pc(CPUState *cs, vaddr value)
3612{
3613 X86CPU *cpu = X86_CPU(cs);
3614
3615 cpu->env.eip = value;
3616}
3617
Andreas Färberbdf7ae52013-06-28 19:31:32 +02003618static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
3619{
3620 X86CPU *cpu = X86_CPU(cs);
3621
3622 cpu->env.eip = tb->pc - tb->cs_base;
3623}
3624
Andreas Färber8c2e1b02013-08-25 18:53:55 +02003625static bool x86_cpu_has_work(CPUState *cs)
3626{
3627 X86CPU *cpu = X86_CPU(cs);
3628 CPUX86State *env = &cpu->env;
3629
Pavel Dovgalyuk6220e902015-09-17 19:23:31 +03003630 return ((cs->interrupt_request & (CPU_INTERRUPT_HARD |
3631 CPU_INTERRUPT_POLL)) &&
Andreas Färber8c2e1b02013-08-25 18:53:55 +02003632 (env->eflags & IF_MASK)) ||
3633 (cs->interrupt_request & (CPU_INTERRUPT_NMI |
3634 CPU_INTERRUPT_INIT |
3635 CPU_INTERRUPT_SIPI |
Paolo Bonzinia9bad652015-05-19 13:46:47 +02003636 CPU_INTERRUPT_MCE)) ||
3637 ((cs->interrupt_request & CPU_INTERRUPT_SMI) &&
3638 !(env->hflags & HF_SMM_MASK));
Andreas Färber8c2e1b02013-08-25 18:53:55 +02003639}
3640
Eduardo Habkost9337e3b2013-07-26 17:09:36 -03003641static Property x86_cpu_properties[] = {
Igor Mammedov2da00e32016-07-06 08:20:41 +02003642#ifdef CONFIG_USER_ONLY
3643 /* apic_id = 0 by default for *-user, see commit 9886e834 */
3644 DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, 0),
Igor Mammedovd89c2b82016-07-06 08:20:42 +02003645 DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, 0),
3646 DEFINE_PROP_INT32("core-id", X86CPU, core_id, 0),
3647 DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, 0),
Igor Mammedov2da00e32016-07-06 08:20:41 +02003648#else
3649 DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, UNASSIGNED_APIC_ID),
Igor Mammedovd89c2b82016-07-06 08:20:42 +02003650 DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, -1),
3651 DEFINE_PROP_INT32("core-id", X86CPU, core_id, -1),
3652 DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, -1),
Igor Mammedov2da00e32016-07-06 08:20:41 +02003653#endif
Eduardo Habkost9337e3b2013-07-26 17:09:36 -03003654 DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
Igor Mammedovc8f0f882013-06-04 15:05:25 +02003655 { .name = "hv-spinlocks", .info = &qdev_prop_spinlocks },
Igor Mammedov89314502012-08-08 13:52:51 +02003656 DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false),
Igor Mammedov0f466852012-08-08 13:54:27 +02003657 DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false),
Vadim Rozenfeld48a5f3b2014-01-24 00:40:49 +11003658 DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false),
Andrey Smetaninf2a53c92015-09-09 14:41:30 +02003659 DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false),
Andrey Smetanin744b8a92015-09-16 12:59:42 +03003660 DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false),
Andrey Smetanin8c145d72015-09-16 12:59:43 +03003661 DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false),
Andrey Smetanin46eb8f92015-09-16 12:59:44 +03003662 DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
Andrey Smetanin866eea92015-11-11 13:18:38 +03003663 DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
Andrey Smetaninff99aa62015-11-25 18:21:25 +03003664 DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
Eduardo Habkost15e41342015-08-26 13:25:44 -03003665 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
Igor Mammedov912ffc42013-06-04 15:13:14 +02003666 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
Alex Williamsonf522d2a2014-06-02 11:28:50 -06003667 DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
Dr. David Alan Gilbertaf459072016-07-08 16:01:36 +01003668 DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0),
Dr. David Alan Gilbert11f6fee2016-07-11 20:28:46 +01003669 DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false),
Dr. David Alan Gilbertfcc35e72016-07-08 16:01:38 +01003670 DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true),
Eduardo Habkostc39c0ed2016-09-21 13:30:12 -03003671 DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, UINT32_MAX),
3672 DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, UINT32_MAX),
3673 DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, UINT32_MAX),
3674 DEFINE_PROP_UINT32("min-level", X86CPU, env.cpuid_min_level, 0),
3675 DEFINE_PROP_UINT32("min-xlevel", X86CPU, env.cpuid_min_xlevel, 0),
3676 DEFINE_PROP_UINT32("min-xlevel2", X86CPU, env.cpuid_min_xlevel2, 0),
3677 DEFINE_PROP_BOOL("full-cpuid-auto-level", X86CPU, full_cpuid_auto_level, true),
Alex Williamson1c4a55d2015-10-16 09:38:22 -06003678 DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
Radim Krčmář5232d002016-05-12 19:24:26 +02003679 DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
Ashok Raj87f8b622016-06-22 14:56:21 +08003680 DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false),
Longpeng(Mike)14c985c2016-09-07 13:21:13 +08003681 DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true),
Eduardo Habkost9337e3b2013-07-26 17:09:36 -03003682 DEFINE_PROP_END_OF_LIST()
3683};
3684
Andreas Färber5fd20872012-04-02 23:20:08 +02003685static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
3686{
3687 X86CPUClass *xcc = X86_CPU_CLASS(oc);
3688 CPUClass *cc = CPU_CLASS(oc);
Andreas Färber2b6f2942013-01-16 03:41:47 +01003689 DeviceClass *dc = DEVICE_CLASS(oc);
3690
3691 xcc->parent_realize = dc->realize;
Laurent Vivier7bbc1242016-10-20 13:26:04 +02003692 xcc->parent_unrealize = dc->unrealize;
Andreas Färber2b6f2942013-01-16 03:41:47 +01003693 dc->realize = x86_cpu_realizefn;
Igor Mammedovc8847762016-06-24 16:01:02 +02003694 dc->unrealize = x86_cpu_unrealizefn;
Eduardo Habkost9337e3b2013-07-26 17:09:36 -03003695 dc->props = x86_cpu_properties;
Andreas Färber5fd20872012-04-02 23:20:08 +02003696
3697 xcc->parent_reset = cc->reset;
3698 cc->reset = x86_cpu_reset;
Andreas Färber91b1df82013-06-16 07:49:48 +02003699 cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
Andreas Färberf56e3a12013-02-02 13:38:08 +01003700
Andreas Färber500050d2014-02-10 22:02:44 +01003701 cc->class_by_name = x86_cpu_class_by_name;
Andreas Färber94a444b2014-03-03 23:19:19 +01003702 cc->parse_features = x86_cpu_parse_featurestr;
Andreas Färber8c2e1b02013-08-25 18:53:55 +02003703 cc->has_work = x86_cpu_has_work;
Andreas Färber97a8ea52013-02-02 10:57:51 +01003704 cc->do_interrupt = x86_cpu_do_interrupt;
Richard Henderson42f53fe2014-09-13 09:45:33 -07003705 cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
Andreas Färber878096e2013-05-27 01:33:50 +02003706 cc->dump_state = x86_cpu_dump_state;
Andreas Färberf45748f2013-06-21 19:09:18 +02003707 cc->set_pc = x86_cpu_set_pc;
Andreas Färberbdf7ae52013-06-28 19:31:32 +02003708 cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
Andreas Färber5b50e792013-06-29 04:18:45 +02003709 cc->gdb_read_register = x86_cpu_gdb_read_register;
3710 cc->gdb_write_register = x86_cpu_gdb_write_register;
Andreas Färber444d5592013-05-28 13:28:38 +02003711 cc->get_arch_id = x86_cpu_get_arch_id;
3712 cc->get_paging_enabled = x86_cpu_get_paging_enabled;
Andreas Färber75104542013-08-26 03:01:33 +02003713#ifdef CONFIG_USER_ONLY
3714 cc->handle_mmu_fault = x86_cpu_handle_mmu_fault;
3715#else
Andreas Färbera23bbfd2013-05-28 13:52:01 +02003716 cc->get_memory_mapping = x86_cpu_get_memory_mapping;
Andreas Färber00b941e2013-06-29 18:55:54 +02003717 cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
Jens Freimannc72bf462013-04-19 16:45:06 +02003718 cc->write_elf64_note = x86_cpu_write_elf64_note;
3719 cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
3720 cc->write_elf32_note = x86_cpu_write_elf32_note;
3721 cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
Andreas Färber00b941e2013-06-29 18:55:54 +02003722 cc->vmsd = &vmstate_x86_cpu;
Jens Freimannc72bf462013-04-19 16:45:06 +02003723#endif
Andreas Färbera0e372f2013-06-28 23:18:47 +02003724 cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
Peter Maydell86025ee2014-09-12 14:06:48 +01003725#ifndef CONFIG_USER_ONLY
3726 cc->debug_excp_handler = breakpoint_handler;
3727#endif
Richard Henderson374e0cd2014-09-13 09:45:14 -07003728 cc->cpu_exec_enter = x86_cpu_exec_enter;
3729 cc->cpu_exec_exit = x86_cpu_exec_exit;
Markus Armbruster4c315c22015-10-01 10:59:58 +02003730
Igor Mammedovedd12112016-05-27 13:50:48 +02003731 dc->cannot_instantiate_with_device_add_yet = false;
Andreas Färber5fd20872012-04-02 23:20:08 +02003732}
3733
3734static const TypeInfo x86_cpu_type_info = {
3735 .name = TYPE_X86_CPU,
3736 .parent = TYPE_CPU,
3737 .instance_size = sizeof(X86CPU),
Andreas Färberde024812012-04-03 00:00:17 +02003738 .instance_init = x86_cpu_initfn,
Eduardo Habkostd940ee92014-02-10 08:21:30 -02003739 .abstract = true,
Andreas Färber5fd20872012-04-02 23:20:08 +02003740 .class_size = sizeof(X86CPUClass),
3741 .class_init = x86_cpu_common_class_init,
3742};
3743
3744static void x86_cpu_register_types(void)
3745{
Eduardo Habkostd940ee92014-02-10 08:21:30 -02003746 int i;
3747
Andreas Färber5fd20872012-04-02 23:20:08 +02003748 type_register_static(&x86_cpu_type_info);
Eduardo Habkostd940ee92014-02-10 08:21:30 -02003749 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
3750 x86_register_cpudef_type(&builtin_x86_defs[i]);
3751 }
3752#ifdef CONFIG_KVM
3753 type_register_static(&host_x86_cpu_type_info);
3754#endif
Andreas Färber5fd20872012-04-02 23:20:08 +02003755}
3756
3757type_init(x86_cpu_register_types)