Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[sfrench/cifs-2.6.git] / arch / x86 / events / amd / uncore.c
index ad44af0dd6679b50ce2c48bf37b56959b967c3cb..f5cbbba992833af251e750a1d64a120e9f46368d 100644 (file)
@@ -400,11 +400,24 @@ static int amd_uncore_cpu_starting(unsigned int cpu)
 
        if (amd_uncore_llc) {
                unsigned int apicid = cpu_data(cpu).apicid;
-               unsigned int nshared;
+               unsigned int nshared, subleaf, prev_eax = 0;
 
                uncore = *per_cpu_ptr(amd_uncore_llc, cpu);
-               cpuid_count(0x8000001d, 2, &eax, &ebx, &ecx, &edx);
-               nshared = ((eax >> 14) & 0xfff) + 1;
+               /*
+                * Iterate over Cache Topology Definition leaves until no
+                * more cache descriptions are available.
+                */
+               for (subleaf = 0; subleaf < 5; subleaf++) {
+                       cpuid_count(0x8000001d, subleaf, &eax, &ebx, &ecx, &edx);
+
+                       /* EAX[0:4] gives type of cache */
+                       if (!(eax & 0x1f))
+                               break;
+
+                       prev_eax = eax;
+               }
+               nshared = ((prev_eax >> 14) & 0xfff) + 1;
+
                uncore->id = apicid - (apicid % nshared);
 
                uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_llc);
@@ -555,7 +568,7 @@ static int __init amd_uncore_init(void)
                ret = 0;
        }
 
-       if (boot_cpu_has(X86_FEATURE_PERFCTR_L2)) {
+       if (boot_cpu_has(X86_FEATURE_PERFCTR_LLC)) {
                amd_uncore_llc = alloc_percpu(struct amd_uncore *);
                if (!amd_uncore_llc) {
                        ret = -ENOMEM;