Statistics
| Branch: | Revision:

root / target-i386 / cpuid.c @ 7943a2fa

History | View | Annotate | Download (42.3 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 c6dc6f63 Andre Przywara
#include "kvm.h"
26 c6dc6f63 Andre Przywara
27 c6dc6f63 Andre Przywara
#include "qemu-option.h"
28 c6dc6f63 Andre Przywara
#include "qemu-config.h"
29 c6dc6f63 Andre Przywara
30 c6dc6f63 Andre Przywara
/* feature flags taken from "Intel Processor Identification and the CPUID
31 c6dc6f63 Andre Przywara
 * Instruction" and AMD's "CPUID Specification".  In cases of disagreement
32 c6dc6f63 Andre Przywara
 * between feature naming conventions, aliases may be added.
33 c6dc6f63 Andre Przywara
 */
34 c6dc6f63 Andre Przywara
static const char *feature_name[] = {
35 c6dc6f63 Andre Przywara
    "fpu", "vme", "de", "pse",
36 c6dc6f63 Andre Przywara
    "tsc", "msr", "pae", "mce",
37 c6dc6f63 Andre Przywara
    "cx8", "apic", NULL, "sep",
38 c6dc6f63 Andre Przywara
    "mtrr", "pge", "mca", "cmov",
39 c6dc6f63 Andre Przywara
    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
40 c6dc6f63 Andre Przywara
    NULL, "ds" /* Intel dts */, "acpi", "mmx",
41 c6dc6f63 Andre Przywara
    "fxsr", "sse", "sse2", "ss",
42 c6dc6f63 Andre Przywara
    "ht" /* Intel htt */, "tm", "ia64", "pbe",
43 c6dc6f63 Andre Przywara
};
44 c6dc6f63 Andre Przywara
static const char *ext_feature_name[] = {
45 e117f772 Andre Przywara
    "pni|sse3" /* Intel,AMD sse3 */, "pclmuldq", "dtes64", "monitor",
46 e117f772 Andre Przywara
    "ds_cpl", "vmx", "smx", "est",
47 c6dc6f63 Andre Przywara
    "tm2", "ssse3", "cid", NULL,
48 e117f772 Andre Przywara
    "fma", "cx16", "xtpr", "pdcm",
49 c6dc6f63 Andre Przywara
    NULL, NULL, "dca", "sse4.1|sse4_1",
50 e117f772 Andre Przywara
    "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
51 e117f772 Andre Przywara
    NULL, "aes", "xsave", "osxsave",
52 e117f772 Andre Przywara
    "avx", NULL, NULL, "hypervisor",
53 c6dc6f63 Andre Przywara
};
54 c6dc6f63 Andre Przywara
static const char *ext2_feature_name[] = {
55 c6dc6f63 Andre Przywara
    "fpu", "vme", "de", "pse",
56 c6dc6f63 Andre Przywara
    "tsc", "msr", "pae", "mce",
57 c6dc6f63 Andre Przywara
    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall",
58 c6dc6f63 Andre Przywara
    "mtrr", "pge", "mca", "cmov",
59 c6dc6f63 Andre Przywara
    "pat", "pse36", NULL, NULL /* Linux mp */,
60 c6dc6f63 Andre Przywara
    "nx" /* Intel xd */, NULL, "mmxext", "mmx",
61 c6dc6f63 Andre Przywara
    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp",
62 c6dc6f63 Andre Przywara
    NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
63 c6dc6f63 Andre Przywara
};
64 c6dc6f63 Andre Przywara
static const char *ext3_feature_name[] = {
65 c6dc6f63 Andre Przywara
    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
66 c6dc6f63 Andre Przywara
    "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
67 e117f772 Andre Przywara
    "3dnowprefetch", "osvw", "ibs", "xop",
68 c6dc6f63 Andre Przywara
    "skinit", "wdt", NULL, NULL,
69 e117f772 Andre Przywara
    "fma4", NULL, "cvt16", "nodeid_msr",
70 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL,
71 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL,
72 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL,
73 c6dc6f63 Andre Przywara
};
74 c6dc6f63 Andre Przywara
75 c6dc6f63 Andre Przywara
static const char *kvm_feature_name[] = {
76 f6584ee2 Gleb Natapov
    "kvmclock", "kvm_nopiodelay", "kvm_mmu", NULL, "kvm_asyncpf", NULL, NULL, NULL,
77 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
78 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
79 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
80 c6dc6f63 Andre Przywara
};
81 c6dc6f63 Andre Przywara
82 296acb64 Joerg Roedel
static const char *svm_feature_name[] = {
83 296acb64 Joerg Roedel
    "npt", "lbrv", "svm_lock", "nrip_save",
84 296acb64 Joerg Roedel
    "tsc_scale", "vmcb_clean",  "flushbyasid", "decodeassists",
85 296acb64 Joerg Roedel
    NULL, NULL, "pause_filter", NULL,
86 296acb64 Joerg Roedel
    "pfthreshold", NULL, NULL, NULL,
87 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
88 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
89 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
90 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
91 296acb64 Joerg Roedel
};
92 296acb64 Joerg Roedel
93 c6dc6f63 Andre Przywara
/* collects per-function cpuid data
94 c6dc6f63 Andre Przywara
 */
95 c6dc6f63 Andre Przywara
typedef struct model_features_t {
96 c6dc6f63 Andre Przywara
    uint32_t *guest_feat;
97 c6dc6f63 Andre Przywara
    uint32_t *host_feat;
98 c6dc6f63 Andre Przywara
    uint32_t check_feat;
99 c6dc6f63 Andre Przywara
    const char **flag_names;
100 c6dc6f63 Andre Przywara
    uint32_t cpuid;
101 c6dc6f63 Andre Przywara
    } model_features_t;
102 c6dc6f63 Andre Przywara
103 c6dc6f63 Andre Przywara
int check_cpuid = 0;
104 c6dc6f63 Andre Przywara
int enforce_cpuid = 0;
105 c6dc6f63 Andre Przywara
106 bdde476a Andre Przywara
static void host_cpuid(uint32_t function, uint32_t count,
107 bdde476a Andre Przywara
                       uint32_t *eax, uint32_t *ebx,
108 bdde476a Andre Przywara
                       uint32_t *ecx, uint32_t *edx)
109 bdde476a Andre Przywara
{
110 bdde476a Andre Przywara
#if defined(CONFIG_KVM)
111 bdde476a Andre Przywara
    uint32_t vec[4];
112 bdde476a Andre Przywara
113 bdde476a Andre Przywara
#ifdef __x86_64__
114 bdde476a Andre Przywara
    asm volatile("cpuid"
115 bdde476a Andre Przywara
                 : "=a"(vec[0]), "=b"(vec[1]),
116 bdde476a Andre Przywara
                   "=c"(vec[2]), "=d"(vec[3])
117 bdde476a Andre Przywara
                 : "0"(function), "c"(count) : "cc");
118 bdde476a Andre Przywara
#else
119 bdde476a Andre Przywara
    asm volatile("pusha \n\t"
120 bdde476a Andre Przywara
                 "cpuid \n\t"
121 bdde476a Andre Przywara
                 "mov %%eax, 0(%2) \n\t"
122 bdde476a Andre Przywara
                 "mov %%ebx, 4(%2) \n\t"
123 bdde476a Andre Przywara
                 "mov %%ecx, 8(%2) \n\t"
124 bdde476a Andre Przywara
                 "mov %%edx, 12(%2) \n\t"
125 bdde476a Andre Przywara
                 "popa"
126 bdde476a Andre Przywara
                 : : "a"(function), "c"(count), "S"(vec)
127 bdde476a Andre Przywara
                 : "memory", "cc");
128 bdde476a Andre Przywara
#endif
129 bdde476a Andre Przywara
130 bdde476a Andre Przywara
    if (eax)
131 2f7a21c4 Aurelien Jarno
        *eax = vec[0];
132 bdde476a Andre Przywara
    if (ebx)
133 2f7a21c4 Aurelien Jarno
        *ebx = vec[1];
134 bdde476a Andre Przywara
    if (ecx)
135 2f7a21c4 Aurelien Jarno
        *ecx = vec[2];
136 bdde476a Andre Przywara
    if (edx)
137 2f7a21c4 Aurelien Jarno
        *edx = vec[3];
138 bdde476a Andre Przywara
#endif
139 bdde476a Andre Przywara
}
140 c6dc6f63 Andre Przywara
141 c6dc6f63 Andre Przywara
#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
142 c6dc6f63 Andre Przywara
143 c6dc6f63 Andre Przywara
/* general substring compare of *[s1..e1) and *[s2..e2).  sx is start of
144 c6dc6f63 Andre Przywara
 * a substring.  ex if !NULL points to the first char after a substring,
145 c6dc6f63 Andre Przywara
 * otherwise the string is assumed to sized by a terminating nul.
146 c6dc6f63 Andre Przywara
 * Return lexical ordering of *s1:*s2.
147 c6dc6f63 Andre Przywara
 */
148 c6dc6f63 Andre Przywara
static int sstrcmp(const char *s1, const char *e1, const char *s2,
149 c6dc6f63 Andre Przywara
    const char *e2)
150 c6dc6f63 Andre Przywara
{
151 c6dc6f63 Andre Przywara
    for (;;) {
152 c6dc6f63 Andre Przywara
        if (!*s1 || !*s2 || *s1 != *s2)
153 c6dc6f63 Andre Przywara
            return (*s1 - *s2);
154 c6dc6f63 Andre Przywara
        ++s1, ++s2;
155 c6dc6f63 Andre Przywara
        if (s1 == e1 && s2 == e2)
156 c6dc6f63 Andre Przywara
            return (0);
157 c6dc6f63 Andre Przywara
        else if (s1 == e1)
158 c6dc6f63 Andre Przywara
            return (*s2);
159 c6dc6f63 Andre Przywara
        else if (s2 == e2)
160 c6dc6f63 Andre Przywara
            return (*s1);
161 c6dc6f63 Andre Przywara
    }
162 c6dc6f63 Andre Przywara
}
163 c6dc6f63 Andre Przywara
164 c6dc6f63 Andre Przywara
/* compare *[s..e) to *altstr.  *altstr may be a simple string or multiple
165 c6dc6f63 Andre Przywara
 * '|' delimited (possibly empty) strings in which case search for a match
166 c6dc6f63 Andre Przywara
 * within the alternatives proceeds left to right.  Return 0 for success,
167 c6dc6f63 Andre Przywara
 * non-zero otherwise.
168 c6dc6f63 Andre Przywara
 */
169 c6dc6f63 Andre Przywara
static int altcmp(const char *s, const char *e, const char *altstr)
170 c6dc6f63 Andre Przywara
{
171 c6dc6f63 Andre Przywara
    const char *p, *q;
172 c6dc6f63 Andre Przywara
173 c6dc6f63 Andre Przywara
    for (q = p = altstr; ; ) {
174 c6dc6f63 Andre Przywara
        while (*p && *p != '|')
175 c6dc6f63 Andre Przywara
            ++p;
176 c6dc6f63 Andre Przywara
        if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
177 c6dc6f63 Andre Przywara
            return (0);
178 c6dc6f63 Andre Przywara
        if (!*p)
179 c6dc6f63 Andre Przywara
            return (1);
180 c6dc6f63 Andre Przywara
        else
181 c6dc6f63 Andre Przywara
            q = ++p;
182 c6dc6f63 Andre Przywara
    }
183 c6dc6f63 Andre Przywara
}
184 c6dc6f63 Andre Przywara
185 c6dc6f63 Andre Przywara
/* search featureset for flag *[s..e), if found set corresponding bit in
186 c6dc6f63 Andre Przywara
 * *pval and return success, otherwise return zero
187 c6dc6f63 Andre Przywara
 */
188 c6dc6f63 Andre Przywara
static int lookup_feature(uint32_t *pval, const char *s, const char *e,
189 c6dc6f63 Andre Przywara
    const char **featureset)
190 c6dc6f63 Andre Przywara
{
191 c6dc6f63 Andre Przywara
    uint32_t mask;
192 c6dc6f63 Andre Przywara
    const char **ppc;
193 c6dc6f63 Andre Przywara
194 c6dc6f63 Andre Przywara
    for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc)
195 c6dc6f63 Andre Przywara
        if (*ppc && !altcmp(s, e, *ppc)) {
196 c6dc6f63 Andre Przywara
            *pval |= mask;
197 c6dc6f63 Andre Przywara
            break;
198 c6dc6f63 Andre Przywara
        }
199 c6dc6f63 Andre Przywara
    return (mask ? 1 : 0);
200 c6dc6f63 Andre Przywara
}
201 c6dc6f63 Andre Przywara
202 c6dc6f63 Andre Przywara
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
203 c6dc6f63 Andre Przywara
                                    uint32_t *ext_features,
