]>
Commit | Line | Data |
---|---|---|
9be61fa4 OB |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Robert Hoo <robert.hu@linux.intel.com> | |
3 | Date: Mon, 15 Oct 2018 12:47:24 +0800 | |
4 | Subject: [PATCH 6/9] x86: Data structure changes to support MSR based features | |
5 | ||
6 | Add FeatureWordType indicator in struct FeatureWordInfo. | |
7 | Change feature_word_info[] accordingly. | |
8 | Change existing functions that refer to feature_word_info[] accordingly. | |
9 | ||
10 | Signed-off-by: Robert Hoo <robert.hu@linux.intel.com> | |
11 | Message-Id: <1539578845-37944-3-git-send-email-robert.hu@linux.intel.com> | |
12 | [ehabkost: fixed hvf_enabled() case] | |
13 | Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> | |
14 | --- | |
15 | target/i386/cpu.c | 197 +++++++++++++++++++++++++++++++++------------- | |
16 | 1 file changed, 142 insertions(+), 55 deletions(-) | |
17 | ||
18 | diff --git a/target/i386/cpu.c b/target/i386/cpu.c | |
19 | index 1d74be02ce..d2985144a3 100644 | |
20 | --- a/target/i386/cpu.c | |
21 | +++ b/target/i386/cpu.c | |
22 | @@ -770,17 +770,36 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, | |
23 | /* missing: | |
24 | CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */ | |
25 | ||
26 | +typedef enum FeatureWordType { | |
27 | + CPUID_FEATURE_WORD, | |
28 | + MSR_FEATURE_WORD, | |
29 | +} FeatureWordType; | |
30 | + | |
31 | typedef struct FeatureWordInfo { | |
32 | + FeatureWordType type; | |
33 | /* feature flags names are taken from "Intel Processor Identification and | |
34 | * the CPUID Instruction" and AMD's "CPUID Specification". | |
35 | * In cases of disagreement between feature naming conventions, | |
36 | * aliases may be added. | |
37 | */ | |
38 | const char *feat_names[32]; | |
39 | - uint32_t cpuid_eax; /* Input EAX for CPUID */ | |
40 | - bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */ | |
41 | - uint32_t cpuid_ecx; /* Input ECX value for CPUID */ | |
42 | - int cpuid_reg; /* output register (R_* constant) */ | |
43 | + union { | |
44 | + /* If type==CPUID_FEATURE_WORD */ | |
45 | + struct { | |
46 | + uint32_t eax; /* Input EAX for CPUID */ | |
47 | + bool needs_ecx; /* CPUID instruction uses ECX as input */ | |
48 | + uint32_t ecx; /* Input ECX value for CPUID */ | |
49 | + int reg; /* output register (R_* constant) */ | |
50 | + } cpuid; | |
51 | + /* If type==MSR_FEATURE_WORD */ | |
52 | + struct { | |
53 | + uint32_t index; | |
54 | + struct { /*CPUID that enumerate this MSR*/ | |
55 | + FeatureWord cpuid_class; | |
56 | + uint32_t cpuid_flag; | |
57 | + } cpuid_dep; | |
58 | + } msr; | |
59 | + }; | |
60 | uint32_t tcg_features; /* Feature flags supported by TCG */ | |
61 | uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */ | |
62 | uint32_t migratable_flags; /* Feature flags known to be migratable */ | |
63 | @@ -790,6 +809,7 @@ typedef struct FeatureWordInfo { | |
64 | ||
65 | static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
66 | [FEAT_1_EDX] = { | |
67 | + .type = CPUID_FEATURE_WORD, | |
68 | .feat_names = { | |
69 | "fpu", "vme", "de", "pse", | |
70 | "tsc", "msr", "pae", "mce", | |
71 | @@ -800,10 +820,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
72 | "fxsr", "sse", "sse2", "ss", | |
73 | "ht" /* Intel htt */, "tm", "ia64", "pbe", | |
74 | }, | |
75 | - .cpuid_eax = 1, .cpuid_reg = R_EDX, | |
76 | + .cpuid = {.eax = 1, .reg = R_EDX, }, | |
77 | .tcg_features = TCG_FEATURES, | |
78 | }, | |
79 | [FEAT_1_ECX] = { | |
80 | + .type = CPUID_FEATURE_WORD, | |
81 | .feat_names = { | |
82 | "pni" /* Intel,AMD sse3 */, "pclmulqdq", "dtes64", "monitor", | |
83 | "ds-cpl", "vmx", "smx", "est", | |
84 | @@ -814,7 +835,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
85 | "tsc-deadline", "aes", "xsave", NULL /* osxsave */, | |
86 | "avx", "f16c", "rdrand", "hypervisor", | |
87 | }, | |
88 | - .cpuid_eax = 1, .cpuid_reg = R_ECX, | |
89 | + .cpuid = { .eax = 1, .reg = R_ECX, }, | |
90 | .tcg_features = TCG_EXT_FEATURES, | |
91 | }, | |
92 | /* Feature names that are already defined on feature_name[] but | |
93 | @@ -823,6 +844,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
94 | * to features[FEAT_8000_0001_EDX] if and only if CPU vendor is AMD. | |
95 | */ | |
96 | [FEAT_8000_0001_EDX] = { | |
97 | + .type = CPUID_FEATURE_WORD, | |
98 | .feat_names = { | |
99 | NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */, | |
100 | NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */, | |
101 | @@ -833,10 +855,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
102 | NULL /* fxsr */, "fxsr-opt", "pdpe1gb", "rdtscp", | |
103 | NULL, "lm", "3dnowext", "3dnow", | |
104 | }, | |
105 | - .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX, | |
106 | + .cpuid = { .eax = 0x80000001, .reg = R_EDX, }, | |
107 | .tcg_features = TCG_EXT2_FEATURES, | |
108 | }, | |
109 | [FEAT_8000_0001_ECX] = { | |
110 | + .type = CPUID_FEATURE_WORD, | |
111 | .feat_names = { | |
112 | "lahf-lm", "cmp-legacy", "svm", "extapic", | |
113 | "cr8legacy", "abm", "sse4a", "misalignsse", | |
114 | @@ -847,7 +870,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
115 | "perfctr-nb", NULL, NULL, NULL, | |
116 | NULL, NULL, NULL, NULL, | |
117 | }, | |
118 | - .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX, | |
119 | + .cpuid = { .eax = 0x80000001, .reg = R_ECX, }, | |
120 | .tcg_features = TCG_EXT3_FEATURES, | |
121 | /* | |
122 | * TOPOEXT is always allowed but can't be enabled blindly by | |
123 | @@ -857,6 +880,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
124 | .no_autoenable_flags = CPUID_EXT3_TOPOEXT, | |
125 | }, | |
126 | [FEAT_C000_0001_EDX] = { | |
127 | + .type = CPUID_FEATURE_WORD, | |
128 | .feat_names = { | |
129 | NULL, NULL, "xstore", "xstore-en", | |
130 | NULL, NULL, "xcrypt", "xcrypt-en", | |
131 | @@ -867,10 +891,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
132 | NULL, NULL, NULL, NULL, | |
133 | NULL, NULL, NULL, NULL, | |
134 | }, | |
135 | - .cpuid_eax = 0xC0000001, .cpuid_reg = R_EDX, | |
136 | + .cpuid = { .eax = 0xC0000001, .reg = R_EDX, }, | |
137 | .tcg_features = TCG_EXT4_FEATURES, | |
138 | }, | |
139 | [FEAT_KVM] = { | |
140 | + .type = CPUID_FEATURE_WORD, | |
141 | .feat_names = { | |
142 | "kvmclock", "kvm-nopiodelay", "kvm-mmu", "kvmclock", | |
143 | "kvm-asyncpf", "kvm-steal-time", "kvm-pv-eoi", "kvm-pv-unhalt", | |
144 | @@ -881,10 +906,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
145 | "kvmclock-stable-bit", NULL, NULL, NULL, | |
146 | NULL, NULL, NULL, NULL, | |
147 | }, | |
148 | - .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX, | |
149 | + .cpuid = { .eax = KVM_CPUID_FEATURES, .reg = R_EAX, }, | |
150 | .tcg_features = TCG_KVM_FEATURES, | |
151 | }, | |
152 | [FEAT_KVM_HINTS] = { | |
153 | + .type = CPUID_FEATURE_WORD, | |
154 | .feat_names = { | |
155 | "kvm-hint-dedicated", NULL, NULL, NULL, | |
156 | NULL, NULL, NULL, NULL, | |
157 | @@ -895,7 +921,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
158 | NULL, NULL, NULL, NULL, | |
159 | NULL, NULL, NULL, NULL, | |
160 | }, | |
161 | - .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EDX, | |
162 | + .cpuid = { .eax = KVM_CPUID_FEATURES, .reg = R_EDX, }, | |
163 | .tcg_features = TCG_KVM_FEATURES, | |
164 | /* | |
165 | * KVM hints aren't auto-enabled by -cpu host, they need to be | |
166 | @@ -904,6 +930,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
167 | .no_autoenable_flags = ~0U, | |
168 | }, | |
169 | [FEAT_HYPERV_EAX] = { | |
170 | + .type = CPUID_FEATURE_WORD, | |
171 | .feat_names = { | |
172 | NULL /* hv_msr_vp_runtime_access */, NULL /* hv_msr_time_refcount_access */, | |
173 | NULL /* hv_msr_synic_access */, NULL /* hv_msr_stimer_access */, | |
174 | @@ -918,9 +945,10 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
175 | NULL, NULL, NULL, NULL, | |
176 | NULL, NULL, NULL, NULL, | |
177 | }, | |
178 | - .cpuid_eax = 0x40000003, .cpuid_reg = R_EAX, | |
179 | + .cpuid = { .eax = 0x40000003, .reg = R_EAX, }, | |
180 | }, | |
181 | [FEAT_HYPERV_EBX] = { | |
182 | + .type = CPUID_FEATURE_WORD, | |
183 | .feat_names = { | |
184 | NULL /* hv_create_partitions */, NULL /* hv_access_partition_id */, | |
185 | NULL /* hv_access_memory_pool */, NULL /* hv_adjust_message_buffers */, | |
186 | @@ -934,9 +962,10 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
187 | NULL, NULL, NULL, NULL, | |
188 | NULL, NULL, NULL, NULL, | |
189 | }, | |
190 | - .cpuid_eax = 0x40000003, .cpuid_reg = R_EBX, | |
191 | + .cpuid = { .eax = 0x40000003, .reg = R_EBX, }, | |
192 | }, | |
193 | [FEAT_HYPERV_EDX] = { | |
194 | + .type = CPUID_FEATURE_WORD, | |
195 | .feat_names = { | |
196 | NULL /* hv_mwait */, NULL /* hv_guest_debugging */, | |
197 | NULL /* hv_perf_monitor */, NULL /* hv_cpu_dynamic_part */, | |
198 | @@ -949,9 +978,10 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
199 | NULL, NULL, NULL, NULL, | |
200 | NULL, NULL, NULL, NULL, | |
201 | }, | |
202 | - .cpuid_eax = 0x40000003, .cpuid_reg = R_EDX, | |
203 | + .cpuid = { .eax = 0x40000003, .reg = R_EDX, }, | |
204 | }, | |
205 | [FEAT_SVM] = { | |
206 | + .type = CPUID_FEATURE_WORD, | |
207 | .feat_names = { | |
208 | "npt", "lbrv", "svm-lock", "nrip-save", | |
209 | "tsc-scale", "vmcb-clean", "flushbyasid", "decodeassists", | |
210 | @@ -962,10 +992,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
211 | NULL, NULL, NULL, NULL, | |
212 | NULL, NULL, NULL, NULL, | |
213 | }, | |
214 | - .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX, | |
215 | + .cpuid = { .eax = 0x8000000A, .reg = R_EDX, }, | |
216 | .tcg_features = TCG_SVM_FEATURES, | |
217 | }, | |
218 | [FEAT_7_0_EBX] = { | |
219 | + .type = CPUID_FEATURE_WORD, | |
220 | .feat_names = { | |
221 | "fsgsbase", "tsc-adjust", NULL, "bmi1", | |
222 | "hle", "avx2", NULL, "smep", | |
223 | @@ -976,12 +1007,15 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
224 | "clwb", "intel-pt", "avx512pf", "avx512er", | |
225 | "avx512cd", "sha-ni", "avx512bw", "avx512vl", | |
226 | }, | |
227 | - .cpuid_eax = 7, | |
228 | - .cpuid_needs_ecx = true, .cpuid_ecx = 0, | |
229 | - .cpuid_reg = R_EBX, | |
230 | + .cpuid = { | |
231 | + .eax = 7, | |
232 | + .needs_ecx = true, .ecx = 0, | |
233 | + .reg = R_EBX, | |
234 | + }, | |
235 | .tcg_features = TCG_7_0_EBX_FEATURES, | |
236 | }, | |
237 | [FEAT_7_0_ECX] = { | |
238 | + .type = CPUID_FEATURE_WORD, | |
239 | .feat_names = { | |
240 | NULL, "avx512vbmi", "umip", "pku", | |
241 | NULL /* ospke */, NULL, "avx512vbmi2", NULL, | |
242 | @@ -992,12 +1026,15 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
243 | NULL, "cldemote", NULL, NULL, | |
244 | NULL, NULL, NULL, NULL, | |
245 | }, | |
246 | - .cpuid_eax = 7, | |
247 | - .cpuid_needs_ecx = true, .cpuid_ecx = 0, | |
248 | - .cpuid_reg = R_ECX, | |
249 | + .cpuid = { | |
250 | + .eax = 7, | |
251 | + .needs_ecx = true, .ecx = 0, | |
252 | + .reg = R_ECX, | |
253 | + }, | |
254 | .tcg_features = TCG_7_0_ECX_FEATURES, | |
255 | }, | |
256 | [FEAT_7_0_EDX] = { | |
257 | + .type = CPUID_FEATURE_WORD, | |
258 | .feat_names = { | |
259 | NULL, NULL, "avx512-4vnniw", "avx512-4fmaps", | |
260 | NULL, NULL, NULL, NULL, | |
261 | @@ -1008,13 +1045,16 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
262 | NULL, NULL, "spec-ctrl", NULL, | |
263 | NULL, "arch-capabilities", NULL, "ssbd", | |
264 | }, | |
265 | - .cpuid_eax = 7, | |
266 | - .cpuid_needs_ecx = true, .cpuid_ecx = 0, | |
267 | - .cpuid_reg = R_EDX, | |
268 | + .cpuid = { | |
269 | + .eax = 7, | |
270 | + .needs_ecx = true, .ecx = 0, | |
271 | + .reg = R_EDX, | |
272 | + }, | |
273 | .tcg_features = TCG_7_0_EDX_FEATURES, | |
274 | .unmigratable_flags = CPUID_7_0_EDX_ARCH_CAPABILITIES, | |
275 | }, | |
276 | [FEAT_8000_0007_EDX] = { | |
277 | + .type = CPUID_FEATURE_WORD, | |
278 | .feat_names = { | |
279 | NULL, NULL, NULL, NULL, | |
280 | NULL, NULL, NULL, NULL, | |
281 | @@ -1025,12 +1065,12 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
282 | NULL, NULL, NULL, NULL, | |
283 | NULL, NULL, NULL, NULL, | |
284 | }, | |
285 | - .cpuid_eax = 0x80000007, | |
286 | - .cpuid_reg = R_EDX, | |
287 | + .cpuid = { .eax = 0x80000007, .reg = R_EDX, }, | |
288 | .tcg_features = TCG_APM_FEATURES, | |
289 | .unmigratable_flags = CPUID_APM_INVTSC, | |
290 | }, | |
291 | [FEAT_8000_0008_EBX] = { | |
292 | + .type = CPUID_FEATURE_WORD, | |
293 | .feat_names = { | |
294 | NULL, NULL, NULL, NULL, | |
295 | NULL, NULL, NULL, NULL, | |
296 | @@ -1041,12 +1081,12 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
297 | "amd-ssbd", "virt-ssbd", "amd-no-ssb", NULL, | |
298 | NULL, NULL, NULL, NULL, | |
299 | }, | |
300 | - .cpuid_eax = 0x80000008, | |
301 | - .cpuid_reg = R_EBX, | |
302 | + .cpuid = { .eax = 0x80000008, .reg = R_EBX, }, | |
303 | .tcg_features = 0, | |
304 | .unmigratable_flags = 0, | |
305 | }, | |
306 | [FEAT_XSAVE] = { | |
307 | + .type = CPUID_FEATURE_WORD, | |
308 | .feat_names = { | |
309 | "xsaveopt", "xsavec", "xgetbv1", "xsaves", | |
310 | NULL, NULL, NULL, NULL, | |
311 | @@ -1057,12 +1097,15 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
312 | NULL, NULL, NULL, NULL, | |
313 | NULL, NULL, NULL, NULL, | |
314 | }, | |
315 | - .cpuid_eax = 0xd, | |
316 | - .cpuid_needs_ecx = true, .cpuid_ecx = 1, | |
317 | - .cpuid_reg = R_EAX, | |
318 | + .cpuid = { | |
319 | + .eax = 0xd, | |
320 | + .needs_ecx = true, .ecx = 1, | |
321 | + .reg = R_EAX, | |
322 | + }, | |
323 | .tcg_features = TCG_XSAVE_FEATURES, | |
324 | }, | |
325 | [FEAT_6_EAX] = { | |
326 | + .type = CPUID_FEATURE_WORD, | |
327 | .feat_names = { | |
328 | NULL, NULL, "arat", NULL, | |
329 | NULL, NULL, NULL, NULL, | |
330 | @@ -1073,13 +1116,16 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
331 | NULL, NULL, NULL, NULL, | |
332 | NULL, NULL, NULL, NULL, | |
333 | }, | |
334 | - .cpuid_eax = 6, .cpuid_reg = R_EAX, | |
335 | + .cpuid = { .eax = 6, .reg = R_EAX, }, | |
336 | .tcg_features = TCG_6_EAX_FEATURES, | |
337 | }, | |
338 | [FEAT_XSAVE_COMP_LO] = { | |
339 | - .cpuid_eax = 0xD, | |
340 | - .cpuid_needs_ecx = true, .cpuid_ecx = 0, | |
341 | - .cpuid_reg = R_EAX, | |
342 | + .type = CPUID_FEATURE_WORD, | |
343 | + .cpuid = { | |
344 | + .eax = 0xD, | |
345 | + .needs_ecx = true, .ecx = 0, | |
346 | + .reg = R_EAX, | |
347 | + }, | |
348 | .tcg_features = ~0U, | |
349 | .migratable_flags = XSTATE_FP_MASK | XSTATE_SSE_MASK | | |
350 | XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK | | |
351 | @@ -1087,9 +1133,12 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { | |
352 | XSTATE_PKRU_MASK, | |
353 | }, | |
354 | [FEAT_XSAVE_COMP_HI] = { | |
355 | - .cpuid_eax = 0xD, | |
356 | - .cpuid_needs_ecx = true, .cpuid_ecx = 0, | |
357 | - .cpuid_reg = R_EDX, | |
358 | + .type = CPUID_FEATURE_WORD, | |
359 | + .cpuid = { | |
360 | + .eax = 0xD, | |
361 | + .needs_ecx = true, .ecx = 0, | |
362 | + .reg = R_EDX, | |
363 | + }, | |
364 | .tcg_features = ~0U, | |
365 | }, | |
366 | }; | |
367 | @@ -2860,21 +2909,41 @@ static const TypeInfo host_x86_cpu_type_info = { | |
368 | ||
369 | #endif | |
370 | ||
371 | +static char *feature_word_description(FeatureWordInfo *f, uint32_t bit) | |
372 | +{ | |
373 | + assert(f->type == CPUID_FEATURE_WORD || f->type == MSR_FEATURE_WORD); | |
374 | + | |
375 | + switch (f->type) { | |
376 | + case CPUID_FEATURE_WORD: | |
377 | + { | |
378 | + const char *reg = get_register_name_32(f->cpuid.reg); | |
379 | + assert(reg); | |
380 | + return g_strdup_printf("CPUID.%02XH:%s", | |
381 | + f->cpuid.eax, reg); | |
382 | + } | |
383 | + case MSR_FEATURE_WORD: | |
384 | + return g_strdup_printf("MSR(%02XH)", | |
385 | + f->msr.index); | |
386 | + } | |
387 | + | |
388 | + return NULL; | |
389 | +} | |
390 | + | |
391 | static void report_unavailable_features(FeatureWord w, uint32_t mask) | |
392 | { | |
393 | FeatureWordInfo *f = &feature_word_info[w]; | |
394 | int i; | |
395 | + char *feat_word_str; | |
396 | ||
397 | for (i = 0; i < 32; ++i) { | |
398 | if ((1UL << i) & mask) { | |
399 | - const char *reg = get_register_name_32(f->cpuid_reg); | |
400 | - assert(reg); | |
401 | - warn_report("%s doesn't support requested feature: " | |
402 | - "CPUID.%02XH:%s%s%s [bit %d]", | |
403 | + feat_word_str = feature_word_description(f, i); | |
404 | + warn_report("%s doesn't support requested feature: %s%s%s [bit %d]", | |
405 | accel_uses_host_cpuid() ? "host" : "TCG", | |
406 | - f->cpuid_eax, reg, | |
407 | + feat_word_str, | |
408 | f->feat_names[i] ? "." : "", | |
409 | f->feat_names[i] ? f->feat_names[i] : "", i); | |
410 | + g_free(feat_word_str); | |
411 | } | |
412 | } | |
413 | } | |
414 | @@ -3118,11 +3187,18 @@ static void x86_cpu_get_feature_words(Object *obj, Visitor *v, | |
415 | ||
416 | for (w = 0; w < FEATURE_WORDS; w++) { | |
417 | FeatureWordInfo *wi = &feature_word_info[w]; | |
418 | + /* | |
419 | + * We didn't have MSR features when "feature-words" was | |
420 | + * introduced. Therefore skipped other type entries. | |
421 | + */ | |
422 | + if (wi->type != CPUID_FEATURE_WORD) { | |
423 | + continue; | |
424 | + } | |
425 | X86CPUFeatureWordInfo *qwi = &word_infos[w]; | |
426 | - qwi->cpuid_input_eax = wi->cpuid_eax; | |
427 | - qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx; | |
428 | - qwi->cpuid_input_ecx = wi->cpuid_ecx; | |
429 | - qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum; | |
430 | + qwi->cpuid_input_eax = wi->cpuid.eax; | |
431 | + qwi->has_cpuid_input_ecx = wi->cpuid.needs_ecx; | |
432 | + qwi->cpuid_input_ecx = wi->cpuid.ecx; | |
433 | + qwi->cpuid_register = x86_reg_info_32[wi->cpuid.reg].qapi_enum; | |
434 | qwi->features = array[w]; | |
435 | ||
436 | /* List will be in reverse order, but order shouldn't matter */ | |
437 | @@ -3495,16 +3571,26 @@ static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w, | |
438 | bool migratable_only) | |
439 | { | |
440 | FeatureWordInfo *wi = &feature_word_info[w]; | |
441 | - uint32_t r; | |
442 | + uint32_t r = 0; | |
443 | ||
444 | if (kvm_enabled()) { | |
445 | - r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid_eax, | |
446 | - wi->cpuid_ecx, | |
447 | - wi->cpuid_reg); | |
448 | + switch (wi->type) { | |
449 | + case CPUID_FEATURE_WORD: | |
450 | + r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid.eax, | |
451 | + wi->cpuid.ecx, | |
452 | + wi->cpuid.reg); | |
453 | + break; | |
454 | + case MSR_FEATURE_WORD: | |
455 | + r = kvm_arch_get_supported_msr_feature(kvm_state, wi->msr.index); | |
456 | + break; | |
457 | + } | |
458 | } else if (hvf_enabled()) { | |
459 | - r = hvf_get_supported_cpuid(wi->cpuid_eax, | |
460 | - wi->cpuid_ecx, | |
461 | - wi->cpuid_reg); | |
462 | + if (wi->type != CPUID_FEATURE_WORD) { | |
463 | + return 0; | |
464 | + } | |
465 | + r = hvf_get_supported_cpuid(wi->cpuid.eax, | |
466 | + wi->cpuid.ecx, | |
467 | + wi->cpuid.reg); | |
468 | } else if (tcg_enabled()) { | |
469 | r = wi->tcg_features; | |
470 | } else { | |
471 | @@ -4568,9 +4654,10 @@ static void x86_cpu_adjust_feat_level(X86CPU *cpu, FeatureWord w) | |
472 | { | |
473 | CPUX86State *env = &cpu->env; | |
474 | FeatureWordInfo *fi = &feature_word_info[w]; | |
475 | - uint32_t eax = fi->cpuid_eax; | |
476 | + uint32_t eax = fi->cpuid.eax; | |
477 | uint32_t region = eax & 0xF0000000; | |
478 | ||
479 | + assert(feature_word_info[w].type == CPUID_FEATURE_WORD); | |
480 | if (!env->features[w]) { | |
481 | return; | |
482 | } | |
483 | -- | |
484 | 2.20.1 | |
485 |