linux/arch/x86/kernel/cpu/intel_cacheinfo.c
<<
>>
Prefs
   1/*
   2 *      Routines to indentify caches on Intel CPU.
   3 *
   4 *      Changes:
   5 *      Venkatesh Pallipadi     : Adding cache identification through cpuid(4)
   6 *      Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
   7 *      Andi Kleen / Andreas Herrmann   : CPUID4 emulation on AMD.
   8 */
   9
  10#include <linux/init.h>
  11#include <linux/slab.h>
  12#include <linux/device.h>
  13#include <linux/compiler.h>
  14#include <linux/cpu.h>
  15#include <linux/sched.h>
  16#include <linux/pci.h>
  17
  18#include <asm/processor.h>
  19#include <linux/smp.h>
  20#include <asm/k8.h>
  21
  22#define LVL_1_INST      1
  23#define LVL_1_DATA      2
  24#define LVL_2           3
  25#define LVL_3           4
  26#define LVL_TRACE       5
  27
  28struct _cache_table {
  29        unsigned char descriptor;
  30        char cache_type;
  31        short size;
  32};
  33
  34/* All the cache descriptor types we care about (no TLB or
  35   trace cache entries) */
  36
  37static const struct _cache_table __cpuinitconst cache_table[] =
  38{
  39        { 0x06, LVL_1_INST, 8 },        /* 4-way set assoc, 32 byte line size */
  40        { 0x08, LVL_1_INST, 16 },       /* 4-way set assoc, 32 byte line size */
  41        { 0x09, LVL_1_INST, 32 },       /* 4-way set assoc, 64 byte line size */
  42        { 0x0a, LVL_1_DATA, 8 },        /* 2 way set assoc, 32 byte line size */
  43        { 0x0c, LVL_1_DATA, 16 },       /* 4-way set assoc, 32 byte line size */
  44        { 0x0d, LVL_1_DATA, 16 },       /* 4-way set assoc, 64 byte line size */
  45        { 0x21, LVL_2,      256 },      /* 8-way set assoc, 64 byte line size */
  46        { 0x22, LVL_3,      512 },      /* 4-way set assoc, sectored cache, 64 byte line size */
  47        { 0x23, LVL_3,      1024 },     /* 8-way set assoc, sectored cache, 64 byte line size */
  48        { 0x25, LVL_3,      2048 },     /* 8-way set assoc, sectored cache, 64 byte line size */
  49        { 0x29, LVL_3,      4096 },     /* 8-way set assoc, sectored cache, 64 byte line size */
  50        { 0x2c, LVL_1_DATA, 32 },       /* 8-way set assoc, 64 byte line size */
  51        { 0x30, LVL_1_INST, 32 },       /* 8-way set assoc, 64 byte line size */
  52        { 0x39, LVL_2,      128 },      /* 4-way set assoc, sectored cache, 64 byte line size */
  53        { 0x3a, LVL_2,      192 },      /* 6-way set assoc, sectored cache, 64 byte line size */
  54        { 0x3b, LVL_2,      128 },      /* 2-way set assoc, sectored cache, 64 byte line size */
  55        { 0x3c, LVL_2,      256 },      /* 4-way set assoc, sectored cache, 64 byte line size */
  56        { 0x3d, LVL_2,      384 },      /* 6-way set assoc, sectored cache, 64 byte line size */
  57        { 0x3e, LVL_2,      512 },      /* 4-way set assoc, sectored cache, 64 byte line size */
  58        { 0x3f, LVL_2,      256 },      /* 2-way set assoc, 64 byte line size */
  59        { 0x41, LVL_2,      128 },      /* 4-way set assoc, 32 byte line size */
  60        { 0x42, LVL_2,      256 },      /* 4-way set assoc, 32 byte line size */
  61        { 0x43, LVL_2,      512 },      /* 4-way set assoc, 32 byte line size */
  62        { 0x44, LVL_2,      1024 },     /* 4-way set assoc, 32 byte line size */
  63        { 0x45, LVL_2,      2048 },     /* 4-way set assoc, 32 byte line size */
  64        { 0x46, LVL_3,      4096 },     /* 4-way set assoc, 64 byte line size */
  65        { 0x47, LVL_3,      8192 },     /* 8-way set assoc, 64 byte line size */
  66        { 0x49, LVL_3,      4096 },     /* 16-way set assoc, 64 byte line size */
  67        { 0x4a, LVL_3,      6144 },     /* 12-way set assoc, 64 byte line size */
  68        { 0x4b, LVL_3,      8192 },     /* 16-way set assoc, 64 byte line size */
  69        { 0x4c, LVL_3,     12288 },     /* 12-way set assoc, 64 byte line size */
  70        { 0x4d, LVL_3,     16384 },     /* 16-way set assoc, 64 byte line size */
  71        { 0x4e, LVL_2,      6144 },     /* 24-way set assoc, 64 byte line size */
  72        { 0x60, LVL_1_DATA, 16 },       /* 8-way set assoc, sectored cache, 64 byte line size */
  73        { 0x66, LVL_1_DATA, 8 },        /* 4-way set assoc, sectored cache, 64 byte line size */
  74        { 0x67, LVL_1_DATA, 16 },       /* 4-way set assoc, sectored cache, 64 byte line size */
  75        { 0x68, LVL_1_DATA, 32 },       /* 4-way set assoc, sectored cache, 64 byte line size */
  76        { 0x70, LVL_TRACE,  12 },       /* 8-way set assoc */
  77        { 0x71, LVL_TRACE,  16 },       /* 8-way set assoc */
  78        { 0x72, LVL_TRACE,  32 },       /* 8-way set assoc */
  79        { 0x73, LVL_TRACE,  64 },       /* 8-way set assoc */
  80        { 0x78, LVL_2,    1024 },       /* 4-way set assoc, 64 byte line size */
  81        { 0x79, LVL_2,     128 },       /* 8-way set assoc, sectored cache, 64 byte line size */
  82        { 0x7a, LVL_2,     256 },       /* 8-way set assoc, sectored cache, 64 byte line size */
  83        { 0x7b, LVL_2,     512 },       /* 8-way set assoc, sectored cache, 64 byte line size */
  84        { 0x7c, LVL_2,    1024 },       /* 8-way set assoc, sectored cache, 64 byte line size */
  85        { 0x7d, LVL_2,    2048 },       /* 8-way set assoc, 64 byte line size */
  86        { 0x7f, LVL_2,     512 },       /* 2-way set assoc, 64 byte line size */
  87        { 0x82, LVL_2,     256 },       /* 8-way set assoc, 32 byte line size */
  88        { 0x83, LVL_2,     512 },       /* 8-way set assoc, 32 byte line size */
  89        { 0x84, LVL_2,    1024 },       /* 8-way set assoc, 32 byte line size */
  90        { 0x85, LVL_2,    2048 },       /* 8-way set assoc, 32 byte line size */
  91        { 0x86, LVL_2,     512 },       /* 4-way set assoc, 64 byte line size */
  92        { 0x87, LVL_2,    1024 },       /* 8-way set assoc, 64 byte line size */
  93        { 0xd0, LVL_3,     512 },       /* 4-way set assoc, 64 byte line size */
  94        { 0xd1, LVL_3,    1024 },       /* 4-way set assoc, 64 byte line size */
  95        { 0xd2, LVL_3,    2048 },       /* 4-way set assoc, 64 byte line size */
  96        { 0xd6, LVL_3,    1024 },       /* 8-way set assoc, 64 byte line size */
  97        { 0xd7, LVL_3,    2038 },       /* 8-way set assoc, 64 byte line size */
  98        { 0xd8, LVL_3,    4096 },       /* 12-way set assoc, 64 byte line size */
  99        { 0xdc, LVL_3,    2048 },       /* 12-way set assoc, 64 byte line size */
 100        { 0xdd, LVL_3,    4096 },       /* 12-way set assoc, 64 byte line size */
 101        { 0xde, LVL_3,    8192 },       /* 12-way set assoc, 64 byte line size */
 102        { 0xe2, LVL_3,    2048 },       /* 16-way set assoc, 64 byte line size */
 103        { 0xe3, LVL_3,    4096 },       /* 16-way set assoc, 64 byte line size */
 104        { 0xe4, LVL_3,    8192 },       /* 16-way set assoc, 64 byte line size */
 105        { 0x00, 0, 0}
 106};
 107
 108
 109enum _cache_type {
 110        CACHE_TYPE_NULL = 0,
 111        CACHE_TYPE_DATA = 1,
 112        CACHE_TYPE_INST = 2,
 113        CACHE_TYPE_UNIFIED = 3
 114};
 115
 116union _cpuid4_leaf_eax {
 117        struct {
 118                enum _cache_type        type:5;
 119                unsigned int            level:3;
 120                unsigned int            is_self_initializing:1;
 121                unsigned int            is_fully_associative:1;
 122                unsigned int            reserved:4;
 123                unsigned int            num_threads_sharing:12;
 124                unsigned int            num_cores_on_die:6;
 125        } split;
 126        u32 full;
 127};
 128
 129union _cpuid4_leaf_ebx {
 130        struct {
 131                unsigned int            coherency_line_size:12;
 132                unsigned int            physical_line_partition:10;
 133                unsigned int            ways_of_associativity:10;
 134        } split;
 135        u32 full;
 136};
 137
 138union _cpuid4_leaf_ecx {
 139        struct {
 140                unsigned int            number_of_sets:32;
 141        } split;
 142        u32 full;
 143};
 144
 145struct _cpuid4_info {
 146        union _cpuid4_leaf_eax eax;
 147        union _cpuid4_leaf_ebx ebx;
 148        union _cpuid4_leaf_ecx ecx;
 149        unsigned long size;
 150        unsigned long can_disable;
 151        DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
 152};
 153
 154/* subset of above _cpuid4_info w/o shared_cpu_map */
 155struct _cpuid4_info_regs {
 156        union _cpuid4_leaf_eax eax;
 157        union _cpuid4_leaf_ebx ebx;
 158        union _cpuid4_leaf_ecx ecx;
 159        unsigned long size;
 160        unsigned long can_disable;
 161};
 162
 163unsigned short                  num_cache_leaves;
 164
 165/* AMD doesn't have CPUID4. Emulate it here to report the same
 166   information to the user.  This makes some assumptions about the machine:
 167   L2 not shared, no SMT etc. that is currently true on AMD CPUs.
 168
 169   In theory the TLBs could be reported as fake type (they are in "dummy").
 170   Maybe later */
 171union l1_cache {
 172        struct {
 173                unsigned line_size:8;
 174                unsigned lines_per_tag:8;
 175                unsigned assoc:8;
 176                unsigned size_in_kb:8;
 177        };
 178        unsigned val;
 179};
 180
 181union l2_cache {
 182        struct {
 183                unsigned line_size:8;
 184                unsigned lines_per_tag:4;
 185                unsigned assoc:4;
 186                unsigned size_in_kb:16;
 187        };
 188        unsigned val;
 189};
 190
 191union l3_cache {
 192        struct {
 193                unsigned line_size:8;
 194                unsigned lines_per_tag:4;
 195                unsigned assoc:4;
 196                unsigned res:2;
 197                unsigned size_encoded:14;
 198        };
 199        unsigned val;
 200};
 201
 202static const unsigned short __cpuinitconst assocs[] = {
 203        [1] = 1,
 204        [2] = 2,
 205        [4] = 4,
 206        [6] = 8,
 207        [8] = 16,
 208        [0xa] = 32,
 209        [0xb] = 48,
 210        [0xc] = 64,
 211        [0xd] = 96,
 212        [0xe] = 128,
 213        [0xf] = 0xffff /* fully associative - no way to show this currently */
 214};
 215
 216static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 };
 217static const unsigned char __cpuinitconst types[] = { 1, 2, 3, 3 };
 218
 219static void __cpuinit
 220amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
 221                     union _cpuid4_leaf_ebx *ebx,
 222                     union _cpuid4_leaf_ecx *ecx)
 223{
 224        unsigned dummy;
 225        unsigned line_size, lines_per_tag, assoc, size_in_kb;
 226        union l1_cache l1i, l1d;
 227        union l2_cache l2;
 228        union l3_cache l3;
 229        union l1_cache *l1 = &l1d;
 230
 231        eax->full = 0;
 232        ebx->full = 0;
 233        ecx->full = 0;
 234
 235        cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
 236        cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
 237
 238        switch (leaf) {
 239        case 1:
 240                l1 = &l1i;
 241        case 0:
 242                if (!l1->val)
 243                        return;
 244                assoc = assocs[l1->assoc];
 245                line_size = l1->line_size;
 246                lines_per_tag = l1->lines_per_tag;
 247                size_in_kb = l1->size_in_kb;
 248                break;
 249        case 2:
 250                if (!l2.val)
 251                        return;
 252                assoc = assocs[l2.assoc];
 253                line_size = l2.line_size;
 254                lines_per_tag = l2.lines_per_tag;
 255                /* cpu_data has errata corrections for K7 applied */
 256                size_in_kb = current_cpu_data.x86_cache_size;
 257                break;
 258        case 3:
 259                if (!l3.val)
 260                        return;
 261                assoc = assocs[l3.assoc];
 262                line_size = l3.line_size;
 263                lines_per_tag = l3.lines_per_tag;
 264                size_in_kb = l3.size_encoded * 512;
 265                if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
 266                        size_in_kb = size_in_kb >> 1;
 267                        assoc = assoc >> 1;
 268                }
 269                break;
 270        default:
 271                return;
 272        }
 273
 274        eax->split.is_self_initializing = 1;
 275        eax->split.type = types[leaf];
 276        eax->split.level = levels[leaf];
 277        eax->split.num_threads_sharing = 0;
 278        eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
 279
 280
 281        if (assoc == 0xffff)
 282                eax->split.is_fully_associative = 1;
 283        ebx->split.coherency_line_size = line_size - 1;
 284        ebx->split.ways_of_associativity = assoc - 1;
 285        ebx->split.physical_line_partition = lines_per_tag - 1;
 286        ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
 287                (ebx->split.ways_of_associativity + 1) - 1;
 288}
 289
 290static void __cpuinit
 291amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
 292{
 293        if (index < 3)
 294                return;
 295
 296        if (boot_cpu_data.x86 == 0x11)
 297                return;
 298
 299        /* see erratum #382 */
 300        if ((boot_cpu_data.x86 == 0x10) && (boot_cpu_data.x86_model < 0x8))
 301                return;
 302
 303        this_leaf->can_disable = 1;
 304}
 305
 306static int
 307__cpuinit cpuid4_cache_lookup_regs(int index,
 308                                   struct _cpuid4_info_regs *this_leaf)
 309{
 310        union _cpuid4_leaf_eax  eax;
 311        union _cpuid4_leaf_ebx  ebx;
 312        union _cpuid4_leaf_ecx  ecx;
 313        unsigned                edx;
 314
 315        if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
 316                amd_cpuid4(index, &eax, &ebx, &ecx);
 317                if (boot_cpu_data.x86 >= 0x10)
 318                        amd_check_l3_disable(index, this_leaf);
 319        } else {
 320                cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
 321        }
 322
 323        if (eax.split.type == CACHE_TYPE_NULL)
 324                return -EIO; /* better error ? */
 325
 326        this_leaf->eax = eax;
 327        this_leaf->ebx = ebx;
 328        this_leaf->ecx = ecx;
 329        this_leaf->size = (ecx.split.number_of_sets          + 1) *
 330                          (ebx.split.coherency_line_size     + 1) *
 331                          (ebx.split.physical_line_partition + 1) *
 332                          (ebx.split.ways_of_associativity   + 1);
 333        return 0;
 334}
 335
 336static int __cpuinit find_num_cache_leaves(void)
 337{
 338        unsigned int            eax, ebx, ecx, edx;
 339        union _cpuid4_leaf_eax  cache_eax;
 340        int                     i = -1;
 341
 342        do {
 343                ++i;
 344                /* Do cpuid(4) loop to find out num_cache_leaves */
 345                cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
 346                cache_eax.full = eax;
 347        } while (cache_eax.split.type != CACHE_TYPE_NULL);
 348        return i;
 349}
 350
 351unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 352{
 353        /* Cache sizes */
 354        unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0;
 355        unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
 356        unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
 357        unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
 358#ifdef CONFIG_X86_HT
 359        unsigned int cpu = c->cpu_index;
 360#endif
 361
 362        if (c->cpuid_level > 3) {
 363                static int is_initialized;
 364
 365                if (is_initialized == 0) {
 366                        /* Init num_cache_leaves from boot CPU */
 367                        num_cache_leaves = find_num_cache_leaves();
 368                        is_initialized++;
 369                }
 370
 371                /*
 372                 * Whenever possible use cpuid(4), deterministic cache
 373                 * parameters cpuid leaf to find the cache details
 374                 */
 375                for (i = 0; i < num_cache_leaves; i++) {
 376                        struct _cpuid4_info_regs this_leaf;
 377                        int retval;
 378
 379                        retval = cpuid4_cache_lookup_regs(i, &this_leaf);
 380                        if (retval >= 0) {
 381                                switch (this_leaf.eax.split.level) {
 382                                case 1:
 383                                        if (this_leaf.eax.split.type ==
 384                                                        CACHE_TYPE_DATA)
 385                                                new_l1d = this_leaf.size/1024;
 386                                        else if (this_leaf.eax.split.type ==
 387                                                        CACHE_TYPE_INST)
 388                                                new_l1i = this_leaf.size/1024;
 389                                        break;
 390                                case 2:
 391                                        new_l2 = this_leaf.size/1024;
 392                                        num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
 393                                        index_msb = get_count_order(num_threads_sharing);
 394                                        l2_id = c->apicid >> index_msb;
 395                                        break;
 396                                case 3:
 397                                        new_l3 = this_leaf.size/1024;
 398                                        num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
 399                                        index_msb = get_count_order(
 400                                                        num_threads_sharing);
 401                                        l3_id = c->apicid >> index_msb;
 402                                        break;
 403                                default:
 404                                        break;
 405                                }
 406                        }
 407                }
 408        }
 409        /*
 410         * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
 411         * trace cache
 412         */
 413        if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
 414                /* supports eax=2  call */
 415                int j, n;
 416                unsigned int regs[4];
 417                unsigned char *dp = (unsigned char *)regs;
 418                int only_trace = 0;
 419
 420                if (num_cache_leaves != 0 && c->x86 == 15)
 421                        only_trace = 1;
 422
 423                /* Number of times to iterate */
 424                n = cpuid_eax(2) & 0xFF;
 425
 426                for (i = 0 ; i < n ; i++) {
 427                        cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
 428
 429                        /* If bit 31 is set, this is an unknown format */
 430                        for (j = 0 ; j < 3 ; j++)
 431                                if (regs[j] & (1 << 31))
 432                                        regs[j] = 0;
 433
 434                        /* Byte 0 is level count, not a descriptor */
 435                        for (j = 1 ; j < 16 ; j++) {
 436                                unsigned char des = dp[j];
 437                                unsigned char k = 0;
 438
 439                                /* look up this descriptor in the table */
 440                                while (cache_table[k].descriptor != 0) {
 441                                        if (cache_table[k].descriptor == des) {
 442                                                if (only_trace && cache_table[k].cache_type != LVL_TRACE)
 443                                                        break;
 444                                                switch (cache_table[k].cache_type) {
 445                                                case LVL_1_INST:
 446                                                        l1i += cache_table[k].size;
 447                                                        break;
 448                                                case LVL_1_DATA:
 449                                                        l1d += cache_table[k].size;
 450                                                        break;
 451                                                case LVL_2:
 452                                                        l2 += cache_table[k].size;
 453                                                        break;
 454                                                case LVL_3:
 455                                                        l3 += cache_table[k].size;
 456                                                        break;
 457                                                case LVL_TRACE:
 458                                                        trace += cache_table[k].size;
 459                                                        break;
 460                                                }
 461
 462                                                break;
 463                                        }
 464
 465                                        k++;
 466                                }
 467                        }
 468                }
 469        }
 470
 471        if (new_l1d)
 472                l1d = new_l1d;
 473
 474        if (new_l1i)
 475                l1i = new_l1i;
 476
 477        if (new_l2) {
 478                l2 = new_l2;
 479#ifdef CONFIG_X86_HT
 480                per_cpu(cpu_llc_id, cpu) = l2_id;
 481#endif
 482        }
 483
 484        if (new_l3) {
 485                l3 = new_l3;
 486#ifdef CONFIG_X86_HT
 487                per_cpu(cpu_llc_id, cpu) = l3_id;
 488#endif
 489        }
 490
 491        if (trace)
 492                printk(KERN_INFO "CPU: Trace cache: %dK uops", trace);
 493        else if (l1i)
 494                printk(KERN_INFO "CPU: L1 I cache: %dK", l1i);
 495
 496        if (l1d)
 497                printk(KERN_CONT ", L1 D cache: %dK\n", l1d);
 498        else
 499                printk(KERN_CONT "\n");
 500
 501        if (l2)
 502                printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
 503
 504        if (l3)
 505                printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
 506
 507        c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
 508
 509        return l2;
 510}
 511
 512#ifdef CONFIG_SYSFS
 513
 514/* pointer to _cpuid4_info array (for each cache leaf) */
 515static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
 516#define CPUID4_INFO_IDX(x, y)   (&((per_cpu(cpuid4_info, x))[y]))
 517
 518#ifdef CONFIG_SMP
 519static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
 520{
 521        struct _cpuid4_info     *this_leaf, *sibling_leaf;
 522        unsigned long num_threads_sharing;
 523        int index_msb, i;
 524        struct cpuinfo_x86 *c = &cpu_data(cpu);
 525
 526        if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
 527                struct cpuinfo_x86 *d;
 528                for_each_online_cpu(i) {
 529                        if (!per_cpu(cpuid4_info, i))
 530                                continue;
 531                        d = &cpu_data(i);
 532                        this_leaf = CPUID4_INFO_IDX(i, index);
 533                        cpumask_copy(to_cpumask(this_leaf->shared_cpu_map),
 534                                     d->llc_shared_map);
 535                }
 536                return;
 537        }
 538        this_leaf = CPUID4_INFO_IDX(cpu, index);
 539        num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
 540
 541        if (num_threads_sharing == 1)
 542                cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
 543        else {
 544                index_msb = get_count_order(num_threads_sharing);
 545
 546                for_each_online_cpu(i) {
 547                        if (cpu_data(i).apicid >> index_msb ==
 548                            c->apicid >> index_msb) {
 549                                cpumask_set_cpu(i,
 550                                        to_cpumask(this_leaf->shared_cpu_map));
 551                                if (i != cpu && per_cpu(cpuid4_info, i))  {
 552                                        sibling_leaf =
 553                                                CPUID4_INFO_IDX(i, index);
 554                                        cpumask_set_cpu(cpu, to_cpumask(
 555                                                sibling_leaf->shared_cpu_map));
 556                                }
 557                        }
 558                }
 559        }
 560}
 561static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
 562{
 563        struct _cpuid4_info     *this_leaf, *sibling_leaf;
 564        int sibling;
 565
 566        this_leaf = CPUID4_INFO_IDX(cpu, index);
 567        for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) {
 568                sibling_leaf = CPUID4_INFO_IDX(sibling, index);
 569                cpumask_clear_cpu(cpu,
 570                                  to_cpumask(sibling_leaf->shared_cpu_map));
 571        }
 572}
 573#else
 574static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
 575{
 576}
 577
 578static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
 579{
 580}
 581#endif
 582
 583static void __cpuinit free_cache_attributes(unsigned int cpu)
 584{
 585        int i;
 586
 587        for (i = 0; i < num_cache_leaves; i++)
 588                cache_remove_shared_cpu_map(cpu, i);
 589
 590        kfree(per_cpu(cpuid4_info, cpu));
 591        per_cpu(cpuid4_info, cpu) = NULL;
 592}
 593
 594static int
 595__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
 596{
 597        struct _cpuid4_info_regs *leaf_regs =
 598                (struct _cpuid4_info_regs *)this_leaf;
 599
 600        return cpuid4_cache_lookup_regs(index, leaf_regs);
 601}
 602
 603static void __cpuinit get_cpu_leaves(void *_retval)
 604{
 605        int j, *retval = _retval, cpu = smp_processor_id();
 606
 607        /* Do cpuid and store the results */
 608        for (j = 0; j < num_cache_leaves; j++) {
 609                struct _cpuid4_info *this_leaf;
 610                this_leaf = CPUID4_INFO_IDX(cpu, j);
 611                *retval = cpuid4_cache_lookup(j, this_leaf);
 612                if (unlikely(*retval < 0)) {
 613                        int i;
 614
 615                        for (i = 0; i < j; i++)
 616                                cache_remove_shared_cpu_map(cpu, i);
 617                        break;
 618                }
 619                cache_shared_cpu_map_setup(cpu, j);
 620        }
 621}
 622
 623static int __cpuinit detect_cache_attributes(unsigned int cpu)
 624{
 625        int                     retval;
 626
 627        if (num_cache_leaves == 0)
 628                return -ENOENT;
 629
 630        per_cpu(cpuid4_info, cpu) = kzalloc(
 631            sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
 632        if (per_cpu(cpuid4_info, cpu) == NULL)
 633                return -ENOMEM;
 634
 635        smp_call_function_single(cpu, get_cpu_leaves, &retval, true);
 636        if (retval) {
 637                kfree(per_cpu(cpuid4_info, cpu));
 638                per_cpu(cpuid4_info, cpu) = NULL;
 639        }
 640
 641        return retval;
 642}
 643
 644#include <linux/kobject.h>
 645#include <linux/sysfs.h>
 646
 647extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
 648
 649/* pointer to kobject for cpuX/cache */
 650static DEFINE_PER_CPU(struct kobject *, cache_kobject);
 651
 652struct _index_kobject {
 653        struct kobject kobj;
 654        unsigned int cpu;
 655        unsigned short index;
 656};
 657
 658/* pointer to array of kobjects for cpuX/cache/indexY */
 659static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
 660#define INDEX_KOBJECT_PTR(x, y)         (&((per_cpu(index_kobject, x))[y]))
 661
 662#define show_one_plus(file_name, object, val)                           \
 663static ssize_t show_##file_name                                         \
 664                        (struct _cpuid4_info *this_leaf, char *buf)     \
 665{                                                                       \
 666        return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
 667}
 668
 669show_one_plus(level, eax.split.level, 0);
 670show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
 671show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
 672show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
 673show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
 674
 675static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
 676{
 677        return sprintf(buf, "%luK\n", this_leaf->size / 1024);
 678}
 679
 680static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
 681                                        int type, char *buf)
 682{
 683        ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
 684        int n = 0;
 685
 686        if (len > 1) {
 687                const struct cpumask *mask;
 688
 689                mask = to_cpumask(this_leaf->shared_cpu_map);
 690                n = type ?
 691                        cpulist_scnprintf(buf, len-2, mask) :
 692                        cpumask_scnprintf(buf, len-2, mask);
 693                buf[n++] = '\n';
 694                buf[n] = '\0';
 695        }
 696        return n;
 697}
 698
 699static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
 700{
 701        return show_shared_cpu_map_func(leaf, 0, buf);
 702}
 703
 704static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
 705{
 706        return show_shared_cpu_map_func(leaf, 1, buf);
 707}
 708
 709static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf)
 710{
 711        switch (this_leaf->eax.split.type) {
 712        case CACHE_TYPE_DATA:
 713                return sprintf(buf, "Data\n");
 714        case CACHE_TYPE_INST:
 715                return sprintf(buf, "Instruction\n");
 716        case CACHE_TYPE_UNIFIED:
 717                return sprintf(buf, "Unified\n");
 718        default:
 719                return sprintf(buf, "Unknown\n");
 720        }
 721}
 722
 723#define to_object(k)    container_of(k, struct _index_kobject, kobj)
 724#define to_attr(a)      container_of(a, struct _cache_attr, attr)
 725
 726static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
 727                                  unsigned int index)
 728{
 729        int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
 730        int node = cpu_to_node(cpu);
 731        struct pci_dev *dev = node_to_k8_nb_misc(node);
 732        unsigned int reg = 0;
 733
 734        if (!this_leaf->can_disable)
 735                return -EINVAL;
 736
 737        if (!dev)
 738                return -EINVAL;
 739
 740        pci_read_config_dword(dev, 0x1BC + index * 4, &reg);
 741        return sprintf(buf, "%x\n", reg);
 742}
 743
 744#define SHOW_CACHE_DISABLE(index)                                       \
 745static ssize_t                                                          \
 746show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf)   \
 747{                                                                       \
 748        return show_cache_disable(this_leaf, buf, index);               \
 749}
 750SHOW_CACHE_DISABLE(0)
 751SHOW_CACHE_DISABLE(1)
 752
 753static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
 754        const char *buf, size_t count, unsigned int index)
 755{
 756        int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
 757        int node = cpu_to_node(cpu);
 758        struct pci_dev *dev = node_to_k8_nb_misc(node);
 759        unsigned long val = 0;
 760        unsigned int scrubber = 0;
 761
 762        if (!this_leaf->can_disable)
 763                return -EINVAL;
 764
 765        if (!capable(CAP_SYS_ADMIN))
 766                return -EPERM;
 767
 768        if (!dev)
 769                return -EINVAL;
 770
 771        if (strict_strtoul(buf, 10, &val) < 0)
 772                return -EINVAL;
 773
 774        val |= 0xc0000000;
 775
 776        pci_read_config_dword(dev, 0x58, &scrubber);
 777        scrubber &= ~0x1f000000;
 778        pci_write_config_dword(dev, 0x58, scrubber);
 779
 780        pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000);
 781        wbinvd();
 782        pci_write_config_dword(dev, 0x1BC + index * 4, val);
 783        return count;
 784}
 785
 786#define STORE_CACHE_DISABLE(index)                                      \
 787static ssize_t                                                          \
 788store_cache_disable_##index(struct _cpuid4_info *this_leaf,             \
 789                            const char *buf, size_t count)              \
 790{                                                                       \
 791        return store_cache_disable(this_leaf, buf, count, index);       \
 792}
 793STORE_CACHE_DISABLE(0)
 794STORE_CACHE_DISABLE(1)
 795
 796struct _cache_attr {
 797        struct attribute attr;
 798        ssize_t (*show)(struct _cpuid4_info *, char *);
 799        ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
 800};
 801
 802#define define_one_ro(_name) \
 803static struct _cache_attr _name = \
 804        __ATTR(_name, 0444, show_##_name, NULL)
 805
 806define_one_ro(level);
 807define_one_ro(type);
 808define_one_ro(coherency_line_size);
 809define_one_ro(physical_line_partition);
 810define_one_ro(ways_of_associativity);
 811define_one_ro(number_of_sets);
 812define_one_ro(size);
 813define_one_ro(shared_cpu_map);
 814define_one_ro(shared_cpu_list);
 815
 816static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
 817                show_cache_disable_0, store_cache_disable_0);
 818static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
 819                show_cache_disable_1, store_cache_disable_1);
 820
 821static struct attribute *default_attrs[] = {
 822        &type.attr,
 823        &level.attr,
 824        &coherency_line_size.attr,
 825        &physical_line_partition.attr,
 826        &ways_of_associativity.attr,
 827        &number_of_sets.attr,
 828        &size.attr,
 829        &shared_cpu_map.attr,
 830        &shared_cpu_list.attr,
 831        &cache_disable_0.attr,
 832        &cache_disable_1.attr,
 833        NULL
 834};
 835
 836static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
 837{
 838        struct _cache_attr *fattr = to_attr(attr);
 839        struct _index_kobject *this_leaf = to_object(kobj);
 840        ssize_t ret;
 841
 842        ret = fattr->show ?
 843                fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
 844                        buf) :
 845                0;
 846        return ret;
 847}
 848
 849static ssize_t store(struct kobject *kobj, struct attribute *attr,
 850                     const char *buf, size_t count)
 851{
 852        struct _cache_attr *fattr = to_attr(attr);
 853        struct _index_kobject *this_leaf = to_object(kobj);
 854        ssize_t ret;
 855
 856        ret = fattr->store ?
 857                fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
 858                        buf, count) :
 859                0;
 860        return ret;
 861}
 862
 863static struct sysfs_ops sysfs_ops = {
 864        .show   = show,
 865        .store  = store,
 866};
 867
 868static struct kobj_type ktype_cache = {
 869        .sysfs_ops      = &sysfs_ops,
 870        .default_attrs  = default_attrs,
 871};
 872
 873static struct kobj_type ktype_percpu_entry = {
 874        .sysfs_ops      = &sysfs_ops,
 875};
 876
 877static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
 878{
 879        kfree(per_cpu(cache_kobject, cpu));
 880        kfree(per_cpu(index_kobject, cpu));
 881        per_cpu(cache_kobject, cpu) = NULL;
 882        per_cpu(index_kobject, cpu) = NULL;
 883        free_cache_attributes(cpu);
 884}
 885
 886static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
 887{
 888        int err;
 889
 890        if (num_cache_leaves == 0)
 891                return -ENOENT;
 892
 893        err = detect_cache_attributes(cpu);
 894        if (err)
 895                return err;
 896
 897        /* Allocate all required memory */
 898        per_cpu(cache_kobject, cpu) =
 899                kzalloc(sizeof(struct kobject), GFP_KERNEL);
 900        if (unlikely(per_cpu(cache_kobject, cpu) == NULL))
 901                goto err_out;
 902
 903        per_cpu(index_kobject, cpu) = kzalloc(
 904            sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL);
 905        if (unlikely(per_cpu(index_kobject, cpu) == NULL))
 906                goto err_out;
 907
 908        return 0;
 909
 910err_out:
 911        cpuid4_cache_sysfs_exit(cpu);
 912        return -ENOMEM;
 913}
 914
 915static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
 916
 917/* Add/Remove cache interface for CPU device */
 918static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
 919{
 920        unsigned int cpu = sys_dev->id;
 921        unsigned long i, j;
 922        struct _index_kobject *this_object;
 923        int retval;
 924
 925        retval = cpuid4_cache_sysfs_init(cpu);
 926        if (unlikely(retval < 0))
 927                return retval;
 928
 929        retval = kobject_init_and_add(per_cpu(cache_kobject, cpu),
 930                                      &ktype_percpu_entry,
 931                                      &sys_dev->kobj, "%s", "cache");
 932        if (retval < 0) {
 933                cpuid4_cache_sysfs_exit(cpu);
 934                return retval;
 935        }
 936
 937        for (i = 0; i < num_cache_leaves; i++) {
 938                this_object = INDEX_KOBJECT_PTR(cpu, i);
 939                this_object->cpu = cpu;
 940                this_object->index = i;
 941                retval = kobject_init_and_add(&(this_object->kobj),
 942                                              &ktype_cache,
 943                                              per_cpu(cache_kobject, cpu),
 944                                              "index%1lu", i);
 945                if (unlikely(retval)) {
 946                        for (j = 0; j < i; j++)
 947                                kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj));
 948                        kobject_put(per_cpu(cache_kobject, cpu));
 949                        cpuid4_cache_sysfs_exit(cpu);
 950                        return retval;
 951                }
 952                kobject_uevent(&(this_object->kobj), KOBJ_ADD);
 953        }
 954        cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
 955
 956        kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
 957        return 0;
 958}
 959
 960static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
 961{
 962        unsigned int cpu = sys_dev->id;
 963        unsigned long i;
 964
 965        if (per_cpu(cpuid4_info, cpu) == NULL)
 966                return;
 967        if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
 968                return;
 969        cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
 970
 971        for (i = 0; i < num_cache_leaves; i++)
 972                kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj));
 973        kobject_put(per_cpu(cache_kobject, cpu));
 974        cpuid4_cache_sysfs_exit(cpu);
 975}
 976
 977static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
 978                                        unsigned long action, void *hcpu)
 979{
 980        unsigned int cpu = (unsigned long)hcpu;
 981        struct sys_device *sys_dev;
 982
 983        sys_dev = get_cpu_sysdev(cpu);
 984        switch (action) {
 985        case CPU_ONLINE:
 986        case CPU_ONLINE_FROZEN:
 987                cache_add_dev(sys_dev);
 988                break;
 989        case CPU_DEAD:
 990        case CPU_DEAD_FROZEN:
 991                cache_remove_dev(sys_dev);
 992                break;
 993        }
 994        return NOTIFY_OK;
 995}
 996
 997static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
 998        .notifier_call = cacheinfo_cpu_callback,
 999};
1000
1001static int __cpuinit cache_sysfs_init(void)
1002{
1003        int i;
1004
1005        if (num_cache_leaves == 0)
1006                return 0;
1007
1008        for_each_online_cpu(i) {
1009                int err;
1010                struct sys_device *sys_dev = get_cpu_sysdev(i);
1011
1012                err = cache_add_dev(sys_dev);
1013                if (err)
1014                        return err;
1015        }
1016        register_hotcpu_notifier(&cacheinfo_cpu_notifier);
1017        return 0;
1018}
1019
1020device_initcall(cache_sysfs_init);
1021
1022#endif
1023