204 c6dc6f63 Andre Przywara
                                    uint32_t *ext2_features,
205 c6dc6f63 Andre Przywara
                                    uint32_t *ext3_features,
206 296acb64 Joerg Roedel
                                    uint32_t *kvm_features,
207 296acb64 Joerg Roedel
                                    uint32_t *svm_features)
208 c6dc6f63 Andre Przywara
{
209 c6dc6f63 Andre Przywara
    if (!lookup_feature(features, flagname, NULL, feature_name) &&
210 c6dc6f63 Andre Przywara
        !lookup_feature(ext_features, flagname, NULL, ext_feature_name) &&
211 c6dc6f63 Andre Przywara
        !lookup_feature(ext2_features, flagname, NULL, ext2_feature_name) &&
212 c6dc6f63 Andre Przywara
        !lookup_feature(ext3_features, flagname, NULL, ext3_feature_name) &&
213 296acb64 Joerg Roedel
        !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name) &&
214 296acb64 Joerg Roedel
        !lookup_feature(svm_features, flagname, NULL, svm_feature_name))
215 c6dc6f63 Andre Przywara
            fprintf(stderr, "CPU feature %s not found\n", flagname);
216 c6dc6f63 Andre Przywara
}
217 c6dc6f63 Andre Przywara
218 c6dc6f63 Andre Przywara
typedef struct x86_def_t {
219 c6dc6f63 Andre Przywara
    struct x86_def_t *next;
220 c6dc6f63 Andre Przywara
    const char *name;
221 c6dc6f63 Andre Przywara
    uint32_t level;
222 c6dc6f63 Andre Przywara
    uint32_t vendor1, vendor2, vendor3;
223 c6dc6f63 Andre Przywara
    int family;
224 c6dc6f63 Andre Przywara
    int model;
225 c6dc6f63 Andre Przywara
    int stepping;
226 296acb64 Joerg Roedel
    uint32_t features, ext_features, ext2_features, ext3_features;
227 296acb64 Joerg Roedel
    uint32_t kvm_features, svm_features;
228 c6dc6f63 Andre Przywara
    uint32_t xlevel;
229 c6dc6f63 Andre Przywara
    char model_id[48];
230 c6dc6f63 Andre Przywara
    int vendor_override;
231 c6dc6f63 Andre Przywara
    uint32_t flags;
232 c6dc6f63 Andre Przywara
} x86_def_t;
233 c6dc6f63 Andre Przywara
234 c6dc6f63 Andre Przywara
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
235 c6dc6f63 Andre Przywara
#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
236 c6dc6f63 Andre Przywara
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
237 c6dc6f63 Andre Przywara
#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
238 c6dc6f63 Andre Przywara
          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
239 c6dc6f63 Andre Przywara
          CPUID_PSE36 | CPUID_FXSR)
240 c6dc6f63 Andre Przywara
#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
241 c6dc6f63 Andre Przywara
#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
242 c6dc6f63 Andre Przywara
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
243 c6dc6f63 Andre Przywara
          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
244 c6dc6f63 Andre Przywara
          CPUID_PAE | CPUID_SEP | CPUID_APIC)
245 42673936 Andre Przywara
#define EXT2_FEATURE_MASK 0x0183F3FF
246 c6dc6f63 Andre Przywara
247 551a2dec Andre Przywara
#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
248 551a2dec Andre Przywara
          CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
249 551a2dec Andre Przywara
          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
250 551a2dec Andre Przywara
          CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
251 551a2dec Andre Przywara
          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
252 8560efed Aurelien Jarno
          /* partly implemented:
253 8560efed Aurelien Jarno
          CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
254 8560efed Aurelien Jarno
          CPUID_PSE36 (needed for Solaris) */
255 8560efed Aurelien Jarno
          /* missing:
256 8560efed Aurelien Jarno
          CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
257 551a2dec Andre Przywara
#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | \
258 8713f8ff Andi Kleen
          CPUID_EXT_CX16 | CPUID_EXT_POPCNT | \
259 551a2dec Andre Przywara
          CPUID_EXT_HYPERVISOR)
260 8560efed Aurelien Jarno
          /* missing:
261 8560efed Aurelien Jarno
          CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
262 8713f8ff Andi Kleen
          CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_XSAVE */
263 551a2dec Andre Przywara
#define TCG_EXT2_FEATURES ((TCG_FEATURES & EXT2_FEATURE_MASK) | \
264 551a2dec Andre Przywara
          CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
265 551a2dec Andre Przywara
          CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
266 8560efed Aurelien Jarno
          /* missing:
267 8560efed Aurelien Jarno
          CPUID_EXT2_PDPE1GB */
268 551a2dec Andre Przywara
#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
269 551a2dec Andre Przywara
          CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
270 296acb64 Joerg Roedel
#define TCG_SVM_FEATURES 0
271 551a2dec Andre Przywara
272 c6dc6f63 Andre Przywara
/* maintains list of cpu model definitions
273 c6dc6f63 Andre Przywara
 */
274 c6dc6f63 Andre Przywara
static x86_def_t *x86_defs = {NULL};
275 c6dc6f63 Andre Przywara
276 c6dc6f63 Andre Przywara
/* built-in cpu model definitions (deprecated)
277 c6dc6f63 Andre Przywara
 */
