From: Bhavna Sarathy <bnagendr@redhat.com> Date: Tue, 22 Sep 2009 16:11:06 -0400 Subject: [x86] fix up L3 cache information for AMD Magny-cours Message-id: <20090922161302.7053.39434.sendpatchset@localhost.localdomain> Patchwork-id: 20918 O-Subject: [RHEL5.5 PATCH 2/3] Fix up L3 cache information for AMD Magny-cours Bugzilla: 513684 RH-Acked-by: Christopher Lalancette <clalance@redhat.com> RH-Acked-by: Prarit Bhargava <prarit@redhat.com> Resolves BZ 513684 Fixup L3 cache information for AMD multi-node processors. diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index d0c85d6..9b2b307 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -204,14 +204,14 @@ static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, case 0: if (!l1->val) return; - assoc = l1->assoc; + assoc = assocs[l1->assoc]; line_size = l1->line_size; lines_per_tag = l1->lines_per_tag; size_in_kb = l1->size_in_kb; case 2: if (!l2.val) return; - assoc = l2.assoc; + assoc = assocs[l2.assoc]; line_size = l2.line_size; lines_per_tag = l2.lines_per_tag; /* cpu_data has errata corrections for K7 applied */ @@ -220,7 +220,7 @@ static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, case 3: if (!l3.val) return; - assoc = l3.assoc; + assoc = assocs[l3.assoc]; line_size = l3.line_size; lines_per_tag = l3.lines_per_tag; switch (l3.size_encoded) { @@ -229,6 +229,10 @@ static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, case 12: size_in_kb = 6 * 1024; break; default: size_in_kb = 0; break; } + if (boot_cpu_has(X86_FEATURE_AMD_DCM)) { + size_in_kb = size_in_kb >> 1; + assoc = assoc >> 1; + } break; default: return; @@ -241,10 +245,10 @@ static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1; - if (assoc == 0xf) + if (assoc == 0xffff) eax->split.is_fully_associative = 1; ebx->split.coherency_line_size = line_size - 1; - ebx->split.ways_of_associativity = assocs[assoc] - 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; @@ -463,6 +467,16 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) int index_msb, i; struct cpuinfo_x86 *c = cpu_data; + if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) { + for_each_online_cpu(i) { + if (cpuid4_info[i] == NULL) + continue; + this_leaf = CPUID4_INFO_IDX(i, index); + this_leaf->shared_cpu_map = c[i].llc_shared_map; + } + return; + } + this_leaf = CPUID4_INFO_IDX(cpu, index); num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;