Blame SOURCES/kvm-i386-Clean-up-cache-CPUID-code.patch

1bdc94
From 98205e71073c36234048b60feedc1ce142902572 Mon Sep 17 00:00:00 2001
1bdc94
From: Eduardo Habkost <ehabkost@redhat.com>
1bdc94
Date: Tue, 3 Jul 2018 17:23:51 +0200
1bdc94
Subject: [PATCH 06/89] i386: Clean up cache CPUID code
1bdc94
1bdc94
RH-Author: Eduardo Habkost <ehabkost@redhat.com>
1bdc94
Message-id: <20180703172356.21038-6-ehabkost@redhat.com>
1bdc94
Patchwork-id: 81215
1bdc94
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH v3 05/10] i386: Clean up cache CPUID code
1bdc94
Bugzilla: 1481253
1bdc94
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
1bdc94
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
1bdc94
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
1bdc94
1bdc94
Always initialize CPUCaches structs with cache information, even
1bdc94
if legacy_cache=true.  Use different CPUCaches struct for
1bdc94
CPUID[2], CPUID[4], and the AMD CPUID leaves.
1bdc94
1bdc94
This will simplify a lot the logic inside cpu_x86_cpuid().
1bdc94
1bdc94
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
1bdc94
Signed-off-by: Babu Moger <babu.moger@amd.com>
1bdc94
Message-Id: <1527176614-26271-2-git-send-email-babu.moger@amd.com>
1bdc94
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
1bdc94
(cherry picked from commit a9f27ea9adc8c695197bd08f2e938ef7b4183f07)
1bdc94
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
1bdc94
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
1bdc94
---
1bdc94
 target/i386/cpu.c | 117 +++++++++++++++++++++++++++---------------------------
1bdc94
 target/i386/cpu.h |  14 ++++---
1bdc94
 2 files changed, 67 insertions(+), 64 deletions(-)
1bdc94
1bdc94
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
1bdc94
index 3426130..41d0b72 100644
1bdc94
--- a/target/i386/cpu.c
1bdc94
+++ b/target/i386/cpu.c
1bdc94
@@ -1113,7 +1113,7 @@ struct X86CPUDefinition {
1bdc94
 };
1bdc94
 