278 c6dc6f63 Andre Przywara
static x86_def_t builtin_x86_defs[] = {
279 c6dc6f63 Andre Przywara
    {
280 c6dc6f63 Andre Przywara
        .name = "qemu64",
281 c6dc6f63 Andre Przywara
        .level = 4,
282 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_AMD_1,
283 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_AMD_2,
284 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_AMD_3,
285 c6dc6f63 Andre Przywara
        .family = 6,
286 c6dc6f63 Andre Przywara
        .model = 2,
287 c6dc6f63 Andre Przywara
        .stepping = 3,
288 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
289 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
290 c6dc6f63 Andre Przywara
            CPUID_PSE36,
291 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
292 42673936 Andre Przywara
        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
293 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
294 c6dc6f63 Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
295 c6dc6f63 Andre Przywara
            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
296 c6dc6f63 Andre Przywara
        .xlevel = 0x8000000A,
297 c6dc6f63 Andre Przywara
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
298 c6dc6f63 Andre Przywara
    },
299 c6dc6f63 Andre Przywara
    {
300 c6dc6f63 Andre Przywara
        .name = "phenom",
301 c6dc6f63 Andre Przywara
        .level = 5,
302 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_AMD_1,
303 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_AMD_2,
304 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_AMD_3,
305 c6dc6f63 Andre Przywara
        .family = 16,
306 c6dc6f63 Andre Przywara
        .model = 2,
307 c6dc6f63 Andre Przywara
        .stepping = 3,
308 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
309 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
310 8560efed Aurelien Jarno
            CPUID_PSE36 | CPUID_VME | CPUID_HT,
311 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
312 c6dc6f63 Andre Przywara
            CPUID_EXT_POPCNT,
313 42673936 Andre Przywara
        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
314 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
315 c6dc6f63 Andre Przywara
            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
316 8560efed Aurelien Jarno
            CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
317 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
318 c6dc6f63 Andre Przywara
                    CPUID_EXT3_CR8LEG,
319 c6dc6f63 Andre Przywara
                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
320 c6dc6f63 Andre Przywara
                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
321 c6dc6f63 Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
322 c6dc6f63 Andre Przywara
            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
323 296acb64 Joerg Roedel
        .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV,
324 c6dc6f63 Andre Przywara
        .xlevel = 0x8000001A,
325 c6dc6f63 Andre Przywara
        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
326 c6dc6f63 Andre Przywara
    },
327 c6dc6f63 Andre Przywara
    {
328 c6dc6f63 Andre Przywara
        .name = "core2duo",
329 c6dc6f63 Andre Przywara
        .level = 10,
330 c6dc6f63 Andre Przywara
        .family = 6,
331 c6dc6f63 Andre Przywara
        .model = 15,
332 c6dc6f63 Andre Przywara
        .stepping = 11,
333 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
334 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
335 8560efed Aurelien Jarno
            CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
336 8560efed Aurelien Jarno
            CPUID_HT | CPUID_TM | CPUID_PBE,
337 8560efed Aurelien Jarno
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
338 8560efed Aurelien Jarno
            CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
339 8560efed Aurelien Jarno
            CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
340 c6dc6f63 Andre Przywara
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
341 c6dc6f63 Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM,
342 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
343 c6dc6f63 Andre Przywara
        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
344 c6dc6f63 Andre Przywara
    },
345 c6dc6f63 Andre Przywara
    {
346 c6dc6f63 Andre Przywara
        .name = "kvm64",
347 c6dc6f63 Andre Przywara
        .level = 5,
348 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_INTEL_1,
349 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_INTEL_2,
350 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_INTEL_3,
351 c6dc6f63 Andre Przywara
        .family = 15,
352 c6dc6f63 Andre Przywara
        .model = 6,
353 c6dc6f63 Andre Przywara
        .stepping = 1,
354 c6dc6f63 Andre Przywara
        /* Missing: CPUID_VME, CPUID_HT */
355 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
356 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
357 c6dc6f63 Andre Przywara
            CPUID_PSE36,
358 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
359 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
360 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
361 42673936 Andre Przywara
        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
362 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
363 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
364 c6dc6f63 Andre Przywara
                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
365 c6dc6f63 Andre Przywara
                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
366 c6dc6f63 Andre Przywara
                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
367 c6dc6f63 Andre Przywara
        .ext3_features = 0,
368 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
369 c6dc6f63 Andre Przywara
        .model_id = "Common KVM processor"
370 c6dc6f63 Andre Przywara
    },
371 c6dc6f63 Andre Przywara
    {
372 c6dc6f63 Andre Przywara
        .name = "qemu32",
373 c6dc6f63 Andre Przywara
        .level = 4,
374 c6dc6f63 Andre Przywara
        .family = 6,
375 c6dc6f63 Andre Przywara
        .model = 3,
376 c6dc6f63 Andre Przywara
        .stepping = 3,
377 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES,
378 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
379 58012d66 Andre Przywara
        .xlevel = 0x80000004,
380 c6dc6f63 Andre Przywara
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
381 c6dc6f63 Andre Przywara
    },
382 c6dc6f63 Andre Przywara
    {
383 eafaf1e5 Andre Przywara
        .name = "kvm32",
384 eafaf1e5 Andre Przywara
        .level = 5,
385 eafaf1e5 Andre Przywara
        .family = 15,
386 eafaf1e5 Andre Przywara
        .model = 6,
387 eafaf1e5 Andre Przywara
        .stepping = 1,
388 eafaf1e5 Andre Przywara
        .features = PPRO_FEATURES |
389 eafaf1e5 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
390 eafaf1e5 Andre Przywara
        .ext_features = CPUID_EXT_SSE3,
391 eafaf1e5 Andre Przywara
        .ext2_features = PPRO_FEATURES & EXT2_FEATURE_MASK,
392 eafaf1e5 Andre Przywara
        .ext3_features = 0,
393 eafaf1e5 Andre Przywara
        .xlevel = 0x80000008,
394 eafaf1e5 Andre Przywara
        .model_id = "Common 32-bit KVM processor"
395 eafaf1e5 Andre Przywara
    },
396 eafaf1e5 Andre Przywara
    {
397 c6dc6f63 Andre Przywara
        .name = "coreduo",
398 c6dc6f63 Andre Przywara
        .level = 10,
399 c6dc6f63 Andre Przywara
        .family = 6,
400 c6dc6f63 Andre Przywara
        .model = 14,
401 c6dc6f63 Andre Przywara
        .stepping = 8,
402 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES | CPUID_VME |
403 8560efed Aurelien Jarno
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
404 8560efed Aurelien Jarno
            CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
405 8560efed Aurelien Jarno
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
406 8560efed Aurelien Jarno
            CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
407 c6dc6f63 Andre Przywara
        .ext2_features = CPUID_EXT2_NX,
408 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
409 c6dc6f63 Andre Przywara
        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
410 c6dc6f63 Andre Przywara
    },
411 c6dc6f63 Andre Przywara
    {
412 c6dc6f63 Andre Przywara
        .name = "486",
413 58012d66 Andre Przywara
        .level = 1,
414 c6dc6f63 Andre Przywara
        .family = 4,
415 c6dc6f63 Andre Przywara
        .model = 0,
416 c6dc6f63 Andre Przywara
        .stepping = 0,
417 c6dc6f63 Andre Przywara
        .features = I486_FEATURES,
418 c6dc6f63 Andre Przywara
        .xlevel = 0,
419 c6dc6f63 Andre Przywara
    },
420 c6dc6f63 Andre Przywara
    {
421 c6dc6f63 Andre Przywara
        .name = "pentium",
422 c6dc6f63 Andre Przywara
        .level = 1,
423 c6dc6f63 Andre Przywara
        .family = 5,
424 c6dc6f63 Andre Przywara
        .model = 4,
425 c6dc6f63 Andre Przywara
        .stepping = 3,
426 c6dc6f63 Andre Przywara
        .features = PENTIUM_FEATURES,
427 c6dc6f63 Andre Przywara
        .xlevel = 0,
428 c6dc6f63 Andre Przywara
    },
429 c6dc6f63 Andre Przywara
    {
430 c6dc6f63 Andre Przywara
        .name = "pentium2",
431 c6dc6f63 Andre Przywara
        .level = 2,
432 c6dc6f63 Andre Przywara
        .family = 6,
433 c6dc6f63 Andre Przywara
        .model = 5,
434 c6dc6f63 Andre Przywara
        .stepping = 2,
435 c6dc6f63 Andre Przywara
        .features = PENTIUM2_FEATURES,
436 c6dc6f63 Andre Przywara
        .xlevel = 0,
437 c6dc6f63 Andre Przywara
    },
438 c6dc6f63 Andre Przywara
    {
439 c6dc6f63 Andre Przywara
        .name = "pentium3",
440 c6dc6f63 Andre Przywara
        .level = 2,
441 c6dc6f63 Andre Przywara
        .family = 6,
442 c6dc6f63 Andre Przywara
        .model = 7,
443 c6dc6f63 Andre Przywara
        .stepping = 3,
444 c6dc6f63 Andre Przywara
        .features = PENTIUM3_FEATURES,
445 c6dc6f63 Andre Przywara
        .xlevel = 0,
446 c6dc6f63 Andre Przywara
    },
447 c6dc6f63 Andre Przywara
    {
448 c6dc6f63 Andre Przywara
        .name = "athlon",
449 c6dc6f63 Andre Przywara
        .level = 2,
450 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_AMD_1,
451 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_AMD_2,
452 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_AMD_3,
453 c6dc6f63 Andre Przywara
        .family = 6,
454 c6dc6f63 Andre Przywara
        .model = 2,
455 c6dc6f63 Andre Przywara
        .stepping = 3,
456 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
457 42673936 Andre Przywara
        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
458 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
459 c6dc6f63 Andre Przywara
        /* XXX: put another string ? */
460 c6dc6f63 Andre Przywara
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
461 c6dc6f63 Andre Przywara
    },
462 c6dc6f63 Andre Przywara
    {
463 c6dc6f63 Andre Przywara
        .name = "n270",
464 c6dc6f63 Andre Przywara
        /* original is on level 10 */
465 c6dc6f63 Andre Przywara
        .level = 5,
466 c6dc6f63 Andre Przywara
        .family = 6,
467 c6dc6f63 Andre Przywara
        .model = 28,
468 c6dc6f63 Andre Przywara
        .stepping = 2,
469 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
470 8560efed Aurelien Jarno
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
471 8560efed Aurelien Jarno
            CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
472 c6dc6f63 Andre Przywara
            /* Some CPUs got no CPUID_SEP */
473 8560efed Aurelien Jarno
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
474 8560efed Aurelien Jarno
            CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR,
475 42673936 Andre Przywara
        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_NX,
476 8560efed Aurelien Jarno
        .ext3_features = CPUID_EXT3_LAHF_LM,
477 c6dc6f63 Andre Przywara
        .xlevel = 0x8000000A,
478 c6dc6f63 Andre Przywara
        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
479 c6dc6f63 Andre Przywara
    },
480 c6dc6f63 Andre Przywara
};
481 c6dc6f63 Andre Przywara
482 c6dc6f63 Andre Przywara
static int cpu_x86_fill_model_id(char *str)
483 c6dc6f63 Andre Przywara
{
484 c6dc6f63 Andre Przywara
    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
485 c6dc6f63 Andre Przywara
    int i;
486 c6dc6f63 Andre Przywara
487 c6dc6f63 Andre Przywara
    for (i = 0; i < 3; i++) {
488 c6dc6f63 Andre Przywara
        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
489 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  0, &eax, 4);
490 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  4, &ebx, 4);
491 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  8, &ecx, 4);
492 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 + 12, &edx, 4);
493 c6dc6f63 Andre Przywara
    }
494 c6dc6f63 Andre Przywara
    return 0;
