Statistics
| Branch: | Revision:

root / target-i386 / cpu.c @ 3523e4bd

History | View | Annotate | Download (92.6 kB)

1 c6dc6f63 Andre Przywara
/*
2 c6dc6f63 Andre Przywara
 *  i386 CPUID helper functions
3 c6dc6f63 Andre Przywara
 *
4 c6dc6f63 Andre Przywara
 *  Copyright (c) 2003 Fabrice Bellard
5 c6dc6f63 Andre Przywara
 *
6 c6dc6f63 Andre Przywara
 * This library is free software; you can redistribute it and/or
7 c6dc6f63 Andre Przywara
 * modify it under the terms of the GNU Lesser General Public
8 c6dc6f63 Andre Przywara
 * License as published by the Free Software Foundation; either
9 c6dc6f63 Andre Przywara
 * version 2 of the License, or (at your option) any later version.
10 c6dc6f63 Andre Przywara
 *
11 c6dc6f63 Andre Przywara
 * This library is distributed in the hope that it will be useful,
12 c6dc6f63 Andre Przywara
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 c6dc6f63 Andre Przywara
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 c6dc6f63 Andre Przywara
 * Lesser General Public License for more details.
15 c6dc6f63 Andre Przywara
 *
16 c6dc6f63 Andre Przywara
 * You should have received a copy of the GNU Lesser General Public
17 c6dc6f63 Andre Przywara
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 c6dc6f63 Andre Przywara
 */
19 c6dc6f63 Andre Przywara
#include <stdlib.h>
20 c6dc6f63 Andre Przywara
#include <stdio.h>
21 c6dc6f63 Andre Przywara
#include <string.h>
22 c6dc6f63 Andre Przywara
#include <inttypes.h>
23 c6dc6f63 Andre Przywara
24 c6dc6f63 Andre Przywara
#include "cpu.h"
25 9c17d615 Paolo Bonzini
#include "sysemu/kvm.h"
26 8932cfdf Eduardo Habkost
#include "sysemu/cpus.h"
27 8932cfdf Eduardo Habkost
#include "topology.h"
28 c6dc6f63 Andre Przywara
29 1de7afc9 Paolo Bonzini
#include "qemu/option.h"
30 1de7afc9 Paolo Bonzini
#include "qemu/config-file.h"
31 7b1b5d19 Paolo Bonzini
#include "qapi/qmp/qerror.h"
32 c6dc6f63 Andre Przywara
33 8e8aba50 Eduardo Habkost
#include "qapi-types.h"
34 8e8aba50 Eduardo Habkost
#include "qapi-visit.h"
35 7b1b5d19 Paolo Bonzini
#include "qapi/visitor.h"
36 9c17d615 Paolo Bonzini
#include "sysemu/arch_init.h"
37 71ad61d3 Andreas Färber
38 65dee380 Igor Mammedov
#include "hw/hw.h"
39 b834b508 Stefan Weil
#if defined(CONFIG_KVM)
40 ef8621b1 Anthony Liguori
#include <linux/kvm_para.h>
41 b834b508 Stefan Weil
#endif
42 65dee380 Igor Mammedov
43 9c17d615 Paolo Bonzini
#include "sysemu/sysemu.h"
44 53a89e26 Igor Mammedov
#include "hw/qdev-properties.h"
45 62fc403f Igor Mammedov
#include "hw/cpu/icc_bus.h"
46 bdeec802 Igor Mammedov
#ifndef CONFIG_USER_ONLY
47 0d09e41a Paolo Bonzini
#include "hw/xen/xen.h"
48 0d09e41a Paolo Bonzini
#include "hw/i386/apic_internal.h"
49 bdeec802 Igor Mammedov
#endif
50 bdeec802 Igor Mammedov
51 5e891bf8 Eduardo Habkost
52 5e891bf8 Eduardo Habkost
/* Cache topology CPUID constants: */
53 5e891bf8 Eduardo Habkost
54 5e891bf8 Eduardo Habkost
/* CPUID Leaf 2 Descriptors */
55 5e891bf8 Eduardo Habkost
56 5e891bf8 Eduardo Habkost
#define CPUID_2_L1D_32KB_8WAY_64B 0x2c
57 5e891bf8 Eduardo Habkost
#define CPUID_2_L1I_32KB_8WAY_64B 0x30
58 5e891bf8 Eduardo Habkost
#define CPUID_2_L2_2MB_8WAY_64B   0x7d
59 5e891bf8 Eduardo Habkost
60 5e891bf8 Eduardo Habkost
61 5e891bf8 Eduardo Habkost
/* CPUID Leaf 4 constants: */
62 5e891bf8 Eduardo Habkost
63 5e891bf8 Eduardo Habkost
/* EAX: */
64 5e891bf8 Eduardo Habkost
#define CPUID_4_TYPE_DCACHE  1
65 5e891bf8 Eduardo Habkost
#define CPUID_4_TYPE_ICACHE  2
66 5e891bf8 Eduardo Habkost
#define CPUID_4_TYPE_UNIFIED 3
67 5e891bf8 Eduardo Habkost
68 5e891bf8 Eduardo Habkost
#define CPUID_4_LEVEL(l)          ((l) << 5)
69 5e891bf8 Eduardo Habkost
70 5e891bf8 Eduardo Habkost
#define CPUID_4_SELF_INIT_LEVEL (1 << 8)
71 5e891bf8 Eduardo Habkost
#define CPUID_4_FULLY_ASSOC     (1 << 9)
72 5e891bf8 Eduardo Habkost
73 5e891bf8 Eduardo Habkost
/* EDX: */
74 5e891bf8 Eduardo Habkost
#define CPUID_4_NO_INVD_SHARING (1 << 0)
75 5e891bf8 Eduardo Habkost
#define CPUID_4_INCLUSIVE       (1 << 1)
76 5e891bf8 Eduardo Habkost
#define CPUID_4_COMPLEX_IDX     (1 << 2)
77 5e891bf8 Eduardo Habkost
78 5e891bf8 Eduardo Habkost
#define ASSOC_FULL 0xFF
79 5e891bf8 Eduardo Habkost
80 5e891bf8 Eduardo Habkost
/* AMD associativity encoding used on CPUID Leaf 0x80000006: */
81 5e891bf8 Eduardo Habkost
#define AMD_ENC_ASSOC(a) (a <=   1 ? a   : \
82 5e891bf8 Eduardo Habkost
                          a ==   2 ? 0x2 : \
83 5e891bf8 Eduardo Habkost
                          a ==   4 ? 0x4 : \
84 5e891bf8 Eduardo Habkost
                          a ==   8 ? 0x6 : \
85 5e891bf8 Eduardo Habkost
                          a ==  16 ? 0x8 : \
86 5e891bf8 Eduardo Habkost
                          a ==  32 ? 0xA : \
87 5e891bf8 Eduardo Habkost
                          a ==  48 ? 0xB : \
88 5e891bf8 Eduardo Habkost
                          a ==  64 ? 0xC : \
89 5e891bf8 Eduardo Habkost
                          a ==  96 ? 0xD : \
90 5e891bf8 Eduardo Habkost
                          a == 128 ? 0xE : \
91 5e891bf8 Eduardo Habkost
                          a == ASSOC_FULL ? 0xF : \
92 5e891bf8 Eduardo Habkost
                          0 /* invalid value */)
93 5e891bf8 Eduardo Habkost
94 5e891bf8 Eduardo Habkost
95 5e891bf8 Eduardo Habkost
/* Definitions of the hardcoded cache entries we expose: */
96 5e891bf8 Eduardo Habkost
97 5e891bf8 Eduardo Habkost
/* L1 data cache: */
98 5e891bf8 Eduardo Habkost
#define L1D_LINE_SIZE         64
99 5e891bf8 Eduardo Habkost
#define L1D_ASSOCIATIVITY      8
100 5e891bf8 Eduardo Habkost
#define L1D_SETS              64
101 5e891bf8 Eduardo Habkost
#define L1D_PARTITIONS         1
102 5e891bf8 Eduardo Habkost
/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
103 5e891bf8 Eduardo Habkost
#define L1D_DESCRIPTOR CPUID_2_L1D_32KB_8WAY_64B
104 5e891bf8 Eduardo Habkost
/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
105 5e891bf8 Eduardo Habkost
#define L1D_LINES_PER_TAG      1
106 5e891bf8 Eduardo Habkost
#define L1D_SIZE_KB_AMD       64
107 5e891bf8 Eduardo Habkost
#define L1D_ASSOCIATIVITY_AMD  2
108 5e891bf8 Eduardo Habkost
109 5e891bf8 Eduardo Habkost
/* L1 instruction cache: */
110 5e891bf8 Eduardo Habkost
#define L1I_LINE_SIZE         64
111 5e891bf8 Eduardo Habkost
#define L1I_ASSOCIATIVITY      8
112 5e891bf8 Eduardo Habkost
#define L1I_SETS              64
113 5e891bf8 Eduardo Habkost
#define L1I_PARTITIONS         1
114 5e891bf8 Eduardo Habkost
/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
115 5e891bf8 Eduardo Habkost
#define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
116 5e891bf8 Eduardo Habkost
/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
117 5e891bf8 Eduardo Habkost
#define L1I_LINES_PER_TAG      1
118 5e891bf8 Eduardo Habkost
#define L1I_SIZE_KB_AMD       64
119 5e891bf8 Eduardo Habkost
#define L1I_ASSOCIATIVITY_AMD  2
120 5e891bf8 Eduardo Habkost
121 5e891bf8 Eduardo Habkost
/* Level 2 unified cache: */
122 5e891bf8 Eduardo Habkost
#define L2_LINE_SIZE          64
123 5e891bf8 Eduardo Habkost
#define L2_ASSOCIATIVITY      16
124 5e891bf8 Eduardo Habkost
#define L2_SETS             4096
125 5e891bf8 Eduardo Habkost
#define L2_PARTITIONS          1
126 5e891bf8 Eduardo Habkost
/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
127 5e891bf8 Eduardo Habkost
/*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
128 5e891bf8 Eduardo Habkost
#define L2_DESCRIPTOR CPUID_2_L2_2MB_8WAY_64B
129 5e891bf8 Eduardo Habkost
/*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
130 5e891bf8 Eduardo Habkost
#define L2_LINES_PER_TAG       1
131 5e891bf8 Eduardo Habkost
#define L2_SIZE_KB_AMD       512
132 5e891bf8 Eduardo Habkost
133 5e891bf8 Eduardo Habkost
/* No L3 cache: */
134 5e891bf8 Eduardo Habkost
#define L3_SIZE_KB             0 /* disabled */
135 5e891bf8 Eduardo Habkost
#define L3_ASSOCIATIVITY       0 /* disabled */
136 5e891bf8 Eduardo Habkost
#define L3_LINES_PER_TAG       0 /* disabled */
137 5e891bf8 Eduardo Habkost
#define L3_LINE_SIZE           0 /* disabled */
138 5e891bf8 Eduardo Habkost
139 5e891bf8 Eduardo Habkost
/* TLB definitions: */
140 5e891bf8 Eduardo Habkost
141 5e891bf8 Eduardo Habkost
#define L1_DTLB_2M_ASSOC       1
142 5e891bf8 Eduardo Habkost
#define L1_DTLB_2M_ENTRIES   255
143 5e891bf8 Eduardo Habkost
#define L1_DTLB_4K_ASSOC       1
144 5e891bf8 Eduardo Habkost
#define L1_DTLB_4K_ENTRIES   255
145 5e891bf8 Eduardo Habkost
146 5e891bf8 Eduardo Habkost
#define L1_ITLB_2M_ASSOC       1
147 5e891bf8 Eduardo Habkost
#define L1_ITLB_2M_ENTRIES   255
148 5e891bf8 Eduardo Habkost
#define L1_ITLB_4K_ASSOC       1
149 5e891bf8 Eduardo Habkost
#define L1_ITLB_4K_ENTRIES   255
150 5e891bf8 Eduardo Habkost
151 5e891bf8 Eduardo Habkost
#define L2_DTLB_2M_ASSOC       0 /* disabled */
152 5e891bf8 Eduardo Habkost
#define L2_DTLB_2M_ENTRIES     0 /* disabled */
153 5e891bf8 Eduardo Habkost
#define L2_DTLB_4K_ASSOC       4
154 5e891bf8 Eduardo Habkost
#define L2_DTLB_4K_ENTRIES   512
155 5e891bf8 Eduardo Habkost
156 5e891bf8 Eduardo Habkost
#define L2_ITLB_2M_ASSOC       0 /* disabled */
157 5e891bf8 Eduardo Habkost
#define L2_ITLB_2M_ENTRIES     0 /* disabled */
158 5e891bf8 Eduardo Habkost
#define L2_ITLB_4K_ASSOC       4
159 5e891bf8 Eduardo Habkost
#define L2_ITLB_4K_ENTRIES   512
160 5e891bf8 Eduardo Habkost
161 5e891bf8 Eduardo Habkost
162 5e891bf8 Eduardo Habkost
163 99b88a17 Igor Mammedov
static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
164 99b88a17 Igor Mammedov
                                     uint32_t vendor2, uint32_t vendor3)
165 99b88a17 Igor Mammedov
{
166 99b88a17 Igor Mammedov
    int i;
167 99b88a17 Igor Mammedov
    for (i = 0; i < 4; i++) {
168 99b88a17 Igor Mammedov
        dst[i] = vendor1 >> (8 * i);
169 99b88a17 Igor Mammedov
        dst[i + 4] = vendor2 >> (8 * i);
170 99b88a17 Igor Mammedov
        dst[i + 8] = vendor3 >> (8 * i);
171 99b88a17 Igor Mammedov
    }
172 99b88a17 Igor Mammedov
    dst[CPUID_VENDOR_SZ] = '\0';
173 99b88a17 Igor Mammedov
}
174 99b88a17 Igor Mammedov
175 c6dc6f63 Andre Przywara
/* feature flags taken from "Intel Processor Identification and the CPUID
176 c6dc6f63 Andre Przywara
 * Instruction" and AMD's "CPUID Specification".  In cases of disagreement
177 c6dc6f63 Andre Przywara
 * between feature naming conventions, aliases may be added.
178 c6dc6f63 Andre Przywara
 */
179 c6dc6f63 Andre Przywara
static const char *feature_name[] = {
180 c6dc6f63 Andre Przywara
    "fpu", "vme", "de", "pse",
181 c6dc6f63 Andre Przywara
    "tsc", "msr", "pae", "mce",
182 c6dc6f63 Andre Przywara
    "cx8", "apic", NULL, "sep",
183 c6dc6f63 Andre Przywara
    "mtrr", "pge", "mca", "cmov",
184 c6dc6f63 Andre Przywara
    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
185 c6dc6f63 Andre Przywara
    NULL, "ds" /* Intel dts */, "acpi", "mmx",
186 c6dc6f63 Andre Przywara
    "fxsr", "sse", "sse2", "ss",
187 c6dc6f63 Andre Przywara
    "ht" /* Intel htt */, "tm", "ia64", "pbe",
188 c6dc6f63 Andre Przywara
};
189 c6dc6f63 Andre Przywara
static const char *ext_feature_name[] = {
190 f370be3c Eduardo Habkost
    "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
191 e117f772 Andre Przywara
    "ds_cpl", "vmx", "smx", "est",
192 c6dc6f63 Andre Przywara
    "tm2", "ssse3", "cid", NULL,
193 e117f772 Andre Przywara
    "fma", "cx16", "xtpr", "pdcm",
194 434acb81 Mao, Junjie
    NULL, "pcid", "dca", "sse4.1|sse4_1",
195 e117f772 Andre Przywara
    "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
196 eaf3f097 Eduardo Habkost
    "tsc-deadline", "aes", "xsave", "osxsave",
197 c8acc380 Andre Przywara
    "avx", "f16c", "rdrand", "hypervisor",
198 c6dc6f63 Andre Przywara
};
199 3b671a40 Eduardo Habkost
/* Feature names that are already defined on feature_name[] but are set on
200 3b671a40 Eduardo Habkost
 * CPUID[8000_0001].EDX on AMD CPUs don't have their names on
201 3b671a40 Eduardo Habkost
 * ext2_feature_name[]. They are copied automatically to cpuid_ext2_features
202 3b671a40 Eduardo Habkost
 * if and only if CPU vendor is AMD.
203 3b671a40 Eduardo Habkost
 */
204 c6dc6f63 Andre Przywara
static const char *ext2_feature_name[] = {
205 3b671a40 Eduardo Habkost
    NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
206 3b671a40 Eduardo Habkost
    NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
207 3b671a40 Eduardo Habkost
    NULL /* cx8 */ /* AMD CMPXCHG8B */, NULL /* apic */, NULL, "syscall",
208 3b671a40 Eduardo Habkost
    NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
209 3b671a40 Eduardo Habkost
    NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
210 3b671a40 Eduardo Habkost
    "nx|xd", NULL, "mmxext", NULL /* mmx */,
211 3b671a40 Eduardo Habkost
    NULL /* fxsr */, "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
212 01f590d5 Eduardo Habkost
    NULL, "lm|i64", "3dnowext", "3dnow",
213 c6dc6f63 Andre Przywara
};
214 c6dc6f63 Andre Przywara
static const char *ext3_feature_name[] = {
215 c6dc6f63 Andre Przywara
    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
216 c6dc6f63 Andre Przywara
    "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
217 e117f772 Andre Przywara
    "3dnowprefetch", "osvw", "ibs", "xop",
218 c8acc380 Andre Przywara
    "skinit", "wdt", NULL, "lwp",
219 c8acc380 Andre Przywara
    "fma4", "tce", NULL, "nodeid_msr",
220 c8acc380 Andre Przywara
    NULL, "tbm", "topoext", "perfctr_core",
221 c8acc380 Andre Przywara
    "perfctr_nb", NULL, NULL, NULL,
222 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL,
223 c6dc6f63 Andre Przywara
};
224 c6dc6f63 Andre Przywara
225 89e49c8b Eduardo Habkost
static const char *ext4_feature_name[] = {
226 89e49c8b Eduardo Habkost
    NULL, NULL, "xstore", "xstore-en",
227 89e49c8b Eduardo Habkost
    NULL, NULL, "xcrypt", "xcrypt-en",
228 89e49c8b Eduardo Habkost
    "ace2", "ace2-en", "phe", "phe-en",
229 89e49c8b Eduardo Habkost
    "pmm", "pmm-en", NULL, NULL,
230 89e49c8b Eduardo Habkost
    NULL, NULL, NULL, NULL,
231 89e49c8b Eduardo Habkost
    NULL, NULL, NULL, NULL,
232 89e49c8b Eduardo Habkost
    NULL, NULL, NULL, NULL,
233 89e49c8b Eduardo Habkost
    NULL, NULL, NULL, NULL,
234 89e49c8b Eduardo Habkost
};
235 89e49c8b Eduardo Habkost
236 c6dc6f63 Andre Przywara
static const char *kvm_feature_name[] = {
237 c3d39807 Don Slutz
    "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock",
238 f010bc64 Andrew Jones
    "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", "kvm_pv_unhalt",
239 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
240 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
241 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
242 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
243 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
244 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
245 c6dc6f63 Andre Przywara
};
246 c6dc6f63 Andre Przywara
247 296acb64 Joerg Roedel
static const char *svm_feature_name[] = {
248 296acb64 Joerg Roedel
    "npt", "lbrv", "svm_lock", "nrip_save",
249 296acb64 Joerg Roedel
    "tsc_scale", "vmcb_clean",  "flushbyasid", "decodeassists",
250 296acb64 Joerg Roedel
    NULL, NULL, "pause_filter", NULL,
251 296acb64 Joerg Roedel
    "pfthreshold", NULL, NULL, NULL,
252 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
253 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
254 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
255 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
256 296acb64 Joerg Roedel
};
257 296acb64 Joerg Roedel
258 a9321a4d H. Peter Anvin
static const char *cpuid_7_0_ebx_feature_name[] = {
259 811a8ae0 Eduardo Habkost
    "fsgsbase", NULL, NULL, "bmi1", "hle", "avx2", NULL, "smep",
260 811a8ae0 Eduardo Habkost
    "bmi2", "erms", "invpcid", "rtm", NULL, NULL, NULL, NULL,
261 c8acc380 Andre Przywara
    NULL, NULL, "rdseed", "adx", "smap", NULL, NULL, NULL,
262 a9321a4d H. Peter Anvin
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
263 a9321a4d H. Peter Anvin
};
264 a9321a4d H. Peter Anvin
265 5ef57876 Eduardo Habkost
typedef struct FeatureWordInfo {
266 5ef57876 Eduardo Habkost
    const char **feat_names;
267 04d104b6 Eduardo Habkost
    uint32_t cpuid_eax;   /* Input EAX for CPUID */
268 04d104b6 Eduardo Habkost
    bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
269 04d104b6 Eduardo Habkost
    uint32_t cpuid_ecx;   /* Input ECX value for CPUID */
270 04d104b6 Eduardo Habkost
    int cpuid_reg;        /* output register (R_* constant) */
271 5ef57876 Eduardo Habkost
} FeatureWordInfo;
272 5ef57876 Eduardo Habkost
273 5ef57876 Eduardo Habkost
static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
274 bffd67b0 Eduardo Habkost
    [FEAT_1_EDX] = {
275 bffd67b0 Eduardo Habkost
        .feat_names = feature_name,
276 bffd67b0 Eduardo Habkost
        .cpuid_eax = 1, .cpuid_reg = R_EDX,
277 bffd67b0 Eduardo Habkost
    },
278 bffd67b0 Eduardo Habkost
    [FEAT_1_ECX] = {
279 bffd67b0 Eduardo Habkost
        .feat_names = ext_feature_name,
280 bffd67b0 Eduardo Habkost
        .cpuid_eax = 1, .cpuid_reg = R_ECX,
281 bffd67b0 Eduardo Habkost
    },
282 bffd67b0 Eduardo Habkost
    [FEAT_8000_0001_EDX] = {
283 bffd67b0 Eduardo Habkost
        .feat_names = ext2_feature_name,
284 bffd67b0 Eduardo Habkost
        .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX,
285 bffd67b0 Eduardo Habkost
    },
286 bffd67b0 Eduardo Habkost
    [FEAT_8000_0001_ECX] = {
287 bffd67b0 Eduardo Habkost
        .feat_names = ext3_feature_name,
288 bffd67b0 Eduardo Habkost
        .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
289 bffd67b0 Eduardo Habkost
    },
290 89e49c8b Eduardo Habkost
    [FEAT_C000_0001_EDX] = {
291 89e49c8b Eduardo Habkost
        .feat_names = ext4_feature_name,
292 89e49c8b Eduardo Habkost
        .cpuid_eax = 0xC0000001, .cpuid_reg = R_EDX,
293 89e49c8b Eduardo Habkost
    },
294 bffd67b0 Eduardo Habkost
    [FEAT_KVM] = {
295 bffd67b0 Eduardo Habkost
        .feat_names = kvm_feature_name,
296 bffd67b0 Eduardo Habkost
        .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
297 bffd67b0 Eduardo Habkost
    },
298 bffd67b0 Eduardo Habkost
    [FEAT_SVM] = {
299 bffd67b0 Eduardo Habkost
        .feat_names = svm_feature_name,
300 bffd67b0 Eduardo Habkost
        .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
301 bffd67b0 Eduardo Habkost
    },
