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