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