302 bffd67b0 Eduardo Habkost
    [FEAT_7_0_EBX] = {
303 bffd67b0 Eduardo Habkost
        .feat_names = cpuid_7_0_ebx_feature_name,
304 04d104b6 Eduardo Habkost
        .cpuid_eax = 7,
305 04d104b6 Eduardo Habkost
        .cpuid_needs_ecx = true, .cpuid_ecx = 0,
306 04d104b6 Eduardo Habkost
        .cpuid_reg = R_EBX,
307 bffd67b0 Eduardo Habkost
    },
308 5ef57876 Eduardo Habkost
};
309 5ef57876 Eduardo Habkost
310 8e8aba50 Eduardo Habkost
typedef struct X86RegisterInfo32 {
311 8e8aba50 Eduardo Habkost
    /* Name of register */
312 8e8aba50 Eduardo Habkost
    const char *name;
313 8e8aba50 Eduardo Habkost
    /* QAPI enum value register */
314 8e8aba50 Eduardo Habkost
    X86CPURegister32 qapi_enum;
315 8e8aba50 Eduardo Habkost
} X86RegisterInfo32;
316 8e8aba50 Eduardo Habkost
317 8e8aba50 Eduardo Habkost
#define REGISTER(reg) \
318 8e8aba50 Eduardo Habkost
    [R_##reg] = { .name = #reg, .qapi_enum = X86_C_P_U_REGISTER32_##reg }
319 8e8aba50 Eduardo Habkost
X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
320 8e8aba50 Eduardo Habkost
    REGISTER(EAX),
321 8e8aba50 Eduardo Habkost
    REGISTER(ECX),
322 8e8aba50 Eduardo Habkost
    REGISTER(EDX),
323 8e8aba50 Eduardo Habkost
    REGISTER(EBX),
324 8e8aba50 Eduardo Habkost
    REGISTER(ESP),
325 8e8aba50 Eduardo Habkost
    REGISTER(EBP),
326 8e8aba50 Eduardo Habkost
    REGISTER(ESI),
327 8e8aba50 Eduardo Habkost
    REGISTER(EDI),
328 8e8aba50 Eduardo Habkost
};
329 8e8aba50 Eduardo Habkost
#undef REGISTER
330 8e8aba50 Eduardo Habkost
331 2560f19f Paolo Bonzini
typedef struct ExtSaveArea {
332 2560f19f Paolo Bonzini
    uint32_t feature, bits;
333 2560f19f Paolo Bonzini
    uint32_t offset, size;
334 2560f19f Paolo Bonzini
} ExtSaveArea;
335 2560f19f Paolo Bonzini
336 2560f19f Paolo Bonzini
static const ExtSaveArea ext_save_areas[] = {
337 2560f19f Paolo Bonzini
    [2] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
338 33f373d7 Liu Jinsong
            .offset = 0x240, .size = 0x100 },
339 2560f19f Paolo Bonzini
};
340 8e8aba50 Eduardo Habkost
341 8b4beddc Eduardo Habkost
const char *get_register_name_32(unsigned int reg)
342 8b4beddc Eduardo Habkost
{
343 31ccdde2 Igor Mammedov
    if (reg >= CPU_NB_REGS32) {
344 8b4beddc Eduardo Habkost
        return NULL;
345 8b4beddc Eduardo Habkost
    }
346 8e8aba50 Eduardo Habkost
    return x86_reg_info_32[reg].name;
347 8b4beddc Eduardo Habkost
}
348 8b4beddc Eduardo Habkost
349 c6dc6f63 Andre Przywara
/* collects per-function cpuid data
350 c6dc6f63 Andre Przywara
 */
351 c6dc6f63 Andre Przywara
typedef struct model_features_t {
352 c6dc6f63 Andre Przywara
    uint32_t *guest_feat;
353 c6dc6f63 Andre Przywara
    uint32_t *host_feat;
354 bffd67b0 Eduardo Habkost
    FeatureWord feat_word;
355 8b4beddc Eduardo Habkost
} model_features_t;
356 c6dc6f63 Andre Przywara
357 c6dc6f63 Andre Przywara
int check_cpuid = 0;
358 c6dc6f63 Andre Przywara
int enforce_cpuid = 0;
359 c6dc6f63 Andre Przywara
360 dc59944b Michael S. Tsirkin
static uint32_t kvm_default_features = (1 << KVM_FEATURE_CLOCKSOURCE) |
361 dc59944b Michael S. Tsirkin
        (1 << KVM_FEATURE_NOP_IO_DELAY) |
362 dc59944b Michael S. Tsirkin
        (1 << KVM_FEATURE_CLOCKSOURCE2) |
363 dc59944b Michael S. Tsirkin
        (1 << KVM_FEATURE_ASYNC_PF) |
364 dc59944b Michael S. Tsirkin
        (1 << KVM_FEATURE_STEAL_TIME) |
365 29694758 Eduardo Habkost
        (1 << KVM_FEATURE_PV_EOI) |
366 dc59944b Michael S. Tsirkin
        (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
367 dc59944b Michael S. Tsirkin
368 29694758 Eduardo Habkost
void disable_kvm_pv_eoi(void)
369 dc59944b Michael S. Tsirkin
{
370 29694758 Eduardo Habkost
    kvm_default_features &= ~(1UL << KVM_FEATURE_PV_EOI);
371 dc59944b Michael S. Tsirkin
}
372 dc59944b Michael S. Tsirkin
373 bb44e0d1 Jan Kiszka
void host_cpuid(uint32_t function, uint32_t count,
374 bb44e0d1 Jan Kiszka
                uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
375 bdde476a Andre Przywara
{
376 bdde476a Andre Przywara
#if defined(CONFIG_KVM)
377 a1fd24af Anthony Liguori
    uint32_t vec[4];
378 a1fd24af Anthony Liguori
379 a1fd24af Anthony Liguori
#ifdef __x86_64__
380 a1fd24af Anthony Liguori
    asm volatile("cpuid"
381 a1fd24af Anthony Liguori
                 : "=a"(vec[0]), "=b"(vec[1]),
382 a1fd24af Anthony Liguori
                   "=c"(vec[2]), "=d"(vec[3])
383 a1fd24af Anthony Liguori
                 : "0"(function), "c"(count) : "cc");
384 a1fd24af Anthony Liguori
#else
385 a1fd24af Anthony Liguori
    asm volatile("pusha \n\t"
386 a1fd24af Anthony Liguori
                 "cpuid \n\t"
387 a1fd24af Anthony Liguori
                 "mov %%eax, 0(%2) \n\t"
388 a1fd24af Anthony Liguori
                 "mov %%ebx, 4(%2) \n\t"
389 a1fd24af Anthony Liguori
                 "mov %%ecx, 8(%2) \n\t"
390 a1fd24af Anthony Liguori
                 "mov %%edx, 12(%2) \n\t"
391 a1fd24af Anthony Liguori
                 "popa"
392 a1fd24af Anthony Liguori
                 : : "a"(function), "c"(count), "S"(vec)
393 a1fd24af Anthony Liguori
                 : "memory", "cc");
394 a1fd24af Anthony Liguori
#endif
395 a1fd24af Anthony Liguori
396 bdde476a Andre Przywara
    if (eax)
397 a1fd24af Anthony Liguori
        *eax = vec[0];
398 bdde476a Andre Przywara
    if (ebx)
399 a1fd24af Anthony Liguori
        *ebx = vec[1];
400 bdde476a Andre Przywara
    if (ecx)
401 a1fd24af Anthony Liguori
        *ecx = vec[2];
402 bdde476a Andre Przywara
    if (edx)
403 a1fd24af Anthony Liguori
        *edx = vec[3];
404 bdde476a Andre Przywara
#endif
405 bdde476a Andre Przywara
}
406 c6dc6f63 Andre Przywara
407 c6dc6f63 Andre Przywara
#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
408 c6dc6f63 Andre Przywara
409 c6dc6f63 Andre Przywara
/* general substring compare of *[s1..e1) and *[s2..e2).  sx is start of
410 c6dc6f63 Andre Przywara
 * a substring.  ex if !NULL points to the first char after a substring,
411 c6dc6f63 Andre Przywara
 * otherwise the string is assumed to sized by a terminating nul.
412 c6dc6f63 Andre Przywara
 * Return lexical ordering of *s1:*s2.
413 c6dc6f63 Andre Przywara
 */
414 c6dc6f63 Andre Przywara
static int sstrcmp(const char *s1, const char *e1, const char *s2,
415 c6dc6f63 Andre Przywara
    const char *e2)
416 c6dc6f63 Andre Przywara
{
417 c6dc6f63 Andre Przywara
    for (;;) {
418 c6dc6f63 Andre Przywara
        if (!*s1 || !*s2 || *s1 != *s2)
419 c6dc6f63 Andre Przywara
            return (*s1 - *s2);
420 c6dc6f63 Andre Przywara
        ++s1, ++s2;
421 c6dc6f63 Andre Przywara
        if (s1 == e1 && s2 == e2)
422 c6dc6f63 Andre Przywara
            return (0);
423 c6dc6f63 Andre Przywara
        else if (s1 == e1)
424 c6dc6f63 Andre Przywara
            return (*s2);
425 c6dc6f63 Andre Przywara
        else if (s2 == e2)
426 c6dc6f63 Andre Przywara
            return (*s1);
427 c6dc6f63 Andre Przywara
    }
428 c6dc6f63 Andre Przywara
}
429 c6dc6f63 Andre Przywara
430 c6dc6f63 Andre Przywara
/* compare *[s..e) to *altstr.  *altstr may be a simple string or multiple
431 c6dc6f63 Andre Przywara
 * '|' delimited (possibly empty) strings in which case search for a match
432 c6dc6f63 Andre Przywara
 * within the alternatives proceeds left to right.  Return 0 for success,
433 c6dc6f63 Andre Przywara
 * non-zero otherwise.
434 c6dc6f63 Andre Przywara
 */
435 c6dc6f63 Andre Przywara
static int altcmp(const char *s, const char *e, const char *altstr)
436 c6dc6f63 Andre Przywara
{
437 c6dc6f63 Andre Przywara
    const char *p, *q;
438 c6dc6f63 Andre Przywara
439 c6dc6f63 Andre Przywara
    for (q = p = altstr; ; ) {
440 c6dc6f63 Andre Przywara
        while (*p && *p != '|')
441 c6dc6f63 Andre Przywara
            ++p;
442 c6dc6f63 Andre Przywara
        if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
443 c6dc6f63 Andre Przywara
            return (0);
444 c6dc6f63 Andre Przywara
        if (!*p)
445 c6dc6f63 Andre Przywara
            return (1);
446 c6dc6f63 Andre Przywara
        else
447 c6dc6f63 Andre Przywara
            q = ++p;
448 c6dc6f63 Andre Przywara
    }
449 c6dc6f63 Andre Przywara
}
450 c6dc6f63 Andre Przywara
451 c6dc6f63 Andre Przywara
/* search featureset for flag *[s..e), if found set corresponding bit in
452 e41e0fc6 Jan Kiszka
 * *pval and return true, otherwise return false
453 c6dc6f63 Andre Przywara
 */
454 e41e0fc6 Jan Kiszka
static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
455 e41e0fc6 Jan Kiszka
                           const char **featureset)
456 c6dc6f63 Andre Przywara
{
457 c6dc6f63 Andre Przywara
    uint32_t mask;
458 c6dc6f63 Andre Przywara
    const char **ppc;
459 e41e0fc6 Jan Kiszka
    bool found = false;
460 c6dc6f63 Andre Przywara
461 e41e0fc6 Jan Kiszka
    for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
462 c6dc6f63 Andre Przywara
        if (*ppc && !altcmp(s, e, *ppc)) {
463 c6dc6f63 Andre Przywara
            *pval |= mask;
464 e41e0fc6 Jan Kiszka
            found = true;
465 c6dc6f63 Andre Przywara
        }
466 e41e0fc6 Jan Kiszka
    }
467 e41e0fc6 Jan Kiszka
    return found;
468 c6dc6f63 Andre Przywara
}
469 c6dc6f63 Andre Przywara
470 5ef57876 Eduardo Habkost
static void add_flagname_to_bitmaps(const char *flagname,
471 5ef57876 Eduardo Habkost
                                    FeatureWordArray words)
472 c6dc6f63 Andre Przywara
{
473 5ef57876 Eduardo Habkost
    FeatureWord w;
474 5ef57876 Eduardo Habkost
    for (w = 0; w < FEATURE_WORDS; w++) {
475 5ef57876 Eduardo Habkost
        FeatureWordInfo *wi = &feature_word_info[w];
476 5ef57876 Eduardo Habkost
        if (wi->feat_names &&
477 5ef57876 Eduardo Habkost
            lookup_feature(&words[w], flagname, NULL, wi->feat_names)) {
478 5ef57876 Eduardo Habkost
            break;
479 5ef57876 Eduardo Habkost
        }
480 5ef57876 Eduardo Habkost
    }
481 5ef57876 Eduardo Habkost
    if (w == FEATURE_WORDS) {
482 5ef57876 Eduardo Habkost
        fprintf(stderr, "CPU feature %s not found\n", flagname);
483 5ef57876 Eduardo Habkost
    }
484 c6dc6f63 Andre Przywara
}
485 c6dc6f63 Andre Przywara
486 c6dc6f63 Andre Przywara
typedef struct x86_def_t {
487 c6dc6f63 Andre Przywara
    const char *name;
488 c6dc6f63 Andre Przywara
    uint32_t level;
489 90e4b0c3 Eduardo Habkost
    uint32_t xlevel;
490 90e4b0c3 Eduardo Habkost
    uint32_t xlevel2;
491 99b88a17 Igor Mammedov
    /* vendor is zero-terminated, 12 character ASCII string */
492 99b88a17 Igor Mammedov
    char vendor[CPUID_VENDOR_SZ + 1];
493 c6dc6f63 Andre Przywara
    int family;
494 c6dc6f63 Andre Przywara
    int model;
495 c6dc6f63 Andre Przywara
    int stepping;
496 0514ef2f Eduardo Habkost
    FeatureWordArray features;
497 c6dc6f63 Andre Przywara
    char model_id[48];
498 787aaf57 Benoît Canet
    bool cache_info_passthrough;
499 c6dc6f63 Andre Przywara
} x86_def_t;
500 c6dc6f63 Andre Przywara
501 c6dc6f63 Andre Przywara
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
502 c6dc6f63 Andre Przywara
#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
503 c6dc6f63 Andre Przywara
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
504 c6dc6f63 Andre Przywara
#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
505 c6dc6f63 Andre Przywara
          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
506 c6dc6f63 Andre Przywara
          CPUID_PSE36 | CPUID_FXSR)
507 c6dc6f63 Andre Przywara
#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
508 c6dc6f63 Andre Przywara
#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
509 c6dc6f63 Andre Przywara
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
510 c6dc6f63 Andre Przywara
          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
511 c6dc6f63 Andre Przywara
          CPUID_PAE | CPUID_SEP | CPUID_APIC)
512 c6dc6f63 Andre Przywara
513 551a2dec Andre Przywara
#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
514 551a2dec Andre Przywara
          CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
515 551a2dec Andre Przywara
          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
516 551a2dec Andre Przywara
          CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
517 551a2dec Andre Przywara
          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
518 8560efed Aurelien Jarno
          /* partly implemented:
519 8560efed Aurelien Jarno
          CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
520 8560efed Aurelien Jarno
          CPUID_PSE36 (needed for Solaris) */
521 8560efed Aurelien Jarno
          /* missing:
522 8560efed Aurelien Jarno
          CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
523 e71827bc Aurelien Jarno
#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
524 e71827bc Aurelien Jarno
          CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
525 e71827bc Aurelien Jarno
          CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
526 d640045a Aurelien Jarno
          CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
527 8560efed Aurelien Jarno
          /* missing:
528 e71827bc Aurelien Jarno
          CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
529 e71827bc Aurelien Jarno
          CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
530 e71827bc Aurelien Jarno
          CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
531 d640045a Aurelien Jarno
          CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_XSAVE,
532 d640045a Aurelien Jarno
          CPUID_EXT_OSXSAVE, CPUID_EXT_AVX, CPUID_EXT_F16C,
533 83f7dc28 Aurelien Jarno
          CPUID_EXT_RDRAND */
534 60032ac0 Eduardo Habkost
#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
535 551a2dec Andre Przywara
          CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
536 551a2dec Andre Przywara
          CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
537 8560efed Aurelien Jarno
          /* missing:
538 8560efed Aurelien Jarno
          CPUID_EXT2_PDPE1GB */
539 551a2dec Andre Przywara
#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
540 551a2dec Andre Przywara
          CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
541 296acb64 Joerg Roedel
#define TCG_SVM_FEATURES 0
542 7073fbad Richard Henderson
#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP \
543 cd7f97ca Richard Henderson
          CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX)
544 111994ee Richard Henderson
          /* missing:
545 7073fbad Richard Henderson
          CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
546 7073fbad Richard Henderson
          CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
547 cd7f97ca Richard Henderson
          CPUID_7_0_EBX_RDSEED */
548 551a2dec Andre Przywara
549 7fc9b714 Andreas Färber
/* built-in CPU model definitions
550 c6dc6f63 Andre Przywara
 */
