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