26ba25
From c78647f69c02d1004dfc1a2f1e2e24960634c795 Mon Sep 17 00:00:00 2001
26ba25
From: Eduardo Habkost <ehabkost@redhat.com>
26ba25
Date: Thu, 26 Jul 2018 17:18:57 +0100
26ba25
Subject: [PATCH 07/14] i386: Add new property to control cache info
26ba25
26ba25
RH-Author: Eduardo Habkost <ehabkost@redhat.com>
26ba25
Message-id: <20180726171904.27418-5-ehabkost@redhat.com>
26ba25
Patchwork-id: 81526
26ba25
O-Subject: [qemu-kvm RHEL8/virt212 PATCH v2 04/11] i386: Add new property to control cache info
26ba25
Bugzilla: 1597739
26ba25
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
26ba25
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
26ba25
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
26ba25
26ba25
From: Babu Moger <babu.moger@amd.com>
26ba25
26ba25
The property legacy-cache will be used to control the cache information.
26ba25
If user passes "-cpu legacy-cache" then older information will
26ba25
be displayed even if the hardware supports new information. Otherwise
26ba25
use the statically loaded cache definitions if available.
26ba25
26ba25
Renamed the previous cache structures to legacy_*. If there is any change in
26ba25
the cache information, then it needs to be initialized in builtin_x86_defs.
26ba25
26ba25
Signed-off-by: Babu Moger <babu.moger@amd.com>
26ba25
Tested-by: Geoffrey McRae <geoff@hostfission.com>
26ba25
Message-Id: <20180514164156.27034-3-babu.moger@amd.com>
26ba25
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
26ba25
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
26ba25
(cherry picked from commit ab8f992e3e63e91be257e4e343d386dae7be4bcb)
26ba25
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
26ba25
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
26ba25
---
26ba25
 include/hw/i386/pc.h |  4 +++
26ba25
 target/i386/cpu.c    | 97 ++++++++++++++++++++++++++++++++++++++--------------
26ba25
 target/i386/cpu.h    |  5 +++
26ba25
 3 files changed, 80 insertions(+), 26 deletions(-)
26ba25
26ba25
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
26ba25
index ae84db4..5aebf6e 100644
26ba25
--- a/include/hw/i386/pc.h
26ba25
+++ b/include/hw/i386/pc.h
26ba25
@@ -979,6 +979,10 @@ extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id);
26ba25
             .driver   = "Skylake-Server" "-" TYPE_X86_CPU,\
26ba25
             .property = "clflushopt",\
26ba25
             .value    = "off",\
26ba25
+        },{ /* PC_RHEL7_5_COMPAT from PC_COMPAT_2_12 */ \
26ba25
+            .driver   = TYPE_X86_CPU,\
26ba25
+            .property = "legacy-cache",\
26ba25
+            .value    = "on",\
26ba25
         },
26ba25
 
26ba25
 
26ba25
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
26ba25
index bd0abc2..7dfc0fc 100644
26ba25
--- a/target/i386/cpu.c
26ba25
+++ b/target/i386/cpu.c
26ba25
@@ -336,10 +336,14 @@ static void encode_cache_cpuid80000006(CPUCacheInfo *l2,
26ba25
     }
26ba25
 }
26ba25
 
26ba25
-/* Definitions of the hardcoded cache entries we expose: */
26ba25
+/*
26ba25
+ * Definitions of the hardcoded cache entries we expose:
26ba25
+ * These are legacy cache values. If there is a need to change any
26ba25
+ * of these values please use builtin_x86_defs
26ba25
+ */
26ba25
 
26ba25
 /* L1 data cache: */