495 c6dc6f63 Andre Przywara
}
496 c6dc6f63 Andre Przywara
497 c6dc6f63 Andre Przywara
static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
498 c6dc6f63 Andre Przywara
{
499 c6dc6f63 Andre Przywara
    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
500 c6dc6f63 Andre Przywara
501 c6dc6f63 Andre Przywara
    x86_cpu_def->name = "host";
502 c6dc6f63 Andre Przywara
    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
503 c6dc6f63 Andre Przywara
    x86_cpu_def->level = eax;
504 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor1 = ebx;
505 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor2 = edx;
506 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor3 = ecx;
507 c6dc6f63 Andre Przywara
508 c6dc6f63 Andre Przywara
    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
509 c6dc6f63 Andre Przywara
    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
510 c6dc6f63 Andre Przywara
    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
511 c6dc6f63 Andre Przywara
    x86_cpu_def->stepping = eax & 0x0F;
512 c6dc6f63 Andre Przywara
    x86_cpu_def->ext_features = ecx;
513 c6dc6f63 Andre Przywara
    x86_cpu_def->features = edx;
514 c6dc6f63 Andre Przywara
515 c6dc6f63 Andre Przywara
    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
516 c6dc6f63 Andre Przywara
    x86_cpu_def->xlevel = eax;
517 c6dc6f63 Andre Przywara
518 c6dc6f63 Andre Przywara
    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
519 c6dc6f63 Andre Przywara
    x86_cpu_def->ext2_features = edx;
520 c6dc6f63 Andre Przywara
    x86_cpu_def->ext3_features = ecx;
521 c6dc6f63 Andre Przywara
    cpu_x86_fill_model_id(x86_cpu_def->model_id);
522 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor_override = 0;
523 c6dc6f63 Andre Przywara
524 296acb64 Joerg Roedel
525 296acb64 Joerg Roedel
    /*
526 296acb64 Joerg Roedel
     * Every SVM feature requires emulation support in KVM - so we can't just
527 296acb64 Joerg Roedel
     * read the host features here. KVM might even support SVM features not
528 296acb64 Joerg Roedel
     * available on the host hardware. Just set all bits and mask out the
529 296acb64 Joerg Roedel
     * unsupported ones later.
530 296acb64 Joerg Roedel
     */
531 296acb64 Joerg Roedel
    x86_cpu_def->svm_features = -1;
532 296acb64 Joerg Roedel
533 c6dc6f63 Andre Przywara
    return 0;
534 c6dc6f63 Andre Przywara
}
535 c6dc6f63 Andre Przywara
536 c6dc6f63 Andre Przywara
static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
537 c6dc6f63 Andre Przywara
{
538 c6dc6f63 Andre Przywara
    int i;
539 c6dc6f63 Andre Przywara
540 c6dc6f63 Andre Przywara
    for (i = 0; i < 32; ++i)
541 c6dc6f63 Andre Przywara
        if (1 << i & mask) {
542 c6dc6f63 Andre Przywara
            fprintf(stderr, "warning: host cpuid %04x_%04x lacks requested"
543 c6dc6f63 Andre Przywara
                " flag '%s' [0x%08x]\n",
544 c6dc6f63 Andre Przywara
                f->cpuid >> 16, f->cpuid & 0xffff,
545 c6dc6f63 Andre Przywara
                f->flag_names[i] ? f->flag_names[i] : "[reserved]", mask);
546 c6dc6f63 Andre Przywara
            break;
547 c6dc6f63 Andre Przywara
        }
548 c6dc6f63 Andre Przywara
    return 0;
549 c6dc6f63 Andre Przywara
}
550 c6dc6f63 Andre Przywara
551 c6dc6f63 Andre Przywara
/* best effort attempt to inform user requested cpu flags aren't making
552 c6dc6f63 Andre Przywara
 * their way to the guest.  Note: ft[].check_feat ideally should be
553 c6dc6f63 Andre Przywara
 * specified via a guest_def field to suppress report of extraneous flags.
554 c6dc6f63 Andre Przywara
 */
555 c6dc6f63 Andre Przywara
static int check_features_against_host(x86_def_t *guest_def)
556 c6dc6f63 Andre Przywara
{
557 c6dc6f63 Andre Przywara
    x86_def_t host_def;
558 c6dc6f63 Andre Przywara
    uint32_t mask;
559 c6dc6f63 Andre Przywara
    int rv, i;
560 c6dc6f63 Andre Przywara
    struct model_features_t ft[] = {
561 c6dc6f63 Andre Przywara
        {&guest_def->features, &host_def.features,
562 c6dc6f63 Andre Przywara
            ~0, feature_name, 0x00000000},
563 c6dc6f63 Andre Przywara
        {&guest_def->ext_features, &host_def.ext_features,
564 c6dc6f63 Andre Przywara
            ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
565 c6dc6f63 Andre Przywara
        {&guest_def->ext2_features, &host_def.ext2_features,
566 c6dc6f63 Andre Przywara
            ~PPRO_FEATURES, ext2_feature_name, 0x80000000},
567 c6dc6f63 Andre Przywara
        {&guest_def->ext3_features, &host_def.ext3_features,
568 c6dc6f63 Andre Przywara
            ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
569 c6dc6f63 Andre Przywara
570 c6dc6f63 Andre Przywara
    cpu_x86_fill_host(&host_def);
571 66fe09ee Blue Swirl
    for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i)
572 c6dc6f63 Andre Przywara
        for (mask = 1; mask; mask <<= 1)
573 c6dc6f63 Andre Przywara
            if (ft[i].check_feat & mask && *ft[i].guest_feat & mask &&
574 c6dc6f63 Andre Przywara
                !(*ft[i].host_feat & mask)) {
575 c6dc6f63 Andre Przywara
                    unavailable_host_feature(&ft[i], mask);
576 c6dc6f63 Andre Przywara
                    rv = 1;
577 c6dc6f63 Andre Przywara
                }
578 c6dc6f63 Andre Przywara
    return rv;
579 c6dc6f63 Andre Przywara
}
580 c6dc6f63 Andre Przywara
581 c6dc6f63 Andre Przywara
static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
582 c6dc6f63 Andre Przywara
{
583 c6dc6f63 Andre Przywara
    unsigned int i;
584 c6dc6f63 Andre Przywara
    x86_def_t *def;
585 c6dc6f63 Andre Przywara
586 c6dc6f63 Andre Przywara
    char *s = strdup(cpu_model);
587 c6dc6f63 Andre Przywara
    char *featurestr, *name = strtok(s, ",");
588 296acb64 Joerg Roedel
    /* Features to be added*/
589 296acb64 Joerg Roedel
    uint32_t plus_features = 0, plus_ext_features = 0;
590 296acb64 Joerg Roedel
    uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
591 296acb64 Joerg Roedel
    uint32_t plus_kvm_features = 0, plus_svm_features = 0;
592 296acb64 Joerg Roedel
    /* Features to be removed */
593 296acb64 Joerg Roedel
    uint32_t minus_features = 0, minus_ext_features = 0;
594 296acb64 Joerg Roedel
    uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
595 296acb64 Joerg Roedel
    uint32_t minus_kvm_features = 0, minus_svm_features = 0;
596 c6dc6f63 Andre Przywara
    uint32_t numvalue;
597 c6dc6f63 Andre Przywara
598 c6dc6f63 Andre Przywara
    for (def = x86_defs; def; def = def->next)
599 c6dc6f63 Andre Przywara
        if (!strcmp(name, def->name))
600 c6dc6f63 Andre Przywara
            break;
601 c6dc6f63 Andre Przywara
    if (kvm_enabled() && strcmp(name, "host") == 0) {
602 c6dc6f63 Andre Przywara
        cpu_x86_fill_host(x86_cpu_def);
603 c6dc6f63 Andre Przywara
    } else if (!def) {
604 c6dc6f63 Andre Przywara
        goto error;
605 c6dc6f63 Andre Przywara
    } else {
606 c6dc6f63 Andre Przywara
        memcpy(x86_cpu_def, def, sizeof(*def));
607 c6dc6f63 Andre Przywara
    }
608 c6dc6f63 Andre Przywara
609 c6dc6f63 Andre Przywara
    plus_kvm_features = ~0; /* not supported bits will be filtered out later */
610 c6dc6f63 Andre Przywara
611 c6dc6f63 Andre Przywara
    add_flagname_to_bitmaps("hypervisor", &plus_features,
612 c6dc6f63 Andre Przywara
        &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
613 296acb64 Joerg Roedel
        &plus_kvm_features, &plus_svm_features);
614 c6dc6f63 Andre Przywara
615 c6dc6f63 Andre Przywara
    featurestr = strtok(NULL, ",");
616 c6dc6f63 Andre Przywara
617 c6dc6f63 Andre Przywara
    while (featurestr) {
618 c6dc6f63 Andre Przywara
        char *val;
619 c6dc6f63 Andre Przywara
        if (featurestr[0] == '+') {
620 296acb64 Joerg Roedel
            add_flagname_to_bitmaps(featurestr + 1, &plus_features,
621 296acb64 Joerg Roedel
                            &plus_ext_features, &plus_ext2_features,
622 296acb64 Joerg Roedel
                            &plus_ext3_features, &plus_kvm_features,
623 296acb64 Joerg Roedel
                            &plus_svm_features);
624 c6dc6f63 Andre Przywara
        } else if (featurestr[0] == '-') {
625 296acb64 Joerg Roedel
            add_flagname_to_bitmaps(featurestr + 1, &minus_features,
626 296acb64 Joerg Roedel
                            &minus_ext_features, &minus_ext2_features,
627 296acb64 Joerg Roedel
                            &minus_ext3_features, &minus_kvm_features,
628 296acb64 Joerg Roedel
                            &minus_svm_features);
629 c6dc6f63 Andre Przywara
        } else if ((val = strchr(featurestr, '='))) {
630 c6dc6f63 Andre Przywara
            *val = 0; val++;
631 c6dc6f63 Andre Przywara
            if (!strcmp(featurestr, "family")) {
632 c6dc6f63 Andre Przywara
                char *err;
633 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
634 c6dc6f63 Andre Przywara
                if (!*val || *err) {
635 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
636 c6dc6f63 Andre Przywara
                    goto error;
637 c6dc6f63 Andre Przywara
                }
638 c6dc6f63 Andre Przywara
                x86_cpu_def->family = numvalue;
639 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "model")) {
640 c6dc6f63 Andre Przywara
                char *err;
641 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
642 c6dc6f63 Andre Przywara
                if (!*val || *err || numvalue > 0xff) {
643 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
644 c6dc6f63 Andre Przywara
                    goto error;
645 c6dc6f63 Andre Przywara
                }
646 c6dc6f63 Andre Przywara
                x86_cpu_def->model = numvalue;
647 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "stepping")) {
648 c6dc6f63 Andre Przywara
                char *err;
649 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
650 c6dc6f63 Andre Przywara
                if (!*val || *err || numvalue > 0xf) {
651 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
652 c6dc6f63 Andre Przywara
                    goto error;
653 c6dc6f63 Andre Przywara
                }
654 c6dc6f63 Andre Przywara
                x86_cpu_def->stepping = numvalue ;
655 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "level")) {
656 c6dc6f63 Andre Przywara
                char *err;
657 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
658 c6dc6f63 Andre Przywara
                if (!*val || *err) {
659 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
660 c6dc6f63 Andre Przywara
                    goto error;
661 c6dc6f63 Andre Przywara
                }
662 c6dc6f63 Andre Przywara
                x86_cpu_def->level = numvalue;
663 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "xlevel")) {
664 c6dc6f63 Andre Przywara
                char *err;
665 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
666 c6dc6f63 Andre Przywara
                if (!*val || *err) {
667 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
668 c6dc6f63 Andre Przywara
                    goto error;
669 c6dc6f63 Andre Przywara
                }
670 c6dc6f63 Andre Przywara
                if (numvalue < 0x80000000) {
671 2f7a21c4 Aurelien Jarno
                    numvalue += 0x80000000;
672 c6dc6f63 Andre Przywara
                }
673 c6dc6f63 Andre Przywara
                x86_cpu_def->xlevel = numvalue;
674 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "vendor")) {
675 c6dc6f63 Andre Przywara
                if (strlen(val) != 12) {
676 c6dc6f63 Andre Przywara
                    fprintf(stderr, "vendor string must be 12 chars long\n");
677 c6dc6f63 Andre Przywara
                    goto error;
678 c6dc6f63 Andre Przywara
                }
679 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor1 = 0;
680 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor2 = 0;
681 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor3 = 0;
682 c6dc6f63 Andre Przywara
                for(i = 0; i < 4; i++) {
683 c6dc6f63 Andre Przywara
                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
684 c6dc6f63 Andre Przywara
                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
685 c6dc6f63 Andre Przywara
                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
686 c6dc6f63 Andre Przywara
                }
687 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor_override = 1;
688 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "model_id")) {
689 c6dc6f63 Andre Przywara
                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
690 c6dc6f63 Andre Przywara
                        val);