1bdc94
 static CPUCaches epyc_cache_info = {
1bdc94
-    .l1d_cache = {
1bdc94
+    .l1d_cache = &(CPUCacheInfo) {
1bdc94
         .type = DCACHE,
1bdc94
         .level = 1,
1bdc94
         .size = 32 * KiB,
1bdc94
@@ -1125,7 +1125,7 @@ static CPUCaches epyc_cache_info = {
1bdc94
         .self_init = 1,
1bdc94
         .no_invd_sharing = true,
1bdc94
     },
1bdc94
-    .l1i_cache = {
1bdc94
+    .l1i_cache = &(CPUCacheInfo) {
1bdc94
         .type = ICACHE,
1bdc94
         .level = 1,
1bdc94
         .size = 64 * KiB,
1bdc94
@@ -1137,7 +1137,7 @@ static CPUCaches epyc_cache_info = {
1bdc94
         .self_init = 1,
1bdc94
         .no_invd_sharing = true,
1bdc94
     },
1bdc94
-    .l2_cache = {
1bdc94
+    .l2_cache = &(CPUCacheInfo) {
1bdc94
         .type = UNIFIED_CACHE,
1bdc94
         .level = 2,
1bdc94
         .size = 512 * KiB,
1bdc94
@@ -1147,7 +1147,7 @@ static CPUCaches epyc_cache_info = {
1bdc94
         .sets = 1024,
1bdc94
         .lines_per_tag = 1,
1bdc94
     },
1bdc94
-    .l3_cache = {
1bdc94
+    .l3_cache = &(CPUCacheInfo) {
1bdc94
         .type = UNIFIED_CACHE,
1bdc94
         .level = 3,
1bdc94
         .size = 8 * MiB,
1bdc94
@@ -3325,9 +3325,8 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
1bdc94
         env->features[w] = def->features[w];
1bdc94
     }
1bdc94
 
1bdc94
-    /* Store Cache information from the X86CPUDefinition if available */
1bdc94
-    env->cache_info = def->cache_info;
1bdc94
-    cpu->legacy_cache = def->cache_info ? 0 : 1;
1bdc94
+    /* legacy-cache defaults to 'off' if CPU model provides cache info */
1bdc94
+    cpu->legacy_cache = !def->cache_info;
1bdc94
 
1bdc94
     /* Special cases not set in the X86CPUDefinition structs: */
1bdc94
     /* TODO: in-kernel irqchip for hvf */
1bdc94
@@ -3678,21 +3677,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1bdc94
         if (!cpu->enable_l3_cache) {
1bdc94
             *ecx = 0;
1bdc94
         } else {
1bdc94
-            if (env->cache_info && !cpu->legacy_cache) {
1bdc94
-                *ecx = cpuid2_cache_descriptor(&env->cache_info->l3_cache);
1bdc94
-            } else {
1bdc94
-                *ecx = cpuid2_cache_descriptor(&legacy_l3_cache);
1bdc94
-            }
1bdc94
-        }
1bdc94
-        if (env->cache_info && !cpu->legacy_cache) {
1bdc94
-            *edx = (cpuid2_cache_descriptor(&env->cache_info->l1d_cache) << 16) |
1bdc94
-                   (cpuid2_cache_descriptor(&env->cache_info->l1i_cache) <<  8) |
1bdc94
-                   (cpuid2_cache_descriptor(&env->cache_info->l2_cache));
1bdc94
-        } else {
1bdc94
-            *edx = (cpuid2_cache_descriptor(&legacy_l1d_cache) << 16) |
1bdc94
-                   (cpuid2_cache_descriptor(&legacy_l1i_cache) <<  8) |
1bdc94
-                   (cpuid2_cache_descriptor(&legacy_l2_cache_cpuid2));
1bdc94
+            *ecx = cpuid2_cache_descriptor(env->cache_info_cpuid2.l3_cache);
1bdc94
         }
1bdc94
+        *edx = (cpuid2_cache_descriptor(env->cache_info_cpuid2.l1d_cache) << 16) |
1bdc94
+               (cpuid2_cache_descriptor(env->cache_info_cpuid2.l1i_cache) <<  8) |
1bdc94
+               (cpuid2_cache_descriptor(env->cache_info_cpuid2.l2_cache));
1bdc94
         break;
1bdc94
     case 4:
1bdc94
         /* cache info: needed for Core compatibility */
1bdc94
@@ -3705,35 +3694,27 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1bdc94
             }
1bdc94
         } else {
1bdc94
             *eax = 0;
1bdc94
-            CPUCacheInfo *l1d, *l1i, *l2, *l3;
1bdc94
-            if (env->cache_info && !cpu->legacy_cache) {
1bdc94
-                l1d = &env->cache_info->l1d_cache;
1bdc94
-                l1i = &env->cache_info->l1i_cache;
1bdc94
-                l2 = &env->cache_info->l2_cache;
1bdc94
-                l3 = &env->cache_info->l3_cache;
1bdc94
-            } else {
1bdc94
-                l1d = &legacy_l1d_cache;
1bdc94
-                l1i = &legacy_l1i_cache;
1bdc94
-                l2 = &legacy_l2_cache;
1bdc94
-                l3 = &legacy_l3_cache;
1bdc94
-            }
1bdc94
             switch (count) {
1bdc94
             case 0: /* L1 dcache info */
1bdc94
-                encode_cache_cpuid4(l1d, 1, cs->nr_cores,
1bdc94
+                encode_cache_cpuid4(env->cache_info_cpuid4.l1d_cache,
1bdc94
+                                    1, cs->nr_cores,
1bdc94
                                     eax, ebx, ecx, edx);
1bdc94
                 break;
1bdc94
             case 1: /* L1 icache info */
1bdc94
-                encode_cache_cpuid4(l1i, 1, cs->nr_cores,
1bdc94
+                encode_cache_cpuid4(env->cache_info_cpuid4.l1i_cache,
1bdc94
+                                    1, cs->nr_cores,
1bdc94
                                     eax, ebx, ecx, edx);
1bdc94
                 break;
1bdc94
             case 2: /* L2 cache info */
1bdc94
-                encode_cache_cpuid4(l2, cs->nr_threads, cs->nr_cores,
1bdc94
+                encode_cache_cpuid4(env->cache_info_cpuid4.l2_cache,
1bdc94
+                                    cs->nr_threads, cs->nr_cores,
1bdc94
                                     eax, ebx, ecx, edx);
1bdc94
                 break;
1bdc94
             case 3: /* L3 cache info */
1bdc94
                 pkg_offset = apicid_pkg_offset(cs->nr_cores, cs->nr_threads);
1bdc94
                 if (cpu->enable_l3_cache) {
1bdc94
-                    encode_cache_cpuid4(l3, (1 << pkg_offset), cs->nr_cores,
1bdc94
+                    encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache,
1bdc94
+                                        (1 << pkg_offset), cs->nr_cores,
1bdc94
                                         eax, ebx, ecx, edx);
1bdc94
                     break;
1bdc94
                 }
1bdc94
@@ -3946,13 +3927,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1bdc94
                (L1_ITLB_2M_ASSOC <<  8) | (L1_ITLB_2M_ENTRIES);
1bdc94
         *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
1bdc94
                (L1_ITLB_4K_ASSOC <<  8) | (L1_ITLB_4K_ENTRIES);
1bdc94
-        if (env->cache_info && !cpu->legacy_cache) {
1bdc94
-            *ecx = encode_cache_cpuid80000005(&env->cache_info->l1d_cache);
1bdc94
-            *edx = encode_cache_cpuid80000005(&env->cache_info->l1i_cache);
1bdc94
-        } else {
1bdc94
-            *ecx = encode_cache_cpuid80000005(&legacy_l1d_cache_amd);
1bdc94
-            *edx = encode_cache_cpuid80000005(&legacy_l1i_cache_amd);
1bdc94
-        }
1bdc94
+        *ecx = encode_cache_cpuid80000005(env->cache_info_amd.l1d_cache);
1bdc94
+        *edx = encode_cache_cpuid80000005(env->cache_info_amd.l1i_cache);
1bdc94
         break;
1bdc94
     case 0x80000006:
1bdc94
         /* cache info (L2 cache) */
1bdc94
@@ -3968,17 +3944,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1bdc94
                (L2_DTLB_4K_ENTRIES << 16) | \
1bdc94
                (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
1bdc94
                (L2_ITLB_4K_ENTRIES);
1bdc94
-        if (env->cache_info && !cpu->legacy_cache) {
1bdc94
-            encode_cache_cpuid80000006(&env->cache_info->l2_cache,
1bdc94
-                                       cpu->enable_l3_cache ?
1bdc94
-                                       &env->cache_info->l3_cache : NULL,
1bdc94
-                                       ecx, edx);
1bdc94
-        } else {
1bdc94
-            encode_cache_cpuid80000006(&legacy_l2_cache_amd,
1bdc94
-                                       cpu->enable_l3_cache ?
1bdc94
-                                       &legacy_l3_cache : NULL,
1bdc94
-                                       ecx, edx);
1bdc94
-        }
1bdc94
+        encode_cache_cpuid80000006(env->cache_info_amd.l2_cache,
1bdc94
+                                   cpu->enable_l3_cache ?
1bdc94
+                                   env->cache_info_amd.l3_cache : NULL,
1bdc94
+                                   ecx, edx);
1bdc94
         break;
1bdc94
     case 0x80000007:
1bdc94
         *eax = 0;
1bdc94
@@ -4675,6 +4644,37 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
1bdc94
             cpu->phys_bits = 32;
1bdc94
         }
1bdc94
     }
1bdc94
+
1bdc94
+    /* Cache information initialization */
1bdc94
+    if (!cpu->legacy_cache) {
1bdc94
+        if (!xcc->cpu_def || !xcc->cpu_def->cache_info) {
1bdc94
+            char *name = x86_cpu_class_get_model_name(xcc);
1bdc94
+            error_setg(errp,
1bdc94
+                       "CPU model '%s' doesn't support legacy-cache=off", name);
1bdc94
+            g_free(name);
1bdc94
+            return;
1bdc94
+        }
1bdc94
+        env->cache_info_cpuid2 = env->cache_info_cpuid4 = env->cache_info_amd =
1bdc94
+            *xcc->cpu_def->cache_info;
1bdc94
+    } else {
1bdc94
+        /* Build legacy cache information */
1bdc94
+        env->cache_info_cpuid2.l1d_cache = &legacy_l1d_cache;
1bdc94
+        env->cache_info_cpuid2.l1i_cache = &legacy_l1i_cache;
1bdc94
+        env->cache_info_cpuid2.l2_cache = &legacy_l2_cache_cpuid2;
1bdc94
+        env->cache_info_cpuid2.l3_cache = &legacy_l3_cache;
1bdc94
+
1bdc94
+        env->cache_info_cpuid4.l1d_cache = &legacy_l1d_cache;
1bdc94
+        env->cache_info_cpuid4.l1i_cache = &legacy_l1i_cache;
1bdc94
+        env->cache_info_cpuid4.l2_cache = &legacy_l2_cache;
1bdc94
+        env->cache_info_cpuid4.l3_cache = &legacy_l3_cache;
1bdc94
+
1bdc94
+        env->cache_info_amd.l1d_cache = &legacy_l1d_cache_amd;
1bdc94
+        env->cache_info_amd.l1i_cache = &legacy_l1i_cache_amd;
1bdc94
+        env->cache_info_amd.l2_cache = &legacy_l2_cache_amd;
1bdc94
+        env->cache_info_amd.l3_cache = &legacy_l3_cache;
1bdc94
+    }
1bdc94
+
1bdc94
+
1bdc94
     cpu_exec_realizefn(cs, &local_err);
1bdc94
     if (local_err != NULL) {
1bdc94
         error_propagate(errp, local_err);
1bdc94
@@ -5159,11 +5159,10 @@ static Property x86_cpu_properties[] = {
1bdc94
     DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
1bdc94
     DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
1bdc94
     /*
1bdc94
-     * lecacy_cache defaults to CPU model being chosen. This is set in
1bdc94
-     * x86_cpu_load_def based on cache_info which is initialized in
1bdc94
-     * builtin_x86_defs
1bdc94
+     * lecacy_cache defaults to true unless the CPU model provides its
1bdc94
+     * own cache information (see x86_cpu_load_def()).
1bdc94
      */
1bdc94
-    DEFINE_PROP_BOOL("legacy-cache", X86CPU, legacy_cache, false),
1bdc94
+    DEFINE_PROP_BOOL("legacy-cache", X86CPU, legacy_cache, true),
1bdc94
 
1bdc94
     /*
1bdc94
      * From "Requirements for Implementing the Microsoft
1bdc94
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
1bdc94
index b01b0c1..c80c461 100644
1bdc94
--- a/target/i386/cpu.h
1bdc94
+++ b/target/i386/cpu.h
1bdc94
@@ -1099,10 +1099,10 @@ typedef struct CPUCacheInfo {
1bdc94
 
1bdc94
 
1bdc94
 typedef struct CPUCaches {
1bdc94
-        CPUCacheInfo l1d_cache;
1bdc94
-        CPUCacheInfo l1i_cache;
1bdc94
-        CPUCacheInfo l2_cache;
1bdc94
-        CPUCacheInfo l3_cache;
1bdc94
+        CPUCacheInfo *l1d_cache;
1bdc94
+        CPUCacheInfo *l1i_cache;
1bdc94
+        CPUCacheInfo *l2_cache;
1bdc94
+        CPUCacheInfo *l3_cache;
1bdc94
 } CPUCaches;
1bdc94
 
1bdc94
 typedef struct CPUX86State {
1bdc94
@@ -1291,7 +1291,11 @@ typedef struct CPUX86State {
1bdc94
     /* Features that were explicitly enabled/disabled */
1bdc94
     FeatureWordArray user_features;
1bdc94
     uint32_t cpuid_model[12];
1bdc94
-    CPUCaches *cache_info;
1bdc94
+    /* Cache information for CPUID.  When legacy-cache=on, the cache data
1bdc94
+     * on each CPUID leaf will be different, because we keep compatibility
1bdc94
+     * with old QEMU versions.
1bdc94
+     */
1bdc94
+    CPUCaches cache_info_cpuid2, cache_info_cpuid4, cache_info_amd;
1bdc94
 
1bdc94
     /* MTRRs */
1bdc94
     uint64_t mtrr_fixed[11];
1bdc94
-- 
1bdc94
1.8.3.1
1bdc94