551 c6dc6f63 Andre Przywara
static x86_def_t builtin_x86_defs[] = {
552 c6dc6f63 Andre Przywara
    {
553 c6dc6f63 Andre Przywara
        .name = "qemu64",
554 c6dc6f63 Andre Przywara
        .level = 4,
555 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_AMD,
556 c6dc6f63 Andre Przywara
        .family = 6,
557 f8e6a11a Eduardo Habkost
        .model = 6,
558 c6dc6f63 Andre Przywara
        .stepping = 3,
559 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
560 27861ecc Eduardo Habkost
            PPRO_FEATURES |
561 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
562 c6dc6f63 Andre Przywara
            CPUID_PSE36,
563 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
564 27861ecc Eduardo Habkost
            CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
565 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
566 27861ecc Eduardo Habkost
            (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
567 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
568 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
569 27861ecc Eduardo Habkost
            CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
570 c6dc6f63 Andre Przywara
            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
571 c6dc6f63 Andre Przywara
        .xlevel = 0x8000000A,
572 c6dc6f63 Andre Przywara
    },
573 c6dc6f63 Andre Przywara
    {
574 c6dc6f63 Andre Przywara
        .name = "phenom",
575 c6dc6f63 Andre Przywara
        .level = 5,
576 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_AMD,
577 c6dc6f63 Andre Przywara
        .family = 16,
578 c6dc6f63 Andre Przywara
        .model = 2,
579 c6dc6f63 Andre Przywara
        .stepping = 3,
580 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
581 27861ecc Eduardo Habkost
            PPRO_FEATURES |
582 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
583 8560efed Aurelien Jarno
            CPUID_PSE36 | CPUID_VME | CPUID_HT,
584 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
585 27861ecc Eduardo Habkost
            CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
586 c6dc6f63 Andre Przywara
            CPUID_EXT_POPCNT,
587 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
588 27861ecc Eduardo Habkost
            (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
589 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
590 c6dc6f63 Andre Przywara
            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
591 8560efed Aurelien Jarno
            CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
592 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
593 c6dc6f63 Andre Przywara
                    CPUID_EXT3_CR8LEG,
594 c6dc6f63 Andre Przywara
                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
595 c6dc6f63 Andre Przywara
                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
596 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
597 27861ecc Eduardo Habkost
            CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
598 c6dc6f63 Andre Przywara
            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
599 0514ef2f Eduardo Habkost
        .features[FEAT_SVM] =
600 27861ecc Eduardo Habkost
            CPUID_SVM_NPT | CPUID_SVM_LBRV,
601 c6dc6f63 Andre Przywara
        .xlevel = 0x8000001A,
602 c6dc6f63 Andre Przywara
        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
603 c6dc6f63 Andre Przywara
    },
604 c6dc6f63 Andre Przywara
    {
605 c6dc6f63 Andre Przywara
        .name = "core2duo",
606 c6dc6f63 Andre Przywara
        .level = 10,
607 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
608 c6dc6f63 Andre Przywara
        .family = 6,
609 c6dc6f63 Andre Przywara
        .model = 15,
610 c6dc6f63 Andre Przywara
        .stepping = 11,
611 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
612 27861ecc Eduardo Habkost
            PPRO_FEATURES |
613 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
614 8560efed Aurelien Jarno
            CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
615 8560efed Aurelien Jarno
            CPUID_HT | CPUID_TM | CPUID_PBE,
616 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
617 27861ecc Eduardo Habkost
            CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
618 8560efed Aurelien Jarno
            CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
619 8560efed Aurelien Jarno
            CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
620 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
621 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
622 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
623 27861ecc Eduardo Habkost
            CPUID_EXT3_LAHF_LM,
624 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
625 c6dc6f63 Andre Przywara
        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
626 c6dc6f63 Andre Przywara
    },
627 c6dc6f63 Andre Przywara
    {
628 c6dc6f63 Andre Przywara
        .name = "kvm64",
629 c6dc6f63 Andre Przywara
        .level = 5,
630 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
631 c6dc6f63 Andre Przywara
        .family = 15,
632 c6dc6f63 Andre Przywara
        .model = 6,
633 c6dc6f63 Andre Przywara
        .stepping = 1,
634 c6dc6f63 Andre Przywara
        /* Missing: CPUID_VME, CPUID_HT */
635 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
636 27861ecc Eduardo Habkost
            PPRO_FEATURES |
637 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
638 c6dc6f63 Andre Przywara
            CPUID_PSE36,
639 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
640 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
641 27861ecc Eduardo Habkost
            CPUID_EXT_SSE3 | CPUID_EXT_CX16,
642 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
643 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
644 27861ecc Eduardo Habkost
            (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
645 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
646 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
647 c6dc6f63 Andre Przywara
                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
648 c6dc6f63 Andre Przywara
                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
649 c6dc6f63 Andre Przywara
                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
650 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
651 27861ecc Eduardo Habkost
            0,
652 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
653 c6dc6f63 Andre Przywara
        .model_id = "Common KVM processor"
654 c6dc6f63 Andre Przywara
    },
655 c6dc6f63 Andre Przywara
    {
656 c6dc6f63 Andre Przywara
        .name = "qemu32",
657 c6dc6f63 Andre Przywara
        .level = 4,
658 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
659 c6dc6f63 Andre Przywara
        .family = 6,
660 f8e6a11a Eduardo Habkost
        .model = 6,
661 c6dc6f63 Andre Przywara
        .stepping = 3,
662 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
663 27861ecc Eduardo Habkost
            PPRO_FEATURES,
664 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
665 27861ecc Eduardo Habkost
            CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
666 58012d66 Andre Przywara
        .xlevel = 0x80000004,
667 c6dc6f63 Andre Przywara
    },
668 c6dc6f63 Andre Przywara
    {
669 eafaf1e5 Andre Przywara
        .name = "kvm32",
670 eafaf1e5 Andre Przywara
        .level = 5,
671 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
672 eafaf1e5 Andre Przywara
        .family = 15,
673 eafaf1e5 Andre Przywara
        .model = 6,
674 eafaf1e5 Andre Przywara
        .stepping = 1,
675 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
676 27861ecc Eduardo Habkost
            PPRO_FEATURES |
677 eafaf1e5 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
678 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
679 27861ecc Eduardo Habkost
            CPUID_EXT_SSE3,
680 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
681 27861ecc Eduardo Habkost
            PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES,
682 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
683 27861ecc Eduardo Habkost
            0,
684 eafaf1e5 Andre Przywara
        .xlevel = 0x80000008,
685 eafaf1e5 Andre Przywara
        .model_id = "Common 32-bit KVM processor"
686 eafaf1e5 Andre Przywara
    },
687 eafaf1e5 Andre Przywara
    {
688 c6dc6f63 Andre Przywara
        .name = "coreduo",
689 c6dc6f63 Andre Przywara
        .level = 10,
690 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
691 c6dc6f63 Andre Przywara
        .family = 6,
692 c6dc6f63 Andre Przywara
        .model = 14,
693 c6dc6f63 Andre Przywara
        .stepping = 8,
694 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
695 27861ecc Eduardo Habkost
            PPRO_FEATURES | CPUID_VME |
696 8560efed Aurelien Jarno
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
697 8560efed Aurelien Jarno
            CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
698 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
699 27861ecc Eduardo Habkost
            CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
700 8560efed Aurelien Jarno
            CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
701 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
702 27861ecc Eduardo Habkost
            CPUID_EXT2_NX,
703 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
704 c6dc6f63 Andre Przywara
        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
705 c6dc6f63 Andre Przywara
    },
706 c6dc6f63 Andre Przywara
    {
707 c6dc6f63 Andre Przywara
        .name = "486",
708 58012d66 Andre Przywara
        .level = 1,
709 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
710 c6dc6f63 Andre Przywara
        .family = 4,
711 b2a856d9 Andreas Färber
        .model = 8,
712 c6dc6f63 Andre Przywara
        .stepping = 0,
713 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
714 27861ecc Eduardo Habkost
            I486_FEATURES,
715 c6dc6f63 Andre Przywara
        .xlevel = 0,
716 c6dc6f63 Andre Przywara
    },
717 c6dc6f63 Andre Przywara
    {
718 c6dc6f63 Andre Przywara
        .name = "pentium",
719 c6dc6f63 Andre Przywara
        .level = 1,
720 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
721 c6dc6f63 Andre Przywara
        .family = 5,
722 c6dc6f63 Andre Przywara
        .model = 4,
723 c6dc6f63 Andre Przywara
        .stepping = 3,
724 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
725 27861ecc Eduardo Habkost
            PENTIUM_FEATURES,
726 c6dc6f63 Andre Przywara
        .xlevel = 0,
727 c6dc6f63 Andre Przywara
    },
728 c6dc6f63 Andre Przywara
    {
729 c6dc6f63 Andre Przywara
        .name = "pentium2",
730 c6dc6f63 Andre Przywara
        .level = 2,
731 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
732 c6dc6f63 Andre Przywara
        .family = 6,
733 c6dc6f63 Andre Przywara
        .model = 5,
734 c6dc6f63 Andre Przywara
        .stepping = 2,
735 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
736 27861ecc Eduardo Habkost
            PENTIUM2_FEATURES,
737 c6dc6f63 Andre Przywara
        .xlevel = 0,
738 c6dc6f63 Andre Przywara
    },
739 c6dc6f63 Andre Przywara
    {
740 c6dc6f63 Andre Przywara
        .name = "pentium3",
741 c6dc6f63 Andre Przywara
        .level = 2,
742 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
743 c6dc6f63 Andre Przywara
        .family = 6,
744 c6dc6f63 Andre Przywara
        .model = 7,
745 c6dc6f63 Andre Przywara
        .stepping = 3,
746 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
747 27861ecc Eduardo Habkost
            PENTIUM3_FEATURES,
748 c6dc6f63 Andre Przywara
        .xlevel = 0,
749 c6dc6f63 Andre Przywara
    },
750 c6dc6f63 Andre Przywara
    {
751 c6dc6f63 Andre Przywara
        .name = "athlon",
752 c6dc6f63 Andre Przywara
        .level = 2,
753 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_AMD,
754 c6dc6f63 Andre Przywara
        .family = 6,
755 c6dc6f63 Andre Przywara
        .model = 2,
756 c6dc6f63 Andre Przywara
        .stepping = 3,
757 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
758 27861ecc Eduardo Habkost
            PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
759 60032ac0 Eduardo Habkost
            CPUID_MCA,
760 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
761 27861ecc Eduardo Habkost
            (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
762 60032ac0 Eduardo Habkost
            CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
763 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
764 c6dc6f63 Andre Przywara
    },
765 c6dc6f63 Andre Przywara
    {
766 c6dc6f63 Andre Przywara
        .name = "n270",
767 c6dc6f63 Andre Przywara
        /* original is on level 10 */
768 c6dc6f63 Andre Przywara
        .level = 5,
769 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
770 c6dc6f63 Andre Przywara
        .family = 6,
771 c6dc6f63 Andre Przywara
        .model = 28,
772 c6dc6f63 Andre Przywara
        .stepping = 2,
773 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
774 27861ecc Eduardo Habkost
            PPRO_FEATURES |
775 8560efed Aurelien Jarno
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
776 8560efed Aurelien Jarno
            CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
777 c6dc6f63 Andre Przywara
            /* Some CPUs got no CPUID_SEP */
778 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
779 27861ecc Eduardo Habkost
            CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
780 4458c236 Borislav Petkov
            CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR |
781 4458c236 Borislav Petkov
            CPUID_EXT_MOVBE,
782 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
783 27861ecc Eduardo Habkost
            (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
784 60032ac0 Eduardo Habkost
            CPUID_EXT2_NX,
785 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
786 27861ecc Eduardo Habkost
            CPUID_EXT3_LAHF_LM,
787 c6dc6f63 Andre Przywara
        .xlevel = 0x8000000A,
788 c6dc6f63 Andre Przywara
        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
789 c6dc6f63 Andre Przywara
    },
790 3eca4642 Eduardo Habkost
    {
791 3eca4642 Eduardo Habkost
        .name = "Conroe",
792 6b11322e Eduardo Habkost
        .level = 4,
793 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
794 3eca4642 Eduardo Habkost
        .family = 6,
795 ffce9ebb Eduardo Habkost
        .model = 15,
796 3eca4642 Eduardo Habkost
        .stepping = 3,
797 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
798 27861ecc Eduardo Habkost
            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
799 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
800 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
801 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
802 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
803 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
804 27861ecc Eduardo Habkost
            CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
805 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
806 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
807 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
808 27861ecc Eduardo Habkost
            CPUID_EXT3_LAHF_LM,
809 3eca4642 Eduardo Habkost
        .xlevel = 0x8000000A,
810 3eca4642 Eduardo Habkost
        .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
811 3eca4642 Eduardo Habkost
    },
812 3eca4642 Eduardo Habkost
    {
813 3eca4642 Eduardo Habkost
        .name = "Penryn",
814 6b11322e Eduardo Habkost
        .level = 4,
815 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
816 3eca4642 Eduardo Habkost
        .family = 6,
817 ffce9ebb Eduardo Habkost
        .model = 23,
818 3eca4642 Eduardo Habkost
        .stepping = 3,
819 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
820 27861ecc Eduardo Habkost
            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
821 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
822 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
823 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
824 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
825 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
826 27861ecc Eduardo Habkost
            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
827 3eca4642 Eduardo Habkost
             CPUID_EXT_SSE3,
828 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
829 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
830 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
831 27861ecc Eduardo Habkost
            CPUID_EXT3_LAHF_LM,
832 3eca4642 Eduardo Habkost
        .xlevel = 0x8000000A,
833 3eca4642 Eduardo Habkost
        .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
834 3eca4642 Eduardo Habkost
    },
835 3eca4642 Eduardo Habkost
    {
836 3eca4642 Eduardo Habkost
        .name = "Nehalem",
837 6b11322e Eduardo Habkost
        .level = 4,
838 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
839 3eca4642 Eduardo Habkost
        .family = 6,
840 ffce9ebb Eduardo Habkost
        .model = 26,
841 3eca4642 Eduardo Habkost
        .stepping = 3,
842 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
843 27861ecc Eduardo Habkost
            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
844 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
845 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
846 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
847 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
848 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
849 27861ecc Eduardo Habkost
            CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
850 3eca4642 Eduardo Habkost
             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
851 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
852 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
853 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
854 27861ecc Eduardo Habkost
            CPUID_EXT3_LAHF_LM,
855 3eca4642 Eduardo Habkost
        .xlevel = 0x8000000A,
856 3eca4642 Eduardo Habkost
        .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
857 3eca4642 Eduardo Habkost
    },
858 3eca4642 Eduardo Habkost
    {
859 3eca4642 Eduardo Habkost
        .name = "Westmere",
860 3eca4642 Eduardo Habkost
        .level = 11,
861 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
862 3eca4642 Eduardo Habkost
        .family = 6,
863 3eca4642 Eduardo Habkost
        .model = 44,
864 3eca4642 Eduardo Habkost
        .stepping = 1,
865 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
866 27861ecc Eduardo Habkost
            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
867 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
868 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
869 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
870 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
871 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
872 27861ecc Eduardo Habkost
            CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
873 3eca4642 Eduardo Habkost
             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
874 41cb383f Aurelien Jarno
             CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
875 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
876 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
877 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
878 27861ecc Eduardo Habkost
            CPUID_EXT3_LAHF_LM,
879 3eca4642 Eduardo Habkost
        .xlevel = 0x8000000A,
880 3eca4642 Eduardo Habkost
        .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
881 3eca4642 Eduardo Habkost
    },
882 3eca4642 Eduardo Habkost
    {
883 3eca4642 Eduardo Habkost
        .name = "SandyBridge",
884 3eca4642 Eduardo Habkost
        .level = 0xd,
885 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
886 3eca4642 Eduardo Habkost
        .family = 6,
887 3eca4642 Eduardo Habkost
        .model = 42,
888 3eca4642 Eduardo Habkost
        .stepping = 1,
889 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
890 27861ecc Eduardo Habkost
            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
891 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
892 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
893 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
894 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
895 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
896 27861ecc Eduardo Habkost
            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
897 3eca4642 Eduardo Habkost
             CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
898 3eca4642 Eduardo Habkost
             CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
899 3eca4642 Eduardo Habkost
             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
900 3eca4642 Eduardo Habkost
             CPUID_EXT_SSE3,
901 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
902 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
903 3eca4642 Eduardo Habkost
             CPUID_EXT2_SYSCALL,
904 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
905 27861ecc Eduardo Habkost
            CPUID_EXT3_LAHF_LM,
906 3eca4642 Eduardo Habkost
        .xlevel = 0x8000000A,
907 3eca4642 Eduardo Habkost
        .model_id = "Intel Xeon E312xx (Sandy Bridge)",
908 3eca4642 Eduardo Habkost
    },
909 3eca4642 Eduardo Habkost
    {
910 37507094 Eduardo Habkost
        .name = "Haswell",
911 37507094 Eduardo Habkost
        .level = 0xd,
912 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_INTEL,
913 37507094 Eduardo Habkost
        .family = 6,
914 37507094 Eduardo Habkost
        .model = 60,
915 37507094 Eduardo Habkost
        .stepping = 1,
916 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
917 27861ecc Eduardo Habkost
            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
918 37507094 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
919 80ae4160 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
920 37507094 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
921 37507094 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
922 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
923 27861ecc Eduardo Habkost
            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
924 37507094 Eduardo Habkost
             CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
925 37507094 Eduardo Habkost
             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
926 37507094 Eduardo Habkost
             CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
927 37507094 Eduardo Habkost
             CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
928 37507094 Eduardo Habkost
             CPUID_EXT_PCID,
929 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
930 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
931 80ae4160 Eduardo Habkost
             CPUID_EXT2_SYSCALL,
932 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
933 27861ecc Eduardo Habkost
            CPUID_EXT3_LAHF_LM,
934 0514ef2f Eduardo Habkost
        .features[FEAT_7_0_EBX] =
935 27861ecc Eduardo Habkost
            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
936 37507094 Eduardo Habkost
            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
937 37507094 Eduardo Habkost
            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
938 37507094 Eduardo Habkost
            CPUID_7_0_EBX_RTM,
939 37507094 Eduardo Habkost
        .xlevel = 0x8000000A,
940 37507094 Eduardo Habkost
        .model_id = "Intel Core Processor (Haswell)",
941 37507094 Eduardo Habkost
    },
942 37507094 Eduardo Habkost
    {
943 3eca4642 Eduardo Habkost
        .name = "Opteron_G1",
944 3eca4642 Eduardo Habkost
        .level = 5,
945 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_AMD,
946 3eca4642 Eduardo Habkost
        .family = 15,
947 3eca4642 Eduardo Habkost
        .model = 6,
948 3eca4642 Eduardo Habkost
        .stepping = 1,
949 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
950 27861ecc Eduardo Habkost
            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
951 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
952 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
953 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
954 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
955 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
956 27861ecc Eduardo Habkost
            CPUID_EXT_SSE3,
957 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
958 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
959 3eca4642 Eduardo Habkost
             CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
960 3eca4642 Eduardo Habkost
             CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
961 3eca4642 Eduardo Habkost
             CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
962 3eca4642 Eduardo Habkost
             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
963 3eca4642 Eduardo Habkost
             CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
964 3eca4642 Eduardo Habkost
        .xlevel = 0x80000008,
965 3eca4642 Eduardo Habkost
        .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
966 3eca4642 Eduardo Habkost
    },
967 3eca4642 Eduardo Habkost
    {
968 3eca4642 Eduardo Habkost
        .name = "Opteron_G2",
969 3eca4642 Eduardo Habkost
        .level = 5,
970 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_AMD,
971 3eca4642 Eduardo Habkost
        .family = 15,
972 3eca4642 Eduardo Habkost
        .model = 6,
973 3eca4642 Eduardo Habkost
        .stepping = 1,
974 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
975 27861ecc Eduardo Habkost
            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
976 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
977 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
978 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
979 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
980 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
981 27861ecc Eduardo Habkost
            CPUID_EXT_CX16 | CPUID_EXT_SSE3,
982 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
983 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
984 3eca4642 Eduardo Habkost
             CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
985 3eca4642 Eduardo Habkost
             CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
986 3eca4642 Eduardo Habkost
             CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
987 3eca4642 Eduardo Habkost
             CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
988 3eca4642 Eduardo Habkost
             CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
989 3eca4642 Eduardo Habkost
             CPUID_EXT2_DE | CPUID_EXT2_FPU,
990 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
991 27861ecc Eduardo Habkost
            CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
992 3eca4642 Eduardo Habkost
        .xlevel = 0x80000008,
993 3eca4642 Eduardo Habkost
        .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
994 3eca4642 Eduardo Habkost
    },
995 3eca4642 Eduardo Habkost
    {
996 3eca4642 Eduardo Habkost
        .name = "Opteron_G3",
997 3eca4642 Eduardo Habkost
        .level = 5,
998 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_AMD,
999 3eca4642 Eduardo Habkost
        .family = 15,
1000 3eca4642 Eduardo Habkost
        .model = 6,
1001 3eca4642 Eduardo Habkost
        .stepping = 1,
1002 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
1003 27861ecc Eduardo Habkost
            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1004 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1005 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1006 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1007 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
1008 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
1009 27861ecc Eduardo Habkost
            CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
1010 3eca4642 Eduardo Habkost
             CPUID_EXT_SSE3,
1011 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
1012 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
1013 3eca4642 Eduardo Habkost
             CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1014 3eca4642 Eduardo Habkost
             CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1015 3eca4642 Eduardo Habkost
             CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1016 3eca4642 Eduardo Habkost
             CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1017 3eca4642 Eduardo Habkost
             CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1018 3eca4642 Eduardo Habkost
             CPUID_EXT2_DE | CPUID_EXT2_FPU,
1019 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
1020 27861ecc Eduardo Habkost
            CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
1021 3eca4642 Eduardo Habkost
             CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
1022 3eca4642 Eduardo Habkost
        .xlevel = 0x80000008,
1023 3eca4642 Eduardo Habkost
        .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
1024 3eca4642 Eduardo Habkost
    },
1025 3eca4642 Eduardo Habkost
    {
1026 3eca4642 Eduardo Habkost
        .name = "Opteron_G4",
1027 3eca4642 Eduardo Habkost
        .level = 0xd,
1028 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_AMD,
1029 3eca4642 Eduardo Habkost
        .family = 21,
1030 3eca4642 Eduardo Habkost
        .model = 1,
1031 3eca4642 Eduardo Habkost
        .stepping = 2,
1032 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
1033 27861ecc Eduardo Habkost
            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1034 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1035 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1036 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1037 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
1038 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
1039 27861ecc Eduardo Habkost
            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1040 3eca4642 Eduardo Habkost
             CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1041 3eca4642 Eduardo Habkost
             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1042 3eca4642 Eduardo Habkost
             CPUID_EXT_SSE3,
1043 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
1044 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
1045 3eca4642 Eduardo Habkost
             CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1046 3eca4642 Eduardo Habkost
             CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1047 3eca4642 Eduardo Habkost
             CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1048 3eca4642 Eduardo Habkost
             CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1049 3eca4642 Eduardo Habkost
             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1050 3eca4642 Eduardo Habkost
             CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
1051 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
1052 27861ecc Eduardo Habkost
            CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1053 3eca4642 Eduardo Habkost
             CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1054 3eca4642 Eduardo Habkost
             CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1055 3eca4642 Eduardo Habkost
             CPUID_EXT3_LAHF_LM,
1056 3eca4642 Eduardo Habkost
        .xlevel = 0x8000001A,
1057 3eca4642 Eduardo Habkost
        .model_id = "AMD Opteron 62xx class CPU",
1058 3eca4642 Eduardo Habkost
    },
1059 021941b9 Andre Przywara
    {
1060 021941b9 Andre Przywara
        .name = "Opteron_G5",
1061 021941b9 Andre Przywara
        .level = 0xd,
1062 99b88a17 Igor Mammedov
        .vendor = CPUID_VENDOR_AMD,
1063 021941b9 Andre Przywara
        .family = 21,
1064 021941b9 Andre Przywara
        .model = 2,
1065 021941b9 Andre Przywara
        .stepping = 0,
1066 0514ef2f Eduardo Habkost
        .features[FEAT_1_EDX] =
1067 27861ecc Eduardo Habkost
            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1068 021941b9 Andre Przywara
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1069 021941b9 Andre Przywara
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1070 021941b9 Andre Przywara
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1071 021941b9 Andre Przywara
             CPUID_DE | CPUID_FP87,
1072 0514ef2f Eduardo Habkost
        .features[FEAT_1_ECX] =
1073 27861ecc Eduardo Habkost
            CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
1074 021941b9 Andre Przywara
             CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1075 021941b9 Andre Przywara
             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
1076 021941b9 Andre Przywara
             CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1077 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_EDX] =
1078 27861ecc Eduardo Habkost
            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
1079 021941b9 Andre Przywara
             CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1080 021941b9 Andre Przywara
             CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1081 021941b9 Andre Przywara
             CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1082 021941b9 Andre Przywara
             CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1083 021941b9 Andre Przywara
             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1084 021941b9 Andre Przywara
             CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
1085 0514ef2f Eduardo Habkost
        .features[FEAT_8000_0001_ECX] =
1086 27861ecc Eduardo Habkost
            CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1087 021941b9 Andre Przywara
             CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1088 021941b9 Andre Przywara
             CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1089 021941b9 Andre Przywara
             CPUID_EXT3_LAHF_LM,
1090 021941b9 Andre Przywara
        .xlevel = 0x8000001A,
1091 021941b9 Andre Przywara
        .model_id = "AMD Opteron 63xx class CPU",
1092 021941b9 Andre Przywara
    },
1093 c6dc6f63 Andre Przywara
};
1094 c6dc6f63 Andre Przywara
1095 0668af54 Eduardo Habkost
/**
1096 0668af54 Eduardo Habkost
 * x86_cpu_compat_set_features:
1097 0668af54 Eduardo Habkost
 * @cpu_model: CPU model name to be changed. If NULL, all CPU models are changed
1098 0668af54 Eduardo Habkost
 * @w: Identifies the feature word to be changed.
1099 0668af54 Eduardo Habkost
 * @feat_add: Feature bits to be added to feature word
1100 0668af54 Eduardo Habkost
 * @feat_remove: Feature bits to be removed from feature word
1101 0668af54 Eduardo Habkost
 *
1102 0668af54 Eduardo Habkost
 * Change CPU model feature bits for compatibility.
1103 0668af54 Eduardo Habkost
 *
1104 0668af54 Eduardo Habkost
 * This function may be used by machine-type compatibility functions
1105 0668af54 Eduardo Habkost
 * to enable or disable feature bits on specific CPU models.
1106 0668af54 Eduardo Habkost
 */
1107 0668af54 Eduardo Habkost
void x86_cpu_compat_set_features(const char *cpu_model, FeatureWord w,
1108 0668af54 Eduardo Habkost
                                 uint32_t feat_add, uint32_t feat_remove)
1109 0668af54 Eduardo Habkost
{
1110 0668af54 Eduardo Habkost
    x86_def_t *def;
1111 0668af54 Eduardo Habkost
    int i;
1112 0668af54 Eduardo Habkost
    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1113 0668af54 Eduardo Habkost
        def = &builtin_x86_defs[i];
1114 0668af54 Eduardo Habkost
        if (!cpu_model || !strcmp(cpu_model, def->name)) {
1115 0668af54 Eduardo Habkost
            def->features[w] |= feat_add;
1116 0668af54 Eduardo Habkost
            def->features[w] &= ~feat_remove;
1117 0668af54 Eduardo Habkost
        }
1118 0668af54 Eduardo Habkost
    }
1119 0668af54 Eduardo Habkost
}
1120 0668af54 Eduardo Habkost
1121 e4ab0d6b Eduardo Habkost
#ifdef CONFIG_KVM
1122 c6dc6f63 Andre Przywara
static int cpu_x86_fill_model_id(char *str)
1123 c6dc6f63 Andre Przywara
{
1124 c6dc6f63 Andre Przywara
    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1125 c6dc6f63 Andre Przywara
    int i;
1126 c6dc6f63 Andre Przywara
1127 c6dc6f63 Andre Przywara
    for (i = 0; i < 3; i++) {
1128 c6dc6f63 Andre Przywara
        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
1129 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  0, &eax, 4);
1130 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  4, &ebx, 4);
1131 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  8, &ecx, 4);
1132 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 + 12, &edx, 4);
1133 c6dc6f63 Andre Przywara
    }
1134 c6dc6f63 Andre Przywara
    return 0;
1135 c6dc6f63 Andre Przywara
}
1136 e4ab0d6b Eduardo Habkost
#endif
1137 c6dc6f63 Andre Przywara
1138 6e746f30 Eduardo Habkost
/* Fill a x86_def_t struct with information about the host CPU, and
1139 6e746f30 Eduardo Habkost
 * the CPU features supported by the host hardware + host kernel
1140 6e746f30 Eduardo Habkost
 *
1141 6e746f30 Eduardo Habkost
 * This function may be called only if KVM is enabled.
1142 6e746f30 Eduardo Habkost
 */
