// SPDX-License-Identifier: GPL-2.0
 /*
- *     Routines to identify caches on Intel CPU.
+ * x86 CPU caches detection and configuration
  *
- *     Changes:
- *     Venkatesh Pallipadi     : Adding cache identification through cpuid(4)
- *     Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
- *     Andi Kleen / Andreas Herrmann   : CPUID4 emulation on AMD.
+ * Previous changes
+ * - Venkatesh Pallipadi:              Cache identification through CPUID(4)
+ * - Ashok Raj <ashok.raj@intel.com>:  Work with CPU hotplug infrastructure
+ * - Andi Kleen / Andreas Herrmann:    CPUID(4) emulation on AMD
  */
 
 #include <linux/cacheinfo.h>
 unsigned int memory_caching_control __ro_after_init;
 
 enum _cache_type {
-       CTYPE_NULL = 0,
-       CTYPE_DATA = 1,
-       CTYPE_INST = 2,
-       CTYPE_UNIFIED = 3
+       CTYPE_NULL      = 0,
+       CTYPE_DATA      = 1,
+       CTYPE_INST      = 2,
+       CTYPE_UNIFIED   = 3
 };
 
 union _cpuid4_leaf_eax {
        struct {
-               enum _cache_type        type:5;
-               unsigned int            level:3;
-               unsigned int            is_self_initializing:1;
-               unsigned int            is_fully_associative:1;
-               unsigned int            reserved:4;
-               unsigned int            num_threads_sharing:12;
-               unsigned int            num_cores_on_die:6;
+               enum _cache_type        type                    :5;
+               unsigned int            level                   :3;
+               unsigned int            is_self_initializing    :1;
+               unsigned int            is_fully_associative    :1;
+               unsigned int            reserved                :4;
+               unsigned int            num_threads_sharing     :12;
+               unsigned int            num_cores_on_die        :6;
        } split;
        u32 full;
 };
 
 union _cpuid4_leaf_ebx {
        struct {
-               unsigned int            coherency_line_size:12;
-               unsigned int            physical_line_partition:10;
-               unsigned int            ways_of_associativity:10;
+               unsigned int            coherency_line_size     :12;
+               unsigned int            physical_line_partition :10;
+               unsigned int            ways_of_associativity   :10;
        } split;
        u32 full;
 };
 
 union _cpuid4_leaf_ecx {
        struct {
-               unsigned int            number_of_sets:32;
+               unsigned int            number_of_sets          :32;
        } split;
        u32 full;
 };
 
 union l1_cache {
        struct {
-               unsigned line_size:8;
-               unsigned lines_per_tag:8;
-               unsigned assoc:8;
-               unsigned size_in_kb:8;
+               unsigned line_size      :8;
+               unsigned lines_per_tag  :8;
+               unsigned assoc          :8;
+               unsigned size_in_kb     :8;
        };
-       unsigned val;
+       unsigned int val;
 };
 
 union l2_cache {
        struct {
-               unsigned line_size:8;
-               unsigned lines_per_tag:4;
-               unsigned assoc:4;
-               unsigned size_in_kb:16;
+               unsigned line_size      :8;
+               unsigned lines_per_tag  :4;
+               unsigned assoc          :4;
+               unsigned size_in_kb     :16;
        };
-       unsigned val;
+       unsigned int val;
 };
 
 union l3_cache {
        struct {
-               unsigned line_size:8;
-               unsigned lines_per_tag:4;
-               unsigned assoc:4;
-               unsigned res:2;
-               unsigned size_encoded:14;
+               unsigned line_size      :8;
+               unsigned lines_per_tag  :4;
+               unsigned assoc          :4;
+               unsigned res            :2;
+               unsigned size_encoded   :14;
        };
-       unsigned val;
+       unsigned int val;
 };
 
 static const unsigned short assocs[] = {
-       [1] = 1,
-       [2] = 2,
-       [4] = 4,
-       [6] = 8,
-       [8] = 16,
-       [0xa] = 32,
-       [0xb] = 48,
-       [0xc] = 64,
-       [0xd] = 96,
-       [0xe] = 128,
-       [0xf] = 0xffff /* fully associative - no way to show this currently */
+       [1]             = 1,
+       [2]             = 2,
+       [4]             = 4,
+       [6]             = 8,
+       [8]             = 16,
+       [0xa]           = 32,
+       [0xb]           = 48,
+       [0xc]           = 64,
+       [0xd]           = 96,
+       [0xe]           = 128,
+       [0xf]           = 0xffff        /* Fully associative */
 };
 
 static const unsigned char levels[] = { 1, 1, 2, 3 };
