1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "qemu/units.h"
22#include "qemu/cutils.h"
23#include "qemu/bitops.h"
24
25#include "cpu.h"
26#include "exec/exec-all.h"
27#include "sysemu/kvm.h"
28#include "sysemu/hvf.h"
29#include "sysemu/cpus.h"
30#include "kvm_i386.h"
31#include "sev_i386.h"
32
33#include "qemu/error-report.h"
34#include "qemu/option.h"
35#include "qemu/config-file.h"
36#include "qapi/error.h"
37#include "qapi/qapi-visit-misc.h"
38#include "qapi/qapi-visit-run-state.h"
39#include "qapi/qmp/qdict.h"
40#include "qapi/qmp/qerror.h"
41#include "qapi/visitor.h"
42#include "qom/qom-qobject.h"
43#include "sysemu/arch_init.h"
44
45#include "standard-headers/asm-x86/kvm_para.h"
46
47#include "sysemu/sysemu.h"
48#include "hw/qdev-properties.h"
49#include "hw/i386/topology.h"
50#ifndef CONFIG_USER_ONLY
51#include "exec/address-spaces.h"
52#include "hw/hw.h"
53#include "hw/xen/xen.h"
54#include "hw/i386/apic_internal.h"
55#endif
56
57#include "disas/capstone.h"
58
59
60
61struct CPUID2CacheDescriptorInfo {
62 enum CacheType type;
63 int level;
64 int size;
65 int line_size;
66 int associativity;
67};
68
69
70
71
72
73struct CPUID2CacheDescriptorInfo cpuid2_cache_descriptors[] = {
74 [0x06] = { .level = 1, .type = INSTRUCTION_CACHE, .size = 8 * KiB,
75 .associativity = 4, .line_size = 32, },
76 [0x08] = { .level = 1, .type = INSTRUCTION_CACHE, .size = 16 * KiB,
77 .associativity = 4, .line_size = 32, },
78 [0x09] = { .level = 1, .type = INSTRUCTION_CACHE, .size = 32 * KiB,
79 .associativity = 4, .line_size = 64, },
80 [0x0A] = { .level = 1, .type = DATA_CACHE, .size = 8 * KiB,
81 .associativity = 2, .line_size = 32, },
82 [0x0C] = { .level = 1, .type = DATA_CACHE, .size = 16 * KiB,
83 .associativity = 4, .line_size = 32, },
84 [0x0D] = { .level = 1, .type = DATA_CACHE, .size = 16 * KiB,
85 .associativity = 4, .line_size = 64, },
86 [0x0E] = { .level = 1, .type = DATA_CACHE, .size = 24 * KiB,
87 .associativity = 6, .line_size = 64, },
88 [0x1D] = { .level = 2, .type = UNIFIED_CACHE, .size = 128 * KiB,
89 .associativity = 2, .line_size = 64, },
90 [0x21] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
91 .associativity = 8, .line_size = 64, },
92
93
94
95 [0x24] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
96 .associativity = 16, .line_size = 64, },
97
98
99
100 [0x2C] = { .level = 1, .type = DATA_CACHE, .size = 32 * KiB,
101 .associativity = 8, .line_size = 64, },
102 [0x30] = { .level = 1, .type = INSTRUCTION_CACHE, .size = 32 * KiB,
103 .associativity = 8, .line_size = 64, },
104 [0x41] = { .level = 2, .type = UNIFIED_CACHE, .size = 128 * KiB,
105 .associativity = 4, .line_size = 32, },
106 [0x42] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
107 .associativity = 4, .line_size = 32, },
108 [0x43] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
109 .associativity = 4, .line_size = 32, },
110 [0x44] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
111 .associativity = 4, .line_size = 32, },
112 [0x45] = { .level = 2, .type = UNIFIED_CACHE, .size = 2 * MiB,
113 .associativity = 4, .line_size = 32, },
114 [0x46] = { .level = 3, .type = UNIFIED_CACHE, .size = 4 * MiB,
115 .associativity = 4, .line_size = 64, },
116 [0x47] = { .level = 3, .type = UNIFIED_CACHE, .size = 8 * MiB,
117 .associativity = 8, .line_size = 64, },
118 [0x48] = { .level = 2, .type = UNIFIED_CACHE, .size = 3 * MiB,
119 .associativity = 12, .line_size = 64, },
120
121 [0x4A] = { .level = 3, .type = UNIFIED_CACHE, .size = 6 * MiB,
122 .associativity = 12, .line_size = 64, },
123 [0x4B] = { .level = 3, .type = UNIFIED_CACHE, .size = 8 * MiB,
124 .associativity = 16, .line_size = 64, },
125 [0x4C] = { .level = 3, .type = UNIFIED_CACHE, .size = 12 * MiB,
126 .associativity = 12, .line_size = 64, },
127 [0x4D] = { .level = 3, .type = UNIFIED_CACHE, .size = 16 * MiB,
128 .associativity = 16, .line_size = 64, },
129 [0x4E] = { .level = 2, .type = UNIFIED_CACHE, .size = 6 * MiB,
130 .associativity = 24, .line_size = 64, },
131 [0x60] = { .level = 1, .type = DATA_CACHE, .size = 16 * KiB,
132 .associativity = 8, .line_size = 64, },
133 [0x66] = { .level = 1, .type = DATA_CACHE, .size = 8 * KiB,
134 .associativity = 4, .line_size = 64, },
135 [0x67] = { .level = 1, .type = DATA_CACHE, .size = 16 * KiB,
136 .associativity = 4, .line_size = 64, },
137 [0x68] = { .level = 1, .type = DATA_CACHE, .size = 32 * KiB,
138 .associativity = 4, .line_size = 64, },
139 [0x78] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
140 .associativity = 4, .line_size = 64, },
141
142
143
144 [0x7D] = { .level = 2, .type = UNIFIED_CACHE, .size = 2 * MiB,
145 .associativity = 8, .line_size = 64, },
146 [0x7F] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
147 .associativity = 2, .line_size = 64, },
148 [0x80] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
149 .associativity = 8, .line_size = 64, },
150 [0x82] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
151 .associativity = 8, .line_size = 32, },
152 [0x83] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
153 .associativity = 8, .line_size = 32, },
154 [0x84] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
155 .associativity = 8, .line_size = 32, },
156 [0x85] = { .level = 2, .type = UNIFIED_CACHE, .size = 2 * MiB,
157 .associativity = 8, .line_size = 32, },
158 [0x86] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
159 .associativity = 4, .line_size = 64, },
160 [0x87] = { .level = 2, .type = UNIFIED_CACHE, .size = 1 * MiB,
161 .associativity = 8, .line_size = 64, },
162 [0xD0] = { .level = 3, .type = UNIFIED_CACHE, .size = 512 * KiB,
163 .associativity = 4, .line_size = 64, },
164 [0xD1] = { .level = 3, .type = UNIFIED_CACHE, .size = 1 * MiB,
165 .associativity = 4, .line_size = 64, },
166 [0xD2] = { .level = 3, .type = UNIFIED_CACHE, .size = 2 * MiB,
167 .associativity = 4, .line_size = 64, },
168 [0xD6] = { .level = 3, .type = UNIFIED_CACHE, .size = 1 * MiB,
169 .associativity = 8, .line_size = 64, },
170 [0xD7] = { .level = 3, .type = UNIFIED_CACHE, .size = 2 * MiB,
171 .associativity = 8, .line_size = 64, },
172 [0xD8] = { .level = 3, .type = UNIFIED_CACHE, .size = 4 * MiB,
173 .associativity = 8, .line_size = 64, },
174 [0xDC] = { .level = 3, .type = UNIFIED_CACHE, .size = 1.5 * MiB,
175 .associativity = 12, .line_size = 64, },
176 [0xDD] = { .level = 3, .type = UNIFIED_CACHE, .size = 3 * MiB,
177 .associativity = 12, .line_size = 64, },
178 [0xDE] = { .level = 3, .type = UNIFIED_CACHE, .size = 6 * MiB,
179 .associativity = 12, .line_size = 64, },
180 [0xE2] = { .level = 3, .type = UNIFIED_CACHE, .size = 2 * MiB,
181 .associativity = 16, .line_size = 64, },
182 [0xE3] = { .level = 3, .type = UNIFIED_CACHE, .size = 4 * MiB,
183 .associativity = 16, .line_size = 64, },
184 [0xE4] = { .level = 3, .type = UNIFIED_CACHE, .size = 8 * MiB,
185 .associativity = 16, .line_size = 64, },
186 [0xEA] = { .level = 3, .type = UNIFIED_CACHE, .size = 12 * MiB,
187 .associativity = 24, .line_size = 64, },
188 [0xEB] = { .level = 3, .type = UNIFIED_CACHE, .size = 18 * MiB,
189 .associativity = 24, .line_size = 64, },
190 [0xEC] = { .level = 3, .type = UNIFIED_CACHE, .size = 24 * MiB,
191 .associativity = 24, .line_size = 64, },
192};
193
194
195
196
197
198#define CACHE_DESCRIPTOR_UNAVAILABLE 0xFF
199
200
201
202
203
204static uint8_t cpuid2_cache_descriptor(CPUCacheInfo *cache)
205{
206 int i;
207
208 assert(cache->size > 0);
209 assert(cache->level > 0);
210 assert(cache->line_size > 0);
211 assert(cache->associativity > 0);
212 for (i = 0; i < ARRAY_SIZE(cpuid2_cache_descriptors); i++) {
213 struct CPUID2CacheDescriptorInfo *d = &cpuid2_cache_descriptors[i];
214 if (d->level == cache->level && d->type == cache->type &&
215 d->size == cache->size && d->line_size == cache->line_size &&
216 d->associativity == cache->associativity) {
217 return i;
218 }
219 }
220
221 return CACHE_DESCRIPTOR_UNAVAILABLE;
222}
223
224
225
226
227#define CACHE_TYPE_D 1
228#define CACHE_TYPE_I 2
229#define CACHE_TYPE_UNIFIED 3
230
231#define CACHE_LEVEL(l) (l << 5)
232
233#define CACHE_SELF_INIT_LEVEL (1 << 8)
234
235
236#define CACHE_NO_INVD_SHARING (1 << 0)
237#define CACHE_INCLUSIVE (1 << 1)
238#define CACHE_COMPLEX_IDX (1 << 2)
239
240
241#define CACHE_TYPE(t) (((t) == DATA_CACHE) ? CACHE_TYPE_D : \
242 ((t) == INSTRUCTION_CACHE) ? CACHE_TYPE_I : \
243 ((t) == UNIFIED_CACHE) ? CACHE_TYPE_UNIFIED : \
244 0 )
245
246
247
248static void encode_cache_cpuid4(CPUCacheInfo *cache,
249 int num_apic_ids, int num_cores,
250 uint32_t *eax, uint32_t *ebx,
251 uint32_t *ecx, uint32_t *edx)
252{
253 assert(cache->size == cache->line_size * cache->associativity *
254 cache->partitions * cache->sets);
255
256 assert(num_apic_ids > 0);
257 *eax = CACHE_TYPE(cache->type) |
258 CACHE_LEVEL(cache->level) |
259 (cache->self_init ? CACHE_SELF_INIT_LEVEL : 0) |
260 ((num_cores - 1) << 26) |
261 ((num_apic_ids - 1) << 14);
262
263 assert(cache->line_size > 0);
264 assert(cache->partitions > 0);
265 assert(cache->associativity > 0);
266
267 assert(cache->associativity < cache->sets);
268 *ebx = (cache->line_size - 1) |
269 ((cache->partitions - 1) << 12) |
270 ((cache->associativity - 1) << 22);
271
272 assert(cache->sets > 0);
273 *ecx = cache->sets - 1;
274
275 *edx = (cache->no_invd_sharing ? CACHE_NO_INVD_SHARING : 0) |
276 (cache->inclusive ? CACHE_INCLUSIVE : 0) |
277 (cache->complex_indexing ? CACHE_COMPLEX_IDX : 0);
278}
279
280
281static uint32_t encode_cache_cpuid80000005(CPUCacheInfo *cache)
282{
283 assert(cache->size % 1024 == 0);
284 assert(cache->lines_per_tag > 0);
285 assert(cache->associativity > 0);
286 assert(cache->line_size > 0);
287 return ((cache->size / 1024) << 24) | (cache->associativity << 16) |
288 (cache->lines_per_tag << 8) | (cache->line_size);
289}
290
291#define ASSOC_FULL 0xFF
292
293
294#define AMD_ENC_ASSOC(a) (a <= 1 ? a : \
295 a == 2 ? 0x2 : \
296 a == 4 ? 0x4 : \
297 a == 8 ? 0x6 : \
298 a == 16 ? 0x8 : \
299 a == 32 ? 0xA : \
300 a == 48 ? 0xB : \
301 a == 64 ? 0xC : \
302 a == 96 ? 0xD : \
303 a == 128 ? 0xE : \
304 a == ASSOC_FULL ? 0xF : \
305 0 )
306
307
308
309
310
311static void encode_cache_cpuid80000006(CPUCacheInfo *l2,
312 CPUCacheInfo *l3,
313 uint32_t *ecx, uint32_t *edx)
314{
315 assert(l2->size % 1024 == 0);
316 assert(l2->associativity > 0);
317 assert(l2->lines_per_tag > 0);
318 assert(l2->line_size > 0);
319 *ecx = ((l2->size / 1024) << 16) |
320 (AMD_ENC_ASSOC(l2->associativity) << 12) |
321 (l2->lines_per_tag << 8) | (l2->line_size);
322
323 if (l3) {
324 assert(l3->size % (512 * 1024) == 0);
325 assert(l3->associativity > 0);
326 assert(l3->lines_per_tag > 0);
327 assert(l3->line_size > 0);
328 *edx = ((l3->size / (512 * 1024)) << 18) |
329 (AMD_ENC_ASSOC(l3->associativity) << 12) |
330 (l3->lines_per_tag << 8) | (l3->line_size);
331 } else {
332 *edx = 0;
333 }
334}
335
336
337
338
339
340
341
342
343
344
345#define MAX_CCX 2
346
347#define MAX_CORES_IN_CCX 4
348
349#define MAX_CORES_IN_NODE 8
350
351#define MAX_NODES_PER_SOCKET 4
352
353
354
355
356
357static int nodes_in_socket(int nr_cores)
358{
359 int nodes;
360
361 nodes = DIV_ROUND_UP(nr_cores, MAX_CORES_IN_NODE);
362
363
364 return (nodes == 3) ? 4 : nodes;
365}
366
367
368
369
370
371
372
373
374static int cores_in_core_complex(int nr_cores)
375{
376 int nodes;
377
378
379 if (nr_cores <= MAX_CORES_IN_CCX) {
380 return nr_cores;
381 }
382
383 nodes = nodes_in_socket(nr_cores);
384
385
386
387
388
389 return DIV_ROUND_UP(nr_cores, nodes * MAX_CCX);
390}
391
392
393static void encode_cache_cpuid8000001d(CPUCacheInfo *cache, CPUState *cs,
394 uint32_t *eax, uint32_t *ebx,
395 uint32_t *ecx, uint32_t *edx)
396{
397 uint32_t l3_cores;
398 assert(cache->size == cache->line_size * cache->associativity *
399 cache->partitions * cache->sets);
400
401 *eax = CACHE_TYPE(cache->type) | CACHE_LEVEL(cache->level) |
402 (cache->self_init ? CACHE_SELF_INIT_LEVEL : 0);
403
404
405 if (cache->level == 3) {
406 l3_cores = cores_in_core_complex(cs->nr_cores);
407 *eax |= ((l3_cores * cs->nr_threads) - 1) << 14;
408 } else {
409 *eax |= ((cs->nr_threads - 1) << 14);
410 }
411
412 assert(cache->line_size > 0);
413 assert(cache->partitions > 0);
414 assert(cache->associativity > 0);
415
416 assert(cache->associativity < cache->sets);
417 *ebx = (cache->line_size - 1) |
418 ((cache->partitions - 1) << 12) |
419 ((cache->associativity - 1) << 22);
420
421 assert(cache->sets > 0);
422 *ecx = cache->sets - 1;
423
424 *edx = (cache->no_invd_sharing ? CACHE_NO_INVD_SHARING : 0) |
425 (cache->inclusive ? CACHE_INCLUSIVE : 0) |
426 (cache->complex_indexing ? CACHE_COMPLEX_IDX : 0);
427}
428
429
430struct core_topology {
431
432 int ccx_id;
433
434
435
436
437 int core_id;
438
439 int node_id;
440
441 int num_nodes;
442};
443
444
445
446
447
448
449
450
451
452static void build_core_topology(int nr_cores, int core_id,
453 struct core_topology *topo)
454{
455 int nodes, cores_in_ccx;
456
457
458 nodes = nodes_in_socket(nr_cores);
459
460 cores_in_ccx = cores_in_core_complex(nr_cores);
461
462 topo->node_id = core_id / (cores_in_ccx * MAX_CCX);
463 topo->ccx_id = (core_id % (cores_in_ccx * MAX_CCX)) / cores_in_ccx;
464 topo->core_id = core_id % cores_in_ccx;
465 topo->num_nodes = nodes;
466}
467
468
469static void encode_topo_cpuid8000001e(CPUState *cs, X86CPU *cpu,
470 uint32_t *eax, uint32_t *ebx,
471 uint32_t *ecx, uint32_t *edx)
472{
473 struct core_topology topo = {0};
474 unsigned long nodes;
475 int shift;
476
477 build_core_topology(cs->nr_cores, cpu->core_id, &topo);
478 *eax = cpu->apic_id;
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494 if (cs->nr_threads - 1) {
495 *ebx = ((cs->nr_threads - 1) << 8) | (topo.node_id << 3) |
496 (topo.ccx_id << 2) | topo.core_id;
497 } else {
498 *ebx = (topo.node_id << 4) | (topo.ccx_id << 3) | topo.core_id;
499 }
500
501
502
503
504
505
506
507
508 if (topo.num_nodes <= 4) {
509 *ecx = ((topo.num_nodes - 1) << 8) | (cpu->socket_id << 2) |
510 topo.node_id;
511 } else {
512
513
514
515
516
517
518
519
520
521
522
523
524
525 nodes = topo.num_nodes - 1;
526 shift = find_last_bit(&nodes, 8);
527 *ecx = ((topo.num_nodes - 1) << 8) | (cpu->socket_id << (shift + 1)) |
528 topo.node_id;
529 }
530 *edx = 0;
531}
532
533
534
535
536
537
538
539
540static CPUCacheInfo legacy_l1d_cache = {
541 .type = DATA_CACHE,
542 .level = 1,
543 .size = 32 * KiB,
544 .self_init = 1,
545 .line_size = 64,
546 .associativity = 8,
547 .sets = 64,
548 .partitions = 1,
549 .no_invd_sharing = true,
550};
551
552
553static CPUCacheInfo legacy_l1d_cache_amd = {
554 .type = DATA_CACHE,
555 .level = 1,
556 .size = 64 * KiB,
557 .self_init = 1,
558 .line_size = 64,
559 .associativity = 2,
560 .sets = 512,
561 .partitions = 1,
562 .lines_per_tag = 1,
563 .no_invd_sharing = true,
564};
565
566
567static CPUCacheInfo legacy_l1i_cache = {
568 .type = INSTRUCTION_CACHE,
569 .level = 1,
570 .size = 32 * KiB,
571 .self_init = 1,
572 .line_size = 64,
573 .associativity = 8,
574 .sets = 64,
575 .partitions = 1,
576 .no_invd_sharing = true,
577};
578
579
580static CPUCacheInfo legacy_l1i_cache_amd = {
581 .type = INSTRUCTION_CACHE,
582 .level = 1,
583 .size = 64 * KiB,
584 .self_init = 1,
585 .line_size = 64,
586 .associativity = 2,
587 .sets = 512,
588 .partitions = 1,
589 .lines_per_tag = 1,
590 .no_invd_sharing = true,
591};
592
593
594static CPUCacheInfo legacy_l2_cache = {
595 .type = UNIFIED_CACHE,
596 .level = 2,
597 .size = 4 * MiB,
598 .self_init = 1,
599 .line_size = 64,
600 .associativity = 16,
601 .sets = 4096,
602 .partitions = 1,
603 .no_invd_sharing = true,
604};
605
606
607static CPUCacheInfo legacy_l2_cache_cpuid2 = {
608 .type = UNIFIED_CACHE,
609 .level = 2,
610 .size = 2 * MiB,
611 .line_size = 64,
612 .associativity = 8,
613};
614
615
616
617static CPUCacheInfo legacy_l2_cache_amd = {
618 .type = UNIFIED_CACHE,
619 .level = 2,
620 .size = 512 * KiB,
621 .line_size = 64,
622 .lines_per_tag = 1,
623 .associativity = 16,
624 .sets = 512,
625 .partitions = 1,
626};
627
628
629static CPUCacheInfo legacy_l3_cache = {
630 .type = UNIFIED_CACHE,
631 .level = 3,
632 .size = 16 * MiB,
633 .line_size = 64,
634 .associativity = 16,
635 .sets = 16384,
636 .partitions = 1,
637 .lines_per_tag = 1,
638 .self_init = true,
639 .inclusive = true,
640 .complex_indexing = true,
641};
642
643
644
645#define L1_DTLB_2M_ASSOC 1
646#define L1_DTLB_2M_ENTRIES 255
647#define L1_DTLB_4K_ASSOC 1
648#define L1_DTLB_4K_ENTRIES 255
649
650#define L1_ITLB_2M_ASSOC 1
651#define L1_ITLB_2M_ENTRIES 255
652#define L1_ITLB_4K_ASSOC 1
653#define L1_ITLB_4K_ENTRIES 255
654
655#define L2_DTLB_2M_ASSOC 0
656#define L2_DTLB_2M_ENTRIES 0
657#define L2_DTLB_4K_ASSOC 4
658#define L2_DTLB_4K_ENTRIES 512
659
660#define L2_ITLB_2M_ASSOC 0
661#define L2_ITLB_2M_ENTRIES 0
662#define L2_ITLB_4K_ASSOC 4
663#define L2_ITLB_4K_ENTRIES 512
664
665
666#define INTEL_PT_MAX_SUBLEAF 0x1
667
668
669
670
671
672
673
674
675#define INTEL_PT_MINIMAL_EBX 0xf
676
677
678
679
680
681
682
683
684
685#define INTEL_PT_MINIMAL_ECX 0x7
686
687#define INTEL_PT_IP_LIP (1 << 31)
688#define INTEL_PT_ADDR_RANGES_NUM 0x2
689#define INTEL_PT_ADDR_RANGES_NUM_MASK 0x3
690#define INTEL_PT_MTC_BITMAP (0x0249 << 16)
691#define INTEL_PT_CYCLE_BITMAP 0x1fff
692#define INTEL_PT_PSB_BITMAP (0x003f << 16)
693
694static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
695 uint32_t vendor2, uint32_t vendor3)
696{
697 int i;
698 for (i = 0; i < 4; i++) {
699 dst[i] = vendor1 >> (8 * i);
700 dst[i + 4] = vendor2 >> (8 * i);
701 dst[i + 8] = vendor3 >> (8 * i);
702 }
703 dst[CPUID_VENDOR_SZ] = '\0';
704}
705
706#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
707#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
708 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
709#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
710 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
711 CPUID_PSE36 | CPUID_FXSR)
712#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
713#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
714 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
715 CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
716 CPUID_PAE | CPUID_SEP | CPUID_APIC)
717
718#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
719 CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
720 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
721 CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
722 CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS | CPUID_DE)
723
724
725
726
727#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
728 CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
729 CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
730 CPUID_EXT_XSAVE | \
731 CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
732
733
734
735
736
737
738
739#ifdef TARGET_X86_64
740#define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM)
741#else
742#define TCG_EXT2_X86_64_FEATURES 0
743#endif
744
745#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
746 CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
747 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_PDPE1GB | \
748 TCG_EXT2_X86_64_FEATURES)
749#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
750 CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
751#define TCG_EXT4_FEATURES 0
752#define TCG_SVM_FEATURES CPUID_SVM_NPT
753#define TCG_KVM_FEATURES 0
754#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
755 CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
756 CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT | \
757 CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE | \
758 CPUID_7_0_EBX_ERMS)
759
760
761
762
763#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | \
764 \
765 CPUID_7_0_ECX_LA57)
766#define TCG_7_0_EDX_FEATURES 0
767#define TCG_APM_FEATURES 0
768#define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
769#define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1)
770
771
772
773typedef enum FeatureWordType {
774 CPUID_FEATURE_WORD,
775 MSR_FEATURE_WORD,
776} FeatureWordType;
777
778typedef struct FeatureWordInfo {
779 FeatureWordType type;
780
781
782
783
784
785 const char *feat_names[32];
786 union {
787
788 struct {
789 uint32_t eax;
790 bool needs_ecx;
791 uint32_t ecx;
792 int reg;
793 } cpuid;
794
795 struct {
796 uint32_t index;
797 struct {
798 FeatureWord cpuid_class;
799 uint32_t cpuid_flag;
800 } cpuid_dep;
801 } msr;
802 };
803 uint32_t tcg_features;
804 uint32_t unmigratable_flags;
805 uint32_t migratable_flags;
806
807 uint32_t no_autoenable_flags;
808} FeatureWordInfo;
809
810static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
811 [FEAT_1_EDX] = {
812 .type = CPUID_FEATURE_WORD,
813 .feat_names = {
814 "fpu", "vme", "de", "pse",
815 "tsc", "msr", "pae", "mce",
816 "cx8", "apic", NULL, "sep",
817 "mtrr", "pge", "mca", "cmov",
818 "pat", "pse36", "pn" , "clflush" ,
819 NULL, "ds" , "acpi", "mmx",
820 "fxsr", "sse", "sse2", "ss",
821 "ht" , "tm", "ia64", "pbe",
822 },
823 .cpuid = {.eax = 1, .reg = R_EDX, },
824 .tcg_features = TCG_FEATURES,
825 },
826 [FEAT_1_ECX] = {
827 .type = CPUID_FEATURE_WORD,
828 .feat_names = {
829 "pni" , "pclmulqdq", "dtes64", "monitor",
830 "ds-cpl", "vmx", "smx", "est",
831 "tm2", "ssse3", "cid", NULL,
832 "fma", "cx16", "xtpr", "pdcm",
833 NULL, "pcid", "dca", "sse4.1",
834 "sse4.2", "x2apic", "movbe", "popcnt",
835 "tsc-deadline", "aes", "xsave", NULL ,
836 "avx", "f16c", "rdrand", "hypervisor",
837 },
838 .cpuid = { .eax = 1, .reg = R_ECX, },
839 .tcg_features = TCG_EXT_FEATURES,
840 },
841
842
843
844
845
846 [FEAT_8000_0001_EDX] = {
847 .type = CPUID_FEATURE_WORD,
848 .feat_names = {
849 NULL , NULL , NULL , NULL ,
850 NULL , NULL , NULL , NULL ,
851 NULL , NULL , NULL, "syscall",
852 NULL , NULL , NULL , NULL ,
853 NULL , NULL , NULL, NULL ,
854 "nx", NULL, "mmxext", NULL ,
855 NULL , "fxsr-opt", "pdpe1gb", "rdtscp",
856 NULL, "lm", "3dnowext", "3dnow",
857 },
858 .cpuid = { .eax = 0x80000001, .reg = R_EDX, },
859 .tcg_features = TCG_EXT2_FEATURES,
860 },
861 [FEAT_8000_0001_ECX] = {
862 .type = CPUID_FEATURE_WORD,
863 .feat_names = {
864 "lahf-lm", "cmp-legacy", "svm", "extapic",
865 "cr8legacy", "abm", "sse4a", "misalignsse",
866 "3dnowprefetch", "osvw", "ibs", "xop",
867 "skinit", "wdt", NULL, "lwp",
868 "fma4", "tce", NULL, "nodeid-msr",
869 NULL, "tbm", "topoext", "perfctr-core",
870 "perfctr-nb", NULL, NULL, NULL,
871 NULL, NULL, NULL, NULL,
872 },
873 .cpuid = { .eax = 0x80000001, .reg = R_ECX, },
874 .tcg_features = TCG_EXT3_FEATURES,
875
876
877
878
879
880 .no_autoenable_flags = CPUID_EXT3_TOPOEXT,
881 },
882 [FEAT_C000_0001_EDX] = {
883 .type = CPUID_FEATURE_WORD,
884 .feat_names = {
885 NULL, NULL, "xstore", "xstore-en",
886 NULL, NULL, "xcrypt", "xcrypt-en",
887 "ace2", "ace2-en", "phe", "phe-en",
888 "pmm", "pmm-en", NULL, NULL,
889 NULL, NULL, NULL, NULL,
890 NULL, NULL, NULL, NULL,
891 NULL, NULL, NULL, NULL,
892 NULL, NULL, NULL, NULL,
893 },
894 .cpuid = { .eax = 0xC0000001, .reg = R_EDX, },
895 .tcg_features = TCG_EXT4_FEATURES,
896 },
897 [FEAT_KVM] = {
898 .type = CPUID_FEATURE_WORD,
899 .feat_names = {
900 "kvmclock", "kvm-nopiodelay", "kvm-mmu", "kvmclock",
901 "kvm-asyncpf", "kvm-steal-time", "kvm-pv-eoi", "kvm-pv-unhalt",
902 NULL, "kvm-pv-tlb-flush", NULL, "kvm-pv-ipi",
903 NULL, NULL, NULL, NULL,
904 NULL, NULL, NULL, NULL,
905 NULL, NULL, NULL, NULL,
906 "kvmclock-stable-bit", NULL, NULL, NULL,
907 NULL, NULL, NULL, NULL,
908 },
909 .cpuid = { .eax = KVM_CPUID_FEATURES, .reg = R_EAX, },
910 .tcg_features = TCG_KVM_FEATURES,
911 },
912 [FEAT_KVM_HINTS] = {
913 .type = CPUID_FEATURE_WORD,
914 .feat_names = {
915 "kvm-hint-dedicated", NULL, NULL, NULL,
916 NULL, NULL, NULL, NULL,
917 NULL, NULL, NULL, NULL,
918 NULL, NULL, NULL, NULL,
919 NULL, NULL, NULL, NULL,
920 NULL, NULL, NULL, NULL,
921 NULL, NULL, NULL, NULL,
922 NULL, NULL, NULL, NULL,
923 },
924 .cpuid = { .eax = KVM_CPUID_FEATURES, .reg = R_EDX, },
925 .tcg_features = TCG_KVM_FEATURES,
926
927
928
929
930 .no_autoenable_flags = ~0U,
931 },
932 [FEAT_HYPERV_EAX] = {
933 .type = CPUID_FEATURE_WORD,
934 .feat_names = {
935 NULL , NULL ,
936 NULL , NULL ,
937 NULL , NULL ,
938 NULL , NULL ,
939 NULL , NULL ,
940 NULL , NULL ,
941 NULL , NULL ,
942 NULL, NULL,
943 NULL, NULL, NULL, NULL,
944 NULL, NULL, NULL, NULL,
945 NULL, NULL, NULL, NULL,
946 NULL, NULL, NULL, NULL,
947 },
948 .cpuid = { .eax = 0x40000003, .reg = R_EAX, },
949 },
950 [FEAT_HYPERV_EBX] = {
951 .type = CPUID_FEATURE_WORD,
952 .feat_names = {
953 NULL , NULL ,
954 NULL , NULL ,
955 NULL , NULL ,
956 NULL , NULL ,
957 NULL , NULL, NULL, NULL ,
958 NULL , NULL ,
959 NULL, NULL,
960 NULL, NULL, NULL, NULL,
961 NULL, NULL, NULL, NULL,
962 NULL, NULL, NULL, NULL,
963 NULL, NULL, NULL, NULL,
964 },
965 .cpuid = { .eax = 0x40000003, .reg = R_EBX, },
966 },
967 [FEAT_HYPERV_EDX] = {
968 .type = CPUID_FEATURE_WORD,
969 .feat_names = {
970 NULL , NULL ,
971 NULL , NULL ,
972 NULL , NULL ,
973 NULL, NULL,
974 NULL, NULL, NULL , NULL,
975 NULL, NULL, NULL, NULL,
976 NULL, NULL, NULL, NULL,
977 NULL, NULL, NULL, NULL,
978 NULL, NULL, NULL, NULL,
979 NULL, NULL, NULL, NULL,
980 },
981 .cpuid = { .eax = 0x40000003, .reg = R_EDX, },
982 },
983 [FEAT_SVM] = {
984 .type = CPUID_FEATURE_WORD,
985 .feat_names = {
986 "npt", "lbrv", "svm-lock", "nrip-save",
987 "tsc-scale", "vmcb-clean", "flushbyasid", "decodeassists",
988 NULL, NULL, "pause-filter", NULL,
989 "pfthreshold", NULL, NULL, NULL,
990 NULL, NULL, NULL, NULL,
991 NULL, NULL, NULL, NULL,
992 NULL, NULL, NULL, NULL,
993 NULL, NULL, NULL, NULL,
994 },
995 .cpuid = { .eax = 0x8000000A, .reg = R_EDX, },
996 .tcg_features = TCG_SVM_FEATURES,
997 },
998 [FEAT_7_0_EBX] = {
999 .type = CPUID_FEATURE_WORD,
1000 .feat_names = {
1001 "fsgsbase", "tsc-adjust", NULL, "bmi1",
1002 "hle", "avx2", NULL, "smep",
1003 "bmi2", "erms", "invpcid", "rtm",
1004 NULL, NULL, "mpx", NULL,
1005 "avx512f", "avx512dq", "rdseed", "adx",
1006 "smap", "avx512ifma", "pcommit", "clflushopt",
1007 "clwb", "intel-pt", "avx512pf", "avx512er",
1008 "avx512cd", "sha-ni", "avx512bw", "avx512vl",
1009 },
1010 .cpuid = {
1011 .eax = 7,
1012 .needs_ecx = true, .ecx = 0,
1013 .reg = R_EBX,
1014 },
1015 .tcg_features = TCG_7_0_EBX_FEATURES,
1016 },
1017 [FEAT_7_0_ECX] = {
1018 .type = CPUID_FEATURE_WORD,
1019 .feat_names = {
1020 NULL, "avx512vbmi", "umip", "pku",
1021 NULL , NULL, "avx512vbmi2", NULL,
1022 "gfni", "vaes", "vpclmulqdq", "avx512vnni",
1023 "avx512bitalg", NULL, "avx512-vpopcntdq", NULL,
1024 "la57", NULL, NULL, NULL,
1025 NULL, NULL, "rdpid", NULL,
1026 NULL, "cldemote", NULL, NULL,
1027 NULL, NULL, NULL, NULL,
1028 },
1029 .cpuid = {
1030 .eax = 7,
1031 .needs_ecx = true, .ecx = 0,
1032 .reg = R_ECX,
1033 },
1034 .tcg_features = TCG_7_0_ECX_FEATURES,
1035 },
1036 [FEAT_7_0_EDX] = {
1037 .type = CPUID_FEATURE_WORD,
1038 .feat_names = {
1039 NULL, NULL, "avx512-4vnniw", "avx512-4fmaps",
1040 NULL, NULL, NULL, NULL,
1041 NULL, NULL, NULL, NULL,
1042 NULL, NULL, NULL, NULL,
1043 NULL, NULL, "pconfig", NULL,
1044 NULL, NULL, NULL, NULL,
1045 NULL, NULL, "spec-ctrl", NULL,
1046 NULL, "arch-capabilities", NULL, "ssbd",
1047 },
1048 .cpuid = {
1049 .eax = 7,
1050 .needs_ecx = true, .ecx = 0,
1051 .reg = R_EDX,
1052 },
1053 .tcg_features = TCG_7_0_EDX_FEATURES,
1054 .unmigratable_flags = CPUID_7_0_EDX_ARCH_CAPABILITIES,
1055 },
1056 [FEAT_8000_0007_EDX] = {
1057 .type = CPUID_FEATURE_WORD,
1058 .feat_names = {
1059 NULL, NULL, NULL, NULL,
1060 NULL, NULL, NULL, NULL,
1061 "invtsc", NULL, NULL, NULL,
1062 NULL, NULL, NULL, NULL,
1063 NULL, NULL, NULL, NULL,
1064 NULL, NULL, NULL, NULL,
1065 NULL, NULL, NULL, NULL,
1066 NULL, NULL, NULL, NULL,
1067 },
1068 .cpuid = { .eax = 0x80000007, .reg = R_EDX, },
1069 .tcg_features = TCG_APM_FEATURES,
1070 .unmigratable_flags = CPUID_APM_INVTSC,
1071 },
1072 [FEAT_8000_0008_EBX] = {
1073 .type = CPUID_FEATURE_WORD,
1074 .feat_names = {
1075 NULL, NULL, NULL, NULL,
1076 NULL, NULL, NULL, NULL,
1077 NULL, "wbnoinvd", NULL, NULL,
1078 "ibpb", NULL, NULL, NULL,
1079 NULL, NULL, NULL, NULL,
1080 NULL, NULL, NULL, NULL,
1081 "amd-ssbd", "virt-ssbd", "amd-no-ssb", NULL,
1082 NULL, NULL, NULL, NULL,
1083 },
1084 .cpuid = { .eax = 0x80000008, .reg = R_EBX, },
1085 .tcg_features = 0,
1086 .unmigratable_flags = 0,
1087 },
1088 [FEAT_XSAVE] = {
1089 .type = CPUID_FEATURE_WORD,
1090 .feat_names = {
1091 "xsaveopt", "xsavec", "xgetbv1", "xsaves",
1092 NULL, NULL, NULL, NULL,
1093 NULL, NULL, NULL, NULL,
1094 NULL, NULL, NULL, NULL,
1095 NULL, NULL, NULL, NULL,
1096 NULL, NULL, NULL, NULL,
1097 NULL, NULL, NULL, NULL,
1098 NULL, NULL, NULL, NULL,
1099 },
1100 .cpuid = {
1101 .eax = 0xd,
1102 .needs_ecx = true, .ecx = 1,
1103 .reg = R_EAX,
1104 },
1105 .tcg_features = TCG_XSAVE_FEATURES,
1106 },
1107 [FEAT_6_EAX] = {
1108 .type = CPUID_FEATURE_WORD,
1109 .feat_names = {
1110 NULL, NULL, "arat", NULL,
1111 NULL, NULL, NULL, NULL,
1112 NULL, NULL, NULL, NULL,
1113 NULL, NULL, NULL, NULL,
1114 NULL, NULL, NULL, NULL,
1115 NULL, NULL, NULL, NULL,
1116 NULL, NULL, NULL, NULL,
1117 NULL, NULL, NULL, NULL,
1118 },
1119 .cpuid = { .eax = 6, .reg = R_EAX, },
1120 .tcg_features = TCG_6_EAX_FEATURES,
1121 },
1122 [FEAT_XSAVE_COMP_LO] = {
1123 .type = CPUID_FEATURE_WORD,
1124 .cpuid = {
1125 .eax = 0xD,
1126 .needs_ecx = true, .ecx = 0,
1127 .reg = R_EAX,
1128 },
1129 .tcg_features = ~0U,
1130 .migratable_flags = XSTATE_FP_MASK | XSTATE_SSE_MASK |
1131 XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK |
1132 XSTATE_OPMASK_MASK | XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_MASK |
1133 XSTATE_PKRU_MASK,
1134 },
1135 [FEAT_XSAVE_COMP_HI] = {
1136 .type = CPUID_FEATURE_WORD,
1137 .cpuid = {
1138 .eax = 0xD,
1139 .needs_ecx = true, .ecx = 0,
1140 .reg = R_EDX,
1141 },
1142 .tcg_features = ~0U,
1143 },
1144
1145 [FEAT_ARCH_CAPABILITIES] = {
1146 .type = MSR_FEATURE_WORD,
1147 .feat_names = {
1148 "rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry",
1149 "ssb-no", NULL, NULL, NULL,
1150 NULL, NULL, NULL, NULL,
1151 NULL, NULL, NULL, NULL,
1152 NULL, NULL, NULL, NULL,
1153 NULL, NULL, NULL, NULL,
1154 NULL, NULL, NULL, NULL,
1155 NULL, NULL, NULL, NULL,
1156 },
1157 .msr = {
1158 .index = MSR_IA32_ARCH_CAPABILITIES,
1159 .cpuid_dep = {
1160 FEAT_7_0_EDX,
1161 CPUID_7_0_EDX_ARCH_CAPABILITIES
1162 }
1163 },
1164 },
1165};
1166
1167typedef struct X86RegisterInfo32 {
1168
1169 const char *name;
1170
1171 X86CPURegister32 qapi_enum;
1172} X86RegisterInfo32;
1173
1174#define REGISTER(reg) \
1175 [R_##reg] = { .name = #reg, .qapi_enum = X86_CPU_REGISTER32_##reg }
1176static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
1177 REGISTER(EAX),
1178 REGISTER(ECX),
1179 REGISTER(EDX),
1180 REGISTER(EBX),
1181 REGISTER(ESP),
1182 REGISTER(EBP),
1183 REGISTER(ESI),
1184 REGISTER(EDI),
1185};
1186#undef REGISTER
1187
1188typedef struct ExtSaveArea {
1189 uint32_t feature, bits;
1190 uint32_t offset, size;
1191} ExtSaveArea;
1192
1193static const ExtSaveArea x86_ext_save_areas[] = {
1194 [XSTATE_FP_BIT] = {
1195
1196 .feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
1197
1198 .offset = 0,
1199 .size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
1200 },
1201 [XSTATE_SSE_BIT] = {
1202
1203 .feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
1204
1205 .offset = 0,
1206 .size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
1207 },
1208 [XSTATE_YMM_BIT] =
1209 { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
1210 .offset = offsetof(X86XSaveArea, avx_state),
1211 .size = sizeof(XSaveAVX) },
1212 [XSTATE_BNDREGS_BIT] =
1213 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
1214 .offset = offsetof(X86XSaveArea, bndreg_state),
1215 .size = sizeof(XSaveBNDREG) },
1216 [XSTATE_BNDCSR_BIT] =
1217 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
1218 .offset = offsetof(X86XSaveArea, bndcsr_state),
1219 .size = sizeof(XSaveBNDCSR) },
1220 [XSTATE_OPMASK_BIT] =
1221 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
1222 .offset = offsetof(X86XSaveArea, opmask_state),
1223 .size = sizeof(XSaveOpmask) },
1224 [XSTATE_ZMM_Hi256_BIT] =
1225 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
1226 .offset = offsetof(X86XSaveArea, zmm_hi256_state),
1227 .size = sizeof(XSaveZMM_Hi256) },
1228 [XSTATE_Hi16_ZMM_BIT] =
1229 { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F,
1230 .offset = offsetof(X86XSaveArea, hi16_zmm_state),
1231 .size = sizeof(XSaveHi16_ZMM) },
1232 [XSTATE_PKRU_BIT] =
1233 { .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU,
1234 .offset = offsetof(X86XSaveArea, pkru_state),
1235 .size = sizeof(XSavePKRU) },
1236};
1237
1238static uint32_t xsave_area_size(uint64_t mask)
1239{
1240 int i;
1241 uint64_t ret = 0;
1242
1243 for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
1244 const ExtSaveArea *esa = &x86_ext_save_areas[i];
1245 if ((mask >> i) & 1) {
1246 ret = MAX(ret, esa->offset + esa->size);
1247 }
1248 }
1249 return ret;
1250}
1251
1252static inline bool accel_uses_host_cpuid(void)
1253{
1254 return kvm_enabled() || hvf_enabled();
1255}
1256
1257static inline uint64_t x86_cpu_xsave_components(X86CPU *cpu)
1258{
1259 return ((uint64_t)cpu->env.features[FEAT_XSAVE_COMP_HI]) << 32 |
1260 cpu->env.features[FEAT_XSAVE_COMP_LO];
1261}
1262
1263const char *get_register_name_32(unsigned int reg)
1264{
1265 if (reg >= CPU_NB_REGS32) {
1266 return NULL;
1267 }
1268 return x86_reg_info_32[reg].name;
1269}
1270
1271
1272
1273
1274
1275static uint32_t x86_cpu_get_migratable_flags(FeatureWord w)
1276{
1277 FeatureWordInfo *wi = &feature_word_info[w];
1278 uint32_t r = 0;
1279 int i;
1280
1281 for (i = 0; i < 32; i++) {
1282 uint32_t f = 1U << i;
1283
1284
1285
1286 if ((wi->migratable_flags & f) ||
1287 (wi->feat_names[i] && !(wi->unmigratable_flags & f))) {
1288 r |= f;
1289 }
1290 }
1291 return r;
1292}
1293
1294void host_cpuid(uint32_t function, uint32_t count,
1295 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
1296{
1297 uint32_t vec[4];
1298
1299#ifdef __x86_64__
1300 asm volatile("cpuid"
1301 : "=a"(vec[0]), "=b"(vec[1]),
1302 "=c"(vec[2]), "=d"(vec[3])
1303 : "0"(function), "c"(count) : "cc");
1304#elif defined(__i386__)
1305 asm volatile("pusha \n\t"
1306 "cpuid \n\t"
1307 "mov %%eax, 0(%2) \n\t"
1308 "mov %%ebx, 4(%2) \n\t"
1309 "mov %%ecx, 8(%2) \n\t"
1310 "mov %%edx, 12(%2) \n\t"
1311 "popa"
1312 : : "a"(function), "c"(count), "S"(vec)
1313 : "memory", "cc");
1314#else
1315 abort();
1316#endif
1317
1318 if (eax)
1319 *eax = vec[0];
1320 if (ebx)
1321 *ebx = vec[1];
1322 if (ecx)
1323 *ecx = vec[2];
1324 if (edx)
1325 *edx = vec[3];
1326}
1327
1328void host_vendor_fms(char *vendor, int *family, int *model, int *stepping)
1329{
1330 uint32_t eax, ebx, ecx, edx;
1331
1332 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
1333 x86_cpu_vendor_words2str(vendor, ebx, edx, ecx);
1334
1335 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
1336 if (family) {
1337 *family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1338 }
1339 if (model) {
1340 *model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1341 }
1342 if (stepping) {
1343 *stepping = eax & 0x0F;
1344 }
1345}
1346
1347
1348
1349
1350
1351
1352static char *x86_cpu_type_name(const char *model_name)
1353{
1354 return g_strdup_printf(X86_CPU_TYPE_NAME("%s"), model_name);
1355}
1356
1357static ObjectClass *x86_cpu_class_by_name(const char *cpu_model)
1358{
1359 ObjectClass *oc;
1360 char *typename = x86_cpu_type_name(cpu_model);
1361 oc = object_class_by_name(typename);
1362 g_free(typename);
1363 return oc;
1364}
1365
1366static char *x86_cpu_class_get_model_name(X86CPUClass *cc)
1367{
1368 const char *class_name = object_class_get_name(OBJECT_CLASS(cc));
1369 assert(g_str_has_suffix(class_name, X86_CPU_TYPE_SUFFIX));
1370 return g_strndup(class_name,
1371 strlen(class_name) - strlen(X86_CPU_TYPE_SUFFIX));
1372}
1373
1374struct X86CPUDefinition {
1375 const char *name;
1376 uint32_t level;
1377 uint32_t xlevel;
1378
1379 char vendor[CPUID_VENDOR_SZ + 1];
1380 int family;
1381 int model;
1382 int stepping;
1383 FeatureWordArray features;
1384 const char *model_id;
1385 CPUCaches *cache_info;
1386};
1387
1388static CPUCaches epyc_cache_info = {
1389 .l1d_cache = &(CPUCacheInfo) {
1390 .type = DATA_CACHE,
1391 .level = 1,
1392 .size = 32 * KiB,
1393 .line_size = 64,
1394 .associativity = 8,
1395 .partitions = 1,
1396 .sets = 64,
1397 .lines_per_tag = 1,
1398 .self_init = 1,
1399 .no_invd_sharing = true,
1400 },
1401 .l1i_cache = &(CPUCacheInfo) {
1402 .type = INSTRUCTION_CACHE,
1403 .level = 1,
1404 .size = 64 * KiB,
1405 .line_size = 64,
1406 .associativity = 4,
1407 .partitions = 1,
1408 .sets = 256,
1409 .lines_per_tag = 1,
1410 .self_init = 1,
1411 .no_invd_sharing = true,
1412 },
1413 .l2_cache = &(CPUCacheInfo) {
1414 .type = UNIFIED_CACHE,
1415 .level = 2,
1416 .size = 512 * KiB,
1417 .line_size = 64,
1418 .associativity = 8,
1419 .partitions = 1,
1420 .sets = 1024,
1421 .lines_per_tag = 1,
1422 },
1423 .l3_cache = &(CPUCacheInfo) {
1424 .type = UNIFIED_CACHE,
1425 .level = 3,
1426 .size = 8 * MiB,
1427 .line_size = 64,
1428 .associativity = 16,
1429 .partitions = 1,
1430 .sets = 8192,
1431 .lines_per_tag = 1,
1432 .self_init = true,
1433 .inclusive = true,
1434 .complex_indexing = true,
1435 },
1436};
1437
1438static X86CPUDefinition builtin_x86_defs[] = {
1439 {
1440 .name = "qemu64",
1441 .level = 0xd,
1442 .vendor = CPUID_VENDOR_AMD,
1443 .family = 6,
1444 .model = 6,
1445 .stepping = 3,
1446 .features[FEAT_1_EDX] =
1447 PPRO_FEATURES |
1448 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
1449 CPUID_PSE36,
1450 .features[FEAT_1_ECX] =
1451 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
1452 .features[FEAT_8000_0001_EDX] =
1453 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1454 .features[FEAT_8000_0001_ECX] =
1455 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM,
1456 .xlevel = 0x8000000A,
1457 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
1458 },
1459 {
1460 .name = "phenom",
1461 .level = 5,
1462 .vendor = CPUID_VENDOR_AMD,
1463 .family = 16,
1464 .model = 2,
1465 .stepping = 3,
1466
1467 .features[FEAT_1_EDX] =
1468 PPRO_FEATURES |
1469 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
1470 CPUID_PSE36 | CPUID_VME,
1471 .features[FEAT_1_ECX] =
1472 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
1473 CPUID_EXT_POPCNT,
1474 .features[FEAT_8000_0001_EDX] =
1475 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
1476 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
1477 CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
1478
1479
1480
1481
1482 .features[FEAT_8000_0001_ECX] =
1483 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
1484 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
1485
1486 .features[FEAT_SVM] =
1487 CPUID_SVM_NPT,
1488 .xlevel = 0x8000001A,
1489 .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
1490 },
1491 {
1492 .name = "core2duo",
1493 .level = 10,
1494 .vendor = CPUID_VENDOR_INTEL,
1495 .family = 6,
1496 .model = 15,
1497 .stepping = 11,
1498
1499 .features[FEAT_1_EDX] =
1500 PPRO_FEATURES |
1501 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
1502 CPUID_PSE36 | CPUID_VME | CPUID_ACPI | CPUID_SS,
1503
1504
1505 .features[FEAT_1_ECX] =
1506 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
1507 CPUID_EXT_CX16,
1508 .features[FEAT_8000_0001_EDX] =
1509 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1510 .features[FEAT_8000_0001_ECX] =
1511 CPUID_EXT3_LAHF_LM,
1512 .xlevel = 0x80000008,
1513 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
1514 },
1515 {
1516 .name = "kvm64",
1517 .level = 0xd,
1518 .vendor = CPUID_VENDOR_INTEL,
1519 .family = 15,
1520 .model = 6,
1521 .stepping = 1,
1522
1523 .features[FEAT_1_EDX] =
1524 PPRO_FEATURES | CPUID_VME |
1525 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
1526 CPUID_PSE36,
1527
1528 .features[FEAT_1_ECX] =
1529 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
1530
1531 .features[FEAT_8000_0001_EDX] =
1532 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1533
1534
1535
1536
1537 .features[FEAT_8000_0001_ECX] =
1538 0,
1539 .xlevel = 0x80000008,
1540 .model_id = "Common KVM processor"
1541 },
1542 {
1543 .name = "qemu32",
1544 .level = 4,
1545 .vendor = CPUID_VENDOR_INTEL,
1546 .family = 6,
1547 .model = 6,
1548 .stepping = 3,
1549 .features[FEAT_1_EDX] =
1550 PPRO_FEATURES,
1551 .features[FEAT_1_ECX] =
1552 CPUID_EXT_SSE3,
1553 .xlevel = 0x80000004,
1554 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
1555 },
1556 {
1557 .name = "kvm32",
1558 .level = 5,
1559 .vendor = CPUID_VENDOR_INTEL,
1560 .family = 15,
1561 .model = 6,
1562 .stepping = 1,
1563 .features[FEAT_1_EDX] =
1564 PPRO_FEATURES | CPUID_VME |
1565 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
1566 .features[FEAT_1_ECX] =
1567 CPUID_EXT_SSE3,
1568 .features[FEAT_8000_0001_ECX] =
1569 0,
1570 .xlevel = 0x80000008,
1571 .model_id = "Common 32-bit KVM processor"
1572 },
1573 {
1574 .name = "coreduo",
1575 .level = 10,
1576 .vendor = CPUID_VENDOR_INTEL,
1577 .family = 6,
1578 .model = 14,
1579 .stepping = 8,
1580
1581 .features[FEAT_1_EDX] =
1582 PPRO_FEATURES | CPUID_VME |
1583 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_ACPI |
1584 CPUID_SS,
1585
1586
1587 .features[FEAT_1_ECX] =
1588 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
1589 .features[FEAT_8000_0001_EDX] =
1590 CPUID_EXT2_NX,
1591 .xlevel = 0x80000008,
1592 .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
1593 },
1594 {
1595 .name = "486",
1596 .level = 1,
1597 .vendor = CPUID_VENDOR_INTEL,
1598 .family = 4,
1599 .model = 8,
1600 .stepping = 0,
1601 .features[FEAT_1_EDX] =
1602 I486_FEATURES,
1603 .xlevel = 0,
1604 .model_id = "",
1605 },
1606 {
1607 .name = "pentium",
1608 .level = 1,
1609 .vendor = CPUID_VENDOR_INTEL,
1610 .family = 5,
1611 .model = 4,
1612 .stepping = 3,
1613 .features[FEAT_1_EDX] =
1614 PENTIUM_FEATURES,
1615 .xlevel = 0,
1616 .model_id = "",
1617 },
1618 {
1619 .name = "pentium2",
1620 .level = 2,
1621 .vendor = CPUID_VENDOR_INTEL,
1622 .family = 6,
1623 .model = 5,
1624 .stepping = 2,
1625 .features[FEAT_1_EDX] =
1626 PENTIUM2_FEATURES,
1627 .xlevel = 0,
1628 .model_id = "",
1629 },
1630 {
1631 .name = "pentium3",
1632 .level = 3,
1633 .vendor = CPUID_VENDOR_INTEL,
1634 .family = 6,
1635 .model = 7,
1636 .stepping = 3,
1637 .features[FEAT_1_EDX] =
1638 PENTIUM3_FEATURES,
1639 .xlevel = 0,
1640 .model_id = "",
1641 },
1642 {
1643 .name = "athlon",
1644 .level = 2,
1645 .vendor = CPUID_VENDOR_AMD,
1646 .family = 6,
1647 .model = 2,
1648 .stepping = 3,
1649 .features[FEAT_1_EDX] =
1650 PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
1651 CPUID_MCA,
1652 .features[FEAT_8000_0001_EDX] =
1653 CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
1654 .xlevel = 0x80000008,
1655 .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
1656 },
1657 {
1658 .name = "n270",
1659 .level = 10,
1660 .vendor = CPUID_VENDOR_INTEL,
1661 .family = 6,
1662 .model = 28,
1663 .stepping = 2,
1664
1665 .features[FEAT_1_EDX] =
1666 PPRO_FEATURES |
1667 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME |
1668 CPUID_ACPI | CPUID_SS,
1669
1670
1671
1672 .features[FEAT_1_ECX] =
1673 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
1674 CPUID_EXT_MOVBE,
1675 .features[FEAT_8000_0001_EDX] =
1676 CPUID_EXT2_NX,
1677 .features[FEAT_8000_0001_ECX] =
1678 CPUID_EXT3_LAHF_LM,
1679 .xlevel = 0x80000008,
1680 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
1681 },
1682 {
1683 .name = "Conroe",
1684 .level = 10,
1685 .vendor = CPUID_VENDOR_INTEL,
1686 .family = 6,
1687 .model = 15,
1688 .stepping = 3,
1689 .features[FEAT_1_EDX] =
1690 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1691 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1692 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1693 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1694 CPUID_DE | CPUID_FP87,
1695 .features[FEAT_1_ECX] =
1696 CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
1697 .features[FEAT_8000_0001_EDX] =
1698 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
1699 .features[FEAT_8000_0001_ECX] =
1700 CPUID_EXT3_LAHF_LM,
1701 .xlevel = 0x80000008,
1702 .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
1703 },
1704 {
1705 .name = "Penryn",
1706 .level = 10,
1707 .vendor = CPUID_VENDOR_INTEL,
1708 .family = 6,
1709 .model = 23,
1710 .stepping = 3,
1711 .features[FEAT_1_EDX] =
1712 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1713 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1714 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1715 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1716 CPUID_DE | CPUID_FP87,
1717 .features[FEAT_1_ECX] =
1718 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1719 CPUID_EXT_SSE3,
1720 .features[FEAT_8000_0001_EDX] =
1721 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
1722 .features[FEAT_8000_0001_ECX] =
1723 CPUID_EXT3_LAHF_LM,
1724 .xlevel = 0x80000008,
1725 .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
1726 },
1727 {
1728 .name = "Nehalem",
1729 .level = 11,
1730 .vendor = CPUID_VENDOR_INTEL,
1731 .family = 6,
1732 .model = 26,
1733 .stepping = 3,
1734 .features[FEAT_1_EDX] =
1735 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1736 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1737 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1738 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1739 CPUID_DE | CPUID_FP87,
1740 .features[FEAT_1_ECX] =
1741 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1742 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
1743 .features[FEAT_8000_0001_EDX] =
1744 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1745 .features[FEAT_8000_0001_ECX] =
1746 CPUID_EXT3_LAHF_LM,
1747 .xlevel = 0x80000008,
1748 .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
1749 },
1750 {
1751 .name = "Nehalem-IBRS",
1752 .level = 11,
1753 .vendor = CPUID_VENDOR_INTEL,
1754 .family = 6,
1755 .model = 26,
1756 .stepping = 3,
1757 .features[FEAT_1_EDX] =
1758 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1759 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1760 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1761 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1762 CPUID_DE | CPUID_FP87,
1763 .features[FEAT_1_ECX] =
1764 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1765 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
1766 .features[FEAT_7_0_EDX] =
1767 CPUID_7_0_EDX_SPEC_CTRL,
1768 .features[FEAT_8000_0001_EDX] =
1769 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1770 .features[FEAT_8000_0001_ECX] =
1771 CPUID_EXT3_LAHF_LM,
1772 .xlevel = 0x80000008,
1773 .model_id = "Intel Core i7 9xx (Nehalem Core i7, IBRS update)",
1774 },
1775 {
1776 .name = "Westmere",
1777 .level = 11,
1778 .vendor = CPUID_VENDOR_INTEL,
1779 .family = 6,
1780 .model = 44,
1781 .stepping = 1,
1782 .features[FEAT_1_EDX] =
1783 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1784 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1785 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1786 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1787 CPUID_DE | CPUID_FP87,
1788 .features[FEAT_1_ECX] =
1789 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1790 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1791 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1792 .features[FEAT_8000_0001_EDX] =
1793 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1794 .features[FEAT_8000_0001_ECX] =
1795 CPUID_EXT3_LAHF_LM,
1796 .features[FEAT_6_EAX] =
1797 CPUID_6_EAX_ARAT,
1798 .xlevel = 0x80000008,
1799 .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
1800 },
1801 {
1802 .name = "Westmere-IBRS",
1803 .level = 11,
1804 .vendor = CPUID_VENDOR_INTEL,
1805 .family = 6,
1806 .model = 44,
1807 .stepping = 1,
1808 .features[FEAT_1_EDX] =
1809 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1810 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1811 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1812 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1813 CPUID_DE | CPUID_FP87,
1814 .features[FEAT_1_ECX] =
1815 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1816 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1817 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1818 .features[FEAT_8000_0001_EDX] =
1819 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
1820 .features[FEAT_8000_0001_ECX] =
1821 CPUID_EXT3_LAHF_LM,
1822 .features[FEAT_7_0_EDX] =
1823 CPUID_7_0_EDX_SPEC_CTRL,
1824 .features[FEAT_6_EAX] =
1825 CPUID_6_EAX_ARAT,
1826 .xlevel = 0x80000008,
1827 .model_id = "Westmere E56xx/L56xx/X56xx (IBRS update)",
1828 },
1829 {
1830 .name = "SandyBridge",
1831 .level = 0xd,
1832 .vendor = CPUID_VENDOR_INTEL,
1833 .family = 6,
1834 .model = 42,
1835 .stepping = 1,
1836 .features[FEAT_1_EDX] =
1837 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1838 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1839 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1840 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1841 CPUID_DE | CPUID_FP87,
1842 .features[FEAT_1_ECX] =
1843 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1844 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1845 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1846 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1847 CPUID_EXT_SSE3,
1848 .features[FEAT_8000_0001_EDX] =
1849 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1850 CPUID_EXT2_SYSCALL,
1851 .features[FEAT_8000_0001_ECX] =
1852 CPUID_EXT3_LAHF_LM,
1853 .features[FEAT_XSAVE] =
1854 CPUID_XSAVE_XSAVEOPT,
1855 .features[FEAT_6_EAX] =
1856 CPUID_6_EAX_ARAT,
1857 .xlevel = 0x80000008,
1858 .model_id = "Intel Xeon E312xx (Sandy Bridge)",
1859 },
1860 {
1861 .name = "SandyBridge-IBRS",
1862 .level = 0xd,
1863 .vendor = CPUID_VENDOR_INTEL,
1864 .family = 6,
1865 .model = 42,
1866 .stepping = 1,
1867 .features[FEAT_1_EDX] =
1868 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1869 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1870 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1871 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1872 CPUID_DE | CPUID_FP87,
1873 .features[FEAT_1_ECX] =
1874 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1875 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1876 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1877 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1878 CPUID_EXT_SSE3,
1879 .features[FEAT_8000_0001_EDX] =
1880 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1881 CPUID_EXT2_SYSCALL,
1882 .features[FEAT_8000_0001_ECX] =
1883 CPUID_EXT3_LAHF_LM,
1884 .features[FEAT_7_0_EDX] =
1885 CPUID_7_0_EDX_SPEC_CTRL,
1886 .features[FEAT_XSAVE] =
1887 CPUID_XSAVE_XSAVEOPT,
1888 .features[FEAT_6_EAX] =
1889 CPUID_6_EAX_ARAT,
1890 .xlevel = 0x80000008,
1891 .model_id = "Intel Xeon E312xx (Sandy Bridge, IBRS update)",
1892 },
1893 {
1894 .name = "IvyBridge",
1895 .level = 0xd,
1896 .vendor = CPUID_VENDOR_INTEL,
1897 .family = 6,
1898 .model = 58,
1899 .stepping = 9,
1900 .features[FEAT_1_EDX] =
1901 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1902 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1903 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1904 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1905 CPUID_DE | CPUID_FP87,
1906 .features[FEAT_1_ECX] =
1907 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1908 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1909 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1910 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1911 CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1912 .features[FEAT_7_0_EBX] =
1913 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
1914 CPUID_7_0_EBX_ERMS,
1915 .features[FEAT_8000_0001_EDX] =
1916 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1917 CPUID_EXT2_SYSCALL,
1918 .features[FEAT_8000_0001_ECX] =
1919 CPUID_EXT3_LAHF_LM,
1920 .features[FEAT_XSAVE] =
1921 CPUID_XSAVE_XSAVEOPT,
1922 .features[FEAT_6_EAX] =
1923 CPUID_6_EAX_ARAT,
1924 .xlevel = 0x80000008,
1925 .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)",
1926 },
1927 {
1928 .name = "IvyBridge-IBRS",
1929 .level = 0xd,
1930 .vendor = CPUID_VENDOR_INTEL,
1931 .family = 6,
1932 .model = 58,
1933 .stepping = 9,
1934 .features[FEAT_1_EDX] =
1935 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1936 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1937 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1938 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1939 CPUID_DE | CPUID_FP87,
1940 .features[FEAT_1_ECX] =
1941 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1942 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
1943 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1944 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1945 CPUID_EXT_SSE3 | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1946 .features[FEAT_7_0_EBX] =
1947 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_SMEP |
1948 CPUID_7_0_EBX_ERMS,
1949 .features[FEAT_8000_0001_EDX] =
1950 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1951 CPUID_EXT2_SYSCALL,
1952 .features[FEAT_8000_0001_ECX] =
1953 CPUID_EXT3_LAHF_LM,
1954 .features[FEAT_7_0_EDX] =
1955 CPUID_7_0_EDX_SPEC_CTRL,
1956 .features[FEAT_XSAVE] =
1957 CPUID_XSAVE_XSAVEOPT,
1958 .features[FEAT_6_EAX] =
1959 CPUID_6_EAX_ARAT,
1960 .xlevel = 0x80000008,
1961 .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge, IBRS)",
1962 },
1963 {
1964 .name = "Haswell-noTSX",
1965 .level = 0xd,
1966 .vendor = CPUID_VENDOR_INTEL,
1967 .family = 6,
1968 .model = 60,
1969 .stepping = 1,
1970 .features[FEAT_1_EDX] =
1971 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1972 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1973 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1974 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1975 CPUID_DE | CPUID_FP87,
1976 .features[FEAT_1_ECX] =
1977 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1978 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
1979 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
1980 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
1981 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
1982 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
1983 .features[FEAT_8000_0001_EDX] =
1984 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
1985 CPUID_EXT2_SYSCALL,
1986 .features[FEAT_8000_0001_ECX] =
1987 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
1988 .features[FEAT_7_0_EBX] =
1989 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
1990 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
1991 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
1992 .features[FEAT_XSAVE] =
1993 CPUID_XSAVE_XSAVEOPT,
1994 .features[FEAT_6_EAX] =
1995 CPUID_6_EAX_ARAT,
1996 .xlevel = 0x80000008,
1997 .model_id = "Intel Core Processor (Haswell, no TSX)",
1998 },
1999 {
2000 .name = "Haswell-noTSX-IBRS",
2001 .level = 0xd,
2002 .vendor = CPUID_VENDOR_INTEL,
2003 .family = 6,
2004 .model = 60,
2005 .stepping = 1,
2006 .features[FEAT_1_EDX] =
2007 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2008 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2009 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2010 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2011 CPUID_DE | CPUID_FP87,
2012 .features[FEAT_1_ECX] =
2013 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2014 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2015 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2016 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2017 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2018 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2019 .features[FEAT_8000_0001_EDX] =
2020 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2021 CPUID_EXT2_SYSCALL,
2022 .features[FEAT_8000_0001_ECX] =
2023 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
2024 .features[FEAT_7_0_EDX] =
2025 CPUID_7_0_EDX_SPEC_CTRL,
2026 .features[FEAT_7_0_EBX] =
2027 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2028 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2029 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
2030 .features[FEAT_XSAVE] =
2031 CPUID_XSAVE_XSAVEOPT,
2032 .features[FEAT_6_EAX] =
2033 CPUID_6_EAX_ARAT,
2034 .xlevel = 0x80000008,
2035 .model_id = "Intel Core Processor (Haswell, no TSX, IBRS)",
2036 },
2037 {
2038 .name = "Haswell",
2039 .level = 0xd,
2040 .vendor = CPUID_VENDOR_INTEL,
2041 .family = 6,
2042 .model = 60,
2043 .stepping = 4,
2044 .features[FEAT_1_EDX] =
2045 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2046 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2047 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2048 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2049 CPUID_DE | CPUID_FP87,
2050 .features[FEAT_1_ECX] =
2051 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2052 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2053 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2054 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2055 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2056 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2057 .features[FEAT_8000_0001_EDX] =
2058 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2059 CPUID_EXT2_SYSCALL,
2060 .features[FEAT_8000_0001_ECX] =
2061 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
2062 .features[FEAT_7_0_EBX] =
2063 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2064 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2065 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2066 CPUID_7_0_EBX_RTM,
2067 .features[FEAT_XSAVE] =
2068 CPUID_XSAVE_XSAVEOPT,
2069 .features[FEAT_6_EAX] =
2070 CPUID_6_EAX_ARAT,
2071 .xlevel = 0x80000008,
2072 .model_id = "Intel Core Processor (Haswell)",
2073 },
2074 {
2075 .name = "Haswell-IBRS",
2076 .level = 0xd,
2077 .vendor = CPUID_VENDOR_INTEL,
2078 .family = 6,
2079 .model = 60,
2080 .stepping = 4,
2081 .features[FEAT_1_EDX] =
2082 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2083 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2084 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2085 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2086 CPUID_DE | CPUID_FP87,
2087 .features[FEAT_1_ECX] =
2088 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2089 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2090 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2091 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2092 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2093 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2094 .features[FEAT_8000_0001_EDX] =
2095 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2096 CPUID_EXT2_SYSCALL,
2097 .features[FEAT_8000_0001_ECX] =
2098 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM,
2099 .features[FEAT_7_0_EDX] =
2100 CPUID_7_0_EDX_SPEC_CTRL,
2101 .features[FEAT_7_0_EBX] =
2102 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2103 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2104 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2105 CPUID_7_0_EBX_RTM,
2106 .features[FEAT_XSAVE] =
2107 CPUID_XSAVE_XSAVEOPT,
2108 .features[FEAT_6_EAX] =
2109 CPUID_6_EAX_ARAT,
2110 .xlevel = 0x80000008,
2111 .model_id = "Intel Core Processor (Haswell, IBRS)",
2112 },
2113 {
2114 .name = "Broadwell-noTSX",
2115 .level = 0xd,
2116 .vendor = CPUID_VENDOR_INTEL,
2117 .family = 6,
2118 .model = 61,
2119 .stepping = 2,
2120 .features[FEAT_1_EDX] =
2121 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2122 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2123 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2124 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2125 CPUID_DE | CPUID_FP87,
2126 .features[FEAT_1_ECX] =
2127 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2128 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2129 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2130 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2131 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2132 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2133 .features[FEAT_8000_0001_EDX] =
2134 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2135 CPUID_EXT2_SYSCALL,
2136 .features[FEAT_8000_0001_ECX] =
2137 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2138 .features[FEAT_7_0_EBX] =
2139 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2140 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2141 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2142 CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2143 CPUID_7_0_EBX_SMAP,
2144 .features[FEAT_XSAVE] =
2145 CPUID_XSAVE_XSAVEOPT,
2146 .features[FEAT_6_EAX] =
2147 CPUID_6_EAX_ARAT,
2148 .xlevel = 0x80000008,
2149 .model_id = "Intel Core Processor (Broadwell, no TSX)",
2150 },
2151 {
2152 .name = "Broadwell-noTSX-IBRS",
2153 .level = 0xd,
2154 .vendor = CPUID_VENDOR_INTEL,
2155 .family = 6,
2156 .model = 61,
2157 .stepping = 2,
2158 .features[FEAT_1_EDX] =
2159 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2160 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2161 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2162 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2163 CPUID_DE | CPUID_FP87,
2164 .features[FEAT_1_ECX] =
2165 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2166 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2167 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2168 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2169 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2170 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2171 .features[FEAT_8000_0001_EDX] =
2172 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2173 CPUID_EXT2_SYSCALL,
2174 .features[FEAT_8000_0001_ECX] =
2175 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2176 .features[FEAT_7_0_EDX] =
2177 CPUID_7_0_EDX_SPEC_CTRL,
2178 .features[FEAT_7_0_EBX] =
2179 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2180 CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2181 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2182 CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2183 CPUID_7_0_EBX_SMAP,
2184 .features[FEAT_XSAVE] =
2185 CPUID_XSAVE_XSAVEOPT,
2186 .features[FEAT_6_EAX] =
2187 CPUID_6_EAX_ARAT,
2188 .xlevel = 0x80000008,
2189 .model_id = "Intel Core Processor (Broadwell, no TSX, IBRS)",
2190 },
2191 {
2192 .name = "Broadwell",
2193 .level = 0xd,
2194 .vendor = CPUID_VENDOR_INTEL,
2195 .family = 6,
2196 .model = 61,
2197 .stepping = 2,
2198 .features[FEAT_1_EDX] =
2199 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2200 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2201 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2202 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2203 CPUID_DE | CPUID_FP87,
2204 .features[FEAT_1_ECX] =
2205 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2206 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2207 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2208 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2209 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2210 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2211 .features[FEAT_8000_0001_EDX] =
2212 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2213 CPUID_EXT2_SYSCALL,
2214 .features[FEAT_8000_0001_ECX] =
2215 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2216 .features[FEAT_7_0_EBX] =
2217 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2218 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2219 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2220 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2221 CPUID_7_0_EBX_SMAP,
2222 .features[FEAT_XSAVE] =
2223 CPUID_XSAVE_XSAVEOPT,
2224 .features[FEAT_6_EAX] =
2225 CPUID_6_EAX_ARAT,
2226 .xlevel = 0x80000008,
2227 .model_id = "Intel Core Processor (Broadwell)",
2228 },
2229 {
2230 .name = "Broadwell-IBRS",
2231 .level = 0xd,
2232 .vendor = CPUID_VENDOR_INTEL,
2233 .family = 6,
2234 .model = 61,
2235 .stepping = 2,
2236 .features[FEAT_1_EDX] =
2237 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2238 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2239 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2240 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2241 CPUID_DE | CPUID_FP87,
2242 .features[FEAT_1_ECX] =
2243 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2244 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2245 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2246 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2247 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2248 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2249 .features[FEAT_8000_0001_EDX] =
2250 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2251 CPUID_EXT2_SYSCALL,
2252 .features[FEAT_8000_0001_ECX] =
2253 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2254 .features[FEAT_7_0_EDX] =
2255 CPUID_7_0_EDX_SPEC_CTRL,
2256 .features[FEAT_7_0_EBX] =
2257 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2258 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2259 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2260 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2261 CPUID_7_0_EBX_SMAP,
2262 .features[FEAT_XSAVE] =
2263 CPUID_XSAVE_XSAVEOPT,
2264 .features[FEAT_6_EAX] =
2265 CPUID_6_EAX_ARAT,
2266 .xlevel = 0x80000008,
2267 .model_id = "Intel Core Processor (Broadwell, IBRS)",
2268 },
2269 {
2270 .name = "Skylake-Client",
2271 .level = 0xd,
2272 .vendor = CPUID_VENDOR_INTEL,
2273 .family = 6,
2274 .model = 94,
2275 .stepping = 3,
2276 .features[FEAT_1_EDX] =
2277 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2278 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2279 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2280 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2281 CPUID_DE | CPUID_FP87,
2282 .features[FEAT_1_ECX] =
2283 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2284 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2285 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2286 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2287 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2288 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2289 .features[FEAT_8000_0001_EDX] =
2290 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2291 CPUID_EXT2_SYSCALL,
2292 .features[FEAT_8000_0001_ECX] =
2293 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2294 .features[FEAT_7_0_EBX] =
2295 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2296 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2297 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2298 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2299 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
2300
2301
2302
2303
2304
2305
2306 .features[FEAT_XSAVE] =
2307 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2308 CPUID_XSAVE_XGETBV1,
2309 .features[FEAT_6_EAX] =
2310 CPUID_6_EAX_ARAT,
2311 .xlevel = 0x80000008,
2312 .model_id = "Intel Core Processor (Skylake)",
2313 },
2314 {
2315 .name = "Skylake-Client-IBRS",
2316 .level = 0xd,
2317 .vendor = CPUID_VENDOR_INTEL,
2318 .family = 6,
2319 .model = 94,
2320 .stepping = 3,
2321 .features[FEAT_1_EDX] =
2322 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2323 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2324 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2325 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2326 CPUID_DE | CPUID_FP87,
2327 .features[FEAT_1_ECX] =
2328 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2329 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2330 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2331 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2332 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2333 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2334 .features[FEAT_8000_0001_EDX] =
2335 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2336 CPUID_EXT2_SYSCALL,
2337 .features[FEAT_8000_0001_ECX] =
2338 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2339 .features[FEAT_7_0_EDX] =
2340 CPUID_7_0_EDX_SPEC_CTRL,
2341 .features[FEAT_7_0_EBX] =
2342 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2343 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2344 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2345 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2346 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX,
2347
2348
2349
2350
2351
2352
2353 .features[FEAT_XSAVE] =
2354 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2355 CPUID_XSAVE_XGETBV1,
2356 .features[FEAT_6_EAX] =
2357 CPUID_6_EAX_ARAT,
2358 .xlevel = 0x80000008,
2359 .model_id = "Intel Core Processor (Skylake, IBRS)",
2360 },
2361 {
2362 .name = "Skylake-Server",
2363 .level = 0xd,
2364 .vendor = CPUID_VENDOR_INTEL,
2365 .family = 6,
2366 .model = 85,
2367 .stepping = 4,
2368 .features[FEAT_1_EDX] =
2369 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2370 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2371 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2372 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2373 CPUID_DE | CPUID_FP87,
2374 .features[FEAT_1_ECX] =
2375 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2376 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2377 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2378 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2379 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2380 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2381 .features[FEAT_8000_0001_EDX] =
2382 CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
2383 CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
2384 .features[FEAT_8000_0001_ECX] =
2385 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2386 .features[FEAT_7_0_EBX] =
2387 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2388 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2389 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2390 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2391 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
2392 CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
2393 CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
2394 CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
2395 .features[FEAT_7_0_ECX] =
2396 CPUID_7_0_ECX_PKU,
2397
2398
2399
2400
2401
2402
2403 .features[FEAT_XSAVE] =
2404 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2405 CPUID_XSAVE_XGETBV1,
2406 .features[FEAT_6_EAX] =
2407 CPUID_6_EAX_ARAT,
2408 .xlevel = 0x80000008,
2409 .model_id = "Intel Xeon Processor (Skylake)",
2410 },
2411 {
2412 .name = "Skylake-Server-IBRS",
2413 .level = 0xd,
2414 .vendor = CPUID_VENDOR_INTEL,
2415 .family = 6,
2416 .model = 85,
2417 .stepping = 4,
2418 .features[FEAT_1_EDX] =
2419 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2420 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2421 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2422 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2423 CPUID_DE | CPUID_FP87,
2424 .features[FEAT_1_ECX] =
2425 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2426 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2427 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2428 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2429 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2430 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2431 .features[FEAT_8000_0001_EDX] =
2432 CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
2433 CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
2434 .features[FEAT_8000_0001_ECX] =
2435 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2436 .features[FEAT_7_0_EDX] =
2437 CPUID_7_0_EDX_SPEC_CTRL,
2438 .features[FEAT_7_0_EBX] =
2439 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2440 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2441 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2442 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2443 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
2444 CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
2445 CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
2446 CPUID_7_0_EBX_AVX512VL,
2447 .features[FEAT_7_0_ECX] =
2448 CPUID_7_0_ECX_PKU,
2449
2450
2451
2452
2453
2454
2455 .features[FEAT_XSAVE] =
2456 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2457 CPUID_XSAVE_XGETBV1,
2458 .features[FEAT_6_EAX] =
2459 CPUID_6_EAX_ARAT,
2460 .xlevel = 0x80000008,
2461 .model_id = "Intel Xeon Processor (Skylake, IBRS)",
2462 },
2463 {
2464 .name = "Cascadelake-Server",
2465 .level = 0xd,
2466 .vendor = CPUID_VENDOR_INTEL,
2467 .family = 6,
2468 .model = 85,
2469 .stepping = 5,
2470 .features[FEAT_1_EDX] =
2471 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2472 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2473 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2474 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2475 CPUID_DE | CPUID_FP87,
2476 .features[FEAT_1_ECX] =
2477 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2478 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2479 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2480 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2481 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2482 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2483 .features[FEAT_8000_0001_EDX] =
2484 CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
2485 CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
2486 .features[FEAT_8000_0001_ECX] =
2487 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2488 .features[FEAT_7_0_EBX] =
2489 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2490 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2491 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2492 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2493 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
2494 CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
2495 CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
2496 CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
2497 CPUID_7_0_EBX_INTEL_PT,
2498 .features[FEAT_7_0_ECX] =
2499 CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE |
2500 CPUID_7_0_ECX_AVX512VNNI,
2501 .features[FEAT_7_0_EDX] =
2502 CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
2503
2504
2505
2506
2507
2508
2509 .features[FEAT_XSAVE] =
2510 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2511 CPUID_XSAVE_XGETBV1,
2512 .features[FEAT_6_EAX] =
2513 CPUID_6_EAX_ARAT,
2514 .xlevel = 0x80000008,
2515 .model_id = "Intel Xeon Processor (Cascadelake)",
2516 },
2517 {
2518 .name = "Icelake-Client",
2519 .level = 0xd,
2520 .vendor = CPUID_VENDOR_INTEL,
2521 .family = 6,
2522 .model = 126,
2523 .stepping = 0,
2524 .features[FEAT_1_EDX] =
2525 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2526 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2527 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2528 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2529 CPUID_DE | CPUID_FP87,
2530 .features[FEAT_1_ECX] =
2531 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2532 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2533 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2534 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2535 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2536 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2537 .features[FEAT_8000_0001_EDX] =
2538 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
2539 CPUID_EXT2_SYSCALL,
2540 .features[FEAT_8000_0001_ECX] =
2541 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2542 .features[FEAT_8000_0008_EBX] =
2543 CPUID_8000_0008_EBX_WBNOINVD,
2544 .features[FEAT_7_0_EBX] =
2545 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2546 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2547 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2548 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2549 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_INTEL_PT,
2550 .features[FEAT_7_0_ECX] =
2551 CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
2552 CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
2553 CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
2554 CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
2555 CPUID_7_0_ECX_AVX512_VPOPCNTDQ,
2556 .features[FEAT_7_0_EDX] =
2557 CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
2558
2559
2560
2561
2562
2563
2564 .features[FEAT_XSAVE] =
2565 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2566 CPUID_XSAVE_XGETBV1,
2567 .features[FEAT_6_EAX] =
2568 CPUID_6_EAX_ARAT,
2569 .xlevel = 0x80000008,
2570 .model_id = "Intel Core Processor (Icelake)",
2571 },
2572 {
2573 .name = "Icelake-Server",
2574 .level = 0xd,
2575 .vendor = CPUID_VENDOR_INTEL,
2576 .family = 6,
2577 .model = 134,
2578 .stepping = 0,
2579 .features[FEAT_1_EDX] =
2580 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2581 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2582 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2583 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2584 CPUID_DE | CPUID_FP87,
2585 .features[FEAT_1_ECX] =
2586 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2587 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2588 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2589 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2590 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2591 CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2592 .features[FEAT_8000_0001_EDX] =
2593 CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
2594 CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
2595 .features[FEAT_8000_0001_ECX] =
2596 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2597 .features[FEAT_8000_0008_EBX] =
2598 CPUID_8000_0008_EBX_WBNOINVD,
2599 .features[FEAT_7_0_EBX] =
2600 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
2601 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
2602 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
2603 CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
2604 CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
2605 CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
2606 CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
2607 CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
2608 CPUID_7_0_EBX_INTEL_PT,
2609 .features[FEAT_7_0_ECX] =
2610 CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
2611 CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
2612 CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
2613 CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
2614 CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57,
2615 .features[FEAT_7_0_EDX] =
2616 CPUID_7_0_EDX_PCONFIG | CPUID_7_0_EDX_SPEC_CTRL |
2617 CPUID_7_0_EDX_SPEC_CTRL_SSBD,
2618
2619
2620
2621
2622
2623
2624 .features[FEAT_XSAVE] =
2625 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2626 CPUID_XSAVE_XGETBV1,
2627 .features[FEAT_6_EAX] =
2628 CPUID_6_EAX_ARAT,
2629 .xlevel = 0x80000008,
2630 .model_id = "Intel Xeon Processor (Icelake)",
2631 },
2632 {
2633 .name = "KnightsMill",
2634 .level = 0xd,
2635 .vendor = CPUID_VENDOR_INTEL,
2636 .family = 6,
2637 .model = 133,
2638 .stepping = 0,
2639 .features[FEAT_1_EDX] =
2640 CPUID_VME | CPUID_SS | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
2641 CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV |
2642 CPUID_MCA | CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC |
2643 CPUID_CX8 | CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC |
2644 CPUID_PSE | CPUID_DE | CPUID_FP87,
2645 .features[FEAT_1_ECX] =
2646 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2647 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
2648 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
2649 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
2650 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
2651 CPUID_EXT_F16C | CPUID_EXT_RDRAND,
2652 .features[FEAT_8000_0001_EDX] =
2653 CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
2654 CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
2655 .features[FEAT_8000_0001_ECX] =
2656 CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
2657 .features[FEAT_7_0_EBX] =
2658 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
2659 CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS |
2660 CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_AVX512F |
2661 CPUID_7_0_EBX_AVX512CD | CPUID_7_0_EBX_AVX512PF |
2662 CPUID_7_0_EBX_AVX512ER,
2663 .features[FEAT_7_0_ECX] =
2664 CPUID_7_0_ECX_AVX512_VPOPCNTDQ,
2665 .features[FEAT_7_0_EDX] =
2666 CPUID_7_0_EDX_AVX512_4VNNIW | CPUID_7_0_EDX_AVX512_4FMAPS,
2667 .features[FEAT_XSAVE] =
2668 CPUID_XSAVE_XSAVEOPT,
2669 .features[FEAT_6_EAX] =
2670 CPUID_6_EAX_ARAT,
2671 .xlevel = 0x80000008,
2672 .model_id = "Intel Xeon Phi Processor (Knights Mill)",
2673 },
2674 {
2675 .name = "Opteron_G1",
2676 .level = 5,
2677 .vendor = CPUID_VENDOR_AMD,
2678 .family = 15,
2679 .model = 6,
2680 .stepping = 1,
2681 .features[FEAT_1_EDX] =
2682 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2683 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2684 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2685 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2686 CPUID_DE | CPUID_FP87,
2687 .features[FEAT_1_ECX] =
2688 CPUID_EXT_SSE3,
2689 .features[FEAT_8000_0001_EDX] =
2690 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
2691 .xlevel = 0x80000008,
2692 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
2693 },
2694 {
2695 .name = "Opteron_G2",
2696 .level = 5,
2697 .vendor = CPUID_VENDOR_AMD,
2698 .family = 15,
2699 .model = 6,
2700 .stepping = 1,
2701 .features[FEAT_1_EDX] =
2702 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2703 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2704 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2705 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2706 CPUID_DE | CPUID_FP87,
2707 .features[FEAT_1_ECX] =
2708 CPUID_EXT_CX16 | CPUID_EXT_SSE3,
2709
2710 .features[FEAT_8000_0001_EDX] =
2711 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
2712 .features[FEAT_8000_0001_ECX] =
2713 CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
2714 .xlevel = 0x80000008,
2715 .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
2716 },
2717 {
2718 .name = "Opteron_G3",
2719 .level = 5,
2720 .vendor = CPUID_VENDOR_AMD,
2721 .family = 16,
2722 .model = 2,
2723 .stepping = 3,
2724 .features[FEAT_1_EDX] =
2725 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2726 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2727 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2728 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2729 CPUID_DE | CPUID_FP87,
2730 .features[FEAT_1_ECX] =
2731 CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
2732 CPUID_EXT_SSE3,
2733
2734 .features[FEAT_8000_0001_EDX] =
2735 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
2736 .features[FEAT_8000_0001_ECX] =
2737 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
2738 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
2739 .xlevel = 0x80000008,
2740 .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
2741 },
2742 {
2743 .name = "Opteron_G4",
2744 .level = 0xd,
2745 .vendor = CPUID_VENDOR_AMD,
2746 .family = 21,
2747 .model = 1,
2748 .stepping = 2,
2749 .features[FEAT_1_EDX] =
2750 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2751 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2752 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2753 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2754 CPUID_DE | CPUID_FP87,
2755 .features[FEAT_1_ECX] =
2756 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
2757 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
2758 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
2759 CPUID_EXT_SSE3,
2760
2761 .features[FEAT_8000_0001_EDX] =
2762 CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_NX |
2763 CPUID_EXT2_SYSCALL,
2764 .features[FEAT_8000_0001_ECX] =
2765 CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
2766 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
2767 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
2768 CPUID_EXT3_LAHF_LM,
2769
2770 .xlevel = 0x8000001A,
2771 .model_id = "AMD Opteron 62xx class CPU",
2772 },
2773 {
2774 .name = "Opteron_G5",
2775 .level = 0xd,
2776 .vendor = CPUID_VENDOR_AMD,
2777 .family = 21,
2778 .model = 2,
2779 .stepping = 0,
2780 .features[FEAT_1_EDX] =
2781 CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
2782 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
2783 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
2784 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
2785 CPUID_DE | CPUID_FP87,
2786 .features[FEAT_1_ECX] =
2787 CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
2788 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
2789 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
2790 CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
2791
2792 .features[FEAT_8000_0001_EDX] =
2793 CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_NX |
2794 CPUID_EXT2_SYSCALL,
2795 .features[FEAT_8000_0001_ECX] =
2796 CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
2797 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
2798 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
2799 CPUID_EXT3_LAHF_LM,
2800
2801 .xlevel = 0x8000001A,
2802 .model_id = "AMD Opteron 63xx class CPU",
2803 },
2804 {
2805 .name = "EPYC",
2806 .level = 0xd,
2807 .vendor = CPUID_VENDOR_AMD,
2808 .family = 23,
2809 .model = 1,
2810 .stepping = 2,
2811 .features[FEAT_1_EDX] =
2812 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
2813 CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
2814 CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
2815 CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
2816 CPUID_VME | CPUID_FP87,
2817 .features[FEAT_1_ECX] =
2818 CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
2819 CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT |
2820 CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
2821 CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
2822 CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
2823 .features[FEAT_8000_0001_EDX] =
2824 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
2825 CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
2826 CPUID_EXT2_SYSCALL,
2827 .features[FEAT_8000_0001_ECX] =
2828 CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
2829 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
2830 CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
2831 CPUID_EXT3_TOPOEXT,
2832 .features[FEAT_7_0_EBX] =
2833 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
2834 CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
2835 CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
2836 CPUID_7_0_EBX_SHA_NI,
2837
2838
2839
2840
2841 .features[FEAT_XSAVE] =
2842 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2843 CPUID_XSAVE_XGETBV1,
2844 .features[FEAT_6_EAX] =
2845 CPUID_6_EAX_ARAT,
2846 .xlevel = 0x8000001E,
2847 .model_id = "AMD EPYC Processor",
2848 .cache_info = &epyc_cache_info,
2849 },
2850 {
2851 .name = "EPYC-IBPB",
2852 .level = 0xd,
2853 .vendor = CPUID_VENDOR_AMD,
2854 .family = 23,
2855 .model = 1,
2856 .stepping = 2,
2857 .features[FEAT_1_EDX] =
2858 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
2859 CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
2860 CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
2861 CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
2862 CPUID_VME | CPUID_FP87,
2863 .features[FEAT_1_ECX] =
2864 CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
2865 CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT |
2866 CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
2867 CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
2868 CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
2869 .features[FEAT_8000_0001_EDX] =
2870 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
2871 CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
2872 CPUID_EXT2_SYSCALL,
2873 .features[FEAT_8000_0001_ECX] =
2874 CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
2875 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
2876 CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
2877 CPUID_EXT3_TOPOEXT,
2878 .features[FEAT_8000_0008_EBX] =
2879 CPUID_8000_0008_EBX_IBPB,
2880 .features[FEAT_7_0_EBX] =
2881 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
2882 CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
2883 CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
2884 CPUID_7_0_EBX_SHA_NI,
2885
2886
2887
2888
2889 .features[FEAT_XSAVE] =
2890 CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
2891 CPUID_XSAVE_XGETBV1,
2892 .features[FEAT_6_EAX] =
2893 CPUID_6_EAX_ARAT,
2894 .xlevel = 0x8000001E,
2895 .model_id = "AMD EPYC Processor (with IBPB)",
2896 .cache_info = &epyc_cache_info,
2897 },
2898};
2899
2900typedef struct PropValue {
2901 const char *prop, *value;
2902} PropValue;
2903
2904
2905
2906
2907static PropValue kvm_default_props[] = {
2908 { "kvmclock", "on" },
2909 { "kvm-nopiodelay", "on" },
2910 { "kvm-asyncpf", "on" },
2911 { "kvm-steal-time", "on" },
2912 { "kvm-pv-eoi", "on" },
2913 { "kvmclock-stable-bit", "on" },
2914 { "x2apic", "on" },
2915 { "acpi", "off" },
2916 { "monitor", "off" },
2917 { "svm", "off" },
2918 { NULL, NULL },
2919};
2920
2921
2922
2923static PropValue tcg_default_props[] = {
2924 { "vme", "off" },
2925 { NULL, NULL },
2926};
2927
2928
2929void x86_cpu_change_kvm_default(const char *prop, const char *value)
2930{
2931 PropValue *pv;
2932 for (pv = kvm_default_props; pv->prop; pv++) {
2933 if (!strcmp(pv->prop, prop)) {
2934 pv->value = value;
2935 break;
2936 }
2937 }
2938
2939
2940
2941
2942 assert(pv->prop);
2943}
2944
2945static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
2946 bool migratable_only);
2947
2948static bool lmce_supported(void)
2949{
2950 uint64_t mce_cap = 0;
2951
2952#ifdef CONFIG_KVM
2953 if (kvm_ioctl(kvm_state, KVM_X86_GET_MCE_CAP_SUPPORTED, &mce_cap) < 0) {
2954 return false;
2955 }
2956#endif
2957
2958 return !!(mce_cap & MCG_LMCE_P);
2959}
2960
2961#define CPUID_MODEL_ID_SZ 48
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972static int cpu_x86_fill_model_id(char *str)
2973{
2974 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
2975 int i;
2976
2977 for (i = 0; i < 3; i++) {
2978 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
2979 memcpy(str + i * 16 + 0, &eax, 4);
2980 memcpy(str + i * 16 + 4, &ebx, 4);
2981 memcpy(str + i * 16 + 8, &ecx, 4);
2982 memcpy(str + i * 16 + 12, &edx, 4);
2983 }
2984 return 0;
2985}
2986
2987static Property max_x86_cpu_properties[] = {
2988 DEFINE_PROP_BOOL("migratable", X86CPU, migratable, true),
2989 DEFINE_PROP_BOOL("host-cache-info", X86CPU, cache_info_passthrough, false),
2990 DEFINE_PROP_END_OF_LIST()
2991};
2992
2993static void max_x86_cpu_class_init(ObjectClass *oc, void *data)
2994{
2995 DeviceClass *dc = DEVICE_CLASS(oc);
2996 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2997
2998 xcc->ordering = 9;
2999
3000 xcc->model_description =
3001 "Enables all features supported by the accelerator in the current host";
3002
3003 dc->props = max_x86_cpu_properties;
3004}
3005
3006static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp);
3007
3008static void max_x86_cpu_initfn(Object *obj)
3009{
3010 X86CPU *cpu = X86_CPU(obj);
3011 CPUX86State *env = &cpu->env;
3012 KVMState *s = kvm_state;
3013
3014
3015
3016
3017 cpu->max_features = true;
3018
3019 if (accel_uses_host_cpuid()) {
3020 char vendor[CPUID_VENDOR_SZ + 1] = { 0 };
3021 char model_id[CPUID_MODEL_ID_SZ + 1] = { 0 };
3022 int family, model, stepping;
3023 X86CPUDefinition host_cpudef = { };
3024 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
3025
3026 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
3027 x86_cpu_vendor_words2str(host_cpudef.vendor, ebx, edx, ecx);
3028
3029 host_vendor_fms(vendor, &family, &model, &stepping);
3030
3031 cpu_x86_fill_model_id(model_id);
3032
3033 object_property_set_str(OBJECT(cpu), vendor, "vendor", &error_abort);
3034 object_property_set_int(OBJECT(cpu), family, "family", &error_abort);
3035 object_property_set_int(OBJECT(cpu), model, "model", &error_abort);
3036 object_property_set_int(OBJECT(cpu), stepping, "stepping",
3037 &error_abort);
3038 object_property_set_str(OBJECT(cpu), model_id, "model-id",
3039 &error_abort);
3040
3041 if (kvm_enabled()) {
3042 env->cpuid_min_level =
3043 kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
3044 env->cpuid_min_xlevel =
3045 kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
3046 env->cpuid_min_xlevel2 =
3047 kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
3048 } else {
3049 env->cpuid_min_level =
3050 hvf_get_supported_cpuid(0x0, 0, R_EAX);
3051 env->cpuid_min_xlevel =
3052 hvf_get_supported_cpuid(0x80000000, 0, R_EAX);
3053 env->cpuid_min_xlevel2 =
3054 hvf_get_supported_cpuid(0xC0000000, 0, R_EAX);
3055 }
3056
3057 if (lmce_supported()) {
3058 object_property_set_bool(OBJECT(cpu), true, "lmce", &error_abort);
3059 }
3060 } else {
3061 object_property_set_str(OBJECT(cpu), CPUID_VENDOR_AMD,
3062 "vendor", &error_abort);
3063 object_property_set_int(OBJECT(cpu), 6, "family", &error_abort);
3064 object_property_set_int(OBJECT(cpu), 6, "model", &error_abort);
3065 object_property_set_int(OBJECT(cpu), 3, "stepping", &error_abort);
3066 object_property_set_str(OBJECT(cpu),
3067 "QEMU TCG CPU version " QEMU_HW_VERSION,
3068 "model-id", &error_abort);
3069 }
3070
3071 object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
3072}
3073
3074static const TypeInfo max_x86_cpu_type_info = {
3075 .name = X86_CPU_TYPE_NAME("max"),
3076 .parent = TYPE_X86_CPU,
3077 .instance_init = max_x86_cpu_initfn,
3078 .class_init = max_x86_cpu_class_init,
3079};
3080
3081#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
3082static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
3083{
3084 X86CPUClass *xcc = X86_CPU_CLASS(oc);
3085
3086 xcc->host_cpuid_required = true;
3087 xcc->ordering = 8;
3088
3089#if defined(CONFIG_KVM)
3090 xcc->model_description =
3091 "KVM processor with all supported host features ";
3092#elif defined(CONFIG_HVF)
3093 xcc->model_description =
3094 "HVF processor with all supported host features ";
3095#endif
3096}
3097
3098static const TypeInfo host_x86_cpu_type_info = {
3099 .name = X86_CPU_TYPE_NAME("host"),
3100 .parent = X86_CPU_TYPE_NAME("max"),
3101 .class_init = host_x86_cpu_class_init,
3102};
3103
3104#endif
3105
3106static char *feature_word_description(FeatureWordInfo *f, uint32_t bit)
3107{
3108 assert(f->type == CPUID_FEATURE_WORD || f->type == MSR_FEATURE_WORD);
3109
3110 switch (f->type) {
3111 case CPUID_FEATURE_WORD:
3112 {
3113 const char *reg = get_register_name_32(f->cpuid.reg);
3114 assert(reg);
3115 return g_strdup_printf("CPUID.%02XH:%s",
3116 f->cpuid.eax, reg);
3117 }
3118 case MSR_FEATURE_WORD:
3119 return g_strdup_printf("MSR(%02XH)",
3120 f->msr.index);
3121 }
3122
3123 return NULL;
3124}
3125
3126static void report_unavailable_features(FeatureWord w, uint32_t mask)
3127{
3128 FeatureWordInfo *f = &feature_word_info[w];
3129 int i;
3130 char *feat_word_str;
3131
3132 for (i = 0; i < 32; ++i) {
3133 if ((1UL << i) & mask) {
3134 feat_word_str = feature_word_description(f, i);
3135 warn_report("%s doesn't support requested feature: %s%s%s [bit %d]",
3136 accel_uses_host_cpuid() ? "host" : "TCG",
3137 feat_word_str,
3138 f->feat_names[i] ? "." : "",
3139 f->feat_names[i] ? f->feat_names[i] : "", i);
3140 g_free(feat_word_str);
3141 }
3142 }
3143}
3144
3145static void x86_cpuid_version_get_family(Object *obj, Visitor *v,
3146 const char *name, void *opaque,
3147 Error **errp)
3148{
3149 X86CPU *cpu = X86_CPU(obj);
3150 CPUX86State *env = &cpu->env;
3151 int64_t value;
3152
3153 value = (env->cpuid_version >> 8) & 0xf;
3154 if (value == 0xf) {
3155 value += (env->cpuid_version >> 20) & 0xff;
3156 }
3157 visit_type_int(v, name, &value, errp);
3158}
3159
3160static void x86_cpuid_version_set_family(Object *obj, Visitor *v,
3161 const char *name, void *opaque,
3162 Error **errp)
3163{
3164 X86CPU *cpu = X86_CPU(obj);
3165 CPUX86State *env = &cpu->env;
3166 const int64_t min = 0;
3167 const int64_t max = 0xff + 0xf;
3168 Error *local_err = NULL;
3169 int64_t value;
3170
3171 visit_type_int(v, name, &value, &local_err);
3172 if (local_err) {
3173 error_propagate(errp, local_err);
3174 return;
3175 }
3176 if (value < min || value > max) {
3177 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
3178 name ? name : "null", value, min, max);
3179 return;
3180 }
3181
3182 env->cpuid_version &= ~0xff00f00;
3183 if (value > 0x0f) {
3184 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
3185 } else {
3186 env->cpuid_version |= value << 8;
3187 }
3188}
3189
3190static void x86_cpuid_version_get_model(Object *obj, Visitor *v,
3191 const char *name, void *opaque,
3192 Error **errp)
3193{
3194 X86CPU *cpu = X86_CPU(obj);
3195 CPUX86State *env = &cpu->env;
3196 int64_t value;
3197
3198 value = (env->cpuid_version >> 4) & 0xf;
3199 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
3200 visit_type_int(v, name, &value, errp);
3201}
3202
3203static void x86_cpuid_version_set_model(Object *obj, Visitor *v,
3204 const char *name, void *opaque,
3205 Error **errp)
3206{
3207 X86CPU *cpu = X86_CPU(obj);
3208 CPUX86State *env = &cpu->env;
3209 const int64_t min = 0;
3210 const int64_t max = 0xff;
3211 Error *local_err = NULL;
3212 int64_t value;
3213
3214 visit_type_int(v, name, &value, &local_err);
3215 if (local_err) {
3216 error_propagate(errp, local_err);
3217 return;
3218 }
3219 if (value < min || value > max) {
3220 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
3221 name ? name : "null", value, min, max);
3222 return;
3223 }
3224
3225 env->cpuid_version &= ~0xf00f0;
3226 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
3227}
3228
3229static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
3230 const char *name, void *opaque,
3231 Error **errp)
3232{
3233 X86CPU *cpu = X86_CPU(obj);
3234 CPUX86State *env = &cpu->env;
3235 int64_t value;
3236
3237 value = env->cpuid_version & 0xf;
3238 visit_type_int(v, name, &value, errp);
3239}
3240
3241static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
3242 const char *name, void *opaque,
3243 Error **errp)
3244{
3245 X86CPU *cpu = X86_CPU(obj);
3246 CPUX86State *env = &cpu->env;
3247 const int64_t min = 0;
3248 const int64_t max = 0xf;
3249 Error *local_err = NULL;
3250 int64_t value;
3251
3252 visit_type_int(v, name, &value, &local_err);
3253 if (local_err) {
3254 error_propagate(errp, local_err);
3255 return;
3256 }
3257 if (value < min || value > max) {
3258 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
3259 name ? name : "null", value, min, max);
3260 return;
3261 }
3262
3263 env->cpuid_version &= ~0xf;
3264 env->cpuid_version |= value & 0xf;
3265}
3266
3267static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
3268{
3269 X86CPU *cpu = X86_CPU(obj);
3270 CPUX86State *env = &cpu->env;
3271 char *value;
3272
3273 value = g_malloc(CPUID_VENDOR_SZ + 1);
3274 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
3275 env->cpuid_vendor3);
3276 return value;
3277}
3278
3279static void x86_cpuid_set_vendor(Object *obj, const char *value,
3280 Error **errp)
3281{
3282 X86CPU *cpu = X86_CPU(obj);
3283 CPUX86State *env = &cpu->env;
3284 int i;
3285
3286 if (strlen(value) != CPUID_VENDOR_SZ) {
3287 error_setg(errp, QERR_PROPERTY_VALUE_BAD, "", "vendor", value);
3288 return;
3289 }
3290
3291 env->cpuid_vendor1 = 0;
3292 env->cpuid_vendor2 = 0;
3293 env->cpuid_vendor3 = 0;
3294 for (i = 0; i < 4; i++) {
3295 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
3296 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
3297 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
3298 }
3299}
3300
3301static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
3302{
3303 X86CPU *cpu = X86_CPU(obj);
3304 CPUX86State *env = &cpu->env;
3305 char *value;
3306 int i;
3307
3308 value = g_malloc(48 + 1);
3309 for (i = 0; i < 48; i++) {
3310 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
3311 }
3312 value[48] = '\0';
3313 return value;
3314}
3315
3316static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
3317 Error **errp)
3318{
3319 X86CPU *cpu = X86_CPU(obj);
3320 CPUX86State *env = &cpu->env;
3321 int c, len, i;
3322
3323 if (model_id == NULL) {
3324 model_id = "";
3325 }
3326 len = strlen(model_id);
3327 memset(env->cpuid_model, 0, 48);
3328 for (i = 0; i < 48; i++) {
3329 if (i >= len) {
3330 c = '\0';
3331 } else {
3332 c = (uint8_t)model_id[i];
3333 }
3334 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
3335 }
3336}
3337
3338static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, const char *name,
3339 void *opaque, Error **errp)
3340{
3341 X86CPU *cpu = X86_CPU(obj);
3342 int64_t value;
3343
3344 value = cpu->env.tsc_khz * 1000;
3345 visit_type_int(v, name, &value, errp);
3346}
3347
3348static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, const char *name,
3349 void *opaque, Error **errp)
3350{
3351 X86CPU *cpu = X86_CPU(obj);
3352 const int64_t min = 0;
3353 const int64_t max = INT64_MAX;
3354 Error *local_err = NULL;
3355 int64_t value;
3356
3357 visit_type_int(v, name, &value, &local_err);
3358 if (local_err) {
3359 error_propagate(errp, local_err);
3360 return;
3361 }
3362 if (value < min || value > max) {
3363 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
3364 name ? name : "null", value, min, max);
3365 return;
3366 }
3367
3368 cpu->env.tsc_khz = cpu->env.user_tsc_khz = value / 1000;
3369}
3370
3371
3372static void x86_cpu_get_feature_words(Object *obj, Visitor *v,
3373 const char *name, void *opaque,
3374 Error **errp)
3375{
3376 uint32_t *array = (uint32_t *)opaque;
3377 FeatureWord w;
3378 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
3379 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
3380 X86CPUFeatureWordInfoList *list = NULL;
3381
3382 for (w = 0; w < FEATURE_WORDS; w++) {
3383 FeatureWordInfo *wi = &feature_word_info[w];
3384
3385
3386
3387
3388 if (wi->type != CPUID_FEATURE_WORD) {
3389 continue;
3390 }
3391 X86CPUFeatureWordInfo *qwi = &word_infos[w];
3392 qwi->cpuid_input_eax = wi->cpuid.eax;
3393 qwi->has_cpuid_input_ecx = wi->cpuid.needs_ecx;
3394 qwi->cpuid_input_ecx = wi->cpuid.ecx;
3395 qwi->cpuid_register = x86_reg_info_32[wi->cpuid.reg].qapi_enum;
3396 qwi->features = array[w];
3397
3398
3399 list_entries[w].next = list;
3400 list_entries[w].value = &word_infos[w];
3401 list = &list_entries[w];
3402 }
3403
3404 visit_type_X86CPUFeatureWordInfoList(v, "feature-words", &list, errp);
3405}
3406
3407static void x86_get_hv_spinlocks(Object *obj, Visitor *v, const char *name,
3408 void *opaque, Error **errp)
3409{
3410 X86CPU *cpu = X86_CPU(obj);
3411 int64_t value = cpu->hyperv_spinlock_attempts;
3412
3413 visit_type_int(v, name, &value, errp);
3414}
3415
3416static void x86_set_hv_spinlocks(Object *obj, Visitor *v, const char *name,
3417 void *opaque, Error **errp)
3418{
3419 const int64_t min = 0xFFF;
3420 const int64_t max = UINT_MAX;
3421 X86CPU *cpu = X86_CPU(obj);
3422 Error *err = NULL;
3423 int64_t value;
3424
3425 visit_type_int(v, name, &value, &err);
3426 if (err) {
3427 error_propagate(errp, err);
3428 return;
3429 }
3430
3431 if (value < min || value > max) {
3432 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
3433 " (minimum: %" PRId64 ", maximum: %" PRId64 ")",
3434 object_get_typename(obj), name ? name : "null",
3435 value, min, max);
3436 return;
3437 }
3438 cpu->hyperv_spinlock_attempts = value;
3439}
3440
3441static const PropertyInfo qdev_prop_spinlocks = {
3442 .name = "int",
3443 .get = x86_get_hv_spinlocks,
3444 .set = x86_set_hv_spinlocks,
3445};
3446
3447
3448
3449
3450static inline void feat2prop(char *s)
3451{
3452 while ((s = strchr(s, '_'))) {
3453 *s = '-';
3454 }
3455}
3456
3457
3458static const char *x86_cpu_feature_name(FeatureWord w, int bitnr)
3459{
3460
3461
3462
3463 if (w == FEAT_XSAVE_COMP_LO || w == FEAT_XSAVE_COMP_HI) {
3464 int comp = (w == FEAT_XSAVE_COMP_HI) ? bitnr + 32 : bitnr;
3465
3466 if (comp < ARRAY_SIZE(x86_ext_save_areas) &&
3467 x86_ext_save_areas[comp].bits) {
3468 w = x86_ext_save_areas[comp].feature;
3469 bitnr = ctz32(x86_ext_save_areas[comp].bits);
3470 }
3471 }
3472
3473 assert(bitnr < 32);
3474 assert(w < FEATURE_WORDS);
3475 return feature_word_info[w].feat_names[bitnr];
3476}
3477
3478
3479
3480
3481
3482
3483static GList *plus_features, *minus_features;
3484
3485static gint compare_string(gconstpointer a, gconstpointer b)
3486{
3487 return g_strcmp0(a, b);
3488}
3489
3490
3491
3492static void x86_cpu_parse_featurestr(const char *typename, char *features,
3493 Error **errp)
3494{
3495 char *featurestr;
3496 static bool cpu_globals_initialized;
3497 bool ambiguous = false;
3498
3499 if (cpu_globals_initialized) {
3500 return;
3501 }
3502 cpu_globals_initialized = true;
3503
3504 if (!features) {
3505 return;
3506 }
3507
3508 for (featurestr = strtok(features, ",");
3509 featurestr;
3510 featurestr = strtok(NULL, ",")) {
3511 const char *name;
3512 const char *val = NULL;
3513 char *eq = NULL;
3514 char num[32];
3515 GlobalProperty *prop;
3516
3517
3518 if (featurestr[0] == '+') {
3519 plus_features = g_list_append(plus_features,
3520 g_strdup(featurestr + 1));
3521 continue;
3522 } else if (featurestr[0] == '-') {
3523 minus_features = g_list_append(minus_features,
3524 g_strdup(featurestr + 1));
3525 continue;
3526 }
3527
3528 eq = strchr(featurestr, '=');
3529 if (eq) {
3530 *eq++ = 0;
3531 val = eq;
3532 } else {
3533 val = "on";
3534 }
3535
3536 feat2prop(featurestr);
3537 name = featurestr;
3538
3539 if (g_list_find_custom(plus_features, name, compare_string)) {
3540 warn_report("Ambiguous CPU model string. "
3541 "Don't mix both \"+%s\" and \"%s=%s\"",
3542 name, name, val);
3543 ambiguous = true;
3544 }
3545 if (g_list_find_custom(minus_features, name, compare_string)) {
3546 warn_report("Ambiguous CPU model string. "
3547 "Don't mix both \"-%s\" and \"%s=%s\"",
3548 name, name, val);
3549 ambiguous = true;
3550 }
3551
3552
3553 if (!strcmp(name, "tsc-freq")) {
3554 int ret;
3555 uint64_t tsc_freq;
3556
3557 ret = qemu_strtosz_metric(val, NULL, &tsc_freq);
3558 if (ret < 0 || tsc_freq > INT64_MAX) {
3559 error_setg(errp, "bad numerical value %s", val);
3560 return;
3561 }
3562 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
3563 val = num;
3564 name = "tsc-frequency";
3565 }
3566
3567 prop = g_new0(typeof(*prop), 1);
3568 prop->driver = typename;
3569 prop->property = g_strdup(name);
3570 prop->value = g_strdup(val);
3571 prop->errp = &error_fatal;
3572 qdev_prop_register_global(prop);
3573 }
3574
3575 if (ambiguous) {
3576 warn_report("Compatibility of ambiguous CPU model "
3577 "strings won't be kept on future QEMU versions");
3578 }
3579}
3580
3581static void x86_cpu_expand_features(X86CPU *cpu, Error **errp);
3582static int x86_cpu_filter_features(X86CPU *cpu);
3583
3584
3585
3586
3587static void x86_cpu_class_check_missing_features(X86CPUClass *xcc,
3588 strList **missing_feats)
3589{
3590 X86CPU *xc;
3591 FeatureWord w;
3592 Error *err = NULL;
3593 strList **next = missing_feats;
3594
3595 if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
3596 strList *new = g_new0(strList, 1);
3597 new->value = g_strdup("kvm");
3598 *missing_feats = new;
3599 return;
3600 }
3601
3602 xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc))));
3603
3604 x86_cpu_expand_features(xc, &err);
3605 if (err) {
3606
3607
3608
3609
3610 strList *new = g_new0(strList, 1);
3611 new->value = g_strdup("type");
3612 *next = new;
3613 next = &new->next;
3614 }
3615
3616 x86_cpu_filter_features(xc);
3617
3618 for (w = 0; w < FEATURE_WORDS; w++) {
3619 uint32_t filtered = xc->filtered_features[w];
3620 int i;
3621 for (i = 0; i < 32; i++) {
3622 if (filtered & (1UL << i)) {
3623 strList *new = g_new0(strList, 1);
3624 new->value = g_strdup(x86_cpu_feature_name(w, i));
3625 *next = new;
3626 next = &new->next;
3627 }
3628 }
3629 }
3630
3631 object_unref(OBJECT(xc));
3632}
3633
3634
3635
3636static void listflags(FILE *f, fprintf_function print, GList *features)
3637{
3638 size_t len = 0;
3639 GList *tmp;
3640
3641 for (tmp = features; tmp; tmp = tmp->next) {
3642 const char *name = tmp->data;
3643 if ((len + strlen(name) + 1) >= 75) {
3644 print(f, "\n");
3645 len = 0;
3646 }
3647 print(f, "%s%s", len == 0 ? " " : " ", name);
3648 len += strlen(name) + 1;
3649 }
3650 print(f, "\n");
3651}
3652
3653
3654static gint x86_cpu_list_compare(gconstpointer a, gconstpointer b)
3655{
3656 ObjectClass *class_a = (ObjectClass *)a;
3657 ObjectClass *class_b = (ObjectClass *)b;
3658 X86CPUClass *cc_a = X86_CPU_CLASS(class_a);
3659 X86CPUClass *cc_b = X86_CPU_CLASS(class_b);
3660 char *name_a, *name_b;
3661 int ret;
3662
3663 if (cc_a->ordering != cc_b->ordering) {
3664 ret = cc_a->ordering - cc_b->ordering;
3665 } else {
3666 name_a = x86_cpu_class_get_model_name(cc_a);
3667 name_b = x86_cpu_class_get_model_name(cc_b);
3668 ret = strcmp(name_a, name_b);
3669 g_free(name_a);
3670 g_free(name_b);
3671 }
3672 return ret;
3673}
3674
3675static GSList *get_sorted_cpu_model_list(void)
3676{
3677 GSList *list = object_class_get_list(TYPE_X86_CPU, false);
3678 list = g_slist_sort(list, x86_cpu_list_compare);
3679 return list;
3680}
3681
3682static void x86_cpu_list_entry(gpointer data, gpointer user_data)
3683{
3684 ObjectClass *oc = data;
3685 X86CPUClass *cc = X86_CPU_CLASS(oc);
3686 CPUListState *s = user_data;
3687 char *name = x86_cpu_class_get_model_name(cc);
3688 const char *desc = cc->model_description;
3689 if (!desc && cc->cpu_def) {
3690 desc = cc->cpu_def->model_id;
3691 }
3692
3693 (*s->cpu_fprintf)(s->file, "x86 %-20s %-48s\n",
3694 name, desc);
3695 g_free(name);
3696}
3697
3698
3699void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
3700{
3701 int i, j;
3702 CPUListState s = {
3703 .file = f,
3704 .cpu_fprintf = cpu_fprintf,
3705 };
3706 GSList *list;
3707 GList *names = NULL;
3708
3709 (*cpu_fprintf)(f, "Available CPUs:\n");
3710 list = get_sorted_cpu_model_list();
3711 g_slist_foreach(list, x86_cpu_list_entry, &s);
3712 g_slist_free(list);
3713
3714 names = NULL;
3715 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
3716 FeatureWordInfo *fw = &feature_word_info[i];
3717 for (j = 0; j < 32; j++) {
3718 if (fw->feat_names[j]) {
3719 names = g_list_append(names, (gpointer)fw->feat_names[j]);
3720 }
3721 }
3722 }
3723
3724 names = g_list_sort(names, (GCompareFunc)strcmp);
3725
3726 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
3727 listflags(f, cpu_fprintf, names);
3728 (*cpu_fprintf)(f, "\n");
3729 g_list_free(names);
3730}
3731
3732static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
3733{
3734 ObjectClass *oc = data;
3735 X86CPUClass *cc = X86_CPU_CLASS(oc);
3736 CpuDefinitionInfoList **cpu_list = user_data;
3737 CpuDefinitionInfoList *entry;
3738 CpuDefinitionInfo *info;
3739
3740 info = g_malloc0(sizeof(*info));
3741 info->name = x86_cpu_class_get_model_name(cc);
3742 x86_cpu_class_check_missing_features(cc, &info->unavailable_features);
3743 info->has_unavailable_features = true;
3744 info->q_typename = g_strdup(object_class_get_name(oc));
3745 info->migration_safe = cc->migration_safe;
3746 info->has_migration_safe = true;
3747 info->q_static = cc->static_model;
3748
3749 entry = g_malloc0(sizeof(*entry));
3750 entry->value = info;
3751 entry->next = *cpu_list;
3752 *cpu_list = entry;
3753}
3754
3755CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
3756{
3757 CpuDefinitionInfoList *cpu_list = NULL;
3758 GSList *list = get_sorted_cpu_model_list();
3759 g_slist_foreach(list, x86_cpu_definition_entry, &cpu_list);
3760 g_slist_free(list);
3761 return cpu_list;
3762}
3763
3764static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
3765 bool migratable_only)
3766{
3767 FeatureWordInfo *wi = &feature_word_info[w];
3768 uint32_t r = 0;
3769
3770 if (kvm_enabled()) {
3771 switch (wi->type) {
3772 case CPUID_FEATURE_WORD:
3773 r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid.eax,
3774 wi->cpuid.ecx,
3775 wi->cpuid.reg);
3776 break;
3777 case MSR_FEATURE_WORD:
3778 r = kvm_arch_get_supported_msr_feature(kvm_state,
3779 wi->msr.index);
3780 break;
3781 }
3782 } else if (hvf_enabled()) {
3783 if (wi->type != CPUID_FEATURE_WORD) {
3784 return 0;
3785 }
3786 r = hvf_get_supported_cpuid(wi->cpuid.eax,
3787 wi->cpuid.ecx,
3788 wi->cpuid.reg);
3789 } else if (tcg_enabled()) {
3790 r = wi->tcg_features;
3791 } else {
3792 return ~0;
3793 }
3794 if (migratable_only) {
3795 r &= x86_cpu_get_migratable_flags(w);
3796 }
3797 return r;
3798}
3799
3800static void x86_cpu_report_filtered_features(X86CPU *cpu)
3801{
3802 FeatureWord w;
3803
3804 for (w = 0; w < FEATURE_WORDS; w++) {
3805 report_unavailable_features(w, cpu->filtered_features[w]);
3806 }
3807}
3808
3809static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
3810{
3811 PropValue *pv;
3812 for (pv = props; pv->prop; pv++) {
3813 if (!pv->value) {
3814 continue;
3815 }
3816 object_property_parse(OBJECT(cpu), pv->value, pv->prop,
3817 &error_abort);
3818 }
3819}
3820
3821
3822
3823static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
3824{
3825 CPUX86State *env = &cpu->env;
3826 const char *vendor;
3827 char host_vendor[CPUID_VENDOR_SZ + 1];
3828 FeatureWord w;
3829
3830
3831
3832
3833
3834
3835
3836 object_property_set_uint(OBJECT(cpu), def->level, "min-level", errp);
3837 object_property_set_uint(OBJECT(cpu), def->xlevel, "min-xlevel", errp);
3838
3839 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
3840 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
3841 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
3842 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
3843 for (w = 0; w < FEATURE_WORDS; w++) {
3844 env->features[w] = def->features[w];
3845 }
3846
3847
3848 cpu->legacy_cache = !def->cache_info;
3849
3850
3851
3852 if (kvm_enabled()) {
3853 if (!kvm_irqchip_in_kernel()) {
3854 x86_cpu_change_kvm_default("x2apic", "off");
3855 }
3856
3857 x86_cpu_apply_props(cpu, kvm_default_props);
3858 } else if (tcg_enabled()) {
3859 x86_cpu_apply_props(cpu, tcg_default_props);
3860 }
3861
3862 env->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
3863
3864
3865
3866
3867
3868
3869
3870
3871 vendor = def->vendor;
3872 if (accel_uses_host_cpuid()) {
3873 uint32_t ebx = 0, ecx = 0, edx = 0;
3874 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
3875 x86_cpu_vendor_words2str(host_vendor, ebx, edx, ecx);
3876 vendor = host_vendor;
3877 }
3878
3879 object_property_set_str(OBJECT(cpu), vendor, "vendor", errp);
3880
3881}
3882
3883
3884
3885
3886
3887static QDict *x86_cpu_static_props(void)
3888{
3889 FeatureWord w;
3890 int i;
3891 static const char *props[] = {
3892 "min-level",
3893 "min-xlevel",
3894 "family",
3895 "model",
3896 "stepping",
3897 "model-id",
3898 "vendor",
3899 "lmce",
3900 NULL,
3901 };
3902 static QDict *d;
3903
3904 if (d) {
3905 return d;
3906 }
3907
3908 d = qdict_new();
3909 for (i = 0; props[i]; i++) {
3910 qdict_put_null(d, props[i]);
3911 }
3912
3913 for (w = 0; w < FEATURE_WORDS; w++) {
3914 FeatureWordInfo *fi = &feature_word_info[w];
3915 int bit;
3916 for (bit = 0; bit < 32; bit++) {
3917 if (!fi->feat_names[bit]) {
3918 continue;
3919 }
3920 qdict_put_null(d, fi->feat_names[bit]);
3921 }
3922 }
3923
3924 return d;
3925}
3926
3927
3928static void x86_cpu_expand_prop(X86CPU *cpu, QDict *props, const char *prop)
3929{
3930 QObject *value = object_property_get_qobject(OBJECT(cpu), prop,
3931 &error_abort);
3932
3933 qdict_put_obj(props, prop, value);
3934}
3935
3936
3937
3938
3939static void x86_cpu_to_dict(X86CPU *cpu, QDict *props)
3940{
3941 QDict *sprops = x86_cpu_static_props();
3942 const QDictEntry *e;
3943
3944 for (e = qdict_first(sprops); e; e = qdict_next(sprops, e)) {
3945 const char *prop = qdict_entry_key(e);
3946 x86_cpu_expand_prop(cpu, props, prop);
3947 }
3948}
3949
3950
3951
3952
3953
3954static void x86_cpu_to_dict_full(X86CPU *cpu, QDict *props)
3955{
3956 ObjectPropertyIterator iter;
3957 ObjectProperty *prop;
3958
3959 object_property_iter_init(&iter, OBJECT(cpu));
3960 while ((prop = object_property_iter_next(&iter))) {
3961
3962 if (!prop->get || !prop->set) {
3963 continue;
3964 }
3965
3966
3967
3968
3969
3970
3971 if (!strcmp(prop->name, "hotplugged")) {
3972 continue;
3973 }
3974 x86_cpu_expand_prop(cpu, props, prop->name);
3975 }
3976}
3977
3978static void object_apply_props(Object *obj, QDict *props, Error **errp)
3979{
3980 const QDictEntry *prop;
3981 Error *err = NULL;
3982
3983 for (prop = qdict_first(props); prop; prop = qdict_next(props, prop)) {
3984 object_property_set_qobject(obj, qdict_entry_value(prop),
3985 qdict_entry_key(prop), &err);
3986 if (err) {
3987 break;
3988 }
3989 }
3990
3991 error_propagate(errp, err);
3992}
3993
3994
3995static X86CPU *x86_cpu_from_model(const char *model, QDict *props, Error **errp)
3996{
3997 X86CPU *xc = NULL;
3998 X86CPUClass *xcc;
3999 Error *err = NULL;
4000
4001 xcc = X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model));
4002 if (xcc == NULL) {
4003 error_setg(&err, "CPU model '%s' not found", model);
4004 goto out;
4005 }
4006
4007 xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc))));
4008 if (props) {
4009 object_apply_props(OBJECT(xc), props, &err);
4010 if (err) {
4011 goto out;
4012 }
4013 }
4014
4015 x86_cpu_expand_features(xc, &err);
4016 if (err) {
4017 goto out;
4018 }
4019
4020out:
4021 if (err) {
4022 error_propagate(errp, err);
4023 object_unref(OBJECT(xc));
4024 xc = NULL;
4025 }
4026 return xc;
4027}
4028
4029CpuModelExpansionInfo *
4030arch_query_cpu_model_expansion(CpuModelExpansionType type,
4031 CpuModelInfo *model,
4032 Error **errp)
4033{
4034 X86CPU *xc = NULL;
4035 Error *err = NULL;
4036 CpuModelExpansionInfo *ret = g_new0(CpuModelExpansionInfo, 1);
4037 QDict *props = NULL;
4038 const char *base_name;
4039
4040 xc = x86_cpu_from_model(model->name,
4041 model->has_props ?
4042 qobject_to(QDict, model->props) :
4043 NULL, &err);
4044 if (err) {
4045 goto out;
4046 }
4047
4048 props = qdict_new();
4049 ret->model = g_new0(CpuModelInfo, 1);
4050 ret->model->props = QOBJECT(props);
4051 ret->model->has_props = true;
4052
4053 switch (type) {
4054 case CPU_MODEL_EXPANSION_TYPE_STATIC:
4055
4056 base_name = "base";
4057 x86_cpu_to_dict(xc, props);
4058 break;
4059 case CPU_MODEL_EXPANSION_TYPE_FULL:
4060
4061
4062
4063
4064 base_name = model->name;
4065 x86_cpu_to_dict_full(xc, props);
4066 break;
4067 default:
4068 error_setg(&err, "Unsupportted expansion type");
4069 goto out;
4070 }
4071
4072 x86_cpu_to_dict(xc, props);
4073
4074 ret->model->name = g_strdup(base_name);
4075
4076out:
4077 object_unref(OBJECT(xc));
4078 if (err) {
4079 error_propagate(errp, err);
4080 qapi_free_CpuModelExpansionInfo(ret);
4081 ret = NULL;
4082 }
4083 return ret;
4084}
4085
4086static gchar *x86_gdb_arch_name(CPUState *cs)
4087{
4088#ifdef TARGET_X86_64
4089 return g_strdup("i386:x86-64");
4090#else
4091 return g_strdup("i386");
4092#endif
4093}
4094
4095static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
4096{
4097 X86CPUDefinition *cpudef = data;
4098 X86CPUClass *xcc = X86_CPU_CLASS(oc);
4099
4100 xcc->cpu_def = cpudef;
4101 xcc->migration_safe = true;
4102}
4103
4104static void x86_register_cpudef_type(X86CPUDefinition *def)
4105{
4106 char *typename = x86_cpu_type_name(def->name);
4107 TypeInfo ti = {
4108 .name = typename,
4109 .parent = TYPE_X86_CPU,
4110 .class_init = x86_cpu_cpudef_class_init,
4111 .class_data = def,
4112 };
4113
4114
4115
4116
4117 assert(!(def->features[FEAT_8000_0001_EDX] & CPUID_EXT2_AMD_ALIASES));
4118
4119 assert(def->model_id && strlen(def->model_id) <= 48);
4120
4121
4122 type_register(&ti);
4123 g_free(typename);
4124}
4125
4126#if !defined(CONFIG_USER_ONLY)
4127
4128void cpu_clear_apic_feature(CPUX86State *env)
4129{
4130 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
4131}
4132
4133#endif
4134
4135void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
4136 uint32_t *eax, uint32_t *ebx,
4137 uint32_t *ecx, uint32_t *edx)
4138{
4139 X86CPU *cpu = x86_env_get_cpu(env);
4140 CPUState *cs = CPU(cpu);
4141 uint32_t pkg_offset;
4142 uint32_t limit;
4143 uint32_t signature[3];
4144
4145
4146 if (index >= 0xC0000000) {
4147 limit = env->cpuid_xlevel2;
4148 } else if (index >= 0x80000000) {
4149 limit = env->cpuid_xlevel;
4150 } else if (index >= 0x40000000) {
4151 limit = 0x40000001;
4152 } else {
4153 limit = env->cpuid_level;
4154 }
4155
4156 if (index > limit) {
4157
4158
4159
4160
4161 index = env->cpuid_level;
4162 }
4163
4164 switch(index) {
4165 case 0:
4166 *eax = env->cpuid_level;
4167 *ebx = env->cpuid_vendor1;
4168 *edx = env->cpuid_vendor2;
4169 *ecx = env->cpuid_vendor3;
4170 break;
4171 case 1:
4172 *eax = env->cpuid_version;
4173 *ebx = (cpu->apic_id << 24) |
4174 8 << 8;
4175 *ecx = env->features[FEAT_1_ECX];
4176 if ((*ecx & CPUID_EXT_XSAVE) && (env->cr[4] & CR4_OSXSAVE_MASK)) {
4177 *ecx |= CPUID_EXT_OSXSAVE;
4178 }
4179 *edx = env->features[FEAT_1_EDX];
4180 if (cs->nr_cores * cs->nr_threads > 1) {
4181 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
4182 *edx |= CPUID_HT;
4183 }
4184 break;
4185 case 2:
4186
4187 if (cpu->cache_info_passthrough) {
4188 host_cpuid(index, 0, eax, ebx, ecx, edx);
4189 break;
4190 }
4191 *eax = 1;
4192 *ebx = 0;
4193 if (!cpu->enable_l3_cache) {
4194 *ecx = 0;
4195 } else {
4196 *ecx = cpuid2_cache_descriptor(env->cache_info_cpuid2.l3_cache);
4197 }
4198 *edx = (cpuid2_cache_descriptor(env->cache_info_cpuid2.l1d_cache) << 16) |
4199 (cpuid2_cache_descriptor(env->cache_info_cpuid2.l1i_cache) << 8) |
4200 (cpuid2_cache_descriptor(env->cache_info_cpuid2.l2_cache));
4201 break;
4202 case 4:
4203
4204 if (cpu->cache_info_passthrough) {
4205 host_cpuid(index, count, eax, ebx, ecx, edx);
4206
4207 *eax &= ~0xFC000000;
4208 if ((*eax & 31) && cs->nr_cores > 1) {
4209 *eax |= (cs->nr_cores - 1) << 26;
4210 }
4211 } else {
4212 *eax = 0;
4213 switch (count) {
4214 case 0:
4215 encode_cache_cpuid4(env->cache_info_cpuid4.l1d_cache,
4216 1, cs->nr_cores,
4217 eax, ebx, ecx, edx);
4218 break;
4219 case 1:
4220 encode_cache_cpuid4(env->cache_info_cpuid4.l1i_cache,
4221 1, cs->nr_cores,
4222 eax, ebx, ecx, edx);
4223 break;
4224 case 2:
4225 encode_cache_cpuid4(env->cache_info_cpuid4.l2_cache,
4226 cs->nr_threads, cs->nr_cores,
4227 eax, ebx, ecx, edx);
4228 break;
4229 case 3:
4230 pkg_offset = apicid_pkg_offset(cs->nr_cores, cs->nr_threads);
4231 if (cpu->enable_l3_cache) {
4232 encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache,
4233 (1 << pkg_offset), cs->nr_cores,
4234 eax, ebx, ecx, edx);
4235 break;
4236 }
4237
4238 default:
4239 *eax = *ebx = *ecx = *edx = 0;
4240 break;
4241 }
4242 }
4243 break;
4244 case 5:
4245
4246 *eax = cpu->mwait.eax;
4247 *ebx = cpu->mwait.ebx;
4248 *ecx = cpu->mwait.ecx;
4249 *edx = cpu->mwait.edx;
4250 break;
4251 case 6:
4252
4253 *eax = env->features[FEAT_6_EAX];
4254 *ebx = 0;
4255 *ecx = 0;
4256 *edx = 0;
4257 break;
4258 case 7:
4259
4260 if (count == 0) {
4261 *eax = 0;
4262 *ebx = env->features[FEAT_7_0_EBX];
4263 *ecx = env->features[FEAT_7_0_ECX];
4264 if ((*ecx & CPUID_7_0_ECX_PKU) && env->cr[4] & CR4_PKE_MASK) {
4265 *ecx |= CPUID_7_0_ECX_OSPKE;
4266 }
4267 *edx = env->features[FEAT_7_0_EDX];
4268 } else {
4269 *eax = 0;
4270 *ebx = 0;
4271 *ecx = 0;
4272 *edx = 0;
4273 }
4274 break;
4275 case 9:
4276
4277 *eax = 0;
4278 *ebx = 0;
4279 *ecx = 0;
4280 *edx = 0;
4281 break;
4282 case 0xA:
4283
4284 if (kvm_enabled() && cpu->enable_pmu) {
4285 KVMState *s = cs->kvm_state;
4286
4287 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
4288 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
4289 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
4290 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
4291 } else if (hvf_enabled() && cpu->enable_pmu) {
4292 *eax = hvf_get_supported_cpuid(0xA, count, R_EAX);
4293 *ebx = hvf_get_supported_cpuid(0xA, count, R_EBX);
4294 *ecx = hvf_get_supported_cpuid(0xA, count, R_ECX);
4295 *edx = hvf_get_supported_cpuid(0xA, count, R_EDX);
4296 } else {
4297 *eax = 0;
4298 *ebx = 0;
4299 *ecx = 0;
4300 *edx = 0;
4301 }
4302 break;
4303 case 0xB:
4304
4305 if (!cpu->enable_cpuid_0xb) {
4306 *eax = *ebx = *ecx = *edx = 0;
4307 break;
4308 }
4309
4310 *ecx = count & 0xff;
4311 *edx = cpu->apic_id;
4312
4313 switch (count) {
4314 case 0:
4315 *eax = apicid_core_offset(cs->nr_cores, cs->nr_threads);
4316 *ebx = cs->nr_threads;
4317 *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
4318 break;
4319 case 1:
4320 *eax = apicid_pkg_offset(cs->nr_cores, cs->nr_threads);
4321 *ebx = cs->nr_cores * cs->nr_threads;
4322 *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
4323 break;
4324 default:
4325 *eax = 0;
4326 *ebx = 0;
4327 *ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
4328 }
4329
4330 assert(!(*eax & ~0x1f));
4331 *ebx &= 0xffff;
4332 break;
4333 case 0xD: {
4334
4335 *eax = 0;
4336 *ebx = 0;
4337 *ecx = 0;
4338 *edx = 0;
4339 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
4340 break;
4341 }
4342
4343 if (count == 0) {
4344 *ecx = xsave_area_size(x86_cpu_xsave_components(cpu));
4345 *eax = env->features[FEAT_XSAVE_COMP_LO];
4346 *edx = env->features[FEAT_XSAVE_COMP_HI];
4347 *ebx = xsave_area_size(env->xcr0);
4348 } else if (count == 1) {
4349 *eax = env->features[FEAT_XSAVE];
4350 } else if (count < ARRAY_SIZE(x86_ext_save_areas)) {
4351 if ((x86_cpu_xsave_components(cpu) >> count) & 1) {
4352 const ExtSaveArea *esa = &x86_ext_save_areas[count];
4353 *eax = esa->size;
4354 *ebx = esa->offset;
4355 }
4356 }
4357 break;
4358 }
4359 case 0x14: {
4360
4361 *eax = 0;
4362 *ebx = 0;
4363 *ecx = 0;
4364 *edx = 0;
4365 if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) ||
4366 !kvm_enabled()) {
4367 break;
4368 }
4369
4370 if (count == 0) {
4371 *eax = INTEL_PT_MAX_SUBLEAF;
4372 *ebx = INTEL_PT_MINIMAL_EBX;
4373 *ecx = INTEL_PT_MINIMAL_ECX;
4374 } else if (count == 1) {
4375 *eax = INTEL_PT_MTC_BITMAP | INTEL_PT_ADDR_RANGES_NUM;
4376 *ebx = INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP;
4377 }
4378 break;
4379 }
4380 case 0x40000000:
4381
4382
4383
4384
4385 if (tcg_enabled() && cpu->expose_tcg) {
4386 memcpy(signature, "TCGTCGTCGTCG", 12);
4387 *eax = 0x40000001;
4388 *ebx = signature[0];
4389 *ecx = signature[1];
4390 *edx = signature[2];
4391 } else {
4392 *eax = 0;
4393 *ebx = 0;
4394 *ecx = 0;
4395 *edx = 0;
4396 }
4397 break;
4398 case 0x40000001:
4399 *eax = 0;
4400 *ebx = 0;
4401 *ecx = 0;
4402 *edx = 0;
4403 break;
4404 case 0x80000000:
4405 *eax = env->cpuid_xlevel;
4406 *ebx = env->cpuid_vendor1;
4407 *edx = env->cpuid_vendor2;
4408 *ecx = env->cpuid_vendor3;
4409 break;
4410 case 0x80000001:
4411 *eax = env->cpuid_version;
4412 *ebx = 0;
4413 *ecx = env->features[FEAT_8000_0001_ECX];
4414 *edx = env->features[FEAT_8000_0001_EDX];
4415
4416
4417
4418
4419
4420 if (cs->nr_cores * cs->nr_threads > 1) {
4421 if (env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1 ||
4422 env->cpuid_vendor2 != CPUID_VENDOR_INTEL_2 ||
4423 env->cpuid_vendor3 != CPUID_VENDOR_INTEL_3) {
4424 *ecx |= 1 << 1;
4425 }
4426 }
4427 break;
4428 case 0x80000002:
4429 case 0x80000003:
4430 case 0x80000004:
4431 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
4432 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
4433 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
4434 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
4435 break;
4436 case 0x80000005:
4437
4438 if (cpu->cache_info_passthrough) {
4439 host_cpuid(index, 0, eax, ebx, ecx, edx);
4440 break;
4441 }
4442 *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \
4443 (L1_ITLB_2M_ASSOC << 8) | (L1_ITLB_2M_ENTRIES);
4444 *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
4445 (L1_ITLB_4K_ASSOC << 8) | (L1_ITLB_4K_ENTRIES);
4446 *ecx = encode_cache_cpuid80000005(env->cache_info_amd.l1d_cache);
4447 *edx = encode_cache_cpuid80000005(env->cache_info_amd.l1i_cache);
4448 break;
4449 case 0x80000006:
4450
4451 if (cpu->cache_info_passthrough) {
4452 host_cpuid(index, 0, eax, ebx, ecx, edx);
4453 break;
4454 }
4455 *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \
4456 (L2_DTLB_2M_ENTRIES << 16) | \
4457 (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \
4458 (L2_ITLB_2M_ENTRIES);
4459 *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) | \
4460 (L2_DTLB_4K_ENTRIES << 16) | \
4461 (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
4462 (L2_ITLB_4K_ENTRIES);
4463 encode_cache_cpuid80000006(env->cache_info_amd.l2_cache,
4464 cpu->enable_l3_cache ?
4465 env->cache_info_amd.l3_cache : NULL,
4466 ecx, edx);
4467 break;
4468 case 0x80000007:
4469 *eax = 0;
4470 *ebx = 0;
4471 *ecx = 0;
4472 *edx = env->features[FEAT_8000_0007_EDX];
4473 break;
4474 case 0x80000008:
4475
4476 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
4477
4478 *eax = cpu->phys_bits;
4479 if (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_LA57) {
4480 *eax |= 0x00003900;
4481 } else {
4482 *eax |= 0x00003000;
4483 }
4484 } else {
4485 *eax = cpu->phys_bits;
4486 }
4487 *ebx = env->features[FEAT_8000_0008_EBX];
4488 *ecx = 0;
4489 *edx = 0;
4490 if (cs->nr_cores * cs->nr_threads > 1) {
4491 *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
4492 }
4493 break;
4494 case 0x8000000A:
4495 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
4496 *eax = 0x00000001;
4497 *ebx = 0x00000010;
4498 *ecx = 0;
4499 *edx = env->features[FEAT_SVM];
4500 } else {
4501 *eax = 0;
4502 *ebx = 0;
4503 *ecx = 0;
4504 *edx = 0;
4505 }
4506 break;
4507 case 0x8000001D:
4508 *eax = 0;
4509 switch (count) {
4510 case 0:
4511 encode_cache_cpuid8000001d(env->cache_info_amd.l1d_cache, cs,
4512 eax, ebx, ecx, edx);
4513 break;
4514 case 1:
4515 encode_cache_cpuid8000001d(env->cache_info_amd.l1i_cache, cs,
4516 eax, ebx, ecx, edx);
4517 break;
4518 case 2:
4519 encode_cache_cpuid8000001d(env->cache_info_amd.l2_cache, cs,
4520 eax, ebx, ecx, edx);
4521 break;
4522 case 3:
4523 encode_cache_cpuid8000001d(env->cache_info_amd.l3_cache, cs,
4524 eax, ebx, ecx, edx);
4525 break;
4526 default:
4527 *eax = *ebx = *ecx = *edx = 0;
4528 break;
4529 }
4530 break;
4531 case 0x8000001E:
4532 assert(cpu->core_id <= 255);
4533 encode_topo_cpuid8000001e(cs, cpu,
4534 eax, ebx, ecx, edx);
4535 break;
4536 case 0xC0000000:
4537 *eax = env->cpuid_xlevel2;
4538 *ebx = 0;
4539 *ecx = 0;
4540 *edx = 0;
4541 break;
4542 case 0xC0000001:
4543
4544 *eax = env->cpuid_version;
4545 *ebx = 0;
4546 *ecx = 0;
4547 *edx = env->features[FEAT_C000_0001_EDX];
4548 break;
4549 case 0xC0000002:
4550 case 0xC0000003:
4551 case 0xC0000004:
4552
4553 *eax = 0;
4554 *ebx = 0;
4555 *ecx = 0;
4556 *edx = 0;
4557 break;
4558 case 0x8000001F:
4559 *eax = sev_enabled() ? 0x2 : 0;
4560 *ebx = sev_get_cbit_position();
4561 *ebx |= sev_get_reduced_phys_bits() << 6;
4562 *ecx = 0;
4563 *edx = 0;
4564 break;
4565 default:
4566
4567 *eax = 0;
4568 *ebx = 0;
4569 *ecx = 0;
4570 *edx = 0;
4571 break;
4572 }
4573}
4574
4575
4576static void x86_cpu_reset(CPUState *s)
4577{
4578 X86CPU *cpu = X86_CPU(s);
4579 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
4580 CPUX86State *env = &cpu->env;
4581 target_ulong cr4;
4582 uint64_t xcr0;
4583 int i;
4584
4585 xcc->parent_reset(s);
4586
4587 memset(env, 0, offsetof(CPUX86State, end_reset_fields));
4588
4589 env->old_exception = -1;
4590
4591
4592
4593 env->hflags2 |= HF2_GIF_MASK;
4594
4595 cpu_x86_update_cr0(env, 0x60000010);
4596 env->a20_mask = ~0x0;
4597 env->smbase = 0x30000;
4598 env->msr_smi_count = 0;
4599
4600 env->idt.limit = 0xffff;
4601 env->gdt.limit = 0xffff;
4602 env->ldt.limit = 0xffff;
4603 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
4604 env->tr.limit = 0xffff;
4605 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
4606
4607 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
4608 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
4609 DESC_R_MASK | DESC_A_MASK);
4610 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
4611 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
4612 DESC_A_MASK);
4613 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
4614 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
4615 DESC_A_MASK);
4616 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
4617 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
4618 DESC_A_MASK);
4619 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
4620 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
4621 DESC_A_MASK);
4622 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
4623 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
4624 DESC_A_MASK);
4625
4626 env->eip = 0xfff0;
4627 env->regs[R_EDX] = env->cpuid_version;
4628
4629 env->eflags = 0x2;
4630
4631
4632 for (i = 0; i < 8; i++) {
4633 env->fptags[i] = 1;
4634 }
4635 cpu_set_fpuc(env, 0x37f);
4636
4637 env->mxcsr = 0x1f80;
4638
4639 env->xstate_bv = 0;
4640
4641 env->pat = 0x0007040600070406ULL;
4642 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
4643
4644 memset(env->dr, 0, sizeof(env->dr));
4645 env->dr[6] = DR6_FIXED_1;
4646 env->dr[7] = DR7_FIXED_1;
4647 cpu_breakpoint_remove_all(s, BP_CPU);
4648 cpu_watchpoint_remove_all(s, BP_CPU);
4649
4650 cr4 = 0;
4651 xcr0 = XSTATE_FP_MASK;
4652
4653#ifdef CONFIG_USER_ONLY
4654
4655 if (env->features[FEAT_1_EDX] & CPUID_SSE) {
4656 xcr0 |= XSTATE_SSE_MASK;
4657 }
4658 for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
4659 const ExtSaveArea *esa = &x86_ext_save_areas[i];
4660 if (env->features[esa->feature] & esa->bits) {
4661 xcr0 |= 1ull << i;
4662 }
4663 }
4664
4665 if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) {
4666 cr4 |= CR4_OSFXSR_MASK | CR4_OSXSAVE_MASK;
4667 }
4668 if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_FSGSBASE) {
4669 cr4 |= CR4_FSGSBASE_MASK;
4670 }
4671#endif
4672
4673 env->xcr0 = xcr0;
4674 cpu_x86_update_cr4(env, cr4);
4675
4676
4677
4678
4679
4680
4681
4682 env->mtrr_deftype = 0;
4683 memset(env->mtrr_var, 0, sizeof(env->mtrr_var));
4684 memset(env->mtrr_fixed, 0, sizeof(env->mtrr_fixed));
4685
4686 env->interrupt_injected = -1;
4687 env->exception_injected = -1;
4688 env->nmi_injected = false;
4689#if !defined(CONFIG_USER_ONLY)
4690
4691 apic_designate_bsp(cpu->apic_state, s->cpu_index == 0);
4692
4693 s->halted = !cpu_is_bsp(cpu);
4694
4695 if (kvm_enabled()) {
4696 kvm_arch_reset_vcpu(cpu);
4697 }
4698 else if (hvf_enabled()) {
4699 hvf_reset_vcpu(s);
4700 }
4701#endif
4702}
4703
4704#ifndef CONFIG_USER_ONLY
4705bool cpu_is_bsp(X86CPU *cpu)
4706{
4707 return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
4708}
4709
4710
4711static void x86_cpu_machine_reset_cb(void *opaque)
4712{
4713 X86CPU *cpu = opaque;
4714 cpu_reset(CPU(cpu));
4715}
4716#endif
4717
4718static void mce_init(X86CPU *cpu)
4719{
4720 CPUX86State *cenv = &cpu->env;
4721 unsigned int bank;
4722
4723 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
4724 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
4725 (CPUID_MCE | CPUID_MCA)) {
4726 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF |
4727 (cpu->enable_lmce ? MCG_LMCE_P : 0);
4728 cenv->mcg_ctl = ~(uint64_t)0;
4729 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
4730 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
4731 }
4732 }
4733}
4734
4735#ifndef CONFIG_USER_ONLY
4736APICCommonClass *apic_get_class(void)
4737{
4738 const char *apic_type = "apic";
4739
4740
4741 if (kvm_apic_in_kernel()) {
4742 apic_type = "kvm-apic";
4743 } else if (xen_enabled()) {
4744 apic_type = "xen-apic";
4745 }
4746
4747 return APIC_COMMON_CLASS(object_class_by_name(apic_type));
4748}
4749
4750static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
4751{
4752 APICCommonState *apic;
4753 ObjectClass *apic_class = OBJECT_CLASS(apic_get_class());
4754
4755 cpu->apic_state = DEVICE(object_new(object_class_get_name(apic_class)));
4756
4757 object_property_add_child(OBJECT(cpu), "lapic",
4758 OBJECT(cpu->apic_state), &error_abort);
4759 object_unref(OBJECT(cpu->apic_state));
4760
4761 qdev_prop_set_uint32(cpu->apic_state, "id", cpu->apic_id);
4762
4763 apic = APIC_COMMON(cpu->apic_state);
4764 apic->cpu = cpu;
4765 apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE;
4766}
4767
4768static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
4769{
4770 APICCommonState *apic;
4771 static bool apic_mmio_map_once;
4772
4773 if (cpu->apic_state == NULL) {
4774 return;
4775 }
4776 object_property_set_bool(OBJECT(cpu->apic_state), true, "realized",
4777 errp);
4778
4779
4780 apic = APIC_COMMON(cpu->apic_state);
4781 if (!apic_mmio_map_once) {
4782 memory_region_add_subregion_overlap(get_system_memory(),
4783 apic->apicbase &
4784 MSR_IA32_APICBASE_BASE,
4785 &apic->io_memory,
4786 0x1000);
4787 apic_mmio_map_once = true;
4788 }
4789}
4790
4791static void x86_cpu_machine_done(Notifier *n, void *unused)
4792{
4793 X86CPU *cpu = container_of(n, X86CPU, machine_done);
4794 MemoryRegion *smram =
4795 (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
4796
4797 if (smram) {
4798 cpu->smram = g_new(MemoryRegion, 1);
4799 memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
4800 smram, 0, 1ull << 32);
4801 memory_region_set_enabled(cpu->smram, true);
4802 memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->smram, 1);
4803 }
4804}
4805#else
4806static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
4807{
4808}
4809#endif
4810
4811
4812static uint32_t x86_host_phys_bits(void)
4813{
4814 uint32_t eax;
4815 uint32_t host_phys_bits;
4816
4817 host_cpuid(0x80000000, 0, &eax, NULL, NULL, NULL);
4818 if (eax >= 0x80000008) {
4819 host_cpuid(0x80000008, 0, &eax, NULL, NULL, NULL);
4820
4821
4822
4823
4824
4825 host_phys_bits = eax & 0xff;
4826 } else {
4827
4828
4829
4830
4831 host_phys_bits = 36;
4832 }
4833
4834 return host_phys_bits;
4835}
4836
4837static void x86_cpu_adjust_level(X86CPU *cpu, uint32_t *min, uint32_t value)
4838{
4839 if (*min < value) {
4840 *min = value;
4841 }
4842}
4843
4844
4845static void x86_cpu_adjust_feat_level(X86CPU *cpu, FeatureWord w)
4846{
4847 CPUX86State *env = &cpu->env;
4848 FeatureWordInfo *fi = &feature_word_info[w];
4849 uint32_t eax = fi->cpuid.eax;
4850 uint32_t region = eax & 0xF0000000;
4851
4852 assert(feature_word_info[w].type == CPUID_FEATURE_WORD);
4853 if (!env->features[w]) {
4854 return;
4855 }
4856
4857 switch (region) {
4858 case 0x00000000:
4859 x86_cpu_adjust_level(cpu, &env->cpuid_min_level, eax);
4860 break;
4861 case 0x80000000:
4862 x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, eax);
4863 break;
4864 case 0xC0000000:
4865 x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel2, eax);
4866 break;
4867 }
4868}
4869
4870
4871static void x86_cpu_enable_xsave_components(X86CPU *cpu)
4872{
4873 CPUX86State *env = &cpu->env;
4874 int i;
4875 uint64_t mask;
4876
4877 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
4878 return;
4879 }
4880
4881 mask = 0;
4882 for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
4883 const ExtSaveArea *esa = &x86_ext_save_areas[i];
4884 if (env->features[esa->feature] & esa->bits) {
4885 mask |= (1ULL << i);
4886 }
4887 }
4888
4889 env->features[FEAT_XSAVE_COMP_LO] = mask;
4890 env->features[FEAT_XSAVE_COMP_HI] = mask >> 32;
4891}
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
4934{
4935 CPUX86State *env = &cpu->env;
4936 FeatureWord w;
4937 GList *l;
4938 Error *local_err = NULL;
4939
4940
4941
4942
4943
4944
4945 if (cpu->max_features) {
4946 for (w = 0; w < FEATURE_WORDS; w++) {
4947
4948
4949
4950 env->features[w] |=
4951 x86_cpu_get_supported_feature_word(w, cpu->migratable) &
4952 ~env->user_features[w] & \
4953 ~feature_word_info[w].no_autoenable_flags;
4954 }
4955 }
4956
4957 for (l = plus_features; l; l = l->next) {
4958 const char *prop = l->data;
4959 object_property_set_bool(OBJECT(cpu), true, prop, &local_err);
4960 if (local_err) {
4961 goto out;
4962 }
4963 }
4964
4965 for (l = minus_features; l; l = l->next) {
4966 const char *prop = l->data;
4967 object_property_set_bool(OBJECT(cpu), false, prop, &local_err);
4968 if (local_err) {
4969 goto out;
4970 }
4971 }
4972
4973 if (!kvm_enabled() || !cpu->expose_kvm) {
4974 env->features[FEAT_KVM] = 0;
4975 }
4976
4977 x86_cpu_enable_xsave_components(cpu);
4978
4979
4980 x86_cpu_adjust_feat_level(cpu, FEAT_7_0_EBX);
4981 if (cpu->full_cpuid_auto_level) {
4982 x86_cpu_adjust_feat_level(cpu, FEAT_1_EDX);
4983 x86_cpu_adjust_feat_level(cpu, FEAT_1_ECX);
4984 x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX);
4985 x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX);
4986 x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX);
4987 x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX);
4988 x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX);
4989 x86_cpu_adjust_feat_level(cpu, FEAT_8000_0008_EBX);
4990 x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX);
4991 x86_cpu_adjust_feat_level(cpu, FEAT_SVM);
4992 x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);
4993
4994 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
4995 x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);
4996 }
4997
4998
4999 if (sev_enabled()) {
5000 x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000001F);
5001 }
5002 }
5003
5004
5005 if (env->cpuid_level == UINT32_MAX) {
5006 env->cpuid_level = env->cpuid_min_level;
5007 }
5008 if (env->cpuid_xlevel == UINT32_MAX) {
5009 env->cpuid_xlevel = env->cpuid_min_xlevel;
5010 }
5011 if (env->cpuid_xlevel2 == UINT32_MAX) {
5012 env->cpuid_xlevel2 = env->cpuid_min_xlevel2;
5013 }
5014
5015out:
5016 if (local_err != NULL) {
5017 error_propagate(errp, local_err);
5018 }
5019}
5020
5021
5022
5023
5024
5025
5026
5027static int x86_cpu_filter_features(X86CPU *cpu)
5028{
5029 CPUX86State *env = &cpu->env;
5030 FeatureWord w;
5031 int rv = 0;
5032
5033 for (w = 0; w < FEATURE_WORDS; w++) {
5034 uint32_t host_feat =
5035 x86_cpu_get_supported_feature_word(w, false);
5036 uint32_t requested_features = env->features[w];
5037 env->features[w] &= host_feat;
5038 cpu->filtered_features[w] = requested_features & ~env->features[w];
5039 if (cpu->filtered_features[w]) {
5040 rv = 1;
5041 }
5042 }
5043
5044 if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) &&
5045 kvm_enabled()) {
5046 KVMState *s = CPU(cpu)->kvm_state;
5047 uint32_t eax_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_EAX);
5048 uint32_t ebx_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_EBX);
5049 uint32_t ecx_0 = kvm_arch_get_supported_cpuid(s, 0x14, 0, R_ECX);
5050 uint32_t eax_1 = kvm_arch_get_supported_cpuid(s, 0x14, 1, R_EAX);
5051 uint32_t ebx_1 = kvm_arch_get_supported_cpuid(s, 0x14, 1, R_EBX);
5052
5053 if (!eax_0 ||
5054 ((ebx_0 & INTEL_PT_MINIMAL_EBX) != INTEL_PT_MINIMAL_EBX) ||
5055 ((ecx_0 & INTEL_PT_MINIMAL_ECX) != INTEL_PT_MINIMAL_ECX) ||
5056 ((eax_1 & INTEL_PT_MTC_BITMAP) != INTEL_PT_MTC_BITMAP) ||
5057 ((eax_1 & INTEL_PT_ADDR_RANGES_NUM_MASK) <
5058 INTEL_PT_ADDR_RANGES_NUM) ||
5059 ((ebx_1 & (INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP)) !=
5060 (INTEL_PT_PSB_BITMAP | INTEL_PT_CYCLE_BITMAP)) ||
5061 (ecx_0 & INTEL_PT_IP_LIP)) {
5062
5063
5064
5065
5066
5067 env->features[FEAT_7_0_EBX] &= ~CPUID_7_0_EBX_INTEL_PT;
5068 cpu->filtered_features[FEAT_7_0_EBX] |= CPUID_7_0_EBX_INTEL_PT;
5069 rv = 1;
5070 }
5071 }
5072
5073 return rv;
5074}
5075
5076#define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \
5077 (env)->cpuid_vendor2 == CPUID_VENDOR_INTEL_2 && \
5078 (env)->cpuid_vendor3 == CPUID_VENDOR_INTEL_3)
5079#define IS_AMD_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && \
5080 (env)->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && \
5081 (env)->cpuid_vendor3 == CPUID_VENDOR_AMD_3)
5082static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
5083{
5084 CPUState *cs = CPU(dev);
5085 X86CPU *cpu = X86_CPU(dev);
5086 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
5087 CPUX86State *env = &cpu->env;
5088 Error *local_err = NULL;
5089 static bool ht_warned;
5090
5091 if (xcc->host_cpuid_required) {
5092 if (!accel_uses_host_cpuid()) {
5093 char *name = x86_cpu_class_get_model_name(xcc);
5094 error_setg(&local_err, "CPU model '%s' requires KVM", name);
5095 g_free(name);
5096 goto out;
5097 }
5098
5099 if (enable_cpu_pm) {
5100 host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx,
5101 &cpu->mwait.ecx, &cpu->mwait.edx);
5102 env->features[FEAT_1_ECX] |= CPUID_EXT_MONITOR;
5103 }
5104 }
5105
5106
5107
5108 cpu->mwait.ecx |= CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
5109
5110 if (cpu->apic_id == UNASSIGNED_APIC_ID) {
5111 error_setg(errp, "apic-id property was not initialized properly");
5112 return;
5113 }
5114
5115 x86_cpu_expand_features(cpu, &local_err);
5116 if (local_err) {
5117 goto out;
5118 }
5119
5120 if (x86_cpu_filter_features(cpu) &&
5121 (cpu->check_cpuid || cpu->enforce_cpuid)) {
5122 x86_cpu_report_filtered_features(cpu);
5123 if (cpu->enforce_cpuid) {
5124 error_setg(&local_err,
5125 accel_uses_host_cpuid() ?
5126 "Host doesn't support requested features" :
5127 "TCG doesn't support requested features");
5128 goto out;
5129 }
5130 }
5131
5132
5133
5134
5135 if (IS_AMD_CPU(env)) {
5136 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
5137 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
5138 & CPUID_EXT2_AMD_ALIASES);
5139 }
5140
5141
5142
5143
5144
5145
5146
5147 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
5148 if (accel_uses_host_cpuid()) {
5149 uint32_t host_phys_bits = x86_host_phys_bits();
5150 static bool warned;
5151
5152 if (cpu->host_phys_bits) {
5153
5154 cpu->phys_bits = host_phys_bits;
5155 }
5156
5157
5158
5159
5160 if (cpu->phys_bits != host_phys_bits && cpu->phys_bits != 0 &&
5161 !warned) {
5162 warn_report("Host physical bits (%u)"
5163 " does not match phys-bits property (%u)",
5164 host_phys_bits, cpu->phys_bits);
5165 warned = true;
5166 }
5167
5168 if (cpu->phys_bits &&
5169 (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
5170 cpu->phys_bits < 32)) {
5171 error_setg(errp, "phys-bits should be between 32 and %u "
5172 " (but is %u)",
5173 TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bits);
5174 return;
5175 }
5176 } else {
5177 if (cpu->phys_bits && cpu->phys_bits != TCG_PHYS_ADDR_BITS) {
5178 error_setg(errp, "TCG only supports phys-bits=%u",
5179 TCG_PHYS_ADDR_BITS);
5180 return;
5181 }
5182 }
5183
5184
5185
5186
5187 if (cpu->phys_bits == 0) {
5188 cpu->phys_bits = TCG_PHYS_ADDR_BITS;
5189 }
5190 } else {
5191
5192
5193
5194 if (cpu->phys_bits != 0) {
5195 error_setg(errp, "phys-bits is not user-configurable in 32 bit");
5196 return;
5197 }
5198
5199 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
5200 cpu->phys_bits = 36;
5201 } else {
5202 cpu->phys_bits = 32;
5203 }
5204 }
5205
5206
5207 if (!cpu->legacy_cache) {
5208 if (!xcc->cpu_def || !xcc->cpu_def->cache_info) {
5209 char *name = x86_cpu_class_get_model_name(xcc);
5210 error_setg(errp,
5211 "CPU model '%s' doesn't support legacy-cache=off", name);
5212 g_free(name);
5213 return;
5214 }
5215 env->cache_info_cpuid2 = env->cache_info_cpuid4 = env->cache_info_amd =
5216 *xcc->cpu_def->cache_info;
5217 } else {
5218
5219 env->cache_info_cpuid2.l1d_cache = &legacy_l1d_cache;
5220 env->cache_info_cpuid2.l1i_cache = &legacy_l1i_cache;
5221 env->cache_info_cpuid2.l2_cache = &legacy_l2_cache_cpuid2;
5222 env->cache_info_cpuid2.l3_cache = &legacy_l3_cache;
5223
5224 env->cache_info_cpuid4.l1d_cache = &legacy_l1d_cache;
5225 env->cache_info_cpuid4.l1i_cache = &legacy_l1i_cache;
5226 env->cache_info_cpuid4.l2_cache = &legacy_l2_cache;
5227 env->cache_info_cpuid4.l3_cache = &legacy_l3_cache;
5228
5229 env->cache_info_amd.l1d_cache = &legacy_l1d_cache_amd;
5230 env->cache_info_amd.l1i_cache = &legacy_l1i_cache_amd;
5231 env->cache_info_amd.l2_cache = &legacy_l2_cache_amd;
5232 env->cache_info_amd.l3_cache = &legacy_l3_cache;
5233 }
5234
5235
5236 cpu_exec_realizefn(cs, &local_err);
5237 if (local_err != NULL) {
5238 error_propagate(errp, local_err);
5239 return;
5240 }
5241
5242#ifndef CONFIG_USER_ONLY
5243 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
5244
5245 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
5246 x86_cpu_apic_create(cpu, &local_err);
5247 if (local_err != NULL) {
5248 goto out;
5249 }
5250 }
5251#endif
5252
5253 mce_init(cpu);
5254
5255#ifndef CONFIG_USER_ONLY
5256 if (tcg_enabled()) {
5257 cpu->cpu_as_mem = g_new(MemoryRegion, 1);
5258 cpu->cpu_as_root = g_new(MemoryRegion, 1);
5259
5260
5261 memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
5262 memory_region_set_enabled(cpu->cpu_as_root, true);
5263
5264
5265
5266
5267 memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
5268 get_system_memory(), 0, ~0ull);
5269 memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
5270 memory_region_set_enabled(cpu->cpu_as_mem, true);
5271
5272 cs->num_ases = 2;
5273 cpu_address_space_init(cs, 0, "cpu-memory", cs->memory);
5274 cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root);
5275
5276
5277 cpu->machine_done.notify = x86_cpu_machine_done;
5278 qemu_add_machine_init_done_notifier(&cpu->machine_done);
5279 }
5280#endif
5281
5282 qemu_init_vcpu(cs);
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293 if (IS_AMD_CPU(env) &&
5294 !(env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT) &&
5295 cs->nr_threads > 1 && !ht_warned) {
5296 warn_report("This family of AMD CPU doesn't support "
5297 "hyperthreading(%d)",
5298 cs->nr_threads);
5299 error_printf("Please configure -smp options properly"
5300 " or try enabling topoext feature.\n");
5301 ht_warned = true;
5302 }
5303
5304 x86_cpu_apic_realize(cpu, &local_err);
5305 if (local_err != NULL) {
5306 goto out;
5307 }
5308 cpu_reset(cs);
5309
5310 xcc->parent_realize(dev, &local_err);
5311
5312out:
5313 if (local_err != NULL) {
5314 error_propagate(errp, local_err);
5315 return;
5316 }
5317}
5318
5319static void x86_cpu_unrealizefn(DeviceState *dev, Error **errp)
5320{
5321 X86CPU *cpu = X86_CPU(dev);
5322 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
5323 Error *local_err = NULL;
5324
5325#ifndef CONFIG_USER_ONLY
5326 cpu_remove_sync(CPU(dev));
5327 qemu_unregister_reset(x86_cpu_machine_reset_cb, dev);
5328#endif
5329
5330 if (cpu->apic_state) {
5331 object_unparent(OBJECT(cpu->apic_state));
5332 cpu->apic_state = NULL;
5333 }
5334
5335 xcc->parent_unrealize(dev, &local_err);
5336 if (local_err != NULL) {
5337 error_propagate(errp, local_err);
5338 return;
5339 }
5340}
5341
5342typedef struct BitProperty {
5343 FeatureWord w;
5344 uint32_t mask;
5345} BitProperty;
5346
5347static void x86_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name,
5348 void *opaque, Error **errp)
5349{
5350 X86CPU *cpu = X86_CPU(obj);
5351 BitProperty *fp = opaque;
5352 uint32_t f = cpu->env.features[fp->w];
5353 bool value = (f & fp->mask) == fp->mask;
5354 visit_type_bool(v, name, &value, errp);
5355}
5356
5357static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name,
5358 void *opaque, Error **errp)
5359{
5360 DeviceState *dev = DEVICE(obj);
5361 X86CPU *cpu = X86_CPU(obj);
5362 BitProperty *fp = opaque;
5363 Error *local_err = NULL;
5364 bool value;
5365
5366 if (dev->realized) {
5367 qdev_prop_set_after_realize(dev, name, errp);
5368 return;
5369 }
5370
5371 visit_type_bool(v, name, &value, &local_err);
5372 if (local_err) {
5373 error_propagate(errp, local_err);
5374 return;
5375 }
5376
5377 if (value) {
5378 cpu->env.features[fp->w] |= fp->mask;
5379 } else {
5380 cpu->env.features[fp->w] &= ~fp->mask;
5381 }
5382 cpu->env.user_features[fp->w] |= fp->mask;
5383}
5384
5385static void x86_cpu_release_bit_prop(Object *obj, const char *name,
5386 void *opaque)
5387{
5388 BitProperty *prop = opaque;
5389 g_free(prop);
5390}
5391
5392
5393
5394
5395
5396
5397
5398static void x86_cpu_register_bit_prop(X86CPU *cpu,
5399 const char *prop_name,
5400 FeatureWord w,
5401 int bitnr)
5402{
5403 BitProperty *fp;
5404 ObjectProperty *op;
5405 uint32_t mask = (1UL << bitnr);
5406
5407 op = object_property_find(OBJECT(cpu), prop_name, NULL);
5408 if (op) {
5409 fp = op->opaque;
5410 assert(fp->w == w);
5411 fp->mask |= mask;
5412 } else {
5413 fp = g_new0(BitProperty, 1);
5414 fp->w = w;
5415 fp->mask = mask;
5416 object_property_add(OBJECT(cpu), prop_name, "bool",
5417 x86_cpu_get_bit_prop,
5418 x86_cpu_set_bit_prop,
5419 x86_cpu_release_bit_prop, fp, &error_abort);
5420 }
5421}
5422
5423static void x86_cpu_register_feature_bit_props(X86CPU *cpu,
5424 FeatureWord w,
5425 int bitnr)
5426{
5427 FeatureWordInfo *fi = &feature_word_info[w];
5428 const char *name = fi->feat_names[bitnr];
5429
5430 if (!name) {
5431 return;
5432 }
5433
5434
5435
5436
5437
5438 assert(!strchr(name, '_'));
5439
5440
5441 assert(!strchr(name, '|'));
5442 x86_cpu_register_bit_prop(cpu, name, w, bitnr);
5443}
5444
5445static GuestPanicInformation *x86_cpu_get_crash_info(CPUState *cs)
5446{
5447 X86CPU *cpu = X86_CPU(cs);
5448 CPUX86State *env = &cpu->env;
5449 GuestPanicInformation *panic_info = NULL;
5450
5451 if (env->features[FEAT_HYPERV_EDX] & HV_GUEST_CRASH_MSR_AVAILABLE) {
5452 panic_info = g_malloc0(sizeof(GuestPanicInformation));
5453
5454 panic_info->type = GUEST_PANIC_INFORMATION_TYPE_HYPER_V;
5455
5456 assert(HV_CRASH_PARAMS >= 5);
5457 panic_info->u.hyper_v.arg1 = env->msr_hv_crash_params[0];
5458 panic_info->u.hyper_v.arg2 = env->msr_hv_crash_params[1];
5459 panic_info->u.hyper_v.arg3 = env->msr_hv_crash_params[2];
5460 panic_info->u.hyper_v.arg4 = env->msr_hv_crash_params[3];
5461 panic_info->u.hyper_v.arg5 = env->msr_hv_crash_params[4];
5462 }
5463
5464 return panic_info;
5465}
5466static void x86_cpu_get_crash_info_qom(Object *obj, Visitor *v,
5467 const char *name, void *opaque,
5468 Error **errp)
5469{
5470 CPUState *cs = CPU(obj);
5471 GuestPanicInformation *panic_info;
5472
5473 if (!cs->crash_occurred) {
5474 error_setg(errp, "No crash occured");
5475 return;
5476 }
5477
5478 panic_info = x86_cpu_get_crash_info(cs);
5479 if (panic_info == NULL) {
5480 error_setg(errp, "No crash information");
5481 return;
5482 }
5483
5484 visit_type_GuestPanicInformation(v, "crash-information", &panic_info,
5485 errp);
5486 qapi_free_GuestPanicInformation(panic_info);
5487}
5488
5489static void x86_cpu_initfn(Object *obj)
5490{
5491 CPUState *cs = CPU(obj);
5492 X86CPU *cpu = X86_CPU(obj);
5493 X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
5494 CPUX86State *env = &cpu->env;
5495 FeatureWord w;
5496
5497 cs->env_ptr = env;
5498
5499 object_property_add(obj, "family", "int",
5500 x86_cpuid_version_get_family,
5501 x86_cpuid_version_set_family, NULL, NULL, NULL);
5502 object_property_add(obj, "model", "int",
5503 x86_cpuid_version_get_model,
5504 x86_cpuid_version_set_model, NULL, NULL, NULL);
5505 object_property_add(obj, "stepping", "int",
5506 x86_cpuid_version_get_stepping,
5507 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
5508 object_property_add_str(obj, "vendor",
5509 x86_cpuid_get_vendor,
5510 x86_cpuid_set_vendor, NULL);
5511 object_property_add_str(obj, "model-id",
5512 x86_cpuid_get_model_id,
5513 x86_cpuid_set_model_id, NULL);
5514 object_property_add(obj, "tsc-frequency", "int",
5515 x86_cpuid_get_tsc_freq,
5516 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
5517 object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
5518 x86_cpu_get_feature_words,
5519 NULL, NULL, (void *)env->features, NULL);
5520 object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
5521 x86_cpu_get_feature_words,
5522 NULL, NULL, (void *)cpu->filtered_features, NULL);
5523
5524 object_property_add(obj, "crash-information", "GuestPanicInformation",
5525 x86_cpu_get_crash_info_qom, NULL, NULL, NULL, NULL);
5526
5527 cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
5528
5529 for (w = 0; w < FEATURE_WORDS; w++) {
5530 int bitnr;
5531
5532 for (bitnr = 0; bitnr < 32; bitnr++) {
5533 x86_cpu_register_feature_bit_props(cpu, w, bitnr);
5534 }
5535 }
5536
5537 object_property_add_alias(obj, "sse3", obj, "pni", &error_abort);
5538 object_property_add_alias(obj, "pclmuldq", obj, "pclmulqdq", &error_abort);
5539 object_property_add_alias(obj, "sse4-1", obj, "sse4.1", &error_abort);
5540 object_property_add_alias(obj, "sse4-2", obj, "sse4.2", &error_abort);
5541 object_property_add_alias(obj, "xd", obj, "nx", &error_abort);
5542 object_property_add_alias(obj, "ffxsr", obj, "fxsr-opt", &error_abort);
5543 object_property_add_alias(obj, "i64", obj, "lm", &error_abort);
5544
5545 object_property_add_alias(obj, "ds_cpl", obj, "ds-cpl", &error_abort);
5546 object_property_add_alias(obj, "tsc_adjust", obj, "tsc-adjust", &error_abort);
5547 object_property_add_alias(obj, "fxsr_opt", obj, "fxsr-opt", &error_abort);
5548 object_property_add_alias(obj, "lahf_lm", obj, "lahf-lm", &error_abort);
5549 object_property_add_alias(obj, "cmp_legacy", obj, "cmp-legacy", &error_abort);
5550 object_property_add_alias(obj, "nodeid_msr", obj, "nodeid-msr", &error_abort);
5551 object_property_add_alias(obj, "perfctr_core", obj, "perfctr-core", &error_abort);
5552 object_property_add_alias(obj, "perfctr_nb", obj, "perfctr-nb", &error_abort);
5553 object_property_add_alias(obj, "kvm_nopiodelay", obj, "kvm-nopiodelay", &error_abort);
5554 object_property_add_alias(obj, "kvm_mmu", obj, "kvm-mmu", &error_abort);
5555 object_property_add_alias(obj, "kvm_asyncpf", obj, "kvm-asyncpf", &error_abort);
5556 object_property_add_alias(obj, "kvm_steal_time", obj, "kvm-steal-time", &error_abort);
5557 object_property_add_alias(obj, "kvm_pv_eoi", obj, "kvm-pv-eoi", &error_abort);
5558 object_property_add_alias(obj, "kvm_pv_unhalt", obj, "kvm-pv-unhalt", &error_abort);
5559 object_property_add_alias(obj, "svm_lock", obj, "svm-lock", &error_abort);
5560 object_property_add_alias(obj, "nrip_save", obj, "nrip-save", &error_abort);
5561 object_property_add_alias(obj, "tsc_scale", obj, "tsc-scale", &error_abort);
5562 object_property_add_alias(obj, "vmcb_clean", obj, "vmcb-clean", &error_abort);
5563 object_property_add_alias(obj, "pause_filter", obj, "pause-filter", &error_abort);
5564 object_property_add_alias(obj, "sse4_1", obj, "sse4.1", &error_abort);
5565 object_property_add_alias(obj, "sse4_2", obj, "sse4.2", &error_abort);
5566
5567 if (xcc->cpu_def) {
5568 x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
5569 }
5570}
5571
5572static int64_t x86_cpu_get_arch_id(CPUState *cs)
5573{
5574 X86CPU *cpu = X86_CPU(cs);
5575
5576 return cpu->apic_id;
5577}
5578
5579static bool x86_cpu_get_paging_enabled(const CPUState *cs)
5580{
5581 X86CPU *cpu = X86_CPU(cs);
5582
5583 return cpu->env.cr[0] & CR0_PG_MASK;
5584}
5585
5586static void x86_cpu_set_pc(CPUState *cs, vaddr value)
5587{
5588 X86CPU *cpu = X86_CPU(cs);
5589
5590 cpu->env.eip = value;
5591}
5592
5593static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
5594{
5595 X86CPU *cpu = X86_CPU(cs);
5596
5597 cpu->env.eip = tb->pc - tb->cs_base;
5598}
5599
5600int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request)
5601{
5602 X86CPU *cpu = X86_CPU(cs);
5603 CPUX86State *env = &cpu->env;
5604
5605#if !defined(CONFIG_USER_ONLY)
5606 if (interrupt_request & CPU_INTERRUPT_POLL) {
5607 return CPU_INTERRUPT_POLL;
5608 }
5609#endif
5610 if (interrupt_request & CPU_INTERRUPT_SIPI) {
5611 return CPU_INTERRUPT_SIPI;
5612 }
5613
5614 if (env->hflags2 & HF2_GIF_MASK) {
5615 if ((interrupt_request & CPU_INTERRUPT_SMI) &&
5616 !(env->hflags & HF_SMM_MASK)) {
5617 return CPU_INTERRUPT_SMI;
5618 } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
5619 !(env->hflags2 & HF2_NMI_MASK)) {
5620 return CPU_INTERRUPT_NMI;
5621 } else if (interrupt_request & CPU_INTERRUPT_MCE) {
5622 return CPU_INTERRUPT_MCE;
5623 } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
5624 (((env->hflags2 & HF2_VINTR_MASK) &&
5625 (env->hflags2 & HF2_HIF_MASK)) ||
5626 (!(env->hflags2 & HF2_VINTR_MASK) &&
5627 (env->eflags & IF_MASK &&
5628 !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
5629 return CPU_INTERRUPT_HARD;
5630#if !defined(CONFIG_USER_ONLY)
5631 } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
5632 (env->eflags & IF_MASK) &&
5633 !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
5634 return CPU_INTERRUPT_VIRQ;
5635#endif
5636 }
5637 }
5638
5639 return 0;
5640}
5641
5642static bool x86_cpu_has_work(CPUState *cs)
5643{
5644 return x86_cpu_pending_interrupt(cs, cs->interrupt_request) != 0;
5645}
5646
5647static void x86_disas_set_info(CPUState *cs, disassemble_info *info)
5648{
5649 X86CPU *cpu = X86_CPU(cs);
5650 CPUX86State *env = &cpu->env;
5651
5652 info->mach = (env->hflags & HF_CS64_MASK ? bfd_mach_x86_64
5653 : env->hflags & HF_CS32_MASK ? bfd_mach_i386_i386
5654 : bfd_mach_i386_i8086);
5655 info->print_insn = print_insn_i386;
5656
5657 info->cap_arch = CS_ARCH_X86;
5658 info->cap_mode = (env->hflags & HF_CS64_MASK ? CS_MODE_64
5659 : env->hflags & HF_CS32_MASK ? CS_MODE_32
5660 : CS_MODE_16);
5661 info->cap_insn_unit = 1;
5662 info->cap_insn_split = 8;
5663}
5664
5665void x86_update_hflags(CPUX86State *env)
5666{
5667 uint32_t hflags;
5668#define HFLAG_COPY_MASK \
5669 ~( HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
5670 HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
5671 HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
5672 HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)
5673
5674 hflags = env->hflags & HFLAG_COPY_MASK;
5675 hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
5676 hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
5677 hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
5678 (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
5679 hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
5680
5681 if (env->cr[4] & CR4_OSFXSR_MASK) {
5682 hflags |= HF_OSFXSR_MASK;
5683 }
5684
5685 if (env->efer & MSR_EFER_LMA) {
5686 hflags |= HF_LMA_MASK;
5687 }
5688
5689 if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
5690 hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
5691 } else {
5692 hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
5693 (DESC_B_SHIFT - HF_CS32_SHIFT);
5694 hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
5695 (DESC_B_SHIFT - HF_SS32_SHIFT);
5696 if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK) ||
5697 !(hflags & HF_CS32_MASK)) {
5698 hflags |= HF_ADDSEG_MASK;
5699 } else {
5700 hflags |= ((env->segs[R_DS].base | env->segs[R_ES].base |
5701 env->segs[R_SS].base) != 0) << HF_ADDSEG_SHIFT;
5702 }
5703 }
5704 env->hflags = hflags;
5705}
5706
5707static Property x86_cpu_properties[] = {
5708#ifdef CONFIG_USER_ONLY
5709
5710 DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, 0),
5711 DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, 0),
5712 DEFINE_PROP_INT32("core-id", X86CPU, core_id, 0),
5713 DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, 0),
5714#else
5715 DEFINE_PROP_UINT32("apic-id", X86CPU, apic_id, UNASSIGNED_APIC_ID),
5716 DEFINE_PROP_INT32("thread-id", X86CPU, thread_id, -1),
5717 DEFINE_PROP_INT32("core-id", X86CPU, core_id, -1),
5718 DEFINE_PROP_INT32("socket-id", X86CPU, socket_id, -1),
5719#endif
5720 DEFINE_PROP_INT32("node-id", X86CPU, node_id, CPU_UNSET_NUMA_NODE_ID),
5721 DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
5722 { .name = "hv-spinlocks", .info = &qdev_prop_spinlocks },
5723 DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false),
5724 DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false),
5725 DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false),
5726 DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false),
5727 DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false),
5728 DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false),
5729 DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
5730 DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
5731 DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
5732 DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
5733 DEFINE_PROP_BOOL("hv-reenlightenment", X86CPU, hyperv_reenlightenment, false),
5734 DEFINE_PROP_BOOL("hv-tlbflush", X86CPU, hyperv_tlbflush, false),
5735 DEFINE_PROP_BOOL("hv-evmcs", X86CPU, hyperv_evmcs, false),
5736 DEFINE_PROP_BOOL("hv-ipi", X86CPU, hyperv_ipi, false),
5737 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
5738 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
5739 DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
5740 DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0),
5741 DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false),
5742 DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true),
5743 DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, UINT32_MAX),
5744 DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, UINT32_MAX),
5745 DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, UINT32_MAX),
5746 DEFINE_PROP_UINT32("min-level", X86CPU, env.cpuid_min_level, 0),
5747 DEFINE_PROP_UINT32("min-xlevel", X86CPU, env.cpuid_min_xlevel, 0),
5748 DEFINE_PROP_UINT32("min-xlevel2", X86CPU, env.cpuid_min_xlevel2, 0),
5749 DEFINE_PROP_BOOL("full-cpuid-auto-level", X86CPU, full_cpuid_auto_level, true),
5750 DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
5751 DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
5752 DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false),
5753 DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true),
5754 DEFINE_PROP_BOOL("kvm-no-smi-migration", X86CPU, kvm_no_smi_migration,
5755 false),
5756 DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
5757 DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
5758 DEFINE_PROP_BOOL("x-migrate-smi-count", X86CPU, migrate_smi_count,
5759 true),
5760
5761
5762
5763
5764 DEFINE_PROP_BOOL("legacy-cache", X86CPU, legacy_cache, true),
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778 DEFINE_PROP_INT32("x-hv-max-vps", X86CPU, hv_max_vps, -1),
5779 DEFINE_PROP_BOOL("x-hv-synic-kvm-only", X86CPU, hyperv_synic_kvm_only,
5780 false),
5781 DEFINE_PROP_END_OF_LIST()
5782};
5783
5784static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
5785{
5786 X86CPUClass *xcc = X86_CPU_CLASS(oc);
5787 CPUClass *cc = CPU_CLASS(oc);
5788 DeviceClass *dc = DEVICE_CLASS(oc);
5789
5790 device_class_set_parent_realize(dc, x86_cpu_realizefn,
5791 &xcc->parent_realize);
5792 device_class_set_parent_unrealize(dc, x86_cpu_unrealizefn,
5793 &xcc->parent_unrealize);
5794 dc->props = x86_cpu_properties;
5795
5796 xcc->parent_reset = cc->reset;
5797 cc->reset = x86_cpu_reset;
5798 cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
5799
5800 cc->class_by_name = x86_cpu_class_by_name;
5801 cc->parse_features = x86_cpu_parse_featurestr;
5802 cc->has_work = x86_cpu_has_work;
5803#ifdef CONFIG_TCG
5804 cc->do_interrupt = x86_cpu_do_interrupt;
5805 cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
5806#endif
5807 cc->dump_state = x86_cpu_dump_state;
5808 cc->get_crash_info = x86_cpu_get_crash_info;
5809 cc->set_pc = x86_cpu_set_pc;
5810 cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
5811 cc->gdb_read_register = x86_cpu_gdb_read_register;
5812 cc->gdb_write_register = x86_cpu_gdb_write_register;
5813 cc->get_arch_id = x86_cpu_get_arch_id;
5814 cc->get_paging_enabled = x86_cpu_get_paging_enabled;
5815#ifdef CONFIG_USER_ONLY
5816 cc->handle_mmu_fault = x86_cpu_handle_mmu_fault;
5817#else
5818 cc->asidx_from_attrs = x86_asidx_from_attrs;
5819 cc->get_memory_mapping = x86_cpu_get_memory_mapping;
5820 cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
5821 cc->write_elf64_note = x86_cpu_write_elf64_note;
5822 cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
5823 cc->write_elf32_note = x86_cpu_write_elf32_note;
5824 cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
5825 cc->vmsd = &vmstate_x86_cpu;
5826#endif
5827 cc->gdb_arch_name = x86_gdb_arch_name;
5828#ifdef TARGET_X86_64
5829 cc->gdb_core_xml_file = "i386-64bit.xml";
5830 cc->gdb_num_core_regs = 57;
5831#else
5832 cc->gdb_core_xml_file = "i386-32bit.xml";
5833 cc->gdb_num_core_regs = 41;
5834#endif
5835#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
5836 cc->debug_excp_handler = breakpoint_handler;
5837#endif
5838 cc->cpu_exec_enter = x86_cpu_exec_enter;
5839 cc->cpu_exec_exit = x86_cpu_exec_exit;
5840#ifdef CONFIG_TCG
5841 cc->tcg_initialize = tcg_x86_init;
5842#endif
5843 cc->disas_set_info = x86_disas_set_info;
5844
5845 dc->user_creatable = true;
5846}
5847
5848static const TypeInfo x86_cpu_type_info = {
5849 .name = TYPE_X86_CPU,
5850 .parent = TYPE_CPU,
5851 .instance_size = sizeof(X86CPU),
5852 .instance_init = x86_cpu_initfn,
5853 .abstract = true,
5854 .class_size = sizeof(X86CPUClass),
5855 .class_init = x86_cpu_common_class_init,
5856};
5857
5858
5859
5860static void x86_cpu_base_class_init(ObjectClass *oc, void *data)
5861{
5862 X86CPUClass *xcc = X86_CPU_CLASS(oc);
5863
5864 xcc->static_model = true;
5865 xcc->migration_safe = true;
5866 xcc->model_description = "base CPU model type with no features enabled";
5867 xcc->ordering = 8;
5868}
5869
5870static const TypeInfo x86_base_cpu_type_info = {
5871 .name = X86_CPU_TYPE_NAME("base"),
5872 .parent = TYPE_X86_CPU,
5873 .class_init = x86_cpu_base_class_init,
5874};
5875
5876static void x86_cpu_register_types(void)
5877{
5878 int i;
5879
5880 type_register_static(&x86_cpu_type_info);
5881 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
5882 x86_register_cpudef_type(&builtin_x86_defs[i]);
5883 }
5884 type_register_static(&max_x86_cpu_type_info);
5885 type_register_static(&x86_base_cpu_type_info);
5886#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
5887 type_register_static(&host_x86_cpu_type_info);
5888#endif
5889}
5890
5891type_init(x86_cpu_register_types)
5892