691 c6dc6f63 Andre Przywara
            } else {
692 c6dc6f63 Andre Przywara
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
693 c6dc6f63 Andre Przywara
                goto error;
694 c6dc6f63 Andre Przywara
            }
695 c6dc6f63 Andre Przywara
        } else if (!strcmp(featurestr, "check")) {
696 c6dc6f63 Andre Przywara
            check_cpuid = 1;
697 c6dc6f63 Andre Przywara
        } else if (!strcmp(featurestr, "enforce")) {
698 c6dc6f63 Andre Przywara
            check_cpuid = enforce_cpuid = 1;
699 c6dc6f63 Andre Przywara
        } else {
700 c6dc6f63 Andre Przywara
            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
701 c6dc6f63 Andre Przywara
            goto error;
702 c6dc6f63 Andre Przywara
        }
703 c6dc6f63 Andre Przywara
        featurestr = strtok(NULL, ",");
704 c6dc6f63 Andre Przywara
    }
705 c6dc6f63 Andre Przywara
    x86_cpu_def->features |= plus_features;
706 c6dc6f63 Andre Przywara
    x86_cpu_def->ext_features |= plus_ext_features;
707 c6dc6f63 Andre Przywara
    x86_cpu_def->ext2_features |= plus_ext2_features;
708 c6dc6f63 Andre Przywara
    x86_cpu_def->ext3_features |= plus_ext3_features;
709 c6dc6f63 Andre Przywara
    x86_cpu_def->kvm_features |= plus_kvm_features;
710 296acb64 Joerg Roedel
    x86_cpu_def->svm_features |= plus_svm_features;
711 c6dc6f63 Andre Przywara
    x86_cpu_def->features &= ~minus_features;
712 c6dc6f63 Andre Przywara
    x86_cpu_def->ext_features &= ~minus_ext_features;
713 c6dc6f63 Andre Przywara
    x86_cpu_def->ext2_features &= ~minus_ext2_features;
714 c6dc6f63 Andre Przywara
    x86_cpu_def->ext3_features &= ~minus_ext3_features;
715 c6dc6f63 Andre Przywara
    x86_cpu_def->kvm_features &= ~minus_kvm_features;
716 296acb64 Joerg Roedel
    x86_cpu_def->svm_features &= ~minus_svm_features;
717 c6dc6f63 Andre Przywara
    if (check_cpuid) {
718 c6dc6f63 Andre Przywara
        if (check_features_against_host(x86_cpu_def) && enforce_cpuid)
719 c6dc6f63 Andre Przywara
            goto error;
720 c6dc6f63 Andre Przywara
    }
721 c6dc6f63 Andre Przywara
    free(s);
722 c6dc6f63 Andre Przywara
    return 0;
723 c6dc6f63 Andre Przywara
724 c6dc6f63 Andre Przywara
error:
725 c6dc6f63 Andre Przywara
    free(s);
726 c6dc6f63 Andre Przywara
    return -1;
727 c6dc6f63 Andre Przywara
}
728 c6dc6f63 Andre Przywara
729 c6dc6f63 Andre Przywara
/* generate a composite string into buf of all cpuid names in featureset
730 c6dc6f63 Andre Przywara
 * selected by fbits.  indicate truncation at bufsize in the event of overflow.
731 c6dc6f63 Andre Przywara
 * if flags, suppress names undefined in featureset.
732 c6dc6f63 Andre Przywara
 */
733 c6dc6f63 Andre Przywara
static void listflags(char *buf, int bufsize, uint32_t fbits,
734 c6dc6f63 Andre Przywara
    const char **featureset, uint32_t flags)
735 c6dc6f63 Andre Przywara
{
736 c6dc6f63 Andre Przywara
    const char **p = &featureset[31];
737 c6dc6f63 Andre Przywara
    char *q, *b, bit;
738 c6dc6f63 Andre Przywara
    int nc;
739 c6dc6f63 Andre Przywara
740 c6dc6f63 Andre Przywara
    b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
741 c6dc6f63 Andre Przywara
    *buf = '\0';
742 c6dc6f63 Andre Przywara
    for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
743 c6dc6f63 Andre Przywara
        if (fbits & 1 << bit && (*p || !flags)) {
744 c6dc6f63 Andre Przywara
            if (*p)
745 c6dc6f63 Andre Przywara
                nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
746 c6dc6f63 Andre Przywara
            else
747 c6dc6f63 Andre Przywara
                nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
748 c6dc6f63 Andre Przywara
            if (bufsize <= nc) {
749 c6dc6f63 Andre Przywara
                if (b) {
750 c6dc6f63 Andre Przywara
                    memcpy(b, "...", sizeof("..."));
751 c6dc6f63 Andre Przywara
                }
752 c6dc6f63 Andre Przywara
                return;
753 c6dc6f63 Andre Przywara
            }
754 c6dc6f63 Andre Przywara
            q += nc;
755 c6dc6f63 Andre Przywara
            bufsize -= nc;
756 c6dc6f63 Andre Przywara
        }
757 c6dc6f63 Andre Przywara
}
758 c6dc6f63 Andre Przywara
759 c6dc6f63 Andre Przywara
/* generate CPU information:
760 c6dc6f63 Andre Przywara
 * -?        list model names
761 c6dc6f63 Andre Przywara
 * -?model   list model names/IDs
762 c6dc6f63 Andre Przywara
 * -?dump    output all model (x86_def_t) data
763 c6dc6f63 Andre Przywara
 * -?cpuid   list all recognized cpuid flag names
764 c6dc6f63 Andre Przywara
 */
765 9a78eead Stefan Weil
void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
766 c6dc6f63 Andre Przywara
{
767 c6dc6f63 Andre Przywara
    unsigned char model = !strcmp("?model", optarg);
768 c6dc6f63 Andre Przywara
    unsigned char dump = !strcmp("?dump", optarg);
769 c6dc6f63 Andre Przywara
    unsigned char cpuid = !strcmp("?cpuid", optarg);
770 c6dc6f63 Andre Przywara
    x86_def_t *def;
771 c6dc6f63 Andre Przywara
    char buf[256];
772 c6dc6f63 Andre Przywara
773 c6dc6f63 Andre Przywara
    if (cpuid) {
774 c6dc6f63 Andre Przywara
        (*cpu_fprintf)(f, "Recognized CPUID flags:\n");
775 c6dc6f63 Andre Przywara
        listflags(buf, sizeof (buf), (uint32_t)~0, feature_name, 1);
776 c6dc6f63 Andre Przywara
        (*cpu_fprintf)(f, "  f_edx: %s\n", buf);
777 c6dc6f63 Andre Przywara
        listflags(buf, sizeof (buf), (uint32_t)~0, ext_feature_name, 1);
778 c6dc6f63 Andre Przywara
        (*cpu_fprintf)(f, "  f_ecx: %s\n", buf);
779 c6dc6f63 Andre Przywara
        listflags(buf, sizeof (buf), (uint32_t)~0, ext2_feature_name, 1);
780 c6dc6f63 Andre Przywara
        (*cpu_fprintf)(f, "  extf_edx: %s\n", buf);
781 c6dc6f63 Andre Przywara
        listflags(buf, sizeof (buf), (uint32_t)~0, ext3_feature_name, 1);
782 c6dc6f63 Andre Przywara
        (*cpu_fprintf)(f, "  extf_ecx: %s\n", buf);
783 c6dc6f63 Andre Przywara
        return;
784 c6dc6f63 Andre Przywara
    }
785 c6dc6f63 Andre Przywara
    for (def = x86_defs; def; def = def->next) {
786 c6dc6f63 Andre Przywara
        snprintf(buf, sizeof (buf), def->flags ? "[%s]": "%s", def->name);
787 c6dc6f63 Andre Przywara
        if (model || dump) {
788 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "x86 %16s  %-48s\n", buf, def->model_id);
789 c6dc6f63 Andre Przywara
        } else {
790 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "x86 %16s\n", buf);
791 c6dc6f63 Andre Przywara
        }
792 c6dc6f63 Andre Przywara
        if (dump) {
793 c6dc6f63 Andre Przywara
            memcpy(buf, &def->vendor1, sizeof (def->vendor1));
794 c6dc6f63 Andre Przywara
            memcpy(buf + 4, &def->vendor2, sizeof (def->vendor2));
795 c6dc6f63 Andre Przywara
            memcpy(buf + 8, &def->vendor3, sizeof (def->vendor3));
796 c6dc6f63 Andre Przywara
            buf[12] = '\0';
797 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f,
798 c6dc6f63 Andre Przywara
                "  family %d model %d stepping %d level %d xlevel 0x%x"
799 c6dc6f63 Andre Przywara
                " vendor \"%s\"\n",
800 c6dc6f63 Andre Przywara
                def->family, def->model, def->stepping, def->level,
801 c6dc6f63 Andre Przywara
                def->xlevel, buf);
802 c6dc6f63 Andre Przywara
            listflags(buf, sizeof (buf), def->features, feature_name, 0);
803 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "  feature_edx %08x (%s)\n", def->features,
804 c6dc6f63 Andre Przywara
                buf);
805 c6dc6f63 Andre Przywara
            listflags(buf, sizeof (buf), def->ext_features, ext_feature_name,
806 c6dc6f63 Andre Przywara
                0);
807 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "  feature_ecx %08x (%s)\n", def->ext_features,
808 c6dc6f63 Andre Przywara
                buf);
809 c6dc6f63 Andre Przywara
            listflags(buf, sizeof (buf), def->ext2_features, ext2_feature_name,
810 c6dc6f63 Andre Przywara
                0);
811 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "  extfeature_edx %08x (%s)\n",
812 c6dc6f63 Andre Przywara
                def->ext2_features, buf);
813 c6dc6f63 Andre Przywara
            listflags(buf, sizeof (buf), def->ext3_features, ext3_feature_name,
814 c6dc6f63 Andre Przywara
                0);
815 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "  extfeature_ecx %08x (%s)\n",
816 c6dc6f63 Andre Przywara
                def->ext3_features, buf);
817 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "\n");
818 c6dc6f63 Andre Przywara
        }
819 c6dc6f63 Andre Przywara
    }
820 ed2c54d4 Andre Przywara
    if (kvm_enabled()) {
821 ed2c54d4 Andre Przywara
        (*cpu_fprintf)(f, "x86 %16s\n", "[host]");
822 ed2c54d4 Andre Przywara
    }
823 c6dc6f63 Andre Przywara
}
824 c6dc6f63 Andre Przywara
825 c6dc6f63 Andre Przywara
int cpu_x86_register (CPUX86State *env, const char *cpu_model)
826 c6dc6f63 Andre Przywara
{
827 c6dc6f63 Andre Przywara
    x86_def_t def1, *def = &def1;
828 c6dc6f63 Andre Przywara
829 db0ad1ba Joerg Roedel
    memset(def, 0, sizeof(*def));
830 db0ad1ba Joerg Roedel
831 c6dc6f63 Andre Przywara
    if (cpu_x86_find_by_name(def, cpu_model) < 0)
832 c6dc6f63 Andre Przywara
        return -1;
833 c6dc6f63 Andre Przywara
    if (def->vendor1) {
834 c6dc6f63 Andre Przywara
        env->cpuid_vendor1 = def->vendor1;
835 c6dc6f63 Andre Przywara
        env->cpuid_vendor2 = def->vendor2;
836 c6dc6f63 Andre Przywara
        env->cpuid_vendor3 = def->vendor3;
837 c6dc6f63 Andre Przywara
    } else {
838 c6dc6f63 Andre Przywara
        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
839 c6dc6f63 Andre Przywara
        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
840 c6dc6f63 Andre Przywara
        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
841 c6dc6f63 Andre Przywara
    }
842 c6dc6f63 Andre Przywara
    env->cpuid_vendor_override = def->vendor_override;
843 c6dc6f63 Andre Przywara
    env->cpuid_level = def->level;
844 c6dc6f63 Andre Przywara
    if (def->family > 0x0f)
845 c6dc6f63 Andre Przywara
        env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
846 c6dc6f63 Andre Przywara
    else
847 c6dc6f63 Andre Przywara
        env->cpuid_version = def->family << 8;
848 c6dc6f63 Andre Przywara
    env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
849 c6dc6f63 Andre Przywara
    env->cpuid_version |= def->stepping;
850 c6dc6f63 Andre Przywara
    env->cpuid_features = def->features;
851 c6dc6f63 Andre Przywara
    env->pat = 0x0007040600070406ULL;
852 c6dc6f63 Andre Przywara
    env->cpuid_ext_features = def->ext_features;
853 c6dc6f63 Andre Przywara
    env->cpuid_ext2_features = def->ext2_features;
854 4d067ed7 Andre Przywara
    env->cpuid_ext3_features = def->ext3_features;
855 c6dc6f63 Andre Przywara
    env->cpuid_xlevel = def->xlevel;
856 c6dc6f63 Andre Przywara
    env->cpuid_kvm_features = def->kvm_features;
857 296acb64 Joerg Roedel
    env->cpuid_svm_features = def->svm_features;
858 551a2dec Andre Przywara
    if (!kvm_enabled()) {
859 551a2dec Andre Przywara
        env->cpuid_features &= TCG_FEATURES;
860 551a2dec Andre Przywara
        env->cpuid_ext_features &= TCG_EXT_FEATURES;
861 551a2dec Andre Przywara
        env->cpuid_ext2_features &= (TCG_EXT2_FEATURES
862 551a2dec Andre Przywara
#ifdef TARGET_X86_64
863 551a2dec Andre Przywara
            | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
864 551a2dec Andre Przywara
#endif
865 551a2dec Andre Przywara
            );
866 551a2dec Andre Przywara
        env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
867 296acb64 Joerg Roedel
        env->cpuid_svm_features &= TCG_SVM_FEATURES;
868 551a2dec Andre Przywara
    }
869 c6dc6f63 Andre Przywara
    {
870 c6dc6f63 Andre Przywara
        const char *model_id = def->model_id;
871 c6dc6f63 Andre Przywara
        int c, len, i;
872 c6dc6f63 Andre Przywara
        if (!model_id)
873 c6dc6f63 Andre Przywara
            model_id = "";
874 c6dc6f63 Andre Przywara
        len = strlen(model_id);
875 c6dc6f63 Andre Przywara
        for(i = 0; i < 48; i++) {
876 c6dc6f63 Andre Przywara
            if (i >= len)
877 c6dc6f63 Andre Przywara
                c = '\0';
878 c6dc6f63 Andre Przywara
            else
879 c6dc6f63 Andre Przywara
                c = (uint8_t)model_id[i];
880 c6dc6f63 Andre Przywara
            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
881 c6dc6f63 Andre Przywara
        }
882 c6dc6f63 Andre Przywara
    }
883 c6dc6f63 Andre Przywara
    return 0;
884 c6dc6f63 Andre Przywara
}
885 c6dc6f63 Andre Przywara
886 c6dc6f63 Andre Przywara
#if !defined(CONFIG_USER_ONLY)
887 c6dc6f63 Andre Przywara
/* copy vendor id string to 32 bit register, nul pad as needed
888 c6dc6f63 Andre Przywara
 */
889 c6dc6f63 Andre Przywara
static void cpyid(const char *s, uint32_t *id)
890 c6dc6f63 Andre Przywara
{
891 c6dc6f63 Andre Przywara
    char *d = (char *)id;
892 c6dc6f63 Andre Przywara
    char i;
893 c6dc6f63 Andre Przywara
894 c6dc6f63 Andre Przywara
    for (i = sizeof (*id); i--; )
895 c6dc6f63 Andre Przywara
        *d++ = *s ? *s++ : '\0';
896 c6dc6f63 Andre Przywara
}
897 c6dc6f63 Andre Przywara
898 c6dc6f63 Andre Przywara
/* interpret radix and convert from string to arbitrary scalar,
899 c6dc6f63 Andre Przywara
 * otherwise flag failure
900 c6dc6f63 Andre Przywara
 */
901 c6dc6f63 Andre Przywara
#define setscalar(pval, str, perr)                      \
902 c6dc6f63 Andre Przywara
{                                                       \
903 c6dc6f63 Andre Przywara
    char *pend;                                         \
904 c6dc6f63 Andre Przywara
    unsigned long ul;                                   \
905 c6dc6f63 Andre Przywara
                                                        \
906 c6dc6f63 Andre Przywara
    ul = strtoul(str, &pend, 0);                        \
907 c6dc6f63 Andre Przywara
    *str && !*pend ? (*pval = ul) : (*perr = 1);        \
908 c6dc6f63 Andre Przywara
}
909 c6dc6f63 Andre Przywara
910 c6dc6f63 Andre Przywara
/* map cpuid options to feature bits, otherwise return failure
911 c6dc6f63 Andre Przywara
 * (option tags in *str are delimited by whitespace)
912 c6dc6f63 Andre Przywara
 */
913 c6dc6f63 Andre Przywara
static void setfeatures(uint32_t *pval, const char *str,
914 c6dc6f63 Andre Przywara
    const char **featureset, int *perr)
915 c6dc6f63 Andre Przywara
{
916 c6dc6f63 Andre Przywara
    const char *p, *q;
917 c6dc6f63 Andre Przywara
918 c6dc6f63 Andre Przywara
    for (q = p = str; *p || *q; q = p) {
919 c6dc6f63 Andre Przywara
        while (iswhite(*p))
920 c6dc6f63 Andre Przywara
            q = ++p;
921 c6dc6f63 Andre Przywara
        while (*p && !iswhite(*p))
922 c6dc6f63 Andre Przywara
            ++p;
923 c6dc6f63 Andre Przywara
        if (!*q && !*p)
924 c6dc6f63 Andre Przywara
            return;
925 c6dc6f63 Andre Przywara
        if (!lookup_feature(pval, q, p, featureset)) {
926 c6dc6f63 Andre Przywara
            fprintf(stderr, "error: feature \"%.*s\" not available in set\n",
927 c6dc6f63 Andre Przywara
                (int)(p - q), q);
928 c6dc6f63 Andre Przywara
            *perr = 1;
929 c6dc6f63 Andre Przywara
            return;
930 c6dc6f63 Andre Przywara
        }
931 c6dc6f63 Andre Przywara
    }
932 c6dc6f63 Andre Przywara
}
933 c6dc6f63 Andre Przywara
934 c6dc6f63 Andre Przywara
/* map config file options to x86_def_t form
935 c6dc6f63 Andre Przywara
 */
936 c6dc6f63 Andre Przywara
static int cpudef_setfield(const char *name, const char *str, void *opaque)
937 c6dc6f63 Andre Przywara
{
938 c6dc6f63 Andre Przywara
    x86_def_t *def = opaque;
939 c6dc6f63 Andre Przywara
    int err = 0;
940 c6dc6f63 Andre Przywara
941 c6dc6f63 Andre Przywara
    if (!strcmp(name, "name")) {
942 c6dc6f63 Andre Przywara
        def->name = strdup(str);
943 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "model_id")) {
944 c6dc6f63 Andre Przywara
        strncpy(def->model_id, str, sizeof (def->model_id));
945 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "level")) {
946 c6dc6f63 Andre Przywara
        setscalar(&def->level, str, &err)
947 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "vendor")) {
948 c6dc6f63 Andre Przywara
        cpyid(&str[0], &def->vendor1);
949 c6dc6f63 Andre Przywara
        cpyid(&str[4], &def->vendor2);
950 c6dc6f63 Andre Przywara
        cpyid(&str[8], &def->vendor3);
951 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "family")) {
952 c6dc6f63 Andre Przywara
        setscalar(&def->family, str, &err)
953 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "model")) {
954 c6dc6f63 Andre Przywara
        setscalar(&def->model, str, &err)
955 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "stepping")) {
956 c6dc6f63 Andre Przywara
        setscalar(&def->stepping, str, &err)
957 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "feature_edx")) {
958 c6dc6f63 Andre Przywara
        setfeatures(&def->features, str, feature_name, &err);
959 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "feature_ecx")) {
960 c6dc6f63 Andre Przywara
        setfeatures(&def->ext_features, str, ext_feature_name, &err);
961 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "extfeature_edx")) {
962 c6dc6f63 Andre Przywara
        setfeatures(&def->ext2_features, str, ext2_feature_name, &err);
963 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "extfeature_ecx")) {
964 c6dc6f63 Andre Przywara
        setfeatures(&def->ext3_features, str, ext3_feature_name, &err);
965 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "xlevel")) {
966 c6dc6f63 Andre Przywara
        setscalar(&def->xlevel, str, &err)
967 c6dc6f63 Andre Przywara
    } else {
968 c6dc6f63 Andre Przywara
        fprintf(stderr, "error: unknown option [%s = %s]\n", name, str);
969 c6dc6f63 Andre Przywara
        return (1);
970 c6dc6f63 Andre Przywara
    }
971 c6dc6f63 Andre Przywara
    if (err) {
972 c6dc6f63 Andre Przywara
        fprintf(stderr, "error: bad option value [%s = %s]\n", name, str);
973 c6dc6f63 Andre Przywara
        return (1);
974 c6dc6f63 Andre Przywara
    }
975 c6dc6f63 Andre Przywara
    return (0);
976 c6dc6f63 Andre Przywara
}
977 c6dc6f63 Andre Przywara
978 c6dc6f63 Andre Przywara
/* register config file entry as x86_def_t
979 c6dc6f63 Andre Przywara
 */
980 c6dc6f63 Andre Przywara
static int cpudef_register(QemuOpts *opts, void *opaque)
981 c6dc6f63 Andre Przywara
{
982 c6dc6f63 Andre Przywara
    x86_def_t *def = qemu_mallocz(sizeof (x86_def_t));
983 c6dc6f63 Andre Przywara
984 c6dc6f63 Andre Przywara
    qemu_opt_foreach(opts, cpudef_setfield, def, 1);
985 c6dc6f63 Andre Przywara
    def->next = x86_defs;
986 c6dc6f63 Andre Przywara
    x86_defs = def;
987 c6dc6f63 Andre Przywara
    return (0);
988 c6dc6f63 Andre Przywara
}
989 0e26b7b8 Blue Swirl
990 0e26b7b8 Blue Swirl
void cpu_clear_apic_feature(CPUX86State *env)
991 0e26b7b8 Blue Swirl
{
992 0e26b7b8 Blue Swirl
    env->cpuid_features &= ~CPUID_APIC;
993 0e26b7b8 Blue Swirl
}
994 0e26b7b8 Blue Swirl
995 c6dc6f63 Andre Przywara
#endif /* !CONFIG_USER_ONLY */
996 c6dc6f63 Andre Przywara
997 c6dc6f63 Andre Przywara
/* register "cpudef" models defined in configuration file.  Here we first
998 c6dc6f63 Andre Przywara
 * preload any built-in definitions
999 c6dc6f63 Andre Przywara
 */
1000 c6dc6f63 Andre Przywara
void x86_cpudef_setup(void)
1001 c6dc6f63 Andre Przywara
{
1002 c6dc6f63 Andre Przywara
    int i;
1003 c6dc6f63 Andre Przywara
1004 c6dc6f63 Andre Przywara
    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
1005 c6dc6f63 Andre Przywara
        builtin_x86_defs[i].next = x86_defs;
1006 c6dc6f63 Andre Przywara
        builtin_x86_defs[i].flags = 1;
1007 c6dc6f63 Andre Przywara
        x86_defs = &builtin_x86_defs[i];
1008 c6dc6f63 Andre Przywara
    }
1009 c6dc6f63 Andre Przywara
#if !defined(CONFIG_USER_ONLY)
1010 3329f07b Gerd Hoffmann
    qemu_opts_foreach(qemu_find_opts("cpudef"), cpudef_register, NULL, 0);
1011 c6dc6f63 Andre Przywara
#endif
1012 c6dc6f63 Andre Przywara
}
1013 c6dc6f63 Andre Przywara
1014 c6dc6f63 Andre Przywara
static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
1015 c6dc6f63 Andre Przywara
                             uint32_t *ecx, uint32_t *edx)
1016 c6dc6f63 Andre Przywara
{
1017 c6dc6f63 Andre Przywara
    *ebx = env->cpuid_vendor1;
1018 c6dc6f63 Andre Przywara
    *edx = env->cpuid_vendor2;
1019 c6dc6f63 Andre Przywara
    *ecx = env->cpuid_vendor3;
1020 c6dc6f63 Andre Przywara
1021 c6dc6f63 Andre Przywara
    /* sysenter isn't supported on compatibility mode on AMD, syscall
1022 c6dc6f63 Andre Przywara
     * isn't supported in compatibility mode on Intel.
1023 c6dc6f63 Andre Przywara
     * Normally we advertise the actual cpu vendor, but you can override
1024 c6dc6f63 Andre Przywara
     * this if you want to use KVM's sysenter/syscall emulation
1025 c6dc6f63 Andre Przywara
     * in compatibility mode and when doing cross vendor migration
1026 c6dc6f63 Andre Przywara
     */
1027 89354998 Andre Przywara
    if (kvm_enabled() && ! env->cpuid_vendor_override) {
1028 c6dc6f63 Andre Przywara
        host_cpuid(0, 0, NULL, ebx, ecx, edx);
1029 c6dc6f63 Andre Przywara
    }
1030 c6dc6f63 Andre Przywara
}
1031 c6dc6f63 Andre Przywara
1032 c6dc6f63 Andre Przywara
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1033 c6dc6f63 Andre Przywara
                   uint32_t *eax, uint32_t *ebx,
1034 c6dc6f63 Andre Przywara
                   uint32_t *ecx, uint32_t *edx)
1035 c6dc6f63 Andre Przywara
{
1036 c6dc6f63 Andre Przywara
    /* test if maximum index reached */
1037 c6dc6f63 Andre Przywara
    if (index & 0x80000000) {
1038 c6dc6f63 Andre Przywara
        if (index > env->cpuid_xlevel)
1039 c6dc6f63 Andre Przywara
            index = env->cpuid_level;
1040 c6dc6f63 Andre Przywara
    } else {
1041 c6dc6f63 Andre Przywara
        if (index > env->cpuid_level)
1042 c6dc6f63 Andre Przywara
            index = env->cpuid_level;
1043 c6dc6f63 Andre Przywara
    }
1044 c6dc6f63 Andre Przywara
1045 c6dc6f63 Andre Przywara
    switch(index) {
1046 c6dc6f63 Andre Przywara
    case 0:
1047 c6dc6f63 Andre Przywara
        *eax = env->cpuid_level;
1048 c6dc6f63 Andre Przywara
        get_cpuid_vendor(env, ebx, ecx, edx);
1049 c6dc6f63 Andre Przywara
        break;
1050 c6dc6f63 Andre Przywara
    case 1:
1051 c6dc6f63 Andre Przywara
        *eax = env->cpuid_version;
1052 c6dc6f63 Andre Przywara
        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
1053 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_ext_features;
1054 c6dc6f63 Andre Przywara
        *edx = env->cpuid_features;
1055 c6dc6f63 Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1056 c6dc6f63 Andre Przywara
            *ebx |= (env->nr_cores * env->nr_threads) << 16;
1057 c6dc6f63 Andre Przywara
            *edx |= 1 << 28;    /* HTT bit */
1058 c6dc6f63 Andre Przywara
        }
1059 c6dc6f63 Andre Przywara
        break;
1060 c6dc6f63 Andre Przywara
    case 2:
1061 c6dc6f63 Andre Przywara
        /* cache info: needed for Pentium Pro compatibility */
1062 c6dc6f63 Andre Przywara
        *eax = 1;
1063 c6dc6f63 Andre Przywara
        *ebx = 0;
1064 c6dc6f63 Andre Przywara
        *ecx = 0;
1065 c6dc6f63 Andre Przywara
        *edx = 0x2c307d;
1066 c6dc6f63 Andre Przywara
        break;
1067 c6dc6f63 Andre Przywara
    case 4:
1068 c6dc6f63 Andre Przywara
        /* cache info: needed for Core compatibility */
1069 c6dc6f63 Andre Przywara
        if (env->nr_cores > 1) {
1070 2f7a21c4 Aurelien Jarno
            *eax = (env->nr_cores - 1) << 26;
1071 c6dc6f63 Andre Przywara
        } else {
1072 2f7a21c4 Aurelien Jarno
            *eax = 0;
1073 c6dc6f63 Andre Przywara
        }
1074 c6dc6f63 Andre Przywara
        switch (count) {
1075 c6dc6f63 Andre Przywara
            case 0: /* L1 dcache info */
1076 c6dc6f63 Andre Przywara
                *eax |= 0x0000121;
1077 c6dc6f63 Andre Przywara
                *ebx = 0x1c0003f;
1078 c6dc6f63 Andre Przywara
                *ecx = 0x000003f;
1079 c6dc6f63 Andre Przywara
                *edx = 0x0000001;
1080 c6dc6f63 Andre Przywara
                break;
1081 c6dc6f63 Andre Przywara
            case 1: /* L1 icache info */
1082 c6dc6f63 Andre Przywara
                *eax |= 0x0000122;
1083 c6dc6f63 Andre Przywara
                *ebx = 0x1c0003f;
1084 c6dc6f63 Andre Przywara
                *ecx = 0x000003f;
1085 c6dc6f63 Andre Przywara
                *edx = 0x0000001;
1086 c6dc6f63 Andre Przywara
                break;
1087 c6dc6f63 Andre Przywara
            case 2: /* L2 cache info */
1088 c6dc6f63 Andre Przywara
                *eax |= 0x0000143;
1089 c6dc6f63 Andre Przywara
                if (env->nr_threads > 1) {
1090 c6dc6f63 Andre Przywara
                    *eax |= (env->nr_threads - 1) << 14;
1091 c6dc6f63 Andre Przywara
                }
1092 c6dc6f63 Andre Przywara
                *ebx = 0x3c0003f;
1093 c6dc6f63 Andre Przywara
                *ecx = 0x0000fff;
1094 c6dc6f63 Andre Przywara
                *edx = 0x0000001;
1095 c6dc6f63 Andre Przywara
                break;
1096 c6dc6f63 Andre Przywara
            default: /* end of info */
1097 c6dc6f63 Andre Przywara
                *eax = 0;
1098 c6dc6f63 Andre Przywara
                *ebx = 0;
1099 c6dc6f63 Andre Przywara
                *ecx = 0;
1100 c6dc6f63 Andre Przywara
                *edx = 0;
1101 c6dc6f63 Andre Przywara
                break;
1102 c6dc6f63 Andre Przywara
        }
1103 c6dc6f63 Andre Przywara
        break;
1104 c6dc6f63 Andre Przywara
    case 5:
1105 c6dc6f63 Andre Przywara
        /* mwait info: needed for Core compatibility */
1106 c6dc6f63 Andre Przywara
        *eax = 0; /* Smallest monitor-line size in bytes */
1107 c6dc6f63 Andre Przywara
        *ebx = 0; /* Largest monitor-line size in bytes */
1108 c6dc6f63 Andre Przywara
        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
1109 c6dc6f63 Andre Przywara
        *edx = 0;
1110 c6dc6f63 Andre Przywara
        break;
1111 c6dc6f63 Andre Przywara
    case 6:
1112 c6dc6f63 Andre Przywara
        /* Thermal and Power Leaf */
1113 c6dc6f63 Andre Przywara
        *eax = 0;
1114 c6dc6f63 Andre Przywara
        *ebx = 0;
1115 c6dc6f63 Andre Przywara
        *ecx = 0;
1116 c6dc6f63 Andre Przywara
        *edx = 0;
1117 c6dc6f63 Andre Przywara
        break;
1118 c6dc6f63 Andre Przywara
    case 9:
1119 c6dc6f63 Andre Przywara
        /* Direct Cache Access Information Leaf */
1120 c6dc6f63 Andre Przywara
        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
1121 c6dc6f63 Andre Przywara
        *ebx = 0;
1122 c6dc6f63 Andre Przywara
        *ecx = 0;
1123 c6dc6f63 Andre Przywara
        *edx = 0;
1124 c6dc6f63 Andre Przywara
        break;
1125 c6dc6f63 Andre Przywara
    case 0xA:
1126 c6dc6f63 Andre Przywara
        /* Architectural Performance Monitoring Leaf */
1127 c6dc6f63 Andre Przywara
        *eax = 0;
1128 c6dc6f63 Andre Przywara
        *ebx = 0;
1129 c6dc6f63 Andre Przywara
        *ecx = 0;
1130 c6dc6f63 Andre Przywara
        *edx = 0;
1131 c6dc6f63 Andre Przywara
        break;
1132 51e49430 Sheng Yang
    case 0xD:
1133 51e49430 Sheng Yang
        /* Processor Extended State */
1134 51e49430 Sheng Yang
        if (!(env->cpuid_ext_features & CPUID_EXT_XSAVE)) {
1135 51e49430 Sheng Yang
            *eax = 0;
1136 51e49430 Sheng Yang
            *ebx = 0;
1137 51e49430 Sheng Yang
            *ecx = 0;
1138 51e49430 Sheng Yang
            *edx = 0;
1139 51e49430 Sheng Yang
            break;
1140 51e49430 Sheng Yang
        }
1141 51e49430 Sheng Yang
        if (kvm_enabled()) {
1142 51e49430 Sheng Yang
            *eax = kvm_arch_get_supported_cpuid(env, 0xd, count, R_EAX);
1143 51e49430 Sheng Yang
            *ebx = kvm_arch_get_supported_cpuid(env, 0xd, count, R_EBX);
1144 51e49430 Sheng Yang
            *ecx = kvm_arch_get_supported_cpuid(env, 0xd, count, R_ECX);
1145 51e49430 Sheng Yang
            *edx = kvm_arch_get_supported_cpuid(env, 0xd, count, R_EDX);
1146 51e49430 Sheng Yang
        } else {
1147 51e49430 Sheng Yang
            *eax = 0;
1148 51e49430 Sheng Yang
            *ebx = 0;
1149 51e49430 Sheng Yang
            *ecx = 0;
1150 51e49430 Sheng Yang
            *edx = 0;
1151 51e49430 Sheng Yang
        }
1152 51e49430 Sheng Yang
        break;
1153 c6dc6f63 Andre Przywara
    case 0x80000000:
1154 c6dc6f63 Andre Przywara
        *eax = env->cpuid_xlevel;
1155 c6dc6f63 Andre Przywara
        *ebx = env->cpuid_vendor1;
1156 c6dc6f63 Andre Przywara
        *edx = env->cpuid_vendor2;
1157 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_vendor3;
1158 c6dc6f63 Andre Przywara
        break;
1159 c6dc6f63 Andre Przywara
    case 0x80000001:
1160 c6dc6f63 Andre Przywara
        *eax = env->cpuid_version;
1161 c6dc6f63 Andre Przywara
        *ebx = 0;
1162 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_ext3_features;
1163 c6dc6f63 Andre Przywara
        *edx = env->cpuid_ext2_features;
1164 c6dc6f63 Andre Przywara
1165 c6dc6f63 Andre Przywara
        /* The Linux kernel checks for the CMPLegacy bit and
1166 c6dc6f63 Andre Przywara
         * discards multiple thread information if it is set.
1167 c6dc6f63 Andre Przywara
         * So dont set it here for Intel to make Linux guests happy.
1168 c6dc6f63 Andre Przywara
         */
1169 c6dc6f63 Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1170 c6dc6f63 Andre Przywara
            uint32_t tebx, tecx, tedx;
1171 c6dc6f63 Andre Przywara
            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
1172 c6dc6f63 Andre Przywara
            if (tebx != CPUID_VENDOR_INTEL_1 ||
1173 c6dc6f63 Andre Przywara
                tedx != CPUID_VENDOR_INTEL_2 ||
1174 c6dc6f63 Andre Przywara
                tecx != CPUID_VENDOR_INTEL_3) {
1175 c6dc6f63 Andre Przywara
                *ecx |= 1 << 1;    /* CmpLegacy bit */
1176 c6dc6f63 Andre Przywara
            }
1177 c6dc6f63 Andre Przywara
        }
1178 c6dc6f63 Andre Przywara
        break;
1179 c6dc6f63 Andre Przywara
    case 0x80000002:
1180 c6dc6f63 Andre Przywara
    case 0x80000003:
1181 c6dc6f63 Andre Przywara
    case 0x80000004:
1182 c6dc6f63 Andre Przywara
        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
1183 c6dc6f63 Andre Przywara
        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
1184 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
1185 c6dc6f63 Andre Przywara
        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
1186 c6dc6f63 Andre Przywara
        break;
1187 c6dc6f63 Andre Przywara
    case 0x80000005:
1188 c6dc6f63 Andre Przywara
        /* cache info (L1 cache) */
1189 c6dc6f63 Andre Przywara
        *eax = 0x01ff01ff;
1190 c6dc6f63 Andre Przywara
        *ebx = 0x01ff01ff;
1191 c6dc6f63 Andre Przywara
        *ecx = 0x40020140;
1192 c6dc6f63 Andre Przywara
        *edx = 0x40020140;
1193 c6dc6f63 Andre Przywara
        break;
1194 c6dc6f63 Andre Przywara
    case 0x80000006:
1195 c6dc6f63 Andre Przywara
        /* cache info (L2 cache) */
1196 c6dc6f63 Andre Przywara
        *eax = 0;
1197 c6dc6f63 Andre Przywara
        *ebx = 0x42004200;
1198 c6dc6f63 Andre Przywara
        *ecx = 0x02008140;
1199 c6dc6f63 Andre Przywara
        *edx = 0;
1200 c6dc6f63 Andre Przywara
        break;
1201 c6dc6f63 Andre Przywara
    case 0x80000008:
1202 c6dc6f63 Andre Przywara
        /* virtual & phys address size in low 2 bytes. */
1203 c6dc6f63 Andre Przywara
/* XXX: This value must match the one used in the MMU code. */
1204 c6dc6f63 Andre Przywara
        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
1205 c6dc6f63 Andre Przywara
            /* 64 bit processor */
1206 c6dc6f63 Andre Przywara
/* XXX: The physical address space is limited to 42 bits in exec.c. */
1207 c6dc6f63 Andre Przywara
            *eax = 0x00003028;        /* 48 bits virtual, 40 bits physical */
1208 c6dc6f63 Andre Przywara
        } else {
1209 c6dc6f63 Andre Przywara
            if (env->cpuid_features & CPUID_PSE36)
1210 c6dc6f63 Andre Przywara
                *eax = 0x00000024; /* 36 bits physical */
1211 c6dc6f63 Andre Przywara
            else
1212 c6dc6f63 Andre Przywara
                *eax = 0x00000020; /* 32 bits physical */
1213 c6dc6f63 Andre Przywara
        }
1214 c6dc6f63 Andre Przywara
        *ebx = 0;
1215 c6dc6f63 Andre Przywara
        *ecx = 0;
1216 c6dc6f63 Andre Przywara
        *edx = 0;
1217 c6dc6f63 Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1218 c6dc6f63 Andre Przywara
            *ecx |= (env->nr_cores * env->nr_threads) - 1;
1219 c6dc6f63 Andre Przywara
        }
1220 c6dc6f63 Andre Przywara
        break;
1221 c6dc6f63 Andre Przywara
    case 0x8000000A:
1222 296acb64 Joerg Roedel
        if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
1223 296acb64 Joerg Roedel
                *eax = 0x00000001; /* SVM Revision */
1224 296acb64 Joerg Roedel
                *ebx = 0x00000010; /* nr of ASIDs */
1225 296acb64 Joerg Roedel
                *ecx = 0;
1226 296acb64 Joerg Roedel
                *edx = env->cpuid_svm_features; /* optional features */
1227 296acb64 Joerg Roedel
        } else {
1228 296acb64 Joerg Roedel
                *eax = 0;
1229 296acb64 Joerg Roedel
                *ebx = 0;
1230 296acb64 Joerg Roedel
                *ecx = 0;
1231 296acb64 Joerg Roedel
                *edx = 0;
1232 296acb64 Joerg Roedel
        }
1233 c6dc6f63 Andre Przywara
        break;
1234 c6dc6f63 Andre Przywara
    default:
1235 c6dc6f63 Andre Przywara
        /* reserved values: zero */
1236 c6dc6f63 Andre Przywara
        *eax = 0;
1237 c6dc6f63 Andre Przywara
        *ebx = 0;
1238 c6dc6f63 Andre Przywara
        *ecx = 0;
1239 c6dc6f63 Andre Przywara
        *edx = 0;
1240 c6dc6f63 Andre Przywara
        break;
1241 c6dc6f63 Andre Przywara
    }
1242 c6dc6f63 Andre Przywara
}