]> Git Repo - qemu.git/blobdiff - target/i386/cpu.c
i386: Add new CPU model Icelake-{Server,Client}
[qemu.git] / target / i386 / cpu.c
index 60deae31001595bcf50fe6744fa9533332e07c8e..ba7abe59ccd108499a317f73d3017304692cd01e 100644 (file)
@@ -18,7 +18,9 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/units.h"
 #include "qemu/cutils.h"
+#include "qemu/bitops.h"
 
 #include "cpu.h"
 #include "exec/exec-all.h"
@@ -64,131 +66,128 @@ struct CPUID2CacheDescriptorInfo {
     int associativity;
 };
 
-#define KiB 1024
-#define MiB (1024 * 1024)
-
 /*
  * Known CPUID 2 cache descriptors.
  * From Intel SDM Volume 2A, CPUID instruction
  */
 struct CPUID2CacheDescriptorInfo cpuid2_cache_descriptors[] = {
-    [0x06] = { .level = 1, .type = ICACHE,        .size =   8 * KiB,
+    [0x06] = { .level = 1, .type = INSTRUCTION_CACHE, .size =   8 * KiB,
                .associativity = 4,  .line_size = 32, },
-    [0x08] = { .level = 1, .type = ICACHE,        .size =  16 * KiB,
+    [0x08] = { .level = 1, .type = INSTRUCTION_CACHE, .size =  16 * KiB,
                .associativity = 4,  .line_size = 32, },
-    [0x09] = { .level = 1, .type = ICACHE,        .size =  32 * KiB,
+    [0x09] = { .level = 1, .type = INSTRUCTION_CACHE, .size =  32 * KiB,
                .associativity = 4,  .line_size = 64, },
-    [0x0A] = { .level = 1, .type = DCACHE,        .size =   8 * KiB,
+    [0x0A] = { .level = 1, .type = DATA_CACHE,        .size =   8 * KiB,
                .associativity = 2,  .line_size = 32, },
-    [0x0C] = { .level = 1, .type = DCACHE,        .size =  16 * KiB,
+    [0x0C] = { .level = 1, .type = DATA_CACHE,        .size =  16 * KiB,
                .associativity = 4,  .line_size = 32, },
-    [0x0D] = { .level = 1, .type = DCACHE,        .size =  16 * KiB,
+    [0x0D] = { .level = 1, .type = DATA_CACHE,        .size =  16 * KiB,
                .associativity = 4,  .line_size = 64, },
-    [0x0E] = { .level = 1, .type = DCACHE,        .size =  24 * KiB,
+    [0x0E] = { .level = 1, .type = DATA_CACHE,        .size =  24 * KiB,
                .associativity = 6,  .line_size = 64, },
-    [0x1D] = { .level = 2, .type = UNIFIED_CACHE, .size = 128 * KiB,
+    [0x1D] = { .level = 2, .type = UNIFIED_CACHE,     .size = 128 * KiB,
                .associativity = 2,  .line_size = 64, },
-    [0x21] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
+    [0x21] = { .level = 2, .type = UNIFIED_CACHE,     .size = 256 * KiB,
                .associativity = 8,  .line_size = 64, },
     /* lines per sector is not supported cpuid2_cache_descriptor(),
     * so descriptors 0x22, 0x23 are not included
     */
-    [0x24] = { .level = 2, .type = UNIFIED_CACHE, .size =   1 * MiB,
+    [0x24] = { .level = 2, .type = UNIFIED_CACHE,     .size =   1 * MiB,
                .associativity = 16, .line_size = 64, },
     /* lines per sector is not supported cpuid2_cache_descriptor(),
     * so descriptors 0x25, 0x20 are not included
     */
-    [0x2C] = { .level = 1, .type = DCACHE,        .size =  32 * KiB,
+    [0x2C] = { .level = 1, .type = DATA_CACHE,        .size =  32 * KiB,
                .associativity = 8,  .line_size = 64, },
-    [0x30] = { .level = 1, .type = ICACHE,        .size =  32 * KiB,
+    [0x30] = { .level = 1, .type = INSTRUCTION_CACHE, .size =  32 * KiB,
                .associativity = 8,  .line_size = 64, },
-    [0x41] = { .level = 2, .type = UNIFIED_CACHE, .size = 128 * KiB,
+    [0x41] = { .level = 2, .type = UNIFIED_CACHE,     .size = 128 * KiB,
                .associativity = 4,  .line_size = 32, },
-    [0x42] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
+    [0x42] = { .level = 2, .type = UNIFIED_CACHE,     .size = 256 * KiB,
                .associativity = 4,  .line_size = 32, },
-    [0x43] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
+    [0x43] = { .level = 2, .type = UNIFIED_CACHE,     .size = 512 * KiB,
                .associativity = 4,  .line_size = 32, },
-    [0x44] = { .level = 2, .type = UNIFIED_CACHE, .size =   1 * MiB,
+    [0x44] = { .level = 2, .type = UNIFIED_CACHE,     .size =   1 * MiB,
                .associativity = 4,  .line_size = 32, },
-    [0x45] = { .level = 2, .type = UNIFIED_CACHE, .size =   2 * MiB,
+    [0x45] = { .level = 2, .type = UNIFIED_CACHE,     .size =   2 * MiB,
                .associativity = 4,  .line_size = 32, },
-    [0x46] = { .level = 3, .type = UNIFIED_CACHE, .size =   4 * MiB,
+    [0x46] = { .level = 3, .type = UNIFIED_CACHE,     .size =   4 * MiB,
                .associativity = 4,  .line_size = 64, },
-    [0x47] = { .level = 3, .type = UNIFIED_CACHE, .size =   8 * MiB,
+    [0x47] = { .level = 3, .type = UNIFIED_CACHE,     .size =   8 * MiB,
                .associativity = 8,  .line_size = 64, },
-    [0x48] = { .level = 2, .type = UNIFIED_CACHE, .size =   3 * MiB,
+    [0x48] = { .level = 2, .type = UNIFIED_CACHE,     .size =   3 * MiB,
                .associativity = 12, .line_size = 64, },
     /* Descriptor 0x49 depends on CPU family/model, so it is not included */
-    [0x4A] = { .level = 3, .type = UNIFIED_CACHE, .size =   6 * MiB,
+    [0x4A] = { .level = 3, .type = UNIFIED_CACHE,     .size =   6 * MiB,
                .associativity = 12, .line_size = 64, },
-    [0x4B] = { .level = 3, .type = UNIFIED_CACHE, .size =   8 * MiB,
+    [0x4B] = { .level = 3, .type = UNIFIED_CACHE,     .size =   8 * MiB,
                .associativity = 16, .line_size = 64, },
-    [0x4C] = { .level = 3, .type = UNIFIED_CACHE, .size =  12 * MiB,
+    [0x4C] = { .level = 3, .type = UNIFIED_CACHE,     .size =  12 * MiB,
                .associativity = 12, .line_size = 64, },
-    [0x4D] = { .level = 3, .type = UNIFIED_CACHE, .size =  16 * MiB,
+    [0x4D] = { .level = 3, .type = UNIFIED_CACHE,     .size =  16 * MiB,
                .associativity = 16, .line_size = 64, },
-    [0x4E] = { .level = 2, .type = UNIFIED_CACHE, .size =   6 * MiB,
+    [0x4E] = { .level = 2, .type = UNIFIED_CACHE,     .size =   6 * MiB,
                .associativity = 24, .line_size = 64, },
-    [0x60] = { .level = 1, .type = DCACHE,        .size =  16 * KiB,
+    [0x60] = { .level = 1, .type = DATA_CACHE,        .size =  16 * KiB,
                .associativity = 8,  .line_size = 64, },
-    [0x66] = { .level = 1, .type = DCACHE,        .size =   8 * KiB,
+    [0x66] = { .level = 1, .type = DATA_CACHE,        .size =   8 * KiB,
                .associativity = 4,  .line_size = 64, },
-    [0x67] = { .level = 1, .type = DCACHE,        .size =  16 * KiB,
+    [0x67] = { .level = 1, .type = DATA_CACHE,        .size =  16 * KiB,
                .associativity = 4,  .line_size = 64, },
-    [0x68] = { .level = 1, .type = DCACHE,        .size =  32 * KiB,
+    [0x68] = { .level = 1, .type = DATA_CACHE,        .size =  32 * KiB,
                .associativity = 4,  .line_size = 64, },
-    [0x78] = { .level = 2, .type = UNIFIED_CACHE, .size =   1 * MiB,
+    [0x78] = { .level = 2, .type = UNIFIED_CACHE,     .size =   1 * MiB,
                .associativity = 4,  .line_size = 64, },
     /* lines per sector is not supported cpuid2_cache_descriptor(),
     * so descriptors 0x79, 0x7A, 0x7B, 0x7C are not included.
     */
-    [0x7D] = { .level = 2, .type = UNIFIED_CACHE, .size =   2 * MiB,
+    [0x7D] = { .level = 2, .type = UNIFIED_CACHE,     .size =   2 * MiB,
                .associativity = 8,  .line_size = 64, },
-    [0x7F] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
+    [0x7F] = { .level = 2, .type = UNIFIED_CACHE,     .size = 512 * KiB,
                .associativity = 2,  .line_size = 64, },
-    [0x80] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
+    [0x80] = { .level = 2, .type = UNIFIED_CACHE,     .size = 512 * KiB,
                .associativity = 8,  .line_size = 64, },
-    [0x82] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
+    [0x82] = { .level = 2, .type = UNIFIED_CACHE,     .size = 256 * KiB,
                .associativity = 8,  .line_size = 32, },
-    [0x83] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
+    [0x83] = { .level = 2, .type = UNIFIED_CACHE,     .size = 512 * KiB,
                .associativity = 8,  .line_size = 32, },
-    [0x84] = { .level = 2, .type = UNIFIED_CACHE, .size =   1 * MiB,
+    [0x84] = { .level = 2, .type = UNIFIED_CACHE,     .size =   1 * MiB,
                .associativity = 8,  .line_size = 32, },
-    [0x85] = { .level = 2, .type = UNIFIED_CACHE, .size =   2 * MiB,
+    [0x85] = { .level = 2, .type = UNIFIED_CACHE,     .size =   2 * MiB,
                .associativity = 8,  .line_size = 32, },
-    [0x86] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
+    [0x86] = { .level = 2, .type = UNIFIED_CACHE,     .size = 512 * KiB,
                .associativity = 4,  .line_size = 64, },
-    [0x87] = { .level = 2, .type = UNIFIED_CACHE, .size =   1 * MiB,
+    [0x87] = { .level = 2, .type = UNIFIED_CACHE,     .size =   1 * MiB,
                .associativity = 8,  .line_size = 64, },
-    [0xD0] = { .level = 3, .type = UNIFIED_CACHE, .size = 512 * KiB,
+    [0xD0] = { .level = 3, .type = UNIFIED_CACHE,     .size = 512 * KiB,
                .associativity = 4,  .line_size = 64, },
-    [0xD1] = { .level = 3, .type = UNIFIED_CACHE, .size =   1 * MiB,
+    [0xD1] = { .level = 3, .type = UNIFIED_CACHE,     .size =   1 * MiB,
                .associativity = 4,  .line_size = 64, },
-    [0xD2] = { .level = 3, .type = UNIFIED_CACHE, .size =   2 * MiB,
+    [0xD2] = { .level = 3, .type = UNIFIED_CACHE,     .size =   2 * MiB,
                .associativity = 4,  .line_size = 64, },
-    [0xD6] = { .level = 3, .type = UNIFIED_CACHE, .size =   1 * MiB,
+    [0xD6] = { .level = 3, .type = UNIFIED_CACHE,     .size =   1 * MiB,
                .associativity = 8,  .line_size = 64, },
-    [0xD7] = { .level = 3, .type = UNIFIED_CACHE, .size =   2 * MiB,
+    [0xD7] = { .level = 3, .type = UNIFIED_CACHE,     .size =   2 * MiB,
                .associativity = 8,  .line_size = 64, },
-    [0xD8] = { .level = 3, .type = UNIFIED_CACHE, .size =   4 * MiB,
+    [0xD8] = { .level = 3, .type = UNIFIED_CACHE,     .size =   4 * MiB,
                .associativity = 8,  .line_size = 64, },
-    [0xDC] = { .level = 3, .type = UNIFIED_CACHE, .size = 1.5 * MiB,
+    [0xDC] = { .level = 3, .type = UNIFIED_CACHE,     .size = 1.5 * MiB,
                .associativity = 12, .line_size = 64, },
-    [0xDD] = { .level = 3, .type = UNIFIED_CACHE, .size =   3 * MiB,
+    [0xDD] = { .level = 3, .type = UNIFIED_CACHE,     .size =   3 * MiB,
                .associativity = 12, .line_size = 64, },
-    [0xDE] = { .level = 3, .type = UNIFIED_CACHE, .size =   6 * MiB,
+    [0xDE] = { .level = 3, .type = UNIFIED_CACHE,     .size =   6 * MiB,
                .associativity = 12, .line_size = 64, },
-    [0xE2] = { .level = 3, .type = UNIFIED_CACHE, .size =   2 * MiB,
+    [0xE2] = { .level = 3, .type = UNIFIED_CACHE,     .size =   2 * MiB,
                .associativity = 16, .line_size = 64, },
-    [0xE3] = { .level = 3, .type = UNIFIED_CACHE, .size =   4 * MiB,
+    [0xE3] = { .level = 3, .type = UNIFIED_CACHE,     .size =   4 * MiB,
                .associativity = 16, .line_size = 64, },
-    [0xE4] = { .level = 3, .type = UNIFIED_CACHE, .size =   8 * MiB,
+    [0xE4] = { .level = 3, .type = UNIFIED_CACHE,     .size =   8 * MiB,
                .associativity = 16, .line_size = 64, },
-    [0xEA] = { .level = 3, .type = UNIFIED_CACHE, .size =  12 * MiB,
+    [0xEA] = { .level = 3, .type = UNIFIED_CACHE,     .size =  12 * MiB,
                .associativity = 24, .line_size = 64, },
-    [0xEB] = { .level = 3, .type = UNIFIED_CACHE, .size =  18 * MiB,
+    [0xEB] = { .level = 3, .type = UNIFIED_CACHE,     .size =  18 * MiB,
                .associativity = 24, .line_size = 64, },
-    [0xEC] = { .level = 3, .type = UNIFIED_CACHE, .size =  24 * MiB,
+    [0xEC] = { .level = 3, .type = UNIFIED_CACHE,     .size =  24 * MiB,
                .associativity = 24, .line_size = 64, },
 };
 
@@ -239,10 +238,10 @@ static uint8_t cpuid2_cache_descriptor(CPUCacheInfo *cache)
 #define CACHE_COMPLEX_IDX     (1 << 2)
 
 /* Encode CacheType for CPUID[4].EAX */
-#define CACHE_TYPE(t) (((t) == DCACHE)  ? CACHE_TYPE_D  : \
-                         ((t) == ICACHE)  ? CACHE_TYPE_I  : \
-                         ((t) == UNIFIED_CACHE) ? CACHE_TYPE_UNIFIED : \
-                         0 /* Invalid value */)
+#define CACHE_TYPE(t) (((t) == DATA_CACHE) ? CACHE_TYPE_D : \
+                       ((t) == INSTRUCTION_CACHE) ? CACHE_TYPE_I : \
+                       ((t) == UNIFIED_CACHE) ? CACHE_TYPE_UNIFIED : \
+                       0 /* Invalid value */)
 
 
 /* Encode cache info for CPUID[4] */
@@ -472,6 +471,8 @@ static void encode_topo_cpuid8000001e(CPUState *cs, X86CPU *cpu,
                                        uint32_t *ecx, uint32_t *edx)
 {
     struct core_topology topo = {0};
+    unsigned long nodes;
+    int shift;
 
     build_core_topology(cs->nr_cores, cpu->core_id, &topo);
     *eax = cpu->apic_id;
@@ -504,7 +505,28 @@ static void encode_topo_cpuid8000001e(CPUState *cs, X86CPU *cpu,
      *         2  Socket id
      *       1:0  Node id
      */
-    *ecx = ((topo.num_nodes - 1) << 8) | (cpu->socket_id << 2) | topo.node_id;
+    if (topo.num_nodes <= 4) {
+        *ecx = ((topo.num_nodes - 1) << 8) | (cpu->socket_id << 2) |
+                topo.node_id;
+    } else {
+        /*
+         * Node id fix up. Actual hardware supports up to 4 nodes. But with
+         * more than 32 cores, we may end up with more than 4 nodes.
+         * Node id is a combination of socket id and node id. Only requirement
+         * here is that this number should be unique accross the system.
+         * Shift the socket id to accommodate more nodes. We dont expect both
+         * socket id and node id to be big number at the same time. This is not
+         * an ideal config but we need to to support it. Max nodes we can have
+         * is 32 (255/8) with 8 cores per node and 255 max cores. We only need
+         * 5 bits for nodes. Find the left most set bit to represent the total
+         * number of nodes. find_last_bit returns last set bit(0 based). Left
+         * shift(+1) the socket id to represent all the nodes.
+         */
+        nodes = topo.num_nodes - 1;
+        shift = find_last_bit(&nodes, 8);
+        *ecx = ((topo.num_nodes - 1) << 8) | (cpu->socket_id << (shift + 1)) |
+                topo.node_id;
+    }
     *edx = 0;
 }
 
@@ -516,7 +538,7 @@ static void encode_topo_cpuid8000001e(CPUState *cs, X86CPU *cpu,
 
 /* L1 data cache: */
 static CPUCacheInfo legacy_l1d_cache = {
-    .type = DCACHE,
+    .type = DATA_CACHE,
     .level = 1,
     .size = 32 * KiB,
     .self_init = 1,
@@ -529,7 +551,7 @@ static CPUCacheInfo legacy_l1d_cache = {
 
 /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
 static CPUCacheInfo legacy_l1d_cache_amd = {
-    .type = DCACHE,
+    .type = DATA_CACHE,
     .level = 1,
     .size = 64 * KiB,
     .self_init = 1,
@@ -543,7 +565,7 @@ static CPUCacheInfo legacy_l1d_cache_amd = {
 
 /* L1 instruction cache: */
 static CPUCacheInfo legacy_l1i_cache = {
-    .type = ICACHE,
+    .type = INSTRUCTION_CACHE,
     .level = 1,
     .size = 32 * KiB,
     .self_init = 1,
@@ -556,7 +578,7 @@ static CPUCacheInfo legacy_l1i_cache = {
 
 /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
 static CPUCacheInfo legacy_l1i_cache_amd = {
-    .type = ICACHE,
+    .type = INSTRUCTION_CACHE,
     .level = 1,
     .size = 64 * KiB,
     .self_init = 1,
@@ -727,7 +749,7 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
 #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
           CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
 #define TCG_EXT4_FEATURES 0
-#define TCG_SVM_FEATURES 0
+#define TCG_SVM_FEATURES CPUID_SVM_NPT
 #define TCG_KVM_FEATURES 0
 #define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
           CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
@@ -738,7 +760,8 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
           CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
           CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
           CPUID_7_0_EBX_RDSEED */
-#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE | \
+#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | \
+          /* CPUID_7_0_ECX_OSPKE is dynamic */ \
           CPUID_7_0_ECX_LA57)
 #define TCG_7_0_EDX_FEATURES 0
 #define TCG_APM_FEATURES 0
@@ -955,7 +978,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
     [FEAT_7_0_ECX] = {
         .feat_names = {
             NULL, "avx512vbmi", "umip", "pku",
-            "ospke", NULL, "avx512vbmi2", NULL,
+            NULL /* ospke */, NULL, "avx512vbmi2", NULL,
             "gfni", "vaes", "vpclmulqdq", "avx512vnni",
             "avx512bitalg", NULL, "avx512-vpopcntdq", NULL,
             "la57", NULL, NULL, NULL,
@@ -974,15 +997,16 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
             NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL,
-            NULL, NULL, NULL, NULL,
+            NULL, NULL, "pconfig", NULL,
             NULL, NULL, NULL, NULL,
             NULL, NULL, "spec-ctrl", NULL,
-            NULL, NULL, NULL, "ssbd",
+            NULL, "arch-capabilities", NULL, "ssbd",
         },
         .cpuid_eax = 7,
         .cpuid_needs_ecx = true, .cpuid_ecx = 0,
         .cpuid_reg = R_EDX,
         .tcg_features = TCG_7_0_EDX_FEATURES,
+        .unmigratable_flags = CPUID_7_0_EDX_ARCH_CAPABILITIES,
     },
     [FEAT_8000_0007_EDX] = {
         .feat_names = {
@@ -1004,11 +1028,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
         .feat_names = {
             NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL,
-            NULL, NULL, NULL, NULL,
+            NULL, "wbnoinvd", NULL, NULL,
             "ibpb", NULL, NULL, NULL,
             NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL,
-            NULL, "virt-ssbd", NULL, NULL,
+            "amd-ssbd", "virt-ssbd", "amd-no-ssb", NULL,
             NULL, NULL, NULL, NULL,
         },
         .cpuid_eax = 0x80000008,
@@ -1287,7 +1311,7 @@ struct X86CPUDefinition {
 
 static CPUCaches epyc_cache_info = {
     .l1d_cache = &(CPUCacheInfo) {
-        .type = DCACHE,
+        .type = DATA_CACHE,
         .level = 1,
         .size = 32 * KiB,
         .line_size = 64,
@@ -1299,7 +1323,7 @@ static CPUCaches epyc_cache_info = {
         .no_invd_sharing = true,
     },
     .l1i_cache = &(CPUCacheInfo) {
-        .type = ICACHE,
+        .type = INSTRUCTION_CACHE,
         .level = 1,
         .size = 64 * KiB,
         .line_size = 64,
@@ -2356,6 +2380,121 @@ static X86CPUDefinition builtin_x86_defs[] = {
         .xlevel = 0x80000008,
         .model_id = "Intel Xeon Processor (Skylake, IBRS)",
     },
+    {
+        .name = "Icelake-Client",
+        .level = 0xd,
+        .vendor = CPUID_VENDOR_INTEL,
+        .family = 6,
+        .model = 126,
+        .stepping = 0,
+        .features[FEAT_1_EDX] =
+            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+            CPUID_DE | CPUID_FP87,
+        .features[FEAT_1_ECX] =
+            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
+            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
+            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
+            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
+            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
+        .features[FEAT_8000_0001_EDX] =
+            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
+            CPUID_EXT2_SYSCALL,
+        .features[FEAT_8000_0001_ECX] =
+            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
+        .features[FEAT_8000_0008_EBX] =
+            CPUID_8000_0008_EBX_WBNOINVD,
+        .features[FEAT_7_0_EBX] =
+            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
+            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
+            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
+            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
+            CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_INTEL_PT,
+        .features[FEAT_7_0_ECX] =
+            CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
+            CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
+            CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
+            CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
+            CPUID_7_0_ECX_AVX512_VPOPCNTDQ,
+        .features[FEAT_7_0_EDX] =
+            CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
+        /* Missing: XSAVES (not supported by some Linux versions,
+                * including v4.1 to v4.12).
+                * KVM doesn't yet expose any XSAVES state save component,
+                * and the only one defined in Skylake (processor tracing)
+                * probably will block migration anyway.
+                */
+        .features[FEAT_XSAVE] =
+            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
+            CPUID_XSAVE_XGETBV1,
+        .features[FEAT_6_EAX] =
+            CPUID_6_EAX_ARAT,
+        .xlevel = 0x80000008,
+        .model_id = "Intel Core Processor (Icelake)",
+    },
+    {
+        .name = "Icelake-Server",
+        .level = 0xd,
+        .vendor = CPUID_VENDOR_INTEL,
+        .family = 6,
+        .model = 134,
+        .stepping = 0,
+        .features[FEAT_1_EDX] =
+            CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+            CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+            CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+            CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+            CPUID_DE | CPUID_FP87,
+        .features[FEAT_1_ECX] =
+            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+            CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
+            CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
+            CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
+            CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
+            CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
+        .features[FEAT_8000_0001_EDX] =
+            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
+            CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
+        .features[FEAT_8000_0001_ECX] =
+            CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
+        .features[FEAT_8000_0008_EBX] =
+            CPUID_8000_0008_EBX_WBNOINVD,
+        .features[FEAT_7_0_EBX] =
+            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
+            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
+            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
+            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
+            CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
+            CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
+            CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
+            CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
+            CPUID_7_0_EBX_INTEL_PT,
+        .features[FEAT_7_0_ECX] =
+            CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
+            CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
+            CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
+            CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
+            CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57,
+        .features[FEAT_7_0_EDX] =
+            CPUID_7_0_EDX_PCONFIG | CPUID_7_0_EDX_SPEC_CTRL |
+            CPUID_7_0_EDX_SPEC_CTRL_SSBD,
+        /* Missing: XSAVES (not supported by some Linux versions,
+                * including v4.1 to v4.12).
+                * KVM doesn't yet expose any XSAVES state save component,
+                * and the only one defined in Skylake (processor tracing)
+                * probably will block migration anyway.
+                */
+        .features[FEAT_XSAVE] =
+            CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
+            CPUID_XSAVE_XGETBV1,
+        .features[FEAT_6_EAX] =
+            CPUID_6_EAX_ARAT,
+        .xlevel = 0x80000008,
+        .model_id = "Intel Xeon Processor (Icelake)",
+    },
     {
         .name = "KnightsMill",
         .level = 0xd,
@@ -2554,7 +2693,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
         .features[FEAT_8000_0001_ECX] =
             CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
             CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
-            CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
+            CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
+            CPUID_EXT3_TOPOEXT,
         .features[FEAT_7_0_EBX] =
             CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
             CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
@@ -2569,7 +2709,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_XSAVE_XGETBV1,
         .features[FEAT_6_EAX] =
             CPUID_6_EAX_ARAT,
-        .xlevel = 0x8000000A,
+        .xlevel = 0x8000001E,
         .model_id = "AMD EPYC Processor",
         .cache_info = &epyc_cache_info,
     },
@@ -2599,7 +2739,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
         .features[FEAT_8000_0001_ECX] =
             CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
             CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
-            CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
+            CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
+            CPUID_EXT3_TOPOEXT,
         .features[FEAT_8000_0008_EBX] =
             CPUID_8000_0008_EBX_IBPB,
         .features[FEAT_7_0_EBX] =
@@ -2616,7 +2757,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_XSAVE_XGETBV1,
         .features[FEAT_6_EAX] =
             CPUID_6_EAX_ARAT,
-        .xlevel = 0x8000000A,
+        .xlevel = 0x8000001E,
         .model_id = "AMD EPYC Processor (with IBPB)",
         .cache_info = &epyc_cache_info,
     },
@@ -2811,13 +2952,13 @@ static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
     xcc->host_cpuid_required = true;
     xcc->ordering = 8;
 
-    if (kvm_enabled()) {
-        xcc->model_description =
-            "KVM processor with all supported host features ";
-    } else if (hvf_enabled()) {
-        xcc->model_description =
-            "HVF processor with all supported host features ";
-    }
+#if defined(CONFIG_KVM)
+    xcc->model_description =
+        "KVM processor with all supported host features ";
+#elif defined(CONFIG_HVF)
+    xcc->model_description =
+        "HVF processor with all supported host features ";
+#endif
 }
 
 static const TypeInfo host_x86_cpu_type_info = {
@@ -3932,11 +4073,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         }
         break;
     case 5:
-        /* mwait info: needed for Core compatibility */
-        *eax = 0; /* Smallest monitor-line size in bytes */
-        *ebx = 0; /* Largest monitor-line size in bytes */
-        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
-        *edx = 0;
+        /* MONITOR/MWAIT Leaf */
+        *eax = cpu->mwait.eax; /* Smallest monitor-line size in bytes */
+        *ebx = cpu->mwait.ebx; /* Largest monitor-line size in bytes */
+        *ecx = cpu->mwait.ecx; /* flags */
+        *edx = cpu->mwait.edx; /* mwait substates */
         break;
     case 6:
         /* Thermal and Power Leaf */
@@ -4777,13 +4918,25 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
     Error *local_err = NULL;
     static bool ht_warned;
 
-    if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
-        char *name = x86_cpu_class_get_model_name(xcc);
-        error_setg(&local_err, "CPU model '%s' requires KVM", name);
-        g_free(name);
-        goto out;
+    if (xcc->host_cpuid_required) {
+        if (!accel_uses_host_cpuid()) {
+            char *name = x86_cpu_class_get_model_name(xcc);
+            error_setg(&local_err, "CPU model '%s' requires KVM", name);
+            g_free(name);
+            goto out;
+        }
+
+        if (enable_cpu_pm) {
+            host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx,
+                       &cpu->mwait.ecx, &cpu->mwait.edx);
+            env->features[FEAT_1_ECX] |= CPUID_EXT_MONITOR;
+        }
     }
 
+    /* mwait extended info: needed for Core compatibility */
+    /* We always wake on interrupt even if host does not have the capability */
+    cpu->mwait.ecx |= CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
+
     if (cpu->apic_id == UNASSIGNED_APIC_ID) {
         error_setg(errp, "apic-id property was not initialized properly");
         return;
@@ -4958,17 +5111,22 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
 
     qemu_init_vcpu(cs);
 
-    /* Only Intel CPUs support hyperthreading. Even though QEMU fixes this
-     * issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX
-     * based on inputs (sockets,cores,threads), it is still better to gives
+    /*
+     * Most Intel and certain AMD CPUs support hyperthreading. Even though QEMU
+     * fixes this issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX
+     * based on inputs (sockets,cores,threads), it is still better to give
      * users a warning.
      *
      * NOTE: the following code has to follow qemu_init_vcpu(). Otherwise
      * cs->nr_threads hasn't be populated yet and the checking is incorrect.
      */
-    if (!IS_INTEL_CPU(env) && cs->nr_threads > 1 && !ht_warned) {
-        error_report("AMD CPU doesn't support hyperthreading. Please configure"
-                     " -smp options properly.");
+     if (IS_AMD_CPU(env) &&
+         !(env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT) &&
+         cs->nr_threads > 1 && !ht_warned) {
+            error_report("This family of AMD CPU doesn't support "
+                         "hyperthreading(%d). Please configure -smp "
+                         "options properly or try enabling topoext feature.",
+                         cs->nr_threads);
         ht_warned = true;
     }
 
@@ -5371,6 +5529,7 @@ static Property x86_cpu_properties[] = {
     DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
     DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
     DEFINE_PROP_BOOL("hv-reenlightenment", X86CPU, hyperv_reenlightenment, false),
+    DEFINE_PROP_BOOL("hv-tlbflush", X86CPU, hyperv_tlbflush, false),
     DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
     DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
     DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
@@ -5392,6 +5551,8 @@ static Property x86_cpu_properties[] = {
                      false),
     DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
     DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
+    DEFINE_PROP_BOOL("x-migrate-smi-count", X86CPU, migrate_smi_count,
+                     true),
     /*
      * lecacy_cache defaults to true unless the CPU model provides its
      * own cache information (see x86_cpu_load_def()).
This page took 0.048313 seconds and 4 git commands to generate.