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