26ba25
-static CPUCacheInfo l1d_cache = {
26ba25
+static CPUCacheInfo legacy_l1d_cache = {
26ba25
     .type = DCACHE,
26ba25
     .level = 1,
26ba25
     .size = 32 * KiB,
26ba25
@@ -352,7 +356,7 @@ static CPUCacheInfo l1d_cache = {
26ba25
 };
26ba25
 
26ba25
 /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
26ba25
-static CPUCacheInfo l1d_cache_amd = {
26ba25
+static CPUCacheInfo legacy_l1d_cache_amd = {
26ba25
     .type = DCACHE,
26ba25
     .level = 1,
26ba25
     .size = 64 * KiB,
26ba25
@@ -366,7 +370,7 @@ static CPUCacheInfo l1d_cache_amd = {
26ba25
 };
26ba25
 
26ba25
 /* L1 instruction cache: */
26ba25
-static CPUCacheInfo l1i_cache = {
26ba25
+static CPUCacheInfo legacy_l1i_cache = {
26ba25
     .type = ICACHE,
26ba25
     .level = 1,
26ba25
     .size = 32 * KiB,
26ba25
@@ -379,7 +383,7 @@ static CPUCacheInfo l1i_cache = {
26ba25
 };
26ba25
 
26ba25
 /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
26ba25
-static CPUCacheInfo l1i_cache_amd = {
26ba25
+static CPUCacheInfo legacy_l1i_cache_amd = {
26ba25
     .type = ICACHE,
26ba25
     .level = 1,
26ba25
     .size = 64 * KiB,
26ba25
@@ -393,7 +397,7 @@ static CPUCacheInfo l1i_cache_amd = {
26ba25
 };
26ba25
 
26ba25
 /* Level 2 unified cache: */
26ba25
-static CPUCacheInfo l2_cache = {
26ba25
+static CPUCacheInfo legacy_l2_cache = {
26ba25
     .type = UNIFIED_CACHE,
26ba25
     .level = 2,
26ba25
     .size = 4 * MiB,
26ba25
@@ -406,7 +410,7 @@ static CPUCacheInfo l2_cache = {
26ba25
 };
26ba25
 
26ba25
 /*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
26ba25
-static CPUCacheInfo l2_cache_cpuid2 = {
26ba25
+static CPUCacheInfo legacy_l2_cache_cpuid2 = {
26ba25
     .type = UNIFIED_CACHE,
26ba25
     .level = 2,
26ba25
     .size = 2 * MiB,
26ba25
@@ -416,7 +420,7 @@ static CPUCacheInfo l2_cache_cpuid2 = {
26ba25
 
26ba25
 
26ba25
 /*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
26ba25
-static CPUCacheInfo l2_cache_amd = {
26ba25
+static CPUCacheInfo legacy_l2_cache_amd = {
26ba25
     .type = UNIFIED_CACHE,
26ba25
     .level = 2,
26ba25
     .size = 512 * KiB,
26ba25
@@ -428,7 +432,7 @@ static CPUCacheInfo l2_cache_amd = {
26ba25
 };
26ba25
 
26ba25
 /* Level 3 unified cache: */
26ba25
-static CPUCacheInfo l3_cache = {
26ba25
+static CPUCacheInfo legacy_l3_cache = {
26ba25
     .type = UNIFIED_CACHE,
26ba25
     .level = 3,
26ba25
     .size = 16 * MiB,
26ba25
@@ -3321,6 +3325,10 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
26ba25
         env->features[w] = def->features[w];
26ba25
     }
26ba25
 
26ba25
+    /* Store Cache information from the X86CPUDefinition if available */
26ba25
+    env->cache_info = def->cache_info;
26ba25
+    cpu->legacy_cache = def->cache_info ? 0 : 1;
26ba25
+
26ba25
     /* Special cases not set in the X86CPUDefinition structs: */
26ba25
     /* TODO: in-kernel irqchip for hvf */
26ba25
     if (kvm_enabled()) {
26ba25
@@ -3670,11 +3678,21 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
26ba25
         if (!cpu->enable_l3_cache) {
26ba25
             *ecx = 0;
26ba25
         } else {
26ba25
-            *ecx = cpuid2_cache_descriptor(&l3_cache);
26ba25
+            if (env->cache_info && !cpu->legacy_cache) {
26ba25
+                *ecx = cpuid2_cache_descriptor(&env->cache_info->l3_cache);
26ba25
+            } else {
26ba25
+                *ecx = cpuid2_cache_descriptor(&legacy_l3_cache);
26ba25
+            }
26ba25
+        }
26ba25
+        if (env->cache_info && !cpu->legacy_cache) {
26ba25
+            *edx = (cpuid2_cache_descriptor(&env->cache_info->l1d_cache) << 16) |
26ba25
+                   (cpuid2_cache_descriptor(&env->cache_info->l1i_cache) <<  8) |
26ba25
+                   (cpuid2_cache_descriptor(&env->cache_info->l2_cache));
26ba25
+        } else {
26ba25
+            *edx = (cpuid2_cache_descriptor(&legacy_l1d_cache) << 16) |
26ba25
+                   (cpuid2_cache_descriptor(&legacy_l1i_cache) <<  8) |
26ba25
+                   (cpuid2_cache_descriptor(&legacy_l2_cache_cpuid2));
26ba25
         }
26ba25
-        *edx = (cpuid2_cache_descriptor(&l1d_cache) << 16) |
26ba25
-               (cpuid2_cache_descriptor(&l1i_cache) <<  8) |
26ba25
-               (cpuid2_cache_descriptor(&l2_cache_cpuid2));
26ba25
         break;
26ba25
     case 4:
26ba25
         /* cache info: needed for Core compatibility */
26ba25
@@ -3687,27 +3705,35 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
26ba25
             }
26ba25
         } else {
26ba25
             *eax = 0;
26ba25
+            CPUCacheInfo *l1d, *l1i, *l2, *l3;
26ba25
+            if (env->cache_info && !cpu->legacy_cache) {
26ba25
+                l1d = &env->cache_info->l1d_cache;
26ba25
+                l1i = &env->cache_info->l1i_cache;
26ba25
+                l2 = &env->cache_info->l2_cache;
26ba25
+                l3 = &env->cache_info->l3_cache;
26ba25
+            } else {
26ba25
+                l1d = &legacy_l1d_cache;
26ba25
+                l1i = &legacy_l1i_cache;
26ba25
+                l2 = &legacy_l2_cache;
26ba25
+                l3 = &legacy_l3_cache;
26ba25
+            }
26ba25
             switch (count) {
26ba25
             case 0: /* L1 dcache info */
26ba25
-                encode_cache_cpuid4(&l1d_cache,
26ba25
-                                    1, cs->nr_cores,
26ba25
+                encode_cache_cpuid4(l1d, 1, cs->nr_cores,
26ba25
                                     eax, ebx, ecx, edx);
26ba25
                 break;
26ba25
             case 1: /* L1 icache info */
26ba25
-                encode_cache_cpuid4(&l1i_cache,
26ba25
-                                    1, cs->nr_cores,
26ba25
+                encode_cache_cpuid4(l1i, 1, cs->nr_cores,
26ba25
                                     eax, ebx, ecx, edx);
26ba25
                 break;
26ba25
             case 2: /* L2 cache info */
26ba25
-                encode_cache_cpuid4(&l2_cache,
26ba25
-                                    cs->nr_threads, cs->nr_cores,
26ba25
+                encode_cache_cpuid4(l2, cs->nr_threads, cs->nr_cores,
26ba25
                                     eax, ebx, ecx, edx);
26ba25
                 break;
26ba25
             case 3: /* L3 cache info */
26ba25
                 pkg_offset = apicid_pkg_offset(cs->nr_cores, cs->nr_threads);
26ba25
                 if (cpu->enable_l3_cache) {
26ba25
-                    encode_cache_cpuid4(&l3_cache,
26ba25
-                                        (1 << pkg_offset), cs->nr_cores,
26ba25
+                    encode_cache_cpuid4(l3, (1 << pkg_offset), cs->nr_cores,
26ba25
                                         eax, ebx, ecx, edx);
26ba25
                     break;
26ba25
                 }
26ba25
@@ -3920,8 +3946,13 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
26ba25
                (L1_ITLB_2M_ASSOC <<  8) | (L1_ITLB_2M_ENTRIES);
26ba25
         *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
26ba25
                (L1_ITLB_4K_ASSOC <<  8) | (L1_ITLB_4K_ENTRIES);
26ba25
-        *ecx = encode_cache_cpuid80000005(&l1d_cache_amd);
26ba25
-        *edx = encode_cache_cpuid80000005(&l1i_cache_amd);
26ba25
+        if (env->cache_info && !cpu->legacy_cache) {
26ba25
+            *ecx = encode_cache_cpuid80000005(&env->cache_info->l1d_cache);
26ba25
+            *edx = encode_cache_cpuid80000005(&env->cache_info->l1i_cache);
26ba25
+        } else {
26ba25
+            *ecx = encode_cache_cpuid80000005(&legacy_l1d_cache_amd);
26ba25
+            *edx = encode_cache_cpuid80000005(&legacy_l1i_cache_amd);
26ba25
+        }
26ba25
         break;
26ba25
     case 0x80000006:
26ba25
         /* cache info (L2 cache) */
26ba25
@@ -3937,9 +3968,17 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
26ba25
                (L2_DTLB_4K_ENTRIES << 16) | \
26ba25
                (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
26ba25
                (L2_ITLB_4K_ENTRIES);
26ba25
-        encode_cache_cpuid80000006(&l2_cache_amd,
26ba25
-                                   cpu->enable_l3_cache ? &l3_cache : NULL,
26ba25
-                                   ecx, edx);
26ba25
+        if (env->cache_info && !cpu->legacy_cache) {
26ba25
+            encode_cache_cpuid80000006(&env->cache_info->l2_cache,
26ba25
+                                       cpu->enable_l3_cache ?
26ba25
+                                       &env->cache_info->l3_cache : NULL,
26ba25
+                                       ecx, edx);
26ba25
+        } else {
26ba25
+            encode_cache_cpuid80000006(&legacy_l2_cache_amd,
26ba25
+                                       cpu->enable_l3_cache ?
26ba25
+                                       &legacy_l3_cache : NULL,
26ba25
+                                       ecx, edx);
26ba25
+        }
26ba25
         break;
26ba25
     case 0x80000007:
26ba25
         *eax = 0;
26ba25
@@ -5119,6 +5158,12 @@ static Property x86_cpu_properties[] = {
26ba25
                      false),
26ba25
     DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
26ba25
     DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
26ba25
+    /*
26ba25
+     * lecacy_cache defaults to CPU model being chosen. This is set in
26ba25
+     * x86_cpu_load_def based on cache_info which is initialized in
26ba25
+     * builtin_x86_defs
26ba25
+     */
26ba25
+    DEFINE_PROP_BOOL("legacy-cache", X86CPU, legacy_cache, false),
26ba25
 
26ba25
     /*
26ba25
      * From "Requirements for Implementing the Microsoft
26ba25
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
26ba25
index 372f8b7..31715d1 100644
26ba25
--- a/target/i386/cpu.h
26ba25
+++ b/target/i386/cpu.h
26ba25
@@ -1394,6 +1394,11 @@ struct X86CPU {
26ba25
      */
26ba25
     bool enable_l3_cache;
26ba25
 
26ba25
+    /* Compatibility bits for old machine types.
26ba25
+     * If true present the old cache topology information
26ba25
+     */
26ba25
+    bool legacy_cache;
26ba25
+
26ba25
     /* Compatibility bits for old machine types: */
26ba25
     bool enable_cpuid_0xb;
26ba25
 
26ba25
-- 
26ba25
1.8.3.1
26ba25