-static const unsigned char types[] = { 1, 2, 3, 3 };
+static const unsigned char types[]  = { 1, 2, 3, 3 };
 
 static void legacy_amd_cpuid4(int index, union _cpuid4_leaf_eax *eax,
                              union _cpuid4_leaf_ebx *ebx, union _cpuid4_leaf_ecx *ecx)
 {
        unsigned int dummy, line_size, lines_per_tag, assoc, size_in_kb;
-       union l1_cache l1i, l1d;
+       union l1_cache l1i, l1d, *l1;
        union l2_cache l2;
        union l3_cache l3;
-       union l1_cache *l1 = &l1d;
 
        eax->full = 0;
        ebx->full = 0;
        cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
        cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
 
+       l1 = &l1d;
        switch (index) {
        case 1:
                l1 = &l1i;
        case 0:
                if (!l1->val)
                        return;
-               assoc = assocs[l1->assoc];
-               line_size = l1->line_size;
-               lines_per_tag = l1->lines_per_tag;
-               size_in_kb = l1->size_in_kb;
+
+               assoc           = assocs[l1->assoc];
+               line_size       = l1->line_size;
+               lines_per_tag   = l1->lines_per_tag;
+               size_in_kb      = l1->size_in_kb;
                break;
        case 2:
                if (!l2.val)
                        return;
-               assoc = assocs[l2.assoc];
-               line_size = l2.line_size;
-               lines_per_tag = l2.lines_per_tag;
-               /* cpu_data has errata corrections for K7 applied */
-               size_in_kb = __this_cpu_read(cpu_info.x86_cache_size);
+
+               /* Use x86_cache_size as it might have K7 errata fixes */
+               assoc           = assocs[l2.assoc];
+               line_size       = l2.line_size;
+               lines_per_tag   = l2.lines_per_tag;
+               size_in_kb      = __this_cpu_read(cpu_info.x86_cache_size);
                break;
        case 3:
                if (!l3.val)
                        return;
-               assoc = assocs[l3.assoc];
-               line_size = l3.line_size;
-               lines_per_tag = l3.lines_per_tag;
-               size_in_kb = l3.size_encoded * 512;
+
+               assoc           = assocs[l3.assoc];
+               line_size       = l3.line_size;
+               lines_per_tag   = l3.lines_per_tag;
+               size_in_kb      = l3.size_encoded * 512;
                if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
-                       size_in_kb = size_in_kb >> 1;
-                       assoc = assoc >> 1;
+                       size_in_kb      = size_in_kb >> 1;
+                       assoc           = assoc >> 1;
                }
                break;
        default:
                return;
        }
 
-       eax->split.is_self_initializing = 1;
-       eax->split.type = types[index];
-       eax->split.level = levels[index];
-       eax->split.num_threads_sharing = 0;
-       eax->split.num_cores_on_die = topology_num_cores_per_package();
+       eax->split.is_self_initializing         = 1;
+       eax->split.type                         = types[index];
+       eax->split.level                        = levels[index];
+       eax->split.num_threads_sharing          = 0;
+       eax->split.num_cores_on_die             = topology_num_cores_per_package();
 
        if (assoc == 0xffff)
                eax->split.is_fully_associative = 1;
-       ebx->split.coherency_line_size = line_size - 1;
-       ebx->split.ways_of_associativity = assoc - 1;
-       ebx->split.physical_line_partition = lines_per_tag - 1;
-       ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
+
+       ebx->split.coherency_line_size          = line_size - 1;
+       ebx->split.ways_of_associativity        = assoc - 1;
+       ebx->split.physical_line_partition      = lines_per_tag - 1;
+       ecx->split.number_of_sets               = (size_in_kb * 1024) / line_size /
                (ebx->split.ways_of_associativity + 1) - 1;
 }
 
 
 static int find_num_cache_leaves(struct cpuinfo_x86 *c)
 {
-       unsigned int            eax, ebx, ecx, edx, op;
-       union _cpuid4_leaf_eax  cache_eax;
-       int                     i = -1;
-
-       if (c->x86_vendor == X86_VENDOR_AMD ||
-           c->x86_vendor == X86_VENDOR_HYGON)
-               op = 0x8000001d;
-       else
-               op = 4;
+       unsigned int eax, ebx, ecx, edx, op;
+       union _cpuid4_leaf_eax cache_eax;
+       int i = -1;
 
+       /* Do a CPUID(op) loop to calculate num_cache_leaves */
+       op = (c->x86_vendor == X86_VENDOR_AMD || c->x86_vendor == X86_VENDOR_HYGON) ? 0x8000001d : 4;
        do {
                ++i;
-               /* Do cpuid(op) loop to find out num_cache_leaves */
                cpuid_count(op, i, &eax, &ebx, &ecx, &edx);
                cache_eax.full = eax;
        } while (cache_eax.split.type != CTYPE_NULL);
                        num_sharing_cache = ((eax >> 14) & 0xfff) + 1;
 
                if (num_sharing_cache) {
-                       int bits = get_count_order(num_sharing_cache);
+                       int index_msb = get_count_order(num_sharing_cache);
 
-                       c->topo.llc_id = c->topo.apicid >> bits;
+                       c->topo.llc_id = c->topo.apicid >> index_msb;
                }
        }
 }
 {
        struct cpu_cacheinfo *ci = get_cpu_cacheinfo(c->cpu_index);
 
-       if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
+       if (boot_cpu_has(X86_FEATURE_TOPOEXT))
                ci->num_leaves = find_num_cache_leaves(c);
-       } else if (c->extended_cpuid_level >= 0x80000006) {
-               if (cpuid_edx(0x80000006) & 0xf000)
-                       ci->num_leaves = 4;
-               else
-                       ci->num_leaves = 3;
-       }
+       else if (c->extended_cpuid_level >= 0x80000006)
+               ci->num_leaves = (cpuid_edx(0x80000006) & 0xf000) ? 4 : 3;
 }
 
 void init_hygon_cacheinfo(struct cpuinfo_x86 *c)
        intel_cacheinfo_0x2(c);
 }
 
