Statistics
| Branch: | Revision:

root / target-i386 / cpuid.c @ c2162a8b

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