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