+/*
+ * linux/cacheinfo.h shared_cpu_map setup, AMD/Hygon
+ */
 static int __cache_amd_cpumap_setup(unsigned int cpu, int index,
                                    const struct _cpuid4_info *id4)
 {
                        this_cpu_ci = get_cpu_cacheinfo(i);
                        if (!this_cpu_ci->info_list)
                                continue;
+
                        ci = this_cpu_ci->info_list + index;
                        for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) {
                                if (!cpu_online(sibling))
                                        continue;
-                               cpumask_set_cpu(sibling,
-                                               &ci->shared_cpu_map);
+                               cpumask_set_cpu(sibling, &ci->shared_cpu_map);
                        }
                }
        } else if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
                                apicid = cpu_data(sibling).topo.apicid;
                                if ((apicid < first) || (apicid > last))
                                        continue;
-                               cpumask_set_cpu(sibling,
-                                               &ci->shared_cpu_map);
+                               cpumask_set_cpu(sibling, &ci->shared_cpu_map);
                        }
                }
        } else
        return 1;
 }
 
+/*
+ * linux/cacheinfo.h shared_cpu_map setup, Intel + fallback AMD/Hygon
+ */
 static void __cache_cpumap_setup(unsigned int cpu, int index,
                                 const struct _cpuid4_info *id4)
 {
        struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
        struct cacheinfo *ci, *sibling_ci;
        unsigned long num_threads_sharing;
        int index_msb, i;
-       struct cpuinfo_x86 *c = &cpu_data(cpu);
 
-       if (c->x86_vendor == X86_VENDOR_AMD ||
-           c->x86_vendor == X86_VENDOR_HYGON) {
+       if (c->x86_vendor == X86_VENDOR_AMD || c->x86_vendor == X86_VENDOR_HYGON) {
                if (__cache_amd_cpumap_setup(cpu, index, id4))
                        return;
        }
                if (cpu_data(i).topo.apicid >> index_msb == c->topo.apicid >> index_msb) {
                        struct cpu_cacheinfo *sib_cpu_ci = get_cpu_cacheinfo(i);
 
+                       /* Skip if itself or no cacheinfo */
                        if (i == cpu || !sib_cpu_ci->info_list)
-                               continue;/* skip if itself or no cacheinfo */
+                               continue;
+
                        sibling_ci = sib_cpu_ci->info_list + index;
                        cpumask_set_cpu(i, &ci->shared_cpu_map);
                        cpumask_set_cpu(cpu, &sibling_ci->shared_cpu_map);
 }
 
 /*
- * The max shared threads number comes from CPUID.4:EAX[25-14] with input
+ * The max shared threads number comes from CPUID(4) EAX[25-14] with input
  * ECX as cache index. Then right shift apicid by the number's order to get
  * cache id for this cache node.
  */
                ci_info_init(ci++, &id4, nb);
                __cache_cpumap_setup(cpu, idx, &id4);
        }
-       this_cpu_ci->cpu_map_populated = true;
 
+       this_cpu_ci->cpu_map_populated = true;
        return 0;
 }
 
        unsigned long cr0;
 
        /*
-        * Note that this is not ideal
-        * since the cache is only flushed/disabled for this CPU while the
-        * MTRRs are changed, but changing this requires more invasive
-        * changes to the way the kernel boots
+        * This is not ideal since the cache is only flushed/disabled
+        * for this CPU while the MTRRs are changed, but changing this
+        * requires more invasive changes to the way the kernel boots.
         */
-
        raw_spin_lock(&cache_disable_lock);
 
        /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */