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