1143 6e746f30 Eduardo Habkost
static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
1144 c6dc6f63 Andre Przywara
{
1145 e4ab0d6b Eduardo Habkost
#ifdef CONFIG_KVM
1146 12869995 Eduardo Habkost
    KVMState *s = kvm_state;
1147 c6dc6f63 Andre Przywara
    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1148 c6dc6f63 Andre Przywara
1149 6e746f30 Eduardo Habkost
    assert(kvm_enabled());
1150 6e746f30 Eduardo Habkost
1151 c6dc6f63 Andre Przywara
    x86_cpu_def->name = "host";
1152 787aaf57 Benoît Canet
    x86_cpu_def->cache_info_passthrough = true;
1153 c6dc6f63 Andre Przywara
    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
1154 99b88a17 Igor Mammedov
    x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1155 c6dc6f63 Andre Przywara
1156 c6dc6f63 Andre Przywara
    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
1157 c6dc6f63 Andre Przywara
    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1158 c6dc6f63 Andre Przywara
    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1159 c6dc6f63 Andre Przywara
    x86_cpu_def->stepping = eax & 0x0F;
1160 c6dc6f63 Andre Przywara
1161 12869995 Eduardo Habkost
    x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
1162 0514ef2f Eduardo Habkost
    x86_cpu_def->features[FEAT_1_EDX] =
1163 27861ecc Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX);
1164 0514ef2f Eduardo Habkost
    x86_cpu_def->features[FEAT_1_ECX] =
1165 27861ecc Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX);
1166 c6dc6f63 Andre Przywara
1167 6e746f30 Eduardo Habkost
    if (x86_cpu_def->level >= 7) {
1168 0514ef2f Eduardo Habkost
        x86_cpu_def->features[FEAT_7_0_EBX] =
1169 12869995 Eduardo Habkost
                    kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX);
1170 13526728 Eduardo Habkost
    } else {
1171 0514ef2f Eduardo Habkost
        x86_cpu_def->features[FEAT_7_0_EBX] = 0;
1172 13526728 Eduardo Habkost
    }
1173 13526728 Eduardo Habkost
1174 12869995 Eduardo Habkost
    x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
1175 0514ef2f Eduardo Habkost
    x86_cpu_def->features[FEAT_8000_0001_EDX] =
1176 12869995 Eduardo Habkost
                kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
1177 0514ef2f Eduardo Habkost
    x86_cpu_def->features[FEAT_8000_0001_ECX] =
1178 12869995 Eduardo Habkost
                kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
1179 c6dc6f63 Andre Przywara
1180 c6dc6f63 Andre Przywara
    cpu_x86_fill_model_id(x86_cpu_def->model_id);
1181 c6dc6f63 Andre Przywara
1182 b3baa152 brillywu@viatech.com.cn
    /* Call Centaur's CPUID instruction. */
1183 99b88a17 Igor Mammedov
    if (!strcmp(x86_cpu_def->vendor, CPUID_VENDOR_VIA)) {
1184 b3baa152 brillywu@viatech.com.cn
        host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
1185 12869995 Eduardo Habkost
        eax = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
1186 b3baa152 brillywu@viatech.com.cn
        if (eax >= 0xC0000001) {
1187 b3baa152 brillywu@viatech.com.cn
            /* Support VIA max extended level */
1188 b3baa152 brillywu@viatech.com.cn
            x86_cpu_def->xlevel2 = eax;
1189 b3baa152 brillywu@viatech.com.cn
            host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
1190 0514ef2f Eduardo Habkost
            x86_cpu_def->features[FEAT_C000_0001_EDX] =
1191 12869995 Eduardo Habkost
                    kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
1192 b3baa152 brillywu@viatech.com.cn
        }
1193 b3baa152 brillywu@viatech.com.cn
    }
1194 296acb64 Joerg Roedel
1195 fcb93c03 Eduardo Habkost
    /* Other KVM-specific feature fields: */
1196 0514ef2f Eduardo Habkost
    x86_cpu_def->features[FEAT_SVM] =
1197 fcb93c03 Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
1198 0514ef2f Eduardo Habkost
    x86_cpu_def->features[FEAT_KVM] =
1199 bd004bef Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
1200 fcb93c03 Eduardo Habkost
1201 e4ab0d6b Eduardo Habkost
#endif /* CONFIG_KVM */
1202 c6dc6f63 Andre Przywara
}
1203 c6dc6f63 Andre Przywara
1204 bffd67b0 Eduardo Habkost
static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask)
1205 c6dc6f63 Andre Przywara
{
1206 c6dc6f63 Andre Przywara
    int i;
1207 c6dc6f63 Andre Przywara
1208 c6dc6f63 Andre Przywara
    for (i = 0; i < 32; ++i)
1209 c6dc6f63 Andre Przywara
        if (1 << i & mask) {
1210 bffd67b0 Eduardo Habkost
            const char *reg = get_register_name_32(f->cpuid_reg);
1211 8b4beddc Eduardo Habkost
            assert(reg);
1212 8b4beddc Eduardo Habkost
            fprintf(stderr, "warning: host doesn't support requested feature: "
1213 8b4beddc Eduardo Habkost
                "CPUID.%02XH:%s%s%s [bit %d]\n",
1214 bffd67b0 Eduardo Habkost
                f->cpuid_eax, reg,
1215 bffd67b0 Eduardo Habkost
                f->feat_names[i] ? "." : "",
1216 bffd67b0 Eduardo Habkost
                f->feat_names[i] ? f->feat_names[i] : "", i);
1217 c6dc6f63 Andre Przywara
            break;
1218 c6dc6f63 Andre Przywara
        }
1219 c6dc6f63 Andre Przywara
    return 0;
1220 c6dc6f63 Andre Przywara
}
1221 c6dc6f63 Andre Przywara
1222 07ca5945 Eduardo Habkost
/* Check if all requested cpu flags are making their way to the guest
1223 07ca5945 Eduardo Habkost
 *
1224 07ca5945 Eduardo Habkost
 * Returns 0 if all flags are supported by the host, non-zero otherwise.
1225 6e746f30 Eduardo Habkost
 *
1226 6e746f30 Eduardo Habkost
 * This function may be called only if KVM is enabled.
1227 c6dc6f63 Andre Przywara
 */
1228 5ec01c2e Igor Mammedov
static int kvm_check_features_against_host(X86CPU *cpu)
1229 c6dc6f63 Andre Przywara
{
1230 5ec01c2e Igor Mammedov
    CPUX86State *env = &cpu->env;
1231 c6dc6f63 Andre Przywara
    x86_def_t host_def;
1232 c6dc6f63 Andre Przywara
    uint32_t mask;
1233 c6dc6f63 Andre Przywara
    int rv, i;
1234 c6dc6f63 Andre Przywara
    struct model_features_t ft[] = {
1235 0514ef2f Eduardo Habkost
        {&env->features[FEAT_1_EDX],
1236 0514ef2f Eduardo Habkost
            &host_def.features[FEAT_1_EDX],
1237 bffd67b0 Eduardo Habkost
            FEAT_1_EDX },
1238 0514ef2f Eduardo Habkost
        {&env->features[FEAT_1_ECX],
1239 0514ef2f Eduardo Habkost
            &host_def.features[FEAT_1_ECX],
1240 bffd67b0 Eduardo Habkost
            FEAT_1_ECX },
1241 0514ef2f Eduardo Habkost
        {&env->features[FEAT_8000_0001_EDX],
1242 0514ef2f Eduardo Habkost
            &host_def.features[FEAT_8000_0001_EDX],
1243 bffd67b0 Eduardo Habkost
            FEAT_8000_0001_EDX },
1244 0514ef2f Eduardo Habkost
        {&env->features[FEAT_8000_0001_ECX],
1245 0514ef2f Eduardo Habkost
            &host_def.features[FEAT_8000_0001_ECX],
1246 bffd67b0 Eduardo Habkost
            FEAT_8000_0001_ECX },
1247 0514ef2f Eduardo Habkost
        {&env->features[FEAT_C000_0001_EDX],
1248 0514ef2f Eduardo Habkost
            &host_def.features[FEAT_C000_0001_EDX],
1249 07ca5945 Eduardo Habkost
            FEAT_C000_0001_EDX },
1250 0514ef2f Eduardo Habkost
        {&env->features[FEAT_7_0_EBX],
1251 0514ef2f Eduardo Habkost
            &host_def.features[FEAT_7_0_EBX],
1252 07ca5945 Eduardo Habkost
            FEAT_7_0_EBX },
1253 0514ef2f Eduardo Habkost
        {&env->features[FEAT_SVM],
1254 0514ef2f Eduardo Habkost
            &host_def.features[FEAT_SVM],
1255 07ca5945 Eduardo Habkost
            FEAT_SVM },
1256 0514ef2f Eduardo Habkost
        {&env->features[FEAT_KVM],
1257 0514ef2f Eduardo Habkost
            &host_def.features[FEAT_KVM],
1258 07ca5945 Eduardo Habkost
            FEAT_KVM },
1259 8b4beddc Eduardo Habkost
    };
1260 c6dc6f63 Andre Przywara
1261 6e746f30 Eduardo Habkost
    assert(kvm_enabled());
1262 6e746f30 Eduardo Habkost
1263 6e746f30 Eduardo Habkost
    kvm_cpu_fill_host(&host_def);
1264 bffd67b0 Eduardo Habkost
    for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i) {
1265 bffd67b0 Eduardo Habkost
        FeatureWord w = ft[i].feat_word;
1266 bffd67b0 Eduardo Habkost
        FeatureWordInfo *wi = &feature_word_info[w];
1267 bffd67b0 Eduardo Habkost
        for (mask = 1; mask; mask <<= 1) {
1268 e8beac00 Eduardo Habkost
            if (*ft[i].guest_feat & mask &&
1269 c6dc6f63 Andre Przywara
                !(*ft[i].host_feat & mask)) {
1270 bffd67b0 Eduardo Habkost
                unavailable_host_feature(wi, mask);
1271 bffd67b0 Eduardo Habkost
                rv = 1;
1272 bffd67b0 Eduardo Habkost
            }
1273 bffd67b0 Eduardo Habkost
        }
1274 bffd67b0 Eduardo Habkost
    }
1275 c6dc6f63 Andre Przywara
    return rv;
1276 c6dc6f63 Andre Przywara
}
1277 c6dc6f63 Andre Przywara
1278 95b8519d Andreas Färber
static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
1279 95b8519d Andreas Färber
                                         const char *name, Error **errp)
1280 95b8519d Andreas Färber
{
1281 95b8519d Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1282 95b8519d Andreas Färber
    CPUX86State *env = &cpu->env;
1283 95b8519d Andreas Färber
    int64_t value;
1284 95b8519d Andreas Färber
1285 95b8519d Andreas Färber
    value = (env->cpuid_version >> 8) & 0xf;
1286 95b8519d Andreas Färber
    if (value == 0xf) {
1287 95b8519d Andreas Färber
        value += (env->cpuid_version >> 20) & 0xff;
1288 95b8519d Andreas Färber
    }
1289 95b8519d Andreas Färber
    visit_type_int(v, &value, name, errp);
1290 95b8519d Andreas Färber
}
1291 95b8519d Andreas Färber
1292 71ad61d3 Andreas Färber
static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
1293 71ad61d3 Andreas Färber
                                         const char *name, Error **errp)
1294 ed5e1ec3 Andreas Färber
{
1295 71ad61d3 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1296 71ad61d3 Andreas Färber
    CPUX86State *env = &cpu->env;
1297 71ad61d3 Andreas Färber
    const int64_t min = 0;
1298 71ad61d3 Andreas Färber
    const int64_t max = 0xff + 0xf;
1299 71ad61d3 Andreas Färber
    int64_t value;
1300 71ad61d3 Andreas Färber
1301 71ad61d3 Andreas Färber
    visit_type_int(v, &value, name, errp);
1302 71ad61d3 Andreas Färber
    if (error_is_set(errp)) {
1303 71ad61d3 Andreas Färber
        return;
1304 71ad61d3 Andreas Färber
    }
1305 71ad61d3 Andreas Färber
    if (value < min || value > max) {
1306 71ad61d3 Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1307 71ad61d3 Andreas Färber
                  name ? name : "null", value, min, max);
1308 71ad61d3 Andreas Färber
        return;
1309 71ad61d3 Andreas Färber
    }
1310 71ad61d3 Andreas Färber
1311 ed5e1ec3 Andreas Färber
    env->cpuid_version &= ~0xff00f00;
1312 71ad61d3 Andreas Färber
    if (value > 0x0f) {
1313 71ad61d3 Andreas Färber
        env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
1314 ed5e1ec3 Andreas Färber
    } else {
1315 71ad61d3 Andreas Färber
        env->cpuid_version |= value << 8;
1316 ed5e1ec3 Andreas Färber
    }
1317 ed5e1ec3 Andreas Färber
}
1318 ed5e1ec3 Andreas Färber
1319 67e30c83 Andreas Färber
static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
1320 67e30c83 Andreas Färber
                                        const char *name, Error **errp)
1321 67e30c83 Andreas Färber
{
1322 67e30c83 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1323 67e30c83 Andreas Färber
    CPUX86State *env = &cpu->env;
1324 67e30c83 Andreas Färber
    int64_t value;
1325 67e30c83 Andreas Färber
1326 67e30c83 Andreas Färber
    value = (env->cpuid_version >> 4) & 0xf;
1327 67e30c83 Andreas Färber
    value |= ((env->cpuid_version >> 16) & 0xf) << 4;
1328 67e30c83 Andreas Färber
    visit_type_int(v, &value, name, errp);
1329 67e30c83 Andreas Färber
}
1330 67e30c83 Andreas Färber
1331 c5291a4f Andreas Färber
static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
1332 c5291a4f Andreas Färber
                                        const char *name, Error **errp)
1333 b0704cbd Andreas Färber
{
1334 c5291a4f Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1335 c5291a4f Andreas Färber
    CPUX86State *env = &cpu->env;
1336 c5291a4f Andreas Färber
    const int64_t min = 0;
1337 c5291a4f Andreas Färber
    const int64_t max = 0xff;
1338 c5291a4f Andreas Färber
    int64_t value;
1339 c5291a4f Andreas Färber
1340 c5291a4f Andreas Färber
    visit_type_int(v, &value, name, errp);
1341 c5291a4f Andreas Färber
    if (error_is_set(errp)) {
1342 c5291a4f Andreas Färber
        return;
1343 c5291a4f Andreas Färber
    }
1344 c5291a4f Andreas Färber
    if (value < min || value > max) {
1345 c5291a4f Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1346 c5291a4f Andreas Färber
                  name ? name : "null", value, min, max);
1347 c5291a4f Andreas Färber
        return;
1348 c5291a4f Andreas Färber
    }
1349 c5291a4f Andreas Färber
1350 b0704cbd Andreas Färber
    env->cpuid_version &= ~0xf00f0;
1351 c5291a4f Andreas Färber
    env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
1352 b0704cbd Andreas Färber
}
1353 b0704cbd Andreas Färber
1354 35112e41 Andreas Färber
static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
1355 35112e41 Andreas Färber
                                           void *opaque, const char *name,
1356 35112e41 Andreas Färber
                                           Error **errp)
1357 35112e41 Andreas Färber
{
1358 35112e41 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1359 35112e41 Andreas Färber
    CPUX86State *env = &cpu->env;
1360 35112e41 Andreas Färber
    int64_t value;
1361 35112e41 Andreas Färber
1362 35112e41 Andreas Färber
    value = env->cpuid_version & 0xf;
1363 35112e41 Andreas Färber
    visit_type_int(v, &value, name, errp);
1364 35112e41 Andreas Färber
}
1365 35112e41 Andreas Färber
1366 036e2222 Andreas Färber
static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
1367 036e2222 Andreas Färber
                                           void *opaque, const char *name,
1368 036e2222 Andreas Färber
                                           Error **errp)
1369 38c3dc46 Andreas Färber
{
1370 036e2222 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1371 036e2222 Andreas Färber
    CPUX86State *env = &cpu->env;
1372 036e2222 Andreas Färber
    const int64_t min = 0;
1373 036e2222 Andreas Färber
    const int64_t max = 0xf;
1374 036e2222 Andreas Färber
    int64_t value;
1375 036e2222 Andreas Färber
1376 036e2222 Andreas Färber
    visit_type_int(v, &value, name, errp);
1377 036e2222 Andreas Färber
    if (error_is_set(errp)) {
1378 036e2222 Andreas Färber
        return;
1379 036e2222 Andreas Färber
    }
1380 036e2222 Andreas Färber
    if (value < min || value > max) {
1381 036e2222 Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1382 036e2222 Andreas Färber
                  name ? name : "null", value, min, max);
1383 036e2222 Andreas Färber
        return;
1384 036e2222 Andreas Färber
    }
1385 036e2222 Andreas Färber
1386 38c3dc46 Andreas Färber
    env->cpuid_version &= ~0xf;
1387 036e2222 Andreas Färber
    env->cpuid_version |= value & 0xf;
1388 38c3dc46 Andreas Färber
}
1389 38c3dc46 Andreas Färber
1390 8e1898bf Andreas Färber
static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
1391 8e1898bf Andreas Färber
                                const char *name, Error **errp)
1392 8e1898bf Andreas Färber
{
1393 8e1898bf Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1394 8e1898bf Andreas Färber
1395 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
1396 8e1898bf Andreas Färber
}
1397 8e1898bf Andreas Färber
1398 8e1898bf Andreas Färber
static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
1399 8e1898bf Andreas Färber
                                const char *name, Error **errp)
1400 8e1898bf Andreas Färber
{
1401 8e1898bf Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1402 8e1898bf Andreas Färber
1403 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
1404 8e1898bf Andreas Färber
}
1405 8e1898bf Andreas Färber
1406 16b93aa8 Andreas Färber
static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
1407 16b93aa8 Andreas Färber
                                 const char *name, Error **errp)
1408 16b93aa8 Andreas Färber
{
1409 16b93aa8 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1410 16b93aa8 Andreas Färber
1411 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1412 16b93aa8 Andreas Färber
}
1413 16b93aa8 Andreas Färber
1414 16b93aa8 Andreas Färber
static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
1415 16b93aa8 Andreas Färber
                                 const char *name, Error **errp)
1416 16b93aa8 Andreas Färber
{
1417 16b93aa8 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1418 16b93aa8 Andreas Färber
1419 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1420 16b93aa8 Andreas Färber
}
1421 16b93aa8 Andreas Färber
1422 d480e1af Andreas Färber
static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1423 d480e1af Andreas Färber
{
1424 d480e1af Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1425 d480e1af Andreas Färber
    CPUX86State *env = &cpu->env;
1426 d480e1af Andreas Färber
    char *value;
1427 d480e1af Andreas Färber
1428 9df694ee Igor Mammedov
    value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
1429 99b88a17 Igor Mammedov
    x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
1430 99b88a17 Igor Mammedov
                             env->cpuid_vendor3);
1431 d480e1af Andreas Färber
    return value;
1432 d480e1af Andreas Färber
}
1433 d480e1af Andreas Färber
1434 d480e1af Andreas Färber
static void x86_cpuid_set_vendor(Object *obj, const char *value,
1435 d480e1af Andreas Färber
                                 Error **errp)
1436 d480e1af Andreas Färber
{
1437 d480e1af Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1438 d480e1af Andreas Färber
    CPUX86State *env = &cpu->env;
1439 d480e1af Andreas Färber
    int i;
1440 d480e1af Andreas Färber
1441 9df694ee Igor Mammedov
    if (strlen(value) != CPUID_VENDOR_SZ) {
1442 d480e1af Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
1443 d480e1af Andreas Färber
                  "vendor", value);
1444 d480e1af Andreas Färber
        return;
1445 d480e1af Andreas Färber
    }
1446 d480e1af Andreas Färber
1447 d480e1af Andreas Färber
    env->cpuid_vendor1 = 0;
1448 d480e1af Andreas Färber
    env->cpuid_vendor2 = 0;
1449 d480e1af Andreas Färber
    env->cpuid_vendor3 = 0;
1450 d480e1af Andreas Färber
    for (i = 0; i < 4; i++) {
1451 d480e1af Andreas Färber
        env->cpuid_vendor1 |= ((uint8_t)value[i    ]) << (8 * i);
1452 d480e1af Andreas Färber
        env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1453 d480e1af Andreas Färber
        env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1454 d480e1af Andreas Färber
    }
1455 d480e1af Andreas Färber
}
1456 d480e1af Andreas Färber
1457 63e886eb Andreas Färber
static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1458 63e886eb Andreas Färber
{
1459 63e886eb Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1460 63e886eb Andreas Färber
    CPUX86State *env = &cpu->env;
1461 63e886eb Andreas Färber
    char *value;
1462 63e886eb Andreas Färber
    int i;
1463 63e886eb Andreas Färber
1464 63e886eb Andreas Färber
    value = g_malloc(48 + 1);
1465 63e886eb Andreas Färber
    for (i = 0; i < 48; i++) {
1466 63e886eb Andreas Färber
        value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1467 63e886eb Andreas Färber
    }
1468 63e886eb Andreas Färber
    value[48] = '\0';
1469 63e886eb Andreas Färber
    return value;
1470 63e886eb Andreas Färber
}
1471 63e886eb Andreas Färber
1472 938d4c25 Andreas Färber
static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1473 938d4c25 Andreas Färber
                                   Error **errp)
1474 dcce6675 Andreas Färber
{
1475 938d4c25 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1476 938d4c25 Andreas Färber
    CPUX86State *env = &cpu->env;
1477 dcce6675 Andreas Färber
    int c, len, i;
1478 dcce6675 Andreas Färber
1479 dcce6675 Andreas Färber
    if (model_id == NULL) {
1480 dcce6675 Andreas Färber
        model_id = "";
1481 dcce6675 Andreas Färber
    }
1482 dcce6675 Andreas Färber
    len = strlen(model_id);
1483 d0a6acf4 Andreas Färber
    memset(env->cpuid_model, 0, 48);
1484 dcce6675 Andreas Färber
    for (i = 0; i < 48; i++) {
1485 dcce6675 Andreas Färber
        if (i >= len) {
1486 dcce6675 Andreas Färber
            c = '\0';
1487 dcce6675 Andreas Färber
        } else {
1488 dcce6675 Andreas Färber
            c = (uint8_t)model_id[i];
1489 dcce6675 Andreas Färber
        }
1490 dcce6675 Andreas Färber
        env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1491 dcce6675 Andreas Färber
    }
1492 dcce6675 Andreas Färber
}
1493 dcce6675 Andreas Färber
1494 89e48965 Andreas Färber
static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
1495 89e48965 Andreas Färber
                                   const char *name, Error **errp)
1496 89e48965 Andreas Färber
{
1497 89e48965 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1498 89e48965 Andreas Färber
    int64_t value;
1499 89e48965 Andreas Färber
1500 89e48965 Andreas Färber
    value = cpu->env.tsc_khz * 1000;
1501 89e48965 Andreas Färber
    visit_type_int(v, &value, name, errp);
1502 89e48965 Andreas Färber
}
1503 89e48965 Andreas Färber
1504 89e48965 Andreas Färber
static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
1505 89e48965 Andreas Färber
                                   const char *name, Error **errp)
1506 89e48965 Andreas Färber
{
1507 89e48965 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1508 89e48965 Andreas Färber
    const int64_t min = 0;
1509 2e84849a Don Slutz
    const int64_t max = INT64_MAX;
1510 89e48965 Andreas Färber
    int64_t value;
1511 89e48965 Andreas Färber
1512 89e48965 Andreas Färber
    visit_type_int(v, &value, name, errp);
1513 89e48965 Andreas Färber
    if (error_is_set(errp)) {
1514 89e48965 Andreas Färber
        return;
1515 89e48965 Andreas Färber
    }
1516 89e48965 Andreas Färber
    if (value < min || value > max) {
1517 89e48965 Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1518 89e48965 Andreas Färber
                  name ? name : "null", value, min, max);
1519 89e48965 Andreas Färber
        return;
1520 89e48965 Andreas Färber
    }
1521 89e48965 Andreas Färber
1522 89e48965 Andreas Färber
    cpu->env.tsc_khz = value / 1000;
1523 89e48965 Andreas Färber
}
1524 89e48965 Andreas Färber
1525 31050930 Igor Mammedov
static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, void *opaque,
1526 31050930 Igor Mammedov
                                  const char *name, Error **errp)
1527 31050930 Igor Mammedov
{
1528 31050930 Igor Mammedov
    X86CPU *cpu = X86_CPU(obj);
1529 31050930 Igor Mammedov
    int64_t value = cpu->env.cpuid_apic_id;
1530 31050930 Igor Mammedov
1531 31050930 Igor Mammedov
    visit_type_int(v, &value, name, errp);
1532 31050930 Igor Mammedov
}
1533 31050930 Igor Mammedov
1534 31050930 Igor Mammedov
static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque,
1535 31050930 Igor Mammedov
                                  const char *name, Error **errp)
1536 31050930 Igor Mammedov
{
1537 31050930 Igor Mammedov
    X86CPU *cpu = X86_CPU(obj);
1538 8d6d4980 Igor Mammedov
    DeviceState *dev = DEVICE(obj);
1539 31050930 Igor Mammedov
    const int64_t min = 0;
1540 31050930 Igor Mammedov
    const int64_t max = UINT32_MAX;
1541 31050930 Igor Mammedov
    Error *error = NULL;
1542 31050930 Igor Mammedov
    int64_t value;
1543 31050930 Igor Mammedov
1544 8d6d4980 Igor Mammedov
    if (dev->realized) {
1545 8d6d4980 Igor Mammedov
        error_setg(errp, "Attempt to set property '%s' on '%s' after "
1546 8d6d4980 Igor Mammedov
                   "it was realized", name, object_get_typename(obj));
1547 8d6d4980 Igor Mammedov
        return;
1548 8d6d4980 Igor Mammedov
    }
1549 8d6d4980 Igor Mammedov
1550 31050930 Igor Mammedov
    visit_type_int(v, &value, name, &error);
1551 31050930 Igor Mammedov
    if (error) {
1552 31050930 Igor Mammedov
        error_propagate(errp, error);
1553 31050930 Igor Mammedov
        return;
1554 31050930 Igor Mammedov
    }
1555 31050930 Igor Mammedov
    if (value < min || value > max) {
1556 31050930 Igor Mammedov
        error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1557 31050930 Igor Mammedov
                   " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
1558 31050930 Igor Mammedov
                   object_get_typename(obj), name, value, min, max);
1559 31050930 Igor Mammedov
        return;
1560 31050930 Igor Mammedov
    }
1561 31050930 Igor Mammedov
1562 31050930 Igor Mammedov
    if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
1563 31050930 Igor Mammedov
        error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
1564 31050930 Igor Mammedov
        return;
1565 31050930 Igor Mammedov
    }
1566 31050930 Igor Mammedov
    cpu->env.cpuid_apic_id = value;
1567 31050930 Igor Mammedov
}
1568 31050930 Igor Mammedov
1569 7e5292b5 Eduardo Habkost
/* Generic getter for "feature-words" and "filtered-features" properties */
1570 8e8aba50 Eduardo Habkost
static void x86_cpu_get_feature_words(Object *obj, Visitor *v, void *opaque,
1571 8e8aba50 Eduardo Habkost
                                      const char *name, Error **errp)
1572 8e8aba50 Eduardo Habkost
{
1573 7e5292b5 Eduardo Habkost
    uint32_t *array = (uint32_t *)opaque;
1574 8e8aba50 Eduardo Habkost
    FeatureWord w;
1575 8e8aba50 Eduardo Habkost
    Error *err = NULL;
1576 8e8aba50 Eduardo Habkost
    X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
1577 8e8aba50 Eduardo Habkost
    X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
1578 8e8aba50 Eduardo Habkost
    X86CPUFeatureWordInfoList *list = NULL;
1579 8e8aba50 Eduardo Habkost
1580 8e8aba50 Eduardo Habkost
    for (w = 0; w < FEATURE_WORDS; w++) {
1581 8e8aba50 Eduardo Habkost
        FeatureWordInfo *wi = &feature_word_info[w];
1582 8e8aba50 Eduardo Habkost
        X86CPUFeatureWordInfo *qwi = &word_infos[w];
1583 8e8aba50 Eduardo Habkost
        qwi->cpuid_input_eax = wi->cpuid_eax;
1584 8e8aba50 Eduardo Habkost
        qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
1585 8e8aba50 Eduardo Habkost
        qwi->cpuid_input_ecx = wi->cpuid_ecx;
1586 8e8aba50 Eduardo Habkost
        qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
1587 7e5292b5 Eduardo Habkost
        qwi->features = array[w];
1588 8e8aba50 Eduardo Habkost
1589 8e8aba50 Eduardo Habkost
        /* List will be in reverse order, but order shouldn't matter */
1590 8e8aba50 Eduardo Habkost
        list_entries[w].next = list;
1591 8e8aba50 Eduardo Habkost
        list_entries[w].value = &word_infos[w];
1592 8e8aba50 Eduardo Habkost
        list = &list_entries[w];
1593 8e8aba50 Eduardo Habkost
    }
1594 8e8aba50 Eduardo Habkost
1595 8e8aba50 Eduardo Habkost
    visit_type_X86CPUFeatureWordInfoList(v, &list, "feature-words", &err);
1596 8e8aba50 Eduardo Habkost
    error_propagate(errp, err);
1597 8e8aba50 Eduardo Habkost
}
1598 8e8aba50 Eduardo Habkost
1599 c1399112 Eduardo Habkost
static int cpu_x86_find_by_name(X86CPU *cpu, x86_def_t *x86_cpu_def,
1600 c1399112 Eduardo Habkost
                                const char *name)
1601 c6dc6f63 Andre Przywara
{
1602 c6dc6f63 Andre Przywara
    x86_def_t *def;
1603 9337e3b6 Eduardo Habkost
    Error *err = NULL;
1604 7fc9b714 Andreas Färber
    int i;
1605 c6dc6f63 Andre Przywara
1606 4bfe910d Andreas Färber
    if (name == NULL) {
1607 4bfe910d Andreas Färber
        return -1;
1608 9f3fb565 Eduardo Habkost
    }
1609 4bfe910d Andreas Färber
    if (kvm_enabled() && strcmp(name, "host") == 0) {
1610 6e746f30 Eduardo Habkost
        kvm_cpu_fill_host(x86_cpu_def);
1611 9337e3b6 Eduardo Habkost
        object_property_set_bool(OBJECT(cpu), true, "pmu", &err);
1612 9337e3b6 Eduardo Habkost
        assert_no_error(err);
1613 4bfe910d Andreas Färber
        return 0;
1614 c6dc6f63 Andre Przywara
    }
1615 c6dc6f63 Andre Przywara
1616 7fc9b714 Andreas Färber
    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1617 7fc9b714 Andreas Färber
        def = &builtin_x86_defs[i];
1618 4bfe910d Andreas Färber
        if (strcmp(name, def->name) == 0) {
1619 4bfe910d Andreas Färber
            memcpy(x86_cpu_def, def, sizeof(*def));
1620 11acfdd5 Igor Mammedov
            /* sysenter isn't supported in compatibility mode on AMD,
1621 11acfdd5 Igor Mammedov
             * syscall isn't supported in compatibility mode on Intel.
1622 11acfdd5 Igor Mammedov
             * Normally we advertise the actual CPU vendor, but you can
1623 11acfdd5 Igor Mammedov
             * override this using the 'vendor' property if you want to use
1624 11acfdd5 Igor Mammedov
             * KVM's sysenter/syscall emulation in compatibility mode and
1625 11acfdd5 Igor Mammedov
             * when doing cross vendor migration
1626 11acfdd5 Igor Mammedov
             */
1627 11acfdd5 Igor Mammedov
            if (kvm_enabled()) {
1628 11acfdd5 Igor Mammedov
                uint32_t  ebx = 0, ecx = 0, edx = 0;
1629 11acfdd5 Igor Mammedov
                host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
1630 11acfdd5 Igor Mammedov
                x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1631 11acfdd5 Igor Mammedov
            }
1632 4bfe910d Andreas Färber
            return 0;
1633 4bfe910d Andreas Färber
        }
1634 4bfe910d Andreas Färber
    }
1635 4bfe910d Andreas Färber
1636 4bfe910d Andreas Färber
    return -1;
1637 8f961357 Eduardo Habkost
}
1638 8f961357 Eduardo Habkost
1639 72ac2e87 Igor Mammedov
/* Convert all '_' in a feature string option name to '-', to make feature
1640 72ac2e87 Igor Mammedov
 * name conform to QOM property naming rule, which uses '-' instead of '_'.
1641 72ac2e87 Igor Mammedov
 */
1642 72ac2e87 Igor Mammedov
static inline void feat2prop(char *s)
1643 72ac2e87 Igor Mammedov
{
1644 72ac2e87 Igor Mammedov
    while ((s = strchr(s, '_'))) {
1645 72ac2e87 Igor Mammedov
        *s = '-';
1646 72ac2e87 Igor Mammedov
    }
1647 72ac2e87 Igor Mammedov
}
1648 72ac2e87 Igor Mammedov
1649 8f961357 Eduardo Habkost
/* Parse "+feature,-feature,feature=foo" CPU feature string
1650 8f961357 Eduardo Habkost
 */
1651 a91987c2 Igor Mammedov
static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
1652 8f961357 Eduardo Habkost
{
1653 8f961357 Eduardo Habkost
    char *featurestr; /* Single 'key=value" string being parsed */
1654 8f961357 Eduardo Habkost
    /* Features to be added */
1655 077c68c3 Igor Mammedov
    FeatureWordArray plus_features = { 0 };
1656 8f961357 Eduardo Habkost
    /* Features to be removed */
1657 5ef57876 Eduardo Habkost
    FeatureWordArray minus_features = { 0 };
1658 8f961357 Eduardo Habkost
    uint32_t numvalue;
1659 a91987c2 Igor Mammedov
    CPUX86State *env = &cpu->env;
1660 8f961357 Eduardo Habkost
1661 8f961357 Eduardo Habkost
    featurestr = features ? strtok(features, ",") : NULL;
1662 c6dc6f63 Andre Przywara
1663 c6dc6f63 Andre Przywara
    while (featurestr) {
1664 c6dc6f63 Andre Przywara
        char *val;
1665 c6dc6f63 Andre Przywara
        if (featurestr[0] == '+') {
1666 5ef57876 Eduardo Habkost
            add_flagname_to_bitmaps(featurestr + 1, plus_features);
1667 c6dc6f63 Andre Przywara
        } else if (featurestr[0] == '-') {
1668 5ef57876 Eduardo Habkost
            add_flagname_to_bitmaps(featurestr + 1, minus_features);
1669 c6dc6f63 Andre Przywara
        } else if ((val = strchr(featurestr, '='))) {
1670 c6dc6f63 Andre Przywara
            *val = 0; val++;
1671 72ac2e87 Igor Mammedov
            feat2prop(featurestr);
1672 c6dc6f63 Andre Przywara
            if (!strcmp(featurestr, "family")) {
1673 a91987c2 Igor Mammedov
                object_property_parse(OBJECT(cpu), val, featurestr, errp);
1674 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "model")) {
1675 a91987c2 Igor Mammedov
                object_property_parse(OBJECT(cpu), val, featurestr, errp);
1676 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "stepping")) {
1677 a91987c2 Igor Mammedov
                object_property_parse(OBJECT(cpu), val, featurestr, errp);
1678 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "level")) {
1679 a91987c2 Igor Mammedov
                object_property_parse(OBJECT(cpu), val, featurestr, errp);
1680 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "xlevel")) {
1681 c6dc6f63 Andre Przywara
                char *err;
1682 a91987c2 Igor Mammedov
                char num[32];
1683 a91987c2 Igor Mammedov
1684 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
1685 c6dc6f63 Andre Przywara
                if (!*val || *err) {
1686 312fd5f2 Markus Armbruster
                    error_setg(errp, "bad numerical value %s", val);
1687 a91987c2 Igor Mammedov
                    goto out;
1688 c6dc6f63 Andre Przywara
                }
1689 c6dc6f63 Andre Przywara
                if (numvalue < 0x80000000) {
1690 8ba8a698 Igor Mammedov
                    fprintf(stderr, "xlevel value shall always be >= 0x80000000"
1691 8ba8a698 Igor Mammedov
                            ", fixup will be removed in future versions\n");
1692 2f7a21c4 Aurelien Jarno
                    numvalue += 0x80000000;
1693 c6dc6f63 Andre Przywara
                }
1694 a91987c2 Igor Mammedov
                snprintf(num, sizeof(num), "%" PRIu32, numvalue);
1695 a91987c2 Igor Mammedov
                object_property_parse(OBJECT(cpu), num, featurestr, errp);
1696 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "vendor")) {
1697 a91987c2 Igor Mammedov
                object_property_parse(OBJECT(cpu), val, featurestr, errp);
1698 72ac2e87 Igor Mammedov
            } else if (!strcmp(featurestr, "model-id")) {
1699 72ac2e87 Igor Mammedov
                object_property_parse(OBJECT(cpu), val, featurestr, errp);
1700 72ac2e87 Igor Mammedov
            } else if (!strcmp(featurestr, "tsc-freq")) {
1701 b862d1fe Joerg Roedel
                int64_t tsc_freq;
1702 b862d1fe Joerg Roedel
                char *err;
1703 a91987c2 Igor Mammedov
                char num[32];
1704 b862d1fe Joerg Roedel
1705 b862d1fe Joerg Roedel
                tsc_freq = strtosz_suffix_unit(val, &err,
1706 b862d1fe Joerg Roedel
                                               STRTOSZ_DEFSUFFIX_B, 1000);
1707 45009a30 Markus Armbruster
                if (tsc_freq < 0 || *err) {
1708 312fd5f2 Markus Armbruster
                    error_setg(errp, "bad numerical value %s", val);
1709 a91987c2 Igor Mammedov
                    goto out;
1710 b862d1fe Joerg Roedel
                }
1711 a91987c2 Igor Mammedov
                snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
1712 a91987c2 Igor Mammedov
                object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
1713 72ac2e87 Igor Mammedov
            } else if (!strcmp(featurestr, "hv-spinlocks")) {
1714 28f52cc0 Vadim Rozenfeld
                char *err;
1715 92067bf4 Igor Mammedov
                const int min = 0xFFF;
1716 28f52cc0 Vadim Rozenfeld
                numvalue = strtoul(val, &err, 0);
1717 28f52cc0 Vadim Rozenfeld
                if (!*val || *err) {
1718 312fd5f2 Markus Armbruster
                    error_setg(errp, "bad numerical value %s", val);
1719 a91987c2 Igor Mammedov
                    goto out;
1720 28f52cc0 Vadim Rozenfeld
                }
1721 92067bf4 Igor Mammedov
                if (numvalue < min) {
1722 92067bf4 Igor Mammedov
                    fprintf(stderr, "hv-spinlocks value shall always be >= 0x%x"
1723 92067bf4 Igor Mammedov
                            ", fixup will be removed in future versions\n",
1724 92067bf4 Igor Mammedov
                            min);
1725 92067bf4 Igor Mammedov
                    numvalue = min;
1726 92067bf4 Igor Mammedov
                }
1727 92067bf4 Igor Mammedov
                cpu->hyperv_spinlock_attempts = numvalue;
1728 c6dc6f63 Andre Przywara
            } else {
1729 312fd5f2 Markus Armbruster
                error_setg(errp, "unrecognized feature %s", featurestr);
1730 a91987c2 Igor Mammedov
                goto out;
1731 c6dc6f63 Andre Przywara
            }
1732 c6dc6f63 Andre Przywara
        } else if (!strcmp(featurestr, "check")) {
1733 c6dc6f63 Andre Przywara
            check_cpuid = 1;
1734 c6dc6f63 Andre Przywara
        } else if (!strcmp(featurestr, "enforce")) {
1735 c6dc6f63 Andre Przywara
            check_cpuid = enforce_cpuid = 1;
1736 28f52cc0 Vadim Rozenfeld
        } else if (!strcmp(featurestr, "hv_relaxed")) {
1737 92067bf4 Igor Mammedov
            cpu->hyperv_relaxed_timing = true;
1738 28f52cc0 Vadim Rozenfeld
        } else if (!strcmp(featurestr, "hv_vapic")) {
1739 92067bf4 Igor Mammedov
            cpu->hyperv_vapic = true;
1740 c6dc6f63 Andre Przywara
        } else {
1741 a91987c2 Igor Mammedov
            error_setg(errp, "feature string `%s' not in format (+feature|"
1742 312fd5f2 Markus Armbruster
                       "-feature|feature=xyz)", featurestr);
1743 a91987c2 Igor Mammedov
            goto out;
1744 a91987c2 Igor Mammedov
        }
1745 a91987c2 Igor Mammedov
        if (error_is_set(errp)) {
1746 a91987c2 Igor Mammedov
            goto out;
1747 c6dc6f63 Andre Przywara
        }
1748 c6dc6f63 Andre Przywara
        featurestr = strtok(NULL, ",");
1749 c6dc6f63 Andre Przywara
    }
1750 0514ef2f Eduardo Habkost
    env->features[FEAT_1_EDX] |= plus_features[FEAT_1_EDX];
1751 0514ef2f Eduardo Habkost
    env->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX];
1752 0514ef2f Eduardo Habkost
    env->features[FEAT_8000_0001_EDX] |= plus_features[FEAT_8000_0001_EDX];
1753 0514ef2f Eduardo Habkost
    env->features[FEAT_8000_0001_ECX] |= plus_features[FEAT_8000_0001_ECX];
1754 0514ef2f Eduardo Habkost
    env->features[FEAT_C000_0001_EDX] |= plus_features[FEAT_C000_0001_EDX];
1755 0514ef2f Eduardo Habkost
    env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
1756 0514ef2f Eduardo Habkost
    env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
1757 0514ef2f Eduardo Habkost
    env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
1758 0514ef2f Eduardo Habkost
    env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
1759 0514ef2f Eduardo Habkost
    env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
1760 0514ef2f Eduardo Habkost
    env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX];
1761 0514ef2f Eduardo Habkost
    env->features[FEAT_8000_0001_ECX] &= ~minus_features[FEAT_8000_0001_ECX];
1762 0514ef2f Eduardo Habkost
    env->features[FEAT_C000_0001_EDX] &= ~minus_features[FEAT_C000_0001_EDX];
1763 0514ef2f Eduardo Habkost
    env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
1764 0514ef2f Eduardo Habkost
    env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
1765 0514ef2f Eduardo Habkost
    env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
1766 c6dc6f63 Andre Przywara
1767 a91987c2 Igor Mammedov
out:
1768 a91987c2 Igor Mammedov
    return;
1769 c6dc6f63 Andre Przywara
}
1770 c6dc6f63 Andre Przywara
1771 c6dc6f63 Andre Przywara
/* generate a composite string into buf of all cpuid names in featureset
1772 c6dc6f63 Andre Przywara
 * selected by fbits.  indicate truncation at bufsize in the event of overflow.
1773 c6dc6f63 Andre Przywara
 * if flags, suppress names undefined in featureset.
1774 c6dc6f63 Andre Przywara
 */
1775 c6dc6f63 Andre Przywara
static void listflags(char *buf, int bufsize, uint32_t fbits,
1776 c6dc6f63 Andre Przywara
    const char **featureset, uint32_t flags)
1777 c6dc6f63 Andre Przywara
{
1778 c6dc6f63 Andre Przywara
    const char **p = &featureset[31];
1779 c6dc6f63 Andre Przywara
    char *q, *b, bit;
1780 c6dc6f63 Andre Przywara
    int nc;
1781 c6dc6f63 Andre Przywara
1782 c6dc6f63 Andre Przywara
    b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1783 c6dc6f63 Andre Przywara
    *buf = '\0';
1784 c6dc6f63 Andre Przywara
    for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1785 c6dc6f63 Andre Przywara
        if (fbits & 1 << bit && (*p || !flags)) {
1786 c6dc6f63 Andre Przywara
            if (*p)
1787 c6dc6f63 Andre Przywara
                nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1788 c6dc6f63 Andre Przywara
            else
1789 c6dc6f63 Andre Przywara
                nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1790 c6dc6f63 Andre Przywara
            if (bufsize <= nc) {
1791 c6dc6f63 Andre Przywara
                if (b) {
1792 c6dc6f63 Andre Przywara
                    memcpy(b, "...", sizeof("..."));
1793 c6dc6f63 Andre Przywara
                }
1794 c6dc6f63 Andre Przywara
                return;
1795 c6dc6f63 Andre Przywara
            }
1796 c6dc6f63 Andre Przywara
            q += nc;
1797 c6dc6f63 Andre Przywara
            bufsize -= nc;
1798 c6dc6f63 Andre Przywara
        }
1799 c6dc6f63 Andre Przywara
}
1800 c6dc6f63 Andre Przywara
1801 e916cbf8 Peter Maydell
/* generate CPU information. */
1802 e916cbf8 Peter Maydell
void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
1803 c6dc6f63 Andre Przywara
{
1804 c6dc6f63 Andre Przywara
    x86_def_t *def;
1805 c6dc6f63 Andre Przywara
    char buf[256];
1806 7fc9b714 Andreas Färber
    int i;
1807 c6dc6f63 Andre Przywara
1808 7fc9b714 Andreas Färber
    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1809 7fc9b714 Andreas Färber
        def = &builtin_x86_defs[i];
1810 c04321b3 Eduardo Habkost
        snprintf(buf, sizeof(buf), "%s", def->name);
1811 6cdf8854 Peter Maydell
        (*cpu_fprintf)(f, "x86 %16s  %-48s\n", buf, def->model_id);
1812 c6dc6f63 Andre Przywara
    }
1813 21ad7789 Jan Kiszka
#ifdef CONFIG_KVM
1814 21ad7789 Jan Kiszka
    (*cpu_fprintf)(f, "x86 %16s  %-48s\n", "host",
1815 21ad7789 Jan Kiszka
                   "KVM processor with all supported host features "
1816 21ad7789 Jan Kiszka
                   "(only available in KVM mode)");
1817 21ad7789 Jan Kiszka
#endif
1818 21ad7789 Jan Kiszka
1819 6cdf8854 Peter Maydell
    (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
1820 3af60be2 Jan Kiszka
    for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
1821 3af60be2 Jan Kiszka
        FeatureWordInfo *fw = &feature_word_info[i];
1822 3af60be2 Jan Kiszka
1823 3af60be2 Jan Kiszka
        listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
1824 3af60be2 Jan Kiszka
        (*cpu_fprintf)(f, "  %s\n", buf);
1825 3af60be2 Jan Kiszka
    }
1826 c6dc6f63 Andre Przywara
}
1827 c6dc6f63 Andre Przywara
1828 76b64a7a Anthony Liguori
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
1829 e3966126 Anthony Liguori
{
1830 e3966126 Anthony Liguori
    CpuDefinitionInfoList *cpu_list = NULL;
1831 e3966126 Anthony Liguori
    x86_def_t *def;
1832 7fc9b714 Andreas Färber
    int i;
1833 e3966126 Anthony Liguori
1834 7fc9b714 Andreas Färber
    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1835 e3966126 Anthony Liguori
        CpuDefinitionInfoList *entry;
1836 e3966126 Anthony Liguori
        CpuDefinitionInfo *info;
1837 e3966126 Anthony Liguori
1838 7fc9b714 Andreas Färber
        def = &builtin_x86_defs[i];
1839 e3966126 Anthony Liguori
        info = g_malloc0(sizeof(*info));
1840 e3966126 Anthony Liguori
        info->name = g_strdup(def->name);
1841 e3966126 Anthony Liguori
1842 e3966126 Anthony Liguori
        entry = g_malloc0(sizeof(*entry));
1843 e3966126 Anthony Liguori
        entry->value = info;
1844 e3966126 Anthony Liguori
        entry->next = cpu_list;
1845 e3966126 Anthony Liguori
        cpu_list = entry;
1846 e3966126 Anthony Liguori
    }
1847 e3966126 Anthony Liguori
1848 e3966126 Anthony Liguori
    return cpu_list;
1849 e3966126 Anthony Liguori
}
1850 e3966126 Anthony Liguori
1851 bc74b7db Eduardo Habkost
#ifdef CONFIG_KVM
1852 bc74b7db Eduardo Habkost
static void filter_features_for_kvm(X86CPU *cpu)
1853 bc74b7db Eduardo Habkost
{
1854 bc74b7db Eduardo Habkost
    CPUX86State *env = &cpu->env;
1855 bc74b7db Eduardo Habkost
    KVMState *s = kvm_state;
1856 bd87d2a2 Eduardo Habkost
    FeatureWord w;
1857 bc74b7db Eduardo Habkost
1858 bd87d2a2 Eduardo Habkost
    for (w = 0; w < FEATURE_WORDS; w++) {
1859 bd87d2a2 Eduardo Habkost
        FeatureWordInfo *wi = &feature_word_info[w];
1860 034acf4a Eduardo Habkost
        uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax,
1861 034acf4a Eduardo Habkost
                                                             wi->cpuid_ecx,
1862 034acf4a Eduardo Habkost
                                                             wi->cpuid_reg);
1863 034acf4a Eduardo Habkost
        uint32_t requested_features = env->features[w];
1864 034acf4a Eduardo Habkost
        env->features[w] &= host_feat;
1865 034acf4a Eduardo Habkost
        cpu->filtered_features[w] = requested_features & ~env->features[w];
1866 bd87d2a2 Eduardo Habkost
    }
1867 bc74b7db Eduardo Habkost
}
1868 bc74b7db Eduardo Habkost
#endif
1869 bc74b7db Eduardo Habkost
1870 2d64255b Andreas Färber
static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
1871 c6dc6f63 Andre Przywara
{
1872 61dcd775 Andreas Färber
    CPUX86State *env = &cpu->env;
1873 c6dc6f63 Andre Przywara
    x86_def_t def1, *def = &def1;
1874 c6dc6f63 Andre Przywara
1875 db0ad1ba Joerg Roedel
    memset(def, 0, sizeof(*def));
1876 db0ad1ba Joerg Roedel
1877 c1399112 Eduardo Habkost
    if (cpu_x86_find_by_name(cpu, def, name) < 0) {
1878 2d64255b Andreas Färber
        error_setg(errp, "Unable to find CPU definition: %s", name);
1879 2d64255b Andreas Färber
        return;
1880 8f961357 Eduardo Habkost
    }
1881 8f961357 Eduardo Habkost
1882 aa87d458 Eduardo Habkost
    if (kvm_enabled()) {
1883 0514ef2f Eduardo Habkost
        def->features[FEAT_KVM] |= kvm_default_features;
1884 aa87d458 Eduardo Habkost
    }
1885 0514ef2f Eduardo Habkost
    def->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
1886 077c68c3 Igor Mammedov
1887 2d64255b Andreas Färber
    object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp);
1888 2d64255b Andreas Färber
    object_property_set_int(OBJECT(cpu), def->level, "level", errp);
1889 2d64255b Andreas Färber
    object_property_set_int(OBJECT(cpu), def->family, "family", errp);
1890 2d64255b Andreas Färber
    object_property_set_int(OBJECT(cpu), def->model, "model", errp);
1891 2d64255b Andreas Färber
    object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
1892 0514ef2f Eduardo Habkost
    env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX];
1893 0514ef2f Eduardo Habkost
    env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX];
1894 0514ef2f Eduardo Habkost
    env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX];
1895 0514ef2f Eduardo Habkost
    env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX];
1896 2d64255b Andreas Färber
    object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
1897 0514ef2f Eduardo Habkost
    env->features[FEAT_KVM] = def->features[FEAT_KVM];
1898 0514ef2f Eduardo Habkost
    env->features[FEAT_SVM] = def->features[FEAT_SVM];
1899 0514ef2f Eduardo Habkost
    env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
1900 0514ef2f Eduardo Habkost
    env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
1901 b3baa152 brillywu@viatech.com.cn
    env->cpuid_xlevel2 = def->xlevel2;
1902 787aaf57 Benoît Canet
    cpu->cache_info_passthrough = def->cache_info_passthrough;
1903 3b671a40 Eduardo Habkost
1904 2d64255b Andreas Färber
    object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
1905 c6dc6f63 Andre Przywara
}
1906 c6dc6f63 Andre Przywara
1907 62fc403f Igor Mammedov
X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
1908 62fc403f Igor Mammedov
                       Error **errp)
1909 5c3c6a68 Andreas Färber
{
1910 2d64255b Andreas Färber
    X86CPU *cpu = NULL;
1911 2d64255b Andreas Färber
    gchar **model_pieces;
1912 2d64255b Andreas Färber
    char *name, *features;
1913 ba2bc7a4 Andreas Färber
    char *typename;
1914 5c3c6a68 Andreas Färber
    Error *error = NULL;
1915 5c3c6a68 Andreas Färber
1916 2d64255b Andreas Färber
    model_pieces = g_strsplit(cpu_model, ",", 2);
1917 2d64255b Andreas Färber
    if (!model_pieces[0]) {
1918 2d64255b Andreas Färber
        error_setg(&error, "Invalid/empty CPU model name");
1919 2d64255b Andreas Färber
        goto out;
1920 2d64255b Andreas Färber
    }
1921 2d64255b Andreas Färber
    name = model_pieces[0];
1922 2d64255b Andreas Färber
    features = model_pieces[1];
1923 2d64255b Andreas Färber
1924 5c3c6a68 Andreas Färber
    cpu = X86_CPU(object_new(TYPE_X86_CPU));
1925 62fc403f Igor Mammedov
#ifndef CONFIG_USER_ONLY
1926 62fc403f Igor Mammedov
    if (icc_bridge == NULL) {
1927 62fc403f Igor Mammedov
        error_setg(&error, "Invalid icc-bridge value");
1928 62fc403f Igor Mammedov
        goto out;
1929 62fc403f Igor Mammedov
    }
1930 62fc403f Igor Mammedov
    qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
1931 62fc403f Igor Mammedov
    object_unref(OBJECT(cpu));
1932 62fc403f Igor Mammedov
#endif
1933 5c3c6a68 Andreas Färber
1934 2d64255b Andreas Färber
    cpu_x86_register(cpu, name, &error);
1935 2d64255b Andreas Färber
    if (error) {
1936 2d64255b Andreas Färber
        goto out;
1937 2d64255b Andreas Färber
    }
1938 2d64255b Andreas Färber
1939 ba2bc7a4 Andreas Färber
    /* Emulate per-model subclasses for global properties */
1940 ba2bc7a4 Andreas Färber
    typename = g_strdup_printf("%s-" TYPE_X86_CPU, name);
1941 ba2bc7a4 Andreas Färber
    qdev_prop_set_globals_for_type(DEVICE(cpu), typename, &error);
1942 ba2bc7a4 Andreas Färber
    g_free(typename);
1943 ba2bc7a4 Andreas Färber
    if (error) {
1944 ba2bc7a4 Andreas Färber
        goto out;
1945 ba2bc7a4 Andreas Färber
    }
1946 ba2bc7a4 Andreas Färber
1947 2d64255b Andreas Färber
    cpu_x86_parse_featurestr(cpu, features, &error);
1948 2d64255b Andreas Färber
    if (error) {
1949 2d64255b Andreas Färber
        goto out;
1950 5c3c6a68 Andreas Färber
    }
1951 5c3c6a68 Andreas Färber
1952 7f833247 Igor Mammedov
out:
1953 cd7b87ff Andreas Färber
    if (error != NULL) {
1954 cd7b87ff Andreas Färber
        error_propagate(errp, error);
1955 cd7b87ff Andreas Färber
        object_unref(OBJECT(cpu));
1956 cd7b87ff Andreas Färber
        cpu = NULL;
1957 cd7b87ff Andreas Färber
    }
1958 7f833247 Igor Mammedov
    g_strfreev(model_pieces);
1959 7f833247 Igor Mammedov
    return cpu;
1960 7f833247 Igor Mammedov
}
1961 7f833247 Igor Mammedov
1962 7f833247 Igor Mammedov
X86CPU *cpu_x86_init(const char *cpu_model)
1963 7f833247 Igor Mammedov
{
1964 7f833247 Igor Mammedov
    Error *error = NULL;
1965 7f833247 Igor Mammedov
    X86CPU *cpu;
1966 7f833247 Igor Mammedov
1967 62fc403f Igor Mammedov
    cpu = cpu_x86_create(cpu_model, NULL, &error);
1968 5c3c6a68 Andreas Färber
    if (error) {
1969 2d64255b Andreas Färber
        goto out;
1970 2d64255b Andreas Färber
    }
1971 2d64255b Andreas Färber
1972 7f833247 Igor Mammedov
    object_property_set_bool(OBJECT(cpu), true, "realized", &error);
1973 7f833247 Igor Mammedov
1974 2d64255b Andreas Färber
out:
1975 2d64255b Andreas Färber
    if (error) {
1976 4a44d85e Seiji Aguchi
        error_report("%s", error_get_pretty(error));
1977 5c3c6a68 Andreas Färber
        error_free(error);
1978 2d64255b Andreas Färber
        if (cpu != NULL) {
1979 2d64255b Andreas Färber
            object_unref(OBJECT(cpu));
1980 2d64255b Andreas Färber
            cpu = NULL;
1981 2d64255b Andreas Färber
        }
1982 5c3c6a68 Andreas Färber
    }
1983 5c3c6a68 Andreas Färber
    return cpu;
1984 5c3c6a68 Andreas Färber
}
1985 5c3c6a68 Andreas Färber
1986 c6dc6f63 Andre Przywara
#if !defined(CONFIG_USER_ONLY)
1987 c6dc6f63 Andre Przywara
1988 0e26b7b8 Blue Swirl
void cpu_clear_apic_feature(CPUX86State *env)
1989 0e26b7b8 Blue Swirl
{
1990 0514ef2f Eduardo Habkost
    env->features[FEAT_1_EDX] &= ~CPUID_APIC;
1991 0e26b7b8 Blue Swirl
}
1992 0e26b7b8 Blue Swirl
1993 c6dc6f63 Andre Przywara
#endif /* !CONFIG_USER_ONLY */
1994 c6dc6f63 Andre Przywara
1995 c04321b3 Eduardo Habkost
/* Initialize list of CPU models, filling some non-static fields if necessary
1996 c6dc6f63 Andre Przywara
 */
1997 c6dc6f63 Andre Przywara
void x86_cpudef_setup(void)
1998 c6dc6f63 Andre Przywara
{
1999 93bfef4c Crístian Viana
    int i, j;
2000 93bfef4c Crístian Viana
    static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
2001 c6dc6f63 Andre Przywara
2002 c6dc6f63 Andre Przywara
    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
2003 bc3e1291 Eduardo Habkost
        x86_def_t *def = &builtin_x86_defs[i];
2004 93bfef4c Crístian Viana
2005 93bfef4c Crístian Viana
        /* Look for specific "cpudef" models that */
2006 09faecf2 Stefan Weil
        /* have the QEMU version in .model_id */
2007 93bfef4c Crístian Viana
        for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
2008 bc3e1291 Eduardo Habkost
            if (strcmp(model_with_versions[j], def->name) == 0) {
2009 bc3e1291 Eduardo Habkost
                pstrcpy(def->model_id, sizeof(def->model_id),
2010 bc3e1291 Eduardo Habkost
                        "QEMU Virtual CPU version ");
2011 bc3e1291 Eduardo Habkost
                pstrcat(def->model_id, sizeof(def->model_id),
2012 bc3e1291 Eduardo Habkost
                        qemu_get_version());
2013 93bfef4c Crístian Viana
                break;
2014 93bfef4c Crístian Viana
            }
2015 93bfef4c Crístian Viana
        }
2016 c6dc6f63 Andre Przywara
    }
2017 c6dc6f63 Andre Przywara
}
2018 c6dc6f63 Andre Przywara
2019 c6dc6f63 Andre Przywara
static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
2020 c6dc6f63 Andre Przywara
                             uint32_t *ecx, uint32_t *edx)
2021 c6dc6f63 Andre Przywara
{
2022 c6dc6f63 Andre Przywara
    *ebx = env->cpuid_vendor1;
2023 c6dc6f63 Andre Przywara
    *edx = env->cpuid_vendor2;
2024 c6dc6f63 Andre Przywara
    *ecx = env->cpuid_vendor3;
2025 c6dc6f63 Andre Przywara
}
2026 c6dc6f63 Andre Przywara
2027 c6dc6f63 Andre Przywara
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
2028 c6dc6f63 Andre Przywara
                   uint32_t *eax, uint32_t *ebx,
2029 c6dc6f63 Andre Przywara
                   uint32_t *ecx, uint32_t *edx)
2030 c6dc6f63 Andre Przywara
{
2031 a60f24b5 Andreas Färber
    X86CPU *cpu = x86_env_get_cpu(env);
2032 a60f24b5 Andreas Färber
    CPUState *cs = CPU(cpu);
2033 a60f24b5 Andreas Färber
2034 c6dc6f63 Andre Przywara
    /* test if maximum index reached */
2035 c6dc6f63 Andre Przywara
    if (index & 0x80000000) {
2036 b3baa152 brillywu@viatech.com.cn
        if (index > env->cpuid_xlevel) {
2037 b3baa152 brillywu@viatech.com.cn
            if (env->cpuid_xlevel2 > 0) {
2038 b3baa152 brillywu@viatech.com.cn
                /* Handle the Centaur's CPUID instruction. */
2039 b3baa152 brillywu@viatech.com.cn
                if (index > env->cpuid_xlevel2) {
2040 b3baa152 brillywu@viatech.com.cn
                    index = env->cpuid_xlevel2;
2041 b3baa152 brillywu@viatech.com.cn
                } else if (index < 0xC0000000) {
2042 b3baa152 brillywu@viatech.com.cn
                    index = env->cpuid_xlevel;
2043 b3baa152 brillywu@viatech.com.cn
                }
2044 b3baa152 brillywu@viatech.com.cn
            } else {
2045 57f26ae7 Eduardo Habkost
                /* Intel documentation states that invalid EAX input will
2046 57f26ae7 Eduardo Habkost
                 * return the same information as EAX=cpuid_level
2047 57f26ae7 Eduardo Habkost
                 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
2048 57f26ae7 Eduardo Habkost
                 */
2049 57f26ae7 Eduardo Habkost
                index =  env->cpuid_level;
2050 b3baa152 brillywu@viatech.com.cn
            }
2051 b3baa152 brillywu@viatech.com.cn
        }
2052 c6dc6f63 Andre Przywara
    } else {
2053 c6dc6f63 Andre Przywara
        if (index > env->cpuid_level)
2054 c6dc6f63 Andre Przywara
            index = env->cpuid_level;
2055 c6dc6f63 Andre Przywara
    }
2056 c6dc6f63 Andre Przywara
2057 c6dc6f63 Andre Przywara
    switch(index) {
2058 c6dc6f63 Andre Przywara
    case 0:
2059 c6dc6f63 Andre Przywara
        *eax = env->cpuid_level;
2060 c6dc6f63 Andre Przywara
        get_cpuid_vendor(env, ebx, ecx, edx);
2061 c6dc6f63 Andre Przywara
        break;
2062 c6dc6f63 Andre Przywara
    case 1:
2063 c6dc6f63 Andre Przywara
        *eax = env->cpuid_version;
2064 c6dc6f63 Andre Przywara
        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
2065 0514ef2f Eduardo Habkost
        *ecx = env->features[FEAT_1_ECX];
2066 0514ef2f Eduardo Habkost
        *edx = env->features[FEAT_1_EDX];
2067 ce3960eb Andreas Färber
        if (cs->nr_cores * cs->nr_threads > 1) {
2068 ce3960eb Andreas Färber
            *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
2069 c6dc6f63 Andre Przywara
            *edx |= 1 << 28;    /* HTT bit */
2070 c6dc6f63 Andre Przywara
        }
2071 c6dc6f63 Andre Przywara
        break;
2072 c6dc6f63 Andre Przywara
    case 2:
2073 c6dc6f63 Andre Przywara
        /* cache info: needed for Pentium Pro compatibility */
2074 787aaf57 Benoît Canet
        if (cpu->cache_info_passthrough) {
2075 787aaf57 Benoît Canet
            host_cpuid(index, 0, eax, ebx, ecx, edx);
2076 787aaf57 Benoît Canet
            break;
2077 787aaf57 Benoît Canet
        }
2078 5e891bf8 Eduardo Habkost
        *eax = 1; /* Number of CPUID[EAX=2] calls required */
2079 c6dc6f63 Andre Przywara
        *ebx = 0;
2080 c6dc6f63 Andre Przywara
        *ecx = 0;
2081 5e891bf8 Eduardo Habkost
        *edx = (L1D_DESCRIPTOR << 16) | \
2082 5e891bf8 Eduardo Habkost
               (L1I_DESCRIPTOR <<  8) | \
2083 5e891bf8 Eduardo Habkost
               (L2_DESCRIPTOR);
2084 c6dc6f63 Andre Przywara
        break;
2085 c6dc6f63 Andre Przywara
    case 4:
2086 c6dc6f63 Andre Przywara
        /* cache info: needed for Core compatibility */
2087 787aaf57 Benoît Canet
        if (cpu->cache_info_passthrough) {
2088 787aaf57 Benoît Canet
            host_cpuid(index, count, eax, ebx, ecx, edx);
2089 76c2975a Paolo Bonzini
            *eax &= ~0xFC000000;
2090 c6dc6f63 Andre Przywara
        } else {
2091 2f7a21c4 Aurelien Jarno
            *eax = 0;
2092 76c2975a Paolo Bonzini
            switch (count) {
2093 c6dc6f63 Andre Przywara
            case 0: /* L1 dcache info */
2094 5e891bf8 Eduardo Habkost
                *eax |= CPUID_4_TYPE_DCACHE | \
2095 5e891bf8 Eduardo Habkost
                        CPUID_4_LEVEL(1) | \
2096 5e891bf8 Eduardo Habkost
                        CPUID_4_SELF_INIT_LEVEL;
2097 5e891bf8 Eduardo Habkost
                *ebx = (L1D_LINE_SIZE - 1) | \
2098 5e891bf8 Eduardo Habkost
                       ((L1D_PARTITIONS - 1) << 12) | \
2099 5e891bf8 Eduardo Habkost
                       ((L1D_ASSOCIATIVITY - 1) << 22);
2100 5e891bf8 Eduardo Habkost
                *ecx = L1D_SETS - 1;
2101 5e891bf8 Eduardo Habkost
                *edx = CPUID_4_NO_INVD_SHARING;
2102 c6dc6f63 Andre Przywara
                break;
2103 c6dc6f63 Andre Przywara
            case 1: /* L1 icache info */
2104 5e891bf8 Eduardo Habkost
                *eax |= CPUID_4_TYPE_ICACHE | \
2105 5e891bf8 Eduardo Habkost
                        CPUID_4_LEVEL(1) | \
2106 5e891bf8 Eduardo Habkost
                        CPUID_4_SELF_INIT_LEVEL;
2107 5e891bf8 Eduardo Habkost
                *ebx = (L1I_LINE_SIZE - 1) | \
2108 5e891bf8 Eduardo Habkost
                       ((L1I_PARTITIONS - 1) << 12) | \
2109 5e891bf8 Eduardo Habkost
                       ((L1I_ASSOCIATIVITY - 1) << 22);
2110 5e891bf8 Eduardo Habkost
                *ecx = L1I_SETS - 1;
2111 5e891bf8 Eduardo Habkost
                *edx = CPUID_4_NO_INVD_SHARING;
2112 c6dc6f63 Andre Przywara
                break;
2113 c6dc6f63 Andre Przywara
            case 2: /* L2 cache info */
2114 5e891bf8 Eduardo Habkost
                *eax |= CPUID_4_TYPE_UNIFIED | \
2115 5e891bf8 Eduardo Habkost
                        CPUID_4_LEVEL(2) | \
2116 5e891bf8 Eduardo Habkost
                        CPUID_4_SELF_INIT_LEVEL;
2117 ce3960eb Andreas Färber
                if (cs->nr_threads > 1) {
2118 ce3960eb Andreas Färber
                    *eax |= (cs->nr_threads - 1) << 14;
2119 c6dc6f63 Andre Przywara
                }
2120 5e891bf8 Eduardo Habkost
                *ebx = (L2_LINE_SIZE - 1) | \
2121 5e891bf8 Eduardo Habkost
                       ((L2_PARTITIONS - 1) << 12) | \
2122 5e891bf8 Eduardo Habkost
                       ((L2_ASSOCIATIVITY - 1) << 22);
2123 5e891bf8 Eduardo Habkost
                *ecx = L2_SETS - 1;
2124 5e891bf8 Eduardo Habkost
                *edx = CPUID_4_NO_INVD_SHARING;
2125 c6dc6f63 Andre Przywara
                break;
2126 c6dc6f63 Andre Przywara
            default: /* end of info */
2127 c6dc6f63 Andre Przywara
                *eax = 0;
2128 c6dc6f63 Andre Przywara
                *ebx = 0;
2129 c6dc6f63 Andre Przywara
                *ecx = 0;
2130 c6dc6f63 Andre Przywara
                *edx = 0;
2131 c6dc6f63 Andre Przywara
                break;
2132 76c2975a Paolo Bonzini
            }
2133 76c2975a Paolo Bonzini
        }
2134 76c2975a Paolo Bonzini
2135 76c2975a Paolo Bonzini
        /* QEMU gives out its own APIC IDs, never pass down bits 31..26.  */
2136 76c2975a Paolo Bonzini
        if ((*eax & 31) && cs->nr_cores > 1) {
2137 76c2975a Paolo Bonzini
            *eax |= (cs->nr_cores - 1) << 26;
2138 c6dc6f63 Andre Przywara
        }
2139 c6dc6f63 Andre Przywara
        break;
2140 c6dc6f63 Andre Przywara
    case 5:
2141 c6dc6f63 Andre Przywara
        /* mwait info: needed for Core compatibility */
2142 c6dc6f63 Andre Przywara
        *eax = 0; /* Smallest monitor-line size in bytes */
2143 c6dc6f63 Andre Przywara
        *ebx = 0; /* Largest monitor-line size in bytes */
2144 c6dc6f63 Andre Przywara
        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
2145 c6dc6f63 Andre Przywara
        *edx = 0;
2146 c6dc6f63 Andre Przywara
        break;
2147 c6dc6f63 Andre Przywara
    case 6:
2148 c6dc6f63 Andre Przywara
        /* Thermal and Power Leaf */
2149 c6dc6f63 Andre Przywara
        *eax = 0;
2150 c6dc6f63 Andre Przywara
        *ebx = 0;
2151 c6dc6f63 Andre Przywara
        *ecx = 0;
2152 c6dc6f63 Andre Przywara
        *edx = 0;
2153 c6dc6f63 Andre Przywara
        break;
2154 f7911686 Yang, Wei Y
    case 7:
2155 13526728 Eduardo Habkost
        /* Structured Extended Feature Flags Enumeration Leaf */
2156 13526728 Eduardo Habkost
        if (count == 0) {
2157 13526728 Eduardo Habkost
            *eax = 0; /* Maximum ECX value for sub-leaves */
2158 0514ef2f Eduardo Habkost
            *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
2159 13526728 Eduardo Habkost
            *ecx = 0; /* Reserved */
2160 13526728 Eduardo Habkost
            *edx = 0; /* Reserved */
2161 f7911686 Yang, Wei Y
        } else {
2162 f7911686 Yang, Wei Y
            *eax = 0;
2163 f7911686 Yang, Wei Y
            *ebx = 0;
2164 f7911686 Yang, Wei Y
            *ecx = 0;
2165 f7911686 Yang, Wei Y
            *edx = 0;
2166 f7911686 Yang, Wei Y
        }
2167 f7911686 Yang, Wei Y
        break;
2168 c6dc6f63 Andre Przywara
    case 9:
2169 c6dc6f63 Andre Przywara
        /* Direct Cache Access Information Leaf */
2170 c6dc6f63 Andre Przywara
        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2171 c6dc6f63 Andre Przywara
        *ebx = 0;
2172 c6dc6f63 Andre Przywara
        *ecx = 0;
2173 c6dc6f63 Andre Przywara
        *edx = 0;
2174 c6dc6f63 Andre Przywara
        break;
2175 c6dc6f63 Andre Przywara
    case 0xA:
2176 c6dc6f63 Andre Przywara
        /* Architectural Performance Monitoring Leaf */
2177 9337e3b6 Eduardo Habkost
        if (kvm_enabled() && cpu->enable_pmu) {
2178 a60f24b5 Andreas Färber
            KVMState *s = cs->kvm_state;
2179 a0fa8208 Gleb Natapov
2180 a0fa8208 Gleb Natapov
            *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
2181 a0fa8208 Gleb Natapov
            *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
2182 a0fa8208 Gleb Natapov
            *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
2183 a0fa8208 Gleb Natapov
            *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
2184 a0fa8208 Gleb Natapov
        } else {
2185 a0fa8208 Gleb Natapov
            *eax = 0;
2186 a0fa8208 Gleb Natapov
            *ebx = 0;
2187 a0fa8208 Gleb Natapov
            *ecx = 0;
2188 a0fa8208 Gleb Natapov
            *edx = 0;
2189 a0fa8208 Gleb Natapov
        }
2190 c6dc6f63 Andre Przywara
        break;
2191 2560f19f Paolo Bonzini
    case 0xD: {
2192 2560f19f Paolo Bonzini
        KVMState *s = cs->kvm_state;
2193 2560f19f Paolo Bonzini
        uint64_t kvm_mask;
2194 2560f19f Paolo Bonzini
        int i;
2195 2560f19f Paolo Bonzini
2196 51e49430 Sheng Yang
        /* Processor Extended State */
2197 2560f19f Paolo Bonzini
        *eax = 0;
2198 2560f19f Paolo Bonzini
        *ebx = 0;
2199 2560f19f Paolo Bonzini
        *ecx = 0;
2200 2560f19f Paolo Bonzini
        *edx = 0;
2201 2560f19f Paolo Bonzini
        if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) || !kvm_enabled()) {
2202 51e49430 Sheng Yang
            break;
2203 51e49430 Sheng Yang
        }
2204 2560f19f Paolo Bonzini
        kvm_mask =
2205 2560f19f Paolo Bonzini
            kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX) |
2206 2560f19f Paolo Bonzini
            ((uint64_t)kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX) << 32);
2207 ba9bc59e Jan Kiszka
2208 2560f19f Paolo Bonzini
        if (count == 0) {
2209 2560f19f Paolo Bonzini
            *ecx = 0x240;
2210 2560f19f Paolo Bonzini
            for (i = 2; i < ARRAY_SIZE(ext_save_areas); i++) {
2211 2560f19f Paolo Bonzini
                const ExtSaveArea *esa = &ext_save_areas[i];
2212 2560f19f Paolo Bonzini
                if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2213 2560f19f Paolo Bonzini
                    (kvm_mask & (1 << i)) != 0) {
2214 2560f19f Paolo Bonzini
                    if (i < 32) {
2215 2560f19f Paolo Bonzini
                        *eax |= 1 << i;
2216 2560f19f Paolo Bonzini
                    } else {
2217 2560f19f Paolo Bonzini
                        *edx |= 1 << (i - 32);
2218 2560f19f Paolo Bonzini
                    }
2219 2560f19f Paolo Bonzini
                    *ecx = MAX(*ecx, esa->offset + esa->size);
2220 2560f19f Paolo Bonzini
                }
2221 2560f19f Paolo Bonzini
            }
2222 2560f19f Paolo Bonzini
            *eax |= kvm_mask & (XSTATE_FP | XSTATE_SSE);
2223 2560f19f Paolo Bonzini
            *ebx = *ecx;
2224 2560f19f Paolo Bonzini
        } else if (count == 1) {
2225 2560f19f Paolo Bonzini
            *eax = kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
2226 2560f19f Paolo Bonzini
        } else if (count < ARRAY_SIZE(ext_save_areas)) {
2227 2560f19f Paolo Bonzini
            const ExtSaveArea *esa = &ext_save_areas[count];
2228 2560f19f Paolo Bonzini
            if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2229 2560f19f Paolo Bonzini
                (kvm_mask & (1 << count)) != 0) {
2230 33f373d7 Liu Jinsong
                *eax = esa->size;
2231 33f373d7 Liu Jinsong
                *ebx = esa->offset;
2232 2560f19f Paolo Bonzini
            }
2233 51e49430 Sheng Yang
        }
2234 51e49430 Sheng Yang
        break;
2235 2560f19f Paolo Bonzini
    }
2236 c6dc6f63 Andre Przywara
    case 0x80000000:
2237 c6dc6f63 Andre Przywara
        *eax = env->cpuid_xlevel;
2238 c6dc6f63 Andre Przywara
        *ebx = env->cpuid_vendor1;
2239 c6dc6f63 Andre Przywara
        *edx = env->cpuid_vendor2;
2240 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_vendor3;
2241 c6dc6f63 Andre Przywara
        break;
2242 c6dc6f63 Andre Przywara
    case 0x80000001:
2243 c6dc6f63 Andre Przywara
        *eax = env->cpuid_version;
2244 c6dc6f63 Andre Przywara
        *ebx = 0;
2245 0514ef2f Eduardo Habkost
        *ecx = env->features[FEAT_8000_0001_ECX];
2246 0514ef2f Eduardo Habkost
        *edx = env->features[FEAT_8000_0001_EDX];
2247 c6dc6f63 Andre Przywara
2248 c6dc6f63 Andre Przywara
        /* The Linux kernel checks for the CMPLegacy bit and
2249 c6dc6f63 Andre Przywara
         * discards multiple thread information if it is set.
2250 c6dc6f63 Andre Przywara
         * So dont set it here for Intel to make Linux guests happy.
2251 c6dc6f63 Andre Przywara
         */
2252 ce3960eb Andreas Färber
        if (cs->nr_cores * cs->nr_threads > 1) {
2253 c6dc6f63 Andre Przywara
            uint32_t tebx, tecx, tedx;
2254 c6dc6f63 Andre Przywara
            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
2255 c6dc6f63 Andre Przywara
            if (tebx != CPUID_VENDOR_INTEL_1 ||
2256 c6dc6f63 Andre Przywara
                tedx != CPUID_VENDOR_INTEL_2 ||
2257 c6dc6f63 Andre Przywara
                tecx != CPUID_VENDOR_INTEL_3) {
2258 c6dc6f63 Andre Przywara
                *ecx |= 1 << 1;    /* CmpLegacy bit */
2259 c6dc6f63 Andre Przywara
            }
2260 c6dc6f63 Andre Przywara
        }
2261 c6dc6f63 Andre Przywara
        break;
2262 c6dc6f63 Andre Przywara
    case 0x80000002:
2263 c6dc6f63 Andre Przywara
    case 0x80000003:
2264 c6dc6f63 Andre Przywara
    case 0x80000004:
2265 c6dc6f63 Andre Przywara
        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2266 c6dc6f63 Andre Przywara
        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2267 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2268 c6dc6f63 Andre Przywara
        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2269 c6dc6f63 Andre Przywara
        break;
2270 c6dc6f63 Andre Przywara
    case 0x80000005:
2271 c6dc6f63 Andre Przywara
        /* cache info (L1 cache) */
2272 787aaf57 Benoît Canet
        if (cpu->cache_info_passthrough) {
2273 787aaf57 Benoît Canet
            host_cpuid(index, 0, eax, ebx, ecx, edx);
2274 787aaf57 Benoît Canet
            break;
2275 787aaf57 Benoît Canet
        }
2276 5e891bf8 Eduardo Habkost
        *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \
2277 5e891bf8 Eduardo Habkost
               (L1_ITLB_2M_ASSOC <<  8) | (L1_ITLB_2M_ENTRIES);
2278 5e891bf8 Eduardo Habkost
        *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
2279 5e891bf8 Eduardo Habkost
               (L1_ITLB_4K_ASSOC <<  8) | (L1_ITLB_4K_ENTRIES);
2280 5e891bf8 Eduardo Habkost
        *ecx = (L1D_SIZE_KB_AMD << 24) | (L1D_ASSOCIATIVITY_AMD << 16) | \
2281 5e891bf8 Eduardo Habkost
               (L1D_LINES_PER_TAG << 8) | (L1D_LINE_SIZE);
2282 5e891bf8 Eduardo Habkost
        *edx = (L1I_SIZE_KB_AMD << 24) | (L1I_ASSOCIATIVITY_AMD << 16) | \
2283 5e891bf8 Eduardo Habkost
               (L1I_LINES_PER_TAG << 8) | (L1I_LINE_SIZE);
2284 c6dc6f63 Andre Przywara
        break;
2285 c6dc6f63 Andre Przywara
    case 0x80000006:
2286 c6dc6f63 Andre Przywara
        /* cache info (L2 cache) */
2287 787aaf57 Benoît Canet
        if (cpu->cache_info_passthrough) {
2288 787aaf57 Benoît Canet
            host_cpuid(index, 0, eax, ebx, ecx, edx);
2289 787aaf57 Benoît Canet
            break;
2290 787aaf57 Benoît Canet
        }
2291 5e891bf8 Eduardo Habkost
        *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \
2292 5e891bf8 Eduardo Habkost
               (L2_DTLB_2M_ENTRIES << 16) | \
2293 5e891bf8 Eduardo Habkost
               (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \
2294 5e891bf8 Eduardo Habkost
               (L2_ITLB_2M_ENTRIES);
2295 5e891bf8 Eduardo Habkost
        *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) | \
2296 5e891bf8 Eduardo Habkost
               (L2_DTLB_4K_ENTRIES << 16) | \
2297 5e891bf8 Eduardo Habkost
               (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
2298 5e891bf8 Eduardo Habkost
               (L2_ITLB_4K_ENTRIES);
2299 5e891bf8 Eduardo Habkost
        *ecx = (L2_SIZE_KB_AMD << 16) | \
2300 5e891bf8 Eduardo Habkost
               (AMD_ENC_ASSOC(L2_ASSOCIATIVITY) << 12) | \
2301 5e891bf8 Eduardo Habkost
               (L2_LINES_PER_TAG << 8) | (L2_LINE_SIZE);
2302 5e891bf8 Eduardo Habkost
        *edx = ((L3_SIZE_KB/512) << 18) | \
2303 5e891bf8 Eduardo Habkost
               (AMD_ENC_ASSOC(L3_ASSOCIATIVITY) << 12) | \
2304 5e891bf8 Eduardo Habkost
               (L3_LINES_PER_TAG << 8) | (L3_LINE_SIZE);
2305 c6dc6f63 Andre Przywara
        break;
2306 c6dc6f63 Andre Przywara
    case 0x80000008:
2307 c6dc6f63 Andre Przywara
        /* virtual & phys address size in low 2 bytes. */
2308 c6dc6f63 Andre Przywara
/* XXX: This value must match the one used in the MMU code. */
2309 0514ef2f Eduardo Habkost
        if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
2310 c6dc6f63 Andre Przywara
            /* 64 bit processor */
2311 c6dc6f63 Andre Przywara
/* XXX: The physical address space is limited to 42 bits in exec.c. */
2312 dd13e088 Eduardo Habkost
            *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
2313 c6dc6f63 Andre Przywara
        } else {
2314 0514ef2f Eduardo Habkost
            if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
2315 c6dc6f63 Andre Przywara
                *eax = 0x00000024; /* 36 bits physical */
2316 dd13e088 Eduardo Habkost
            } else {
2317 c6dc6f63 Andre Przywara
                *eax = 0x00000020; /* 32 bits physical */
2318 dd13e088 Eduardo Habkost
            }
2319 c6dc6f63 Andre Przywara
        }
2320 c6dc6f63 Andre Przywara
        *ebx = 0;
2321 c6dc6f63 Andre Przywara
        *ecx = 0;
2322 c6dc6f63 Andre Przywara
        *edx = 0;
2323 ce3960eb Andreas Färber
        if (cs->nr_cores * cs->nr_threads > 1) {
2324 ce3960eb Andreas Färber
            *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
2325 c6dc6f63 Andre Przywara
        }
2326 c6dc6f63 Andre Przywara
        break;
2327 c6dc6f63 Andre Przywara
    case 0x8000000A:
2328 0514ef2f Eduardo Habkost
        if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
2329 9f3fb565 Eduardo Habkost
            *eax = 0x00000001; /* SVM Revision */
2330 9f3fb565 Eduardo Habkost
            *ebx = 0x00000010; /* nr of ASIDs */
2331 9f3fb565 Eduardo Habkost
            *ecx = 0;
2332 0514ef2f Eduardo Habkost
            *edx = env->features[FEAT_SVM]; /* optional features */
2333 9f3fb565 Eduardo Habkost
        } else {
2334 9f3fb565 Eduardo Habkost
            *eax = 0;
2335 9f3fb565 Eduardo Habkost
            *ebx = 0;
2336 9f3fb565 Eduardo Habkost
            *ecx = 0;
2337 9f3fb565 Eduardo Habkost
            *edx = 0;
2338 9f3fb565 Eduardo Habkost
        }
2339 c6dc6f63 Andre Przywara
        break;
2340 b3baa152 brillywu@viatech.com.cn
    case 0xC0000000:
2341 b3baa152 brillywu@viatech.com.cn
        *eax = env->cpuid_xlevel2;
2342 b3baa152 brillywu@viatech.com.cn
        *ebx = 0;
2343 b3baa152 brillywu@viatech.com.cn
        *ecx = 0;
2344 b3baa152 brillywu@viatech.com.cn
        *edx = 0;
2345 b3baa152 brillywu@viatech.com.cn
        break;
2346 b3baa152 brillywu@viatech.com.cn
    case 0xC0000001:
2347 b3baa152 brillywu@viatech.com.cn
        /* Support for VIA CPU's CPUID instruction */
2348 b3baa152 brillywu@viatech.com.cn
        *eax = env->cpuid_version;
2349 b3baa152 brillywu@viatech.com.cn
        *ebx = 0;
2350 b3baa152 brillywu@viatech.com.cn
        *ecx = 0;
2351 0514ef2f Eduardo Habkost
        *edx = env->features[FEAT_C000_0001_EDX];
2352 b3baa152 brillywu@viatech.com.cn
        break;
2353 b3baa152 brillywu@viatech.com.cn
    case 0xC0000002:
2354 b3baa152 brillywu@viatech.com.cn
    case 0xC0000003:
2355 b3baa152 brillywu@viatech.com.cn
    case 0xC0000004:
2356 b3baa152 brillywu@viatech.com.cn
        /* Reserved for the future, and now filled with zero */
2357 b3baa152 brillywu@viatech.com.cn
        *eax = 0;
2358 b3baa152 brillywu@viatech.com.cn
        *ebx = 0;
2359 b3baa152 brillywu@viatech.com.cn
        *ecx = 0;
2360 b3baa152 brillywu@viatech.com.cn
        *edx = 0;
2361 b3baa152 brillywu@viatech.com.cn
        break;
2362 c6dc6f63 Andre Przywara
    default:
2363 c6dc6f63 Andre Przywara
        /* reserved values: zero */
2364 c6dc6f63 Andre Przywara
        *eax = 0;
2365 c6dc6f63 Andre Przywara
        *ebx = 0;
2366 c6dc6f63 Andre Przywara
        *ecx = 0;
2367 c6dc6f63 Andre Przywara
        *edx = 0;
2368 c6dc6f63 Andre Przywara
        break;
2369 c6dc6f63 Andre Przywara
    }
2370 c6dc6f63 Andre Przywara
}
2371 5fd2087a Andreas Färber
2372 5fd2087a Andreas Färber
/* CPUClass::reset() */
2373 5fd2087a Andreas Färber
static void x86_cpu_reset(CPUState *s)
2374 5fd2087a Andreas Färber
{
2375 5fd2087a Andreas Färber
    X86CPU *cpu = X86_CPU(s);
2376 5fd2087a Andreas Färber
    X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2377 5fd2087a Andreas Färber
    CPUX86State *env = &cpu->env;
2378 c1958aea Andreas Färber
    int i;
2379 c1958aea Andreas Färber
2380 5fd2087a Andreas Färber
    xcc->parent_reset(s);
2381 5fd2087a Andreas Färber
2382 c1958aea Andreas Färber
2383 c1958aea Andreas Färber
    memset(env, 0, offsetof(CPUX86State, breakpoints));
2384 c1958aea Andreas Färber
2385 c1958aea Andreas Färber
    tlb_flush(env, 1);
2386 c1958aea Andreas Färber
2387 c1958aea Andreas Färber
    env->old_exception = -1;
2388 c1958aea Andreas Färber
2389 c1958aea Andreas Färber
    /* init to reset state */
2390 c1958aea Andreas Färber
2391 c1958aea Andreas Färber
#ifdef CONFIG_SOFTMMU
2392 c1958aea Andreas Färber
    env->hflags |= HF_SOFTMMU_MASK;
2393 c1958aea Andreas Färber
#endif
2394 c1958aea Andreas Färber
    env->hflags2 |= HF2_GIF_MASK;
2395 c1958aea Andreas Färber
2396 c1958aea Andreas Färber
    cpu_x86_update_cr0(env, 0x60000010);
2397 c1958aea Andreas Färber
    env->a20_mask = ~0x0;
2398 c1958aea Andreas Färber
    env->smbase = 0x30000;
2399 c1958aea Andreas Färber
2400 c1958aea Andreas Färber
    env->idt.limit = 0xffff;
2401 c1958aea Andreas Färber
    env->gdt.limit = 0xffff;
2402 c1958aea Andreas Färber
    env->ldt.limit = 0xffff;
2403 c1958aea Andreas Färber
    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2404 c1958aea Andreas Färber
    env->tr.limit = 0xffff;
2405 c1958aea Andreas Färber
    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2406 c1958aea Andreas Färber
2407 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2408 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2409 c1958aea Andreas Färber
                           DESC_R_MASK | DESC_A_MASK);
2410 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2411 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2412 c1958aea Andreas Färber
                           DESC_A_MASK);
2413 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
2414 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2415 c1958aea Andreas Färber
                           DESC_A_MASK);
2416 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
2417 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2418 c1958aea Andreas Färber
                           DESC_A_MASK);
2419 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
2420 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2421 c1958aea Andreas Färber
                           DESC_A_MASK);
2422 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
2423 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2424 c1958aea Andreas Färber
                           DESC_A_MASK);
2425 c1958aea Andreas Färber
2426 c1958aea Andreas Färber
    env->eip = 0xfff0;
2427 c1958aea Andreas Färber
    env->regs[R_EDX] = env->cpuid_version;
2428 c1958aea Andreas Färber
2429 c1958aea Andreas Färber
    env->eflags = 0x2;
2430 c1958aea Andreas Färber
2431 c1958aea Andreas Färber
    /* FPU init */
2432 c1958aea Andreas Färber
    for (i = 0; i < 8; i++) {
2433 c1958aea Andreas Färber
        env->fptags[i] = 1;
2434 c1958aea Andreas Färber
    }
2435 c1958aea Andreas Färber
    env->fpuc = 0x37f;
2436 c1958aea Andreas Färber
2437 c1958aea Andreas Färber
    env->mxcsr = 0x1f80;
2438 c74f41bb Paolo Bonzini
    env->xstate_bv = XSTATE_FP | XSTATE_SSE;
2439 c1958aea Andreas Färber
2440 c1958aea Andreas Färber
    env->pat = 0x0007040600070406ULL;
2441 c1958aea Andreas Färber
    env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2442 c1958aea Andreas Färber
2443 c1958aea Andreas Färber
    memset(env->dr, 0, sizeof(env->dr));
2444 c1958aea Andreas Färber
    env->dr[6] = DR6_FIXED_1;
2445 c1958aea Andreas Färber
    env->dr[7] = DR7_FIXED_1;
2446 c1958aea Andreas Färber
    cpu_breakpoint_remove_all(env, BP_CPU);
2447 c1958aea Andreas Färber
    cpu_watchpoint_remove_all(env, BP_CPU);
2448 dd673288 Igor Mammedov
2449 dd673288 Igor Mammedov
#if !defined(CONFIG_USER_ONLY)
2450 dd673288 Igor Mammedov
    /* We hard-wire the BSP to the first CPU. */
2451 55e5c285 Andreas Färber
    if (s->cpu_index == 0) {
2452 dd673288 Igor Mammedov
        apic_designate_bsp(env->apic_state);
2453 dd673288 Igor Mammedov
    }
2454 dd673288 Igor Mammedov
2455 259186a7 Andreas Färber
    s->halted = !cpu_is_bsp(cpu);
2456 dd673288 Igor Mammedov
#endif
2457 5fd2087a Andreas Färber
}
2458 5fd2087a Andreas Färber
2459 dd673288 Igor Mammedov
#ifndef CONFIG_USER_ONLY
2460 dd673288 Igor Mammedov
bool cpu_is_bsp(X86CPU *cpu)
2461 dd673288 Igor Mammedov
{
2462 dd673288 Igor Mammedov
    return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP;
2463 dd673288 Igor Mammedov
}
2464 65dee380 Igor Mammedov
2465 65dee380 Igor Mammedov
/* TODO: remove me, when reset over QOM tree is implemented */
2466 65dee380 Igor Mammedov
static void x86_cpu_machine_reset_cb(void *opaque)
2467 65dee380 Igor Mammedov
{
2468 65dee380 Igor Mammedov
    X86CPU *cpu = opaque;
2469 65dee380 Igor Mammedov
    cpu_reset(CPU(cpu));
2470 65dee380 Igor Mammedov
}
2471 dd673288 Igor Mammedov
#endif
2472 dd673288 Igor Mammedov
2473 de024815 Andreas Färber
static void mce_init(X86CPU *cpu)
2474 de024815 Andreas Färber
{
2475 de024815 Andreas Färber
    CPUX86State *cenv = &cpu->env;
2476 de024815 Andreas Färber
    unsigned int bank;
2477 de024815 Andreas Färber
2478 de024815 Andreas Färber
    if (((cenv->cpuid_version >> 8) & 0xf) >= 6
2479 0514ef2f Eduardo Habkost
        && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
2480 de024815 Andreas Färber
            (CPUID_MCE | CPUID_MCA)) {
2481 de024815 Andreas Färber
        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2482 de024815 Andreas Färber
        cenv->mcg_ctl = ~(uint64_t)0;
2483 de024815 Andreas Färber
        for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2484 de024815 Andreas Färber
            cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2485 de024815 Andreas Färber
        }
2486 de024815 Andreas Färber
    }
2487 de024815 Andreas Färber
}
2488 de024815 Andreas Färber
2489 bdeec802 Igor Mammedov
#ifndef CONFIG_USER_ONLY
2490 d3c64d6a Igor Mammedov
static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
2491 bdeec802 Igor Mammedov
{
2492 bdeec802 Igor Mammedov
    CPUX86State *env = &cpu->env;
2493 53a89e26 Igor Mammedov
    DeviceState *dev = DEVICE(cpu);
2494 449994eb Andreas Färber
    APICCommonState *apic;
2495 bdeec802 Igor Mammedov
    const char *apic_type = "apic";
2496 bdeec802 Igor Mammedov
2497 bdeec802 Igor Mammedov
    if (kvm_irqchip_in_kernel()) {
2498 bdeec802 Igor Mammedov
        apic_type = "kvm-apic";
2499 bdeec802 Igor Mammedov
    } else if (xen_enabled()) {
2500 bdeec802 Igor Mammedov
        apic_type = "xen-apic";
2501 bdeec802 Igor Mammedov
    }
2502 bdeec802 Igor Mammedov
2503 53a89e26 Igor Mammedov
    env->apic_state = qdev_try_create(qdev_get_parent_bus(dev), apic_type);
2504 bdeec802 Igor Mammedov
    if (env->apic_state == NULL) {
2505 bdeec802 Igor Mammedov
        error_setg(errp, "APIC device '%s' could not be created", apic_type);
2506 bdeec802 Igor Mammedov
        return;
2507 bdeec802 Igor Mammedov
    }
2508 bdeec802 Igor Mammedov
2509 bdeec802 Igor Mammedov
    object_property_add_child(OBJECT(cpu), "apic",
2510 bdeec802 Igor Mammedov
                              OBJECT(env->apic_state), NULL);
2511 bdeec802 Igor Mammedov
    qdev_prop_set_uint8(env->apic_state, "id", env->cpuid_apic_id);
2512 bdeec802 Igor Mammedov
    /* TODO: convert to link<> */
2513 449994eb Andreas Färber
    apic = APIC_COMMON(env->apic_state);
2514 60671e58 Andreas Färber
    apic->cpu = cpu;
2515 d3c64d6a Igor Mammedov
}
2516 d3c64d6a Igor Mammedov
2517 d3c64d6a Igor Mammedov
static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2518 d3c64d6a Igor Mammedov
{
2519 d3c64d6a Igor Mammedov
    CPUX86State *env = &cpu->env;
2520 d3c64d6a Igor Mammedov
2521 d3c64d6a Igor Mammedov
    if (env->apic_state == NULL) {
2522 d3c64d6a Igor Mammedov
        return;
2523 d3c64d6a Igor Mammedov
    }
2524 bdeec802 Igor Mammedov
2525 bdeec802 Igor Mammedov
    if (qdev_init(env->apic_state)) {
2526 bdeec802 Igor Mammedov
        error_setg(errp, "APIC device '%s' could not be initialized",
2527 bdeec802 Igor Mammedov
                   object_get_typename(OBJECT(env->apic_state)));
2528 bdeec802 Igor Mammedov
        return;
2529 bdeec802 Igor Mammedov
    }
2530 bdeec802 Igor Mammedov
}
2531 d3c64d6a Igor Mammedov
#else
2532 d3c64d6a Igor Mammedov
static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2533 d3c64d6a Igor Mammedov
{
2534 d3c64d6a Igor Mammedov
}
2535 bdeec802 Igor Mammedov
#endif
2536 bdeec802 Igor Mammedov
2537 2b6f294c Andreas Färber
static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
2538 7a059953 Andreas Färber
{
2539 14a10fc3 Andreas Färber
    CPUState *cs = CPU(dev);
2540 2b6f294c Andreas Färber
    X86CPU *cpu = X86_CPU(dev);
2541 2b6f294c Andreas Färber
    X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
2542 b34d12d1 Igor Mammedov
    CPUX86State *env = &cpu->env;
2543 2b6f294c Andreas Färber
    Error *local_err = NULL;
2544 b34d12d1 Igor Mammedov
2545 0514ef2f Eduardo Habkost
    if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
2546 b34d12d1 Igor Mammedov
        env->cpuid_level = 7;
2547 b34d12d1 Igor Mammedov
    }
2548 7a059953 Andreas Färber
2549 9b15cd9e Igor Mammedov
    /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
2550 9b15cd9e Igor Mammedov
     * CPUID[1].EDX.
2551 9b15cd9e Igor Mammedov
     */
2552 9b15cd9e Igor Mammedov
    if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
2553 9b15cd9e Igor Mammedov
        env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
2554 9b15cd9e Igor Mammedov
        env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
2555 0514ef2f Eduardo Habkost
        env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
2556 0514ef2f Eduardo Habkost
        env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
2557 9b15cd9e Igor Mammedov
           & CPUID_EXT2_AMD_ALIASES);
2558 9b15cd9e Igor Mammedov
    }
2559 9b15cd9e Igor Mammedov
2560 4586f157 Igor Mammedov
    if (!kvm_enabled()) {
2561 0514ef2f Eduardo Habkost
        env->features[FEAT_1_EDX] &= TCG_FEATURES;
2562 0514ef2f Eduardo Habkost
        env->features[FEAT_1_ECX] &= TCG_EXT_FEATURES;
2563 0514ef2f Eduardo Habkost
        env->features[FEAT_8000_0001_EDX] &= (TCG_EXT2_FEATURES
2564 4586f157 Igor Mammedov
#ifdef TARGET_X86_64
2565 4586f157 Igor Mammedov
            | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
2566 4586f157 Igor Mammedov
#endif
2567 4586f157 Igor Mammedov
            );
2568 0514ef2f Eduardo Habkost
        env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES;
2569 0514ef2f Eduardo Habkost
        env->features[FEAT_SVM] &= TCG_SVM_FEATURES;
2570 4586f157 Igor Mammedov
    } else {
2571 5ec01c2e Igor Mammedov
        if (check_cpuid && kvm_check_features_against_host(cpu)
2572 5ec01c2e Igor Mammedov
            && enforce_cpuid) {
2573 4dc1f449 Igor Mammedov
            error_setg(&local_err,
2574 4dc1f449 Igor Mammedov
                       "Host's CPU doesn't support requested features");
2575 4dc1f449 Igor Mammedov
            goto out;
2576 5ec01c2e Igor Mammedov
        }
2577 a509d632 Eduardo Habkost
#ifdef CONFIG_KVM
2578 a509d632 Eduardo Habkost
        filter_features_for_kvm(cpu);
2579 a509d632 Eduardo Habkost
#endif
2580 4586f157 Igor Mammedov
    }
2581 4586f157 Igor Mammedov
2582 65dee380 Igor Mammedov
#ifndef CONFIG_USER_ONLY
2583 65dee380 Igor Mammedov
    qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
2584 bdeec802 Igor Mammedov
2585 0514ef2f Eduardo Habkost
    if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
2586 d3c64d6a Igor Mammedov
        x86_cpu_apic_create(cpu, &local_err);
2587 2b6f294c Andreas Färber
        if (local_err != NULL) {
2588 4dc1f449 Igor Mammedov
            goto out;
2589 bdeec802 Igor Mammedov
        }
2590 bdeec802 Igor Mammedov
    }
2591 65dee380 Igor Mammedov
#endif
2592 65dee380 Igor Mammedov
2593 7a059953 Andreas Färber
    mce_init(cpu);
2594 14a10fc3 Andreas Färber
    qemu_init_vcpu(cs);
2595 d3c64d6a Igor Mammedov
2596 d3c64d6a Igor Mammedov
    x86_cpu_apic_realize(cpu, &local_err);
2597 d3c64d6a Igor Mammedov
    if (local_err != NULL) {
2598 d3c64d6a Igor Mammedov
        goto out;
2599 d3c64d6a Igor Mammedov
    }
2600 14a10fc3 Andreas Färber
    cpu_reset(cs);
2601 2b6f294c Andreas Färber
2602 4dc1f449 Igor Mammedov
    xcc->parent_realize(dev, &local_err);
2603 4dc1f449 Igor Mammedov
out:
2604 4dc1f449 Igor Mammedov
    if (local_err != NULL) {
2605 4dc1f449 Igor Mammedov
        error_propagate(errp, local_err);
2606 4dc1f449 Igor Mammedov
        return;
2607 4dc1f449 Igor Mammedov
    }
2608 7a059953 Andreas Färber
}
2609 7a059953 Andreas Färber
2610 8932cfdf Eduardo Habkost
/* Enables contiguous-apic-ID mode, for compatibility */
2611 8932cfdf Eduardo Habkost
static bool compat_apic_id_mode;
2612 8932cfdf Eduardo Habkost
2613 8932cfdf Eduardo Habkost
void enable_compat_apic_id_mode(void)
2614 8932cfdf Eduardo Habkost
{
2615 8932cfdf Eduardo Habkost
    compat_apic_id_mode = true;
2616 8932cfdf Eduardo Habkost
}
2617 8932cfdf Eduardo Habkost
2618 cb41bad3 Eduardo Habkost
/* Calculates initial APIC ID for a specific CPU index
2619 cb41bad3 Eduardo Habkost
 *
2620 cb41bad3 Eduardo Habkost
 * Currently we need to be able to calculate the APIC ID from the CPU index
2621 cb41bad3 Eduardo Habkost
 * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
2622 cb41bad3 Eduardo Habkost
 * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
2623 cb41bad3 Eduardo Habkost
 * all CPUs up to max_cpus.
2624 cb41bad3 Eduardo Habkost
 */
2625 cb41bad3 Eduardo Habkost
uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
2626 cb41bad3 Eduardo Habkost
{
2627 8932cfdf Eduardo Habkost
    uint32_t correct_id;
2628 8932cfdf Eduardo Habkost
    static bool warned;
2629 8932cfdf Eduardo Habkost
2630 8932cfdf Eduardo Habkost
    correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
2631 8932cfdf Eduardo Habkost
    if (compat_apic_id_mode) {
2632 8932cfdf Eduardo Habkost
        if (cpu_index != correct_id && !warned) {
2633 8932cfdf Eduardo Habkost
            error_report("APIC IDs set in compatibility mode, "
2634 8932cfdf Eduardo Habkost
                         "CPU topology won't match the configuration");
2635 8932cfdf Eduardo Habkost
            warned = true;
2636 8932cfdf Eduardo Habkost
        }
2637 8932cfdf Eduardo Habkost
        return cpu_index;
2638 8932cfdf Eduardo Habkost
    } else {
2639 8932cfdf Eduardo Habkost
        return correct_id;
2640 8932cfdf Eduardo Habkost
    }
2641 cb41bad3 Eduardo Habkost
}
2642 cb41bad3 Eduardo Habkost
2643 de024815 Andreas Färber
static void x86_cpu_initfn(Object *obj)
2644 de024815 Andreas Färber
{
2645 55e5c285 Andreas Färber
    CPUState *cs = CPU(obj);
2646 de024815 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
2647 de024815 Andreas Färber
    CPUX86State *env = &cpu->env;
2648 d65e9815 Igor Mammedov
    static int inited;
2649 de024815 Andreas Färber
2650 c05efcb1 Andreas Färber
    cs->env_ptr = env;
2651 de024815 Andreas Färber
    cpu_exec_init(env);
2652 71ad61d3 Andreas Färber
2653 71ad61d3 Andreas Färber
    object_property_add(obj, "family", "int",
2654 95b8519d Andreas Färber
                        x86_cpuid_version_get_family,
2655 71ad61d3 Andreas Färber
                        x86_cpuid_version_set_family, NULL, NULL, NULL);
2656 c5291a4f Andreas Färber
    object_property_add(obj, "model", "int",
2657 67e30c83 Andreas Färber
                        x86_cpuid_version_get_model,
2658 c5291a4f Andreas Färber
                        x86_cpuid_version_set_model, NULL, NULL, NULL);
2659 036e2222 Andreas Färber
    object_property_add(obj, "stepping", "int",
2660 35112e41 Andreas Färber
                        x86_cpuid_version_get_stepping,
2661 036e2222 Andreas Färber
                        x86_cpuid_version_set_stepping, NULL, NULL, NULL);
2662 8e1898bf Andreas Färber
    object_property_add(obj, "level", "int",
2663 8e1898bf Andreas Färber
                        x86_cpuid_get_level,
2664 8e1898bf Andreas Färber
                        x86_cpuid_set_level, NULL, NULL, NULL);
2665 16b93aa8 Andreas Färber
    object_property_add(obj, "xlevel", "int",
2666 16b93aa8 Andreas Färber
                        x86_cpuid_get_xlevel,
2667 16b93aa8 Andreas Färber
                        x86_cpuid_set_xlevel, NULL, NULL, NULL);
2668 d480e1af Andreas Färber
    object_property_add_str(obj, "vendor",
2669 d480e1af Andreas Färber
                            x86_cpuid_get_vendor,
2670 d480e1af Andreas Färber
                            x86_cpuid_set_vendor, NULL);
2671 938d4c25 Andreas Färber
    object_property_add_str(obj, "model-id",
2672 63e886eb Andreas Färber
                            x86_cpuid_get_model_id,
2673 938d4c25 Andreas Färber
                            x86_cpuid_set_model_id, NULL);
2674 89e48965 Andreas Färber
    object_property_add(obj, "tsc-frequency", "int",
2675 89e48965 Andreas Färber
                        x86_cpuid_get_tsc_freq,
2676 89e48965 Andreas Färber
                        x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
2677 31050930 Igor Mammedov
    object_property_add(obj, "apic-id", "int",
2678 31050930 Igor Mammedov
                        x86_cpuid_get_apic_id,
2679 31050930 Igor Mammedov
                        x86_cpuid_set_apic_id, NULL, NULL, NULL);
2680 8e8aba50 Eduardo Habkost
    object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
2681 8e8aba50 Eduardo Habkost
                        x86_cpu_get_feature_words,
2682 7e5292b5 Eduardo Habkost
                        NULL, NULL, (void *)env->features, NULL);
2683 7e5292b5 Eduardo Habkost
    object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
2684 7e5292b5 Eduardo Habkost
                        x86_cpu_get_feature_words,
2685 7e5292b5 Eduardo Habkost
                        NULL, NULL, (void *)cpu->filtered_features, NULL);
2686 71ad61d3 Andreas Färber
2687 92067bf4 Igor Mammedov
    cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
2688 cb41bad3 Eduardo Habkost
    env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
2689 d65e9815 Igor Mammedov
2690 d65e9815 Igor Mammedov
    /* init various static tables used in TCG mode */
2691 d65e9815 Igor Mammedov
    if (tcg_enabled() && !inited) {
2692 d65e9815 Igor Mammedov
        inited = 1;
2693 d65e9815 Igor Mammedov
        optimize_flags_init();
2694 d65e9815 Igor Mammedov
#ifndef CONFIG_USER_ONLY
2695 d65e9815 Igor Mammedov
        cpu_set_debug_excp_handler(breakpoint_handler);
2696 d65e9815 Igor Mammedov
#endif
2697 d65e9815 Igor Mammedov
    }
2698 de024815 Andreas Färber
}
2699 de024815 Andreas Färber
2700 997395d3 Igor Mammedov
static int64_t x86_cpu_get_arch_id(CPUState *cs)
2701 997395d3 Igor Mammedov
{
2702 997395d3 Igor Mammedov
    X86CPU *cpu = X86_CPU(cs);
2703 997395d3 Igor Mammedov
    CPUX86State *env = &cpu->env;
2704 997395d3 Igor Mammedov
2705 997395d3 Igor Mammedov
    return env->cpuid_apic_id;
2706 997395d3 Igor Mammedov
}
2707 997395d3 Igor Mammedov
2708 444d5590 Andreas Färber
static bool x86_cpu_get_paging_enabled(const CPUState *cs)
2709 444d5590 Andreas Färber
{
2710 444d5590 Andreas Färber
    X86CPU *cpu = X86_CPU(cs);
2711 444d5590 Andreas Färber
2712 444d5590 Andreas Färber
    return cpu->env.cr[0] & CR0_PG_MASK;
2713 444d5590 Andreas Färber
}
2714 444d5590 Andreas Färber
2715 f45748f1 Andreas Färber
static void x86_cpu_set_pc(CPUState *cs, vaddr value)
2716 f45748f1 Andreas Färber
{
2717 f45748f1 Andreas Färber
    X86CPU *cpu = X86_CPU(cs);
2718 f45748f1 Andreas Färber
2719 f45748f1 Andreas Färber
    cpu->env.eip = value;
2720 f45748f1 Andreas Färber
}
2721 f45748f1 Andreas Färber
2722 bdf7ae5b Andreas Färber
static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
2723 bdf7ae5b Andreas Färber
{
2724 bdf7ae5b Andreas Färber
    X86CPU *cpu = X86_CPU(cs);
2725 bdf7ae5b Andreas Färber
2726 bdf7ae5b Andreas Färber
    cpu->env.eip = tb->pc - tb->cs_base;
2727 bdf7ae5b Andreas Färber
}
2728 bdf7ae5b Andreas Färber
2729 9337e3b6 Eduardo Habkost
static Property x86_cpu_properties[] = {
2730 9337e3b6 Eduardo Habkost
    DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
2731 9337e3b6 Eduardo Habkost
    DEFINE_PROP_END_OF_LIST()
2732 9337e3b6 Eduardo Habkost
};
2733 9337e3b6 Eduardo Habkost
2734 5fd2087a Andreas Färber
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
2735 5fd2087a Andreas Färber
{
2736 5fd2087a Andreas Färber
    X86CPUClass *xcc = X86_CPU_CLASS(oc);
2737 5fd2087a Andreas Färber
    CPUClass *cc = CPU_CLASS(oc);
2738 2b6f294c Andreas Färber
    DeviceClass *dc = DEVICE_CLASS(oc);
2739 2b6f294c Andreas Färber
2740 2b6f294c Andreas Färber
    xcc->parent_realize = dc->realize;
2741 2b6f294c Andreas Färber
    dc->realize = x86_cpu_realizefn;
2742 62fc403f Igor Mammedov
    dc->bus_type = TYPE_ICC_BUS;
2743 9337e3b6 Eduardo Habkost
    dc->props = x86_cpu_properties;
2744 5fd2087a Andreas Färber
2745 5fd2087a Andreas Färber
    xcc->parent_reset = cc->reset;
2746 5fd2087a Andreas Färber
    cc->reset = x86_cpu_reset;
2747 91b1df8c Andreas Färber
    cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
2748 f56e3a14 Andreas Färber
2749 97a8ea5a Andreas Färber
    cc->do_interrupt = x86_cpu_do_interrupt;
2750 878096ee Andreas Färber
    cc->dump_state = x86_cpu_dump_state;
2751 f45748f1 Andreas Färber
    cc->set_pc = x86_cpu_set_pc;
2752 bdf7ae5b Andreas Färber
    cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
2753 5b50e790 Andreas Färber
    cc->gdb_read_register = x86_cpu_gdb_read_register;
2754 5b50e790 Andreas Färber
    cc->gdb_write_register = x86_cpu_gdb_write_register;
2755 444d5590 Andreas Färber
    cc->get_arch_id = x86_cpu_get_arch_id;
2756 444d5590 Andreas Färber
    cc->get_paging_enabled = x86_cpu_get_paging_enabled;
2757 c72bf468 Jens Freimann
#ifndef CONFIG_USER_ONLY
2758 a23bbfda Andreas Färber
    cc->get_memory_mapping = x86_cpu_get_memory_mapping;
2759 00b941e5 Andreas Färber
    cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
2760 c72bf468 Jens Freimann
    cc->write_elf64_note = x86_cpu_write_elf64_note;
2761 c72bf468 Jens Freimann
    cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
2762 c72bf468 Jens Freimann
    cc->write_elf32_note = x86_cpu_write_elf32_note;
2763 c72bf468 Jens Freimann
    cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
2764 00b941e5 Andreas Färber
    cc->vmsd = &vmstate_x86_cpu;
2765 c72bf468 Jens Freimann
#endif
2766 a0e372f0 Andreas Färber
    cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
2767 5fd2087a Andreas Färber
}
2768 5fd2087a Andreas Färber
2769 5fd2087a Andreas Färber
static const TypeInfo x86_cpu_type_info = {
2770 5fd2087a Andreas Färber
    .name = TYPE_X86_CPU,
2771 5fd2087a Andreas Färber
    .parent = TYPE_CPU,
2772 5fd2087a Andreas Färber
    .instance_size = sizeof(X86CPU),
2773 de024815 Andreas Färber
    .instance_init = x86_cpu_initfn,
2774 5fd2087a Andreas Färber
    .abstract = false,
2775 5fd2087a Andreas Färber
    .class_size = sizeof(X86CPUClass),
2776 5fd2087a Andreas Färber
    .class_init = x86_cpu_common_class_init,
2777 5fd2087a Andreas Färber
};
2778 5fd2087a Andreas Färber
2779 5fd2087a Andreas Färber
static void x86_cpu_register_types(void)
2780 5fd2087a Andreas Färber
{
2781 5fd2087a Andreas Färber
    type_register_static(&x86_cpu_type_info);
2782 5fd2087a Andreas Färber
}
2783 5fd2087a Andreas Färber
2784 5fd2087a Andreas Färber
type_init(x86_cpu_register_types)