x86, cacheinfo: Add cache index disable sysfs attrs only to L3 caches
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / x86 / kernel / cpu / intel_cacheinfo.c
blob3976ce95095f7b11dbf9f3dde7c16cb702bef31b
1 /*
2 * Routines to indentify caches on Intel CPU.
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 */
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>
18 #include <asm/processor.h>
19 #include <linux/smp.h>
20 #include <asm/k8.h>
21 #include <asm/smp.h>
23 #define LVL_1_INST 1
24 #define LVL_1_DATA 2
25 #define LVL_2 3
26 #define LVL_3 4
27 #define LVL_TRACE 5
29 struct _cache_table {
30 unsigned char descriptor;
31 char cache_type;
32 short size;
35 /* All the cache descriptor types we care about (no TLB or
36 trace cache entries) */
38 static const struct _cache_table __cpuinitconst cache_table[] =
40 { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
41 { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
42 { 0x09, LVL_1_INST, 32 }, /* 4-way set assoc, 64 byte line size */
43 { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */
44 { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */
45 { 0x0d, LVL_1_DATA, 16 }, /* 4-way set assoc, 64 byte line size */
46 { 0x21, LVL_2, 256 }, /* 8-way set assoc, 64 byte line size */
47 { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
48 { 0x23, LVL_3, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */
49 { 0x25, LVL_3, 2048 }, /* 8-way set assoc, sectored cache, 64 byte line size */
50 { 0x29, LVL_3, 4096 }, /* 8-way set assoc, sectored cache, 64 byte line size */
51 { 0x2c, LVL_1_DATA, 32 }, /* 8-way set assoc, 64 byte line size */
52 { 0x30, LVL_1_INST, 32 }, /* 8-way set assoc, 64 byte line size */
53 { 0x39, LVL_2, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */
54 { 0x3a, LVL_2, 192 }, /* 6-way set assoc, sectored cache, 64 byte line size */
55 { 0x3b, LVL_2, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */
56 { 0x3c, LVL_2, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */
57 { 0x3d, LVL_2, 384 }, /* 6-way set assoc, sectored cache, 64 byte line size */
58 { 0x3e, LVL_2, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
59 { 0x3f, LVL_2, 256 }, /* 2-way set assoc, 64 byte line size */
60 { 0x41, LVL_2, 128 }, /* 4-way set assoc, 32 byte line size */
61 { 0x42, LVL_2, 256 }, /* 4-way set assoc, 32 byte line size */
62 { 0x43, LVL_2, 512 }, /* 4-way set assoc, 32 byte line size */
63 { 0x44, LVL_2, 1024 }, /* 4-way set assoc, 32 byte line size */
64 { 0x45, LVL_2, 2048 }, /* 4-way set assoc, 32 byte line size */
65 { 0x46, LVL_3, 4096 }, /* 4-way set assoc, 64 byte line size */
66 { 0x47, LVL_3, 8192 }, /* 8-way set assoc, 64 byte line size */
67 { 0x49, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */
68 { 0x4a, LVL_3, 6144 }, /* 12-way set assoc, 64 byte line size */
69 { 0x4b, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */
70 { 0x4c, LVL_3, 12288 }, /* 12-way set assoc, 64 byte line size */
71 { 0x4d, LVL_3, 16384 }, /* 16-way set assoc, 64 byte line size */
72 { 0x4e, LVL_2, 6144 }, /* 24-way set assoc, 64 byte line size */
73 { 0x60, LVL_1_DATA, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */
74 { 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */
75 { 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */
76 { 0x68, LVL_1_DATA, 32 }, /* 4-way set assoc, sectored cache, 64 byte line size */
77 { 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */
78 { 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */
79 { 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */
80 { 0x73, LVL_TRACE, 64 }, /* 8-way set assoc */
81 { 0x78, LVL_2, 1024 }, /* 4-way set assoc, 64 byte line size */
82 { 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */
83 { 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */
84 { 0x7b, LVL_2, 512 }, /* 8-way set assoc, sectored cache, 64 byte line size */
85 { 0x7c, LVL_2, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */
86 { 0x7d, LVL_2, 2048 }, /* 8-way set assoc, 64 byte line size */
87 { 0x7f, LVL_2, 512 }, /* 2-way set assoc, 64 byte line size */
88 { 0x82, LVL_2, 256 }, /* 8-way set assoc, 32 byte line size */
89 { 0x83, LVL_2, 512 }, /* 8-way set assoc, 32 byte line size */
90 { 0x84, LVL_2, 1024 }, /* 8-way set assoc, 32 byte line size */
91 { 0x85, LVL_2, 2048 }, /* 8-way set assoc, 32 byte line size */
92 { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */
93 { 0x87, LVL_2, 1024 }, /* 8-way set assoc, 64 byte line size */
94 { 0xd0, LVL_3, 512 }, /* 4-way set assoc, 64 byte line size */
95 { 0xd1, LVL_3, 1024 }, /* 4-way set assoc, 64 byte line size */
96 { 0xd2, LVL_3, 2048 }, /* 4-way set assoc, 64 byte line size */
97 { 0xd6, LVL_3, 1024 }, /* 8-way set assoc, 64 byte line size */
98 { 0xd7, LVL_3, 2048 }, /* 8-way set assoc, 64 byte line size */
99 { 0xd8, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */
100 { 0xdc, LVL_3, 2048 }, /* 12-way set assoc, 64 byte line size */
101 { 0xdd, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */
102 { 0xde, LVL_3, 8192 }, /* 12-way set assoc, 64 byte line size */
103 { 0xe2, LVL_3, 2048 }, /* 16-way set assoc, 64 byte line size */
104 { 0xe3, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */
105 { 0xe4, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */
106 { 0xea, LVL_3, 12288 }, /* 24-way set assoc, 64 byte line size */
107 { 0xeb, LVL_3, 18432 }, /* 24-way set assoc, 64 byte line size */
108 { 0xec, LVL_3, 24576 }, /* 24-way set assoc, 64 byte line size */
109 { 0x00, 0, 0}
113 enum _cache_type {
114 CACHE_TYPE_NULL = 0,
115 CACHE_TYPE_DATA = 1,
116 CACHE_TYPE_INST = 2,
117 CACHE_TYPE_UNIFIED = 3
120 union _cpuid4_leaf_eax {
121 struct {
122 enum _cache_type type:5;
123 unsigned int level:3;
124 unsigned int is_self_initializing:1;
125 unsigned int is_fully_associative:1;
126 unsigned int reserved:4;
127 unsigned int num_threads_sharing:12;
128 unsigned int num_cores_on_die:6;
129 } split;
130 u32 full;
133 union _cpuid4_leaf_ebx {
134 struct {
135 unsigned int coherency_line_size:12;
136 unsigned int physical_line_partition:10;
137 unsigned int ways_of_associativity:10;
138 } split;
139 u32 full;
142 union _cpuid4_leaf_ecx {
143 struct {
144 unsigned int number_of_sets:32;
145 } split;
146 u32 full;
149 struct _cpuid4_info {
150 union _cpuid4_leaf_eax eax;
151 union _cpuid4_leaf_ebx ebx;
152 union _cpuid4_leaf_ecx ecx;
153 unsigned long size;
154 unsigned long can_disable;
155 DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
158 /* subset of above _cpuid4_info w/o shared_cpu_map */
159 struct _cpuid4_info_regs {
160 union _cpuid4_leaf_eax eax;
161 union _cpuid4_leaf_ebx ebx;
162 union _cpuid4_leaf_ecx ecx;
163 unsigned long size;
164 unsigned long can_disable;
167 unsigned short num_cache_leaves;
169 /* AMD doesn't have CPUID4. Emulate it here to report the same
170 information to the user. This makes some assumptions about the machine:
171 L2 not shared, no SMT etc. that is currently true on AMD CPUs.
173 In theory the TLBs could be reported as fake type (they are in "dummy").
174 Maybe later */
175 union l1_cache {
176 struct {
177 unsigned line_size:8;
178 unsigned lines_per_tag:8;
179 unsigned assoc:8;
180 unsigned size_in_kb:8;
182 unsigned val;
185 union l2_cache {
186 struct {
187 unsigned line_size:8;
188 unsigned lines_per_tag:4;
189 unsigned assoc:4;
190 unsigned size_in_kb:16;
192 unsigned val;
195 union l3_cache {
196 struct {
197 unsigned line_size:8;
198 unsigned lines_per_tag:4;
199 unsigned assoc:4;
200 unsigned res:2;
201 unsigned size_encoded:14;
203 unsigned val;
206 static const unsigned short __cpuinitconst assocs[] = {
207 [1] = 1,
208 [2] = 2,
209 [4] = 4,
210 [6] = 8,
211 [8] = 16,
212 [0xa] = 32,
213 [0xb] = 48,
214 [0xc] = 64,
215 [0xd] = 96,
216 [0xe] = 128,
217 [0xf] = 0xffff /* fully associative - no way to show this currently */
220 static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 };
221 static const unsigned char __cpuinitconst types[] = { 1, 2, 3, 3 };
223 static void __cpuinit
224 amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
225 union _cpuid4_leaf_ebx *ebx,
226 union _cpuid4_leaf_ecx *ecx)
228 unsigned dummy;
229 unsigned line_size, lines_per_tag, assoc, size_in_kb;
230 union l1_cache l1i, l1d;
231 union l2_cache l2;
232 union l3_cache l3;
233 union l1_cache *l1 = &l1d;
235 eax->full = 0;
236 ebx->full = 0;
237 ecx->full = 0;
239 cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
240 cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
242 switch (leaf) {
243 case 1:
244 l1 = &l1i;
245 case 0:
246 if (!l1->val)
247 return;
248 assoc = assocs[l1->assoc];
249 line_size = l1->line_size;
250 lines_per_tag = l1->lines_per_tag;
251 size_in_kb = l1->size_in_kb;
252 break;
253 case 2:
254 if (!l2.val)
255 return;
256 assoc = assocs[l2.assoc];
257 line_size = l2.line_size;
258 lines_per_tag = l2.lines_per_tag;
259 /* cpu_data has errata corrections for K7 applied */
260 size_in_kb = current_cpu_data.x86_cache_size;
261 break;
262 case 3:
263 if (!l3.val)
264 return;
265 assoc = assocs[l3.assoc];
266 line_size = l3.line_size;
267 lines_per_tag = l3.lines_per_tag;
268 size_in_kb = l3.size_encoded * 512;
269 if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
270 size_in_kb = size_in_kb >> 1;
271 assoc = assoc >> 1;
273 break;
274 default:
275 return;
278 eax->split.is_self_initializing = 1;
279 eax->split.type = types[leaf];
280 eax->split.level = levels[leaf];
281 eax->split.num_threads_sharing = 0;
282 eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
285 if (assoc == 0xffff)
286 eax->split.is_fully_associative = 1;
287 ebx->split.coherency_line_size = line_size - 1;
288 ebx->split.ways_of_associativity = assoc - 1;
289 ebx->split.physical_line_partition = lines_per_tag - 1;
290 ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
291 (ebx->split.ways_of_associativity + 1) - 1;
294 static void __cpuinit
295 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
297 if (index < 3)
298 return;
300 if (boot_cpu_data.x86 == 0x11)
301 return;
303 /* see errata #382 and #388 */
304 if ((boot_cpu_data.x86 == 0x10) &&
305 ((boot_cpu_data.x86_model < 0x9) ||
306 (boot_cpu_data.x86_mask < 0x1)))
307 return;
309 this_leaf->can_disable = 1;
312 static int
313 __cpuinit cpuid4_cache_lookup_regs(int index,
314 struct _cpuid4_info_regs *this_leaf)
316 union _cpuid4_leaf_eax eax;
317 union _cpuid4_leaf_ebx ebx;
318 union _cpuid4_leaf_ecx ecx;
319 unsigned edx;
321 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
322 amd_cpuid4(index, &eax, &ebx, &ecx);
323 if (boot_cpu_data.x86 >= 0x10)
324 amd_check_l3_disable(index, this_leaf);
325 } else {
326 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
329 if (eax.split.type == CACHE_TYPE_NULL)
330 return -EIO; /* better error ? */
332 this_leaf->eax = eax;
333 this_leaf->ebx = ebx;
334 this_leaf->ecx = ecx;
335 this_leaf->size = (ecx.split.number_of_sets + 1) *
336 (ebx.split.coherency_line_size + 1) *
337 (ebx.split.physical_line_partition + 1) *
338 (ebx.split.ways_of_associativity + 1);
339 return 0;
342 static int __cpuinit find_num_cache_leaves(void)
344 unsigned int eax, ebx, ecx, edx;
345 union _cpuid4_leaf_eax cache_eax;
346 int i = -1;
348 do {
349 ++i;
350 /* Do cpuid(4) loop to find out num_cache_leaves */
351 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
352 cache_eax.full = eax;
353 } while (cache_eax.split.type != CACHE_TYPE_NULL);
354 return i;
357 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
359 /* Cache sizes */
360 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0;
361 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
362 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
363 unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
364 #ifdef CONFIG_X86_HT
365 unsigned int cpu = c->cpu_index;
366 #endif
368 if (c->cpuid_level > 3) {
369 static int is_initialized;
371 if (is_initialized == 0) {
372 /* Init num_cache_leaves from boot CPU */
373 num_cache_leaves = find_num_cache_leaves();
374 is_initialized++;
378 * Whenever possible use cpuid(4), deterministic cache
379 * parameters cpuid leaf to find the cache details
381 for (i = 0; i < num_cache_leaves; i++) {
382 struct _cpuid4_info_regs this_leaf;
383 int retval;
385 retval = cpuid4_cache_lookup_regs(i, &this_leaf);
386 if (retval >= 0) {
387 switch (this_leaf.eax.split.level) {
388 case 1:
389 if (this_leaf.eax.split.type ==
390 CACHE_TYPE_DATA)
391 new_l1d = this_leaf.size/1024;
392 else if (this_leaf.eax.split.type ==
393 CACHE_TYPE_INST)
394 new_l1i = this_leaf.size/1024;
395 break;
396 case 2:
397 new_l2 = this_leaf.size/1024;
398 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
399 index_msb = get_count_order(num_threads_sharing);
400 l2_id = c->apicid >> index_msb;
401 break;
402 case 3:
403 new_l3 = this_leaf.size/1024;
404 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
405 index_msb = get_count_order(
406 num_threads_sharing);
407 l3_id = c->apicid >> index_msb;
408 break;
409 default:
410 break;
416 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
417 * trace cache
419 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
420 /* supports eax=2 call */
421 int j, n;
422 unsigned int regs[4];
423 unsigned char *dp = (unsigned char *)regs;
424 int only_trace = 0;
426 if (num_cache_leaves != 0 && c->x86 == 15)
427 only_trace = 1;
429 /* Number of times to iterate */
430 n = cpuid_eax(2) & 0xFF;
432 for (i = 0 ; i < n ; i++) {
433 cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
435 /* If bit 31 is set, this is an unknown format */
436 for (j = 0 ; j < 3 ; j++)
437 if (regs[j] & (1 << 31))
438 regs[j] = 0;
440 /* Byte 0 is level count, not a descriptor */
441 for (j = 1 ; j < 16 ; j++) {
442 unsigned char des = dp[j];
443 unsigned char k = 0;
445 /* look up this descriptor in the table */
446 while (cache_table[k].descriptor != 0) {
447 if (cache_table[k].descriptor == des) {
448 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
449 break;
450 switch (cache_table[k].cache_type) {
451 case LVL_1_INST:
452 l1i += cache_table[k].size;
453 break;
454 case LVL_1_DATA:
455 l1d += cache_table[k].size;
456 break;
457 case LVL_2:
458 l2 += cache_table[k].size;
459 break;
460 case LVL_3:
461 l3 += cache_table[k].size;
462 break;
463 case LVL_TRACE:
464 trace += cache_table[k].size;
465 break;
468 break;
471 k++;
477 if (new_l1d)
478 l1d = new_l1d;
480 if (new_l1i)
481 l1i = new_l1i;
483 if (new_l2) {
484 l2 = new_l2;
485 #ifdef CONFIG_X86_HT
486 per_cpu(cpu_llc_id, cpu) = l2_id;
487 #endif
490 if (new_l3) {
491 l3 = new_l3;
492 #ifdef CONFIG_X86_HT
493 per_cpu(cpu_llc_id, cpu) = l3_id;
494 #endif
497 c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
499 return l2;
502 #ifdef CONFIG_SYSFS
504 /* pointer to _cpuid4_info array (for each cache leaf) */
505 static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
506 #define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))
508 #ifdef CONFIG_SMP
509 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
511 struct _cpuid4_info *this_leaf, *sibling_leaf;
512 unsigned long num_threads_sharing;
513 int index_msb, i, sibling;
514 struct cpuinfo_x86 *c = &cpu_data(cpu);
516 if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
517 for_each_cpu(i, c->llc_shared_map) {
518 if (!per_cpu(ici_cpuid4_info, i))
519 continue;
520 this_leaf = CPUID4_INFO_IDX(i, index);
521 for_each_cpu(sibling, c->llc_shared_map) {
522 if (!cpu_online(sibling))
523 continue;
524 set_bit(sibling, this_leaf->shared_cpu_map);
527 return;
529 this_leaf = CPUID4_INFO_IDX(cpu, index);
530 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
532 if (num_threads_sharing == 1)
533 cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
534 else {
535 index_msb = get_count_order(num_threads_sharing);
537 for_each_online_cpu(i) {
538 if (cpu_data(i).apicid >> index_msb ==
539 c->apicid >> index_msb) {
540 cpumask_set_cpu(i,
541 to_cpumask(this_leaf->shared_cpu_map));
542 if (i != cpu && per_cpu(ici_cpuid4_info, i)) {
543 sibling_leaf =
544 CPUID4_INFO_IDX(i, index);
545 cpumask_set_cpu(cpu, to_cpumask(
546 sibling_leaf->shared_cpu_map));
552 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
554 struct _cpuid4_info *this_leaf, *sibling_leaf;
555 int sibling;
557 this_leaf = CPUID4_INFO_IDX(cpu, index);
558 for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) {
559 sibling_leaf = CPUID4_INFO_IDX(sibling, index);
560 cpumask_clear_cpu(cpu,
561 to_cpumask(sibling_leaf->shared_cpu_map));
564 #else
565 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
569 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
572 #endif
574 static void __cpuinit free_cache_attributes(unsigned int cpu)
576 int i;
578 for (i = 0; i < num_cache_leaves; i++)
579 cache_remove_shared_cpu_map(cpu, i);
581 kfree(per_cpu(ici_cpuid4_info, cpu));
582 per_cpu(ici_cpuid4_info, cpu) = NULL;
585 static int
586 __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
588 struct _cpuid4_info_regs *leaf_regs =
589 (struct _cpuid4_info_regs *)this_leaf;
591 return cpuid4_cache_lookup_regs(index, leaf_regs);
594 static void __cpuinit get_cpu_leaves(void *_retval)
596 int j, *retval = _retval, cpu = smp_processor_id();
598 /* Do cpuid and store the results */
599 for (j = 0; j < num_cache_leaves; j++) {
600 struct _cpuid4_info *this_leaf;
601 this_leaf = CPUID4_INFO_IDX(cpu, j);
602 *retval = cpuid4_cache_lookup(j, this_leaf);
603 if (unlikely(*retval < 0)) {
604 int i;
606 for (i = 0; i < j; i++)
607 cache_remove_shared_cpu_map(cpu, i);
608 break;
610 cache_shared_cpu_map_setup(cpu, j);
614 static int __cpuinit detect_cache_attributes(unsigned int cpu)
616 int retval;
618 if (num_cache_leaves == 0)
619 return -ENOENT;
621 per_cpu(ici_cpuid4_info, cpu) = kzalloc(
622 sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
623 if (per_cpu(ici_cpuid4_info, cpu) == NULL)
624 return -ENOMEM;
626 smp_call_function_single(cpu, get_cpu_leaves, &retval, true);
627 if (retval) {
628 kfree(per_cpu(ici_cpuid4_info, cpu));
629 per_cpu(ici_cpuid4_info, cpu) = NULL;
632 return retval;
635 #include <linux/kobject.h>
636 #include <linux/sysfs.h>
638 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
640 /* pointer to kobject for cpuX/cache */
641 static DEFINE_PER_CPU(struct kobject *, ici_cache_kobject);
643 struct _index_kobject {
644 struct kobject kobj;
645 unsigned int cpu;
646 unsigned short index;
649 /* pointer to array of kobjects for cpuX/cache/indexY */
650 static DEFINE_PER_CPU(struct _index_kobject *, ici_index_kobject);
651 #define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(ici_index_kobject, x))[y]))
653 #define show_one_plus(file_name, object, val) \
654 static ssize_t show_##file_name \
655 (struct _cpuid4_info *this_leaf, char *buf) \
657 return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
660 show_one_plus(level, eax.split.level, 0);
661 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
662 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
663 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
664 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
666 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
668 return sprintf(buf, "%luK\n", this_leaf->size / 1024);
671 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
672 int type, char *buf)
674 ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
675 int n = 0;
677 if (len > 1) {
678 const struct cpumask *mask;
680 mask = to_cpumask(this_leaf->shared_cpu_map);
681 n = type ?
682 cpulist_scnprintf(buf, len-2, mask) :
683 cpumask_scnprintf(buf, len-2, mask);
684 buf[n++] = '\n';
685 buf[n] = '\0';
687 return n;
690 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
692 return show_shared_cpu_map_func(leaf, 0, buf);
695 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
697 return show_shared_cpu_map_func(leaf, 1, buf);
700 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf)
702 switch (this_leaf->eax.split.type) {
703 case CACHE_TYPE_DATA:
704 return sprintf(buf, "Data\n");
705 case CACHE_TYPE_INST:
706 return sprintf(buf, "Instruction\n");
707 case CACHE_TYPE_UNIFIED:
708 return sprintf(buf, "Unified\n");
709 default:
710 return sprintf(buf, "Unknown\n");
714 #define to_object(k) container_of(k, struct _index_kobject, kobj)
715 #define to_attr(a) container_of(a, struct _cache_attr, attr)
717 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
718 unsigned int index)
720 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
721 int node = cpu_to_node(cpu);
722 struct pci_dev *dev = node_to_k8_nb_misc(node);
723 unsigned int reg = 0;
725 if (!this_leaf->can_disable)
726 return -EINVAL;
728 if (!dev)
729 return -EINVAL;
731 pci_read_config_dword(dev, 0x1BC + index * 4, &reg);
732 return sprintf(buf, "0x%08x\n", reg);
735 #define SHOW_CACHE_DISABLE(index) \
736 static ssize_t \
737 show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \
739 return show_cache_disable(this_leaf, buf, index); \
741 SHOW_CACHE_DISABLE(0)
742 SHOW_CACHE_DISABLE(1)
744 static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
745 const char *buf, size_t count, unsigned int index)
747 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
748 int node = cpu_to_node(cpu);
749 struct pci_dev *dev = node_to_k8_nb_misc(node);
750 unsigned long val = 0;
752 #define SUBCACHE_MASK (3UL << 20)
753 #define SUBCACHE_INDEX 0xfff
755 if (!this_leaf->can_disable)
756 return -EINVAL;
758 if (!capable(CAP_SYS_ADMIN))
759 return -EPERM;
761 if (!dev)
762 return -EINVAL;
764 if (strict_strtoul(buf, 10, &val) < 0)
765 return -EINVAL;
767 /* do not allow writes outside of allowed bits */
768 if (val & ~(SUBCACHE_MASK | SUBCACHE_INDEX))
769 return -EINVAL;
771 val |= BIT(30);
772 pci_write_config_dword(dev, 0x1BC + index * 4, val);
774 * We need to WBINVD on a core on the node containing the L3 cache which
775 * indices we disable therefore a simple wbinvd() is not sufficient.
777 wbinvd_on_cpu(cpu);
778 pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31));
779 return count;
782 #define STORE_CACHE_DISABLE(index) \
783 static ssize_t \
784 store_cache_disable_##index(struct _cpuid4_info *this_leaf, \
785 const char *buf, size_t count) \
787 return store_cache_disable(this_leaf, buf, count, index); \
789 STORE_CACHE_DISABLE(0)
790 STORE_CACHE_DISABLE(1)
792 struct _cache_attr {
793 struct attribute attr;
794 ssize_t (*show)(struct _cpuid4_info *, char *);
795 ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
798 #define define_one_ro(_name) \
799 static struct _cache_attr _name = \
800 __ATTR(_name, 0444, show_##_name, NULL)
802 define_one_ro(level);
803 define_one_ro(type);
804 define_one_ro(coherency_line_size);
805 define_one_ro(physical_line_partition);
806 define_one_ro(ways_of_associativity);
807 define_one_ro(number_of_sets);
808 define_one_ro(size);
809 define_one_ro(shared_cpu_map);
810 define_one_ro(shared_cpu_list);
812 static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
813 show_cache_disable_0, store_cache_disable_0);
814 static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
815 show_cache_disable_1, store_cache_disable_1);
817 #define DEFAULT_SYSFS_CACHE_ATTRS \
818 &type.attr, \
819 &level.attr, \
820 &coherency_line_size.attr, \
821 &physical_line_partition.attr, \
822 &ways_of_associativity.attr, \
823 &number_of_sets.attr, \
824 &size.attr, \
825 &shared_cpu_map.attr, \
826 &shared_cpu_list.attr
828 static struct attribute *default_attrs[] = {
829 DEFAULT_SYSFS_CACHE_ATTRS,
830 NULL
833 static struct attribute *default_l3_attrs[] = {
834 DEFAULT_SYSFS_CACHE_ATTRS,
835 &cache_disable_0.attr,
836 &cache_disable_1.attr,
837 NULL
840 static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
842 struct _cache_attr *fattr = to_attr(attr);
843 struct _index_kobject *this_leaf = to_object(kobj);
844 ssize_t ret;
846 ret = fattr->show ?
847 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
848 buf) :
850 return ret;
853 static ssize_t store(struct kobject *kobj, struct attribute *attr,
854 const char *buf, size_t count)
856 struct _cache_attr *fattr = to_attr(attr);
857 struct _index_kobject *this_leaf = to_object(kobj);
858 ssize_t ret;
860 ret = fattr->store ?
861 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
862 buf, count) :
864 return ret;
867 static struct sysfs_ops sysfs_ops = {
868 .show = show,
869 .store = store,
872 static struct kobj_type ktype_cache = {
873 .sysfs_ops = &sysfs_ops,
874 .default_attrs = default_attrs,
877 static struct kobj_type ktype_percpu_entry = {
878 .sysfs_ops = &sysfs_ops,
881 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
883 kfree(per_cpu(ici_cache_kobject, cpu));
884 kfree(per_cpu(ici_index_kobject, cpu));
885 per_cpu(ici_cache_kobject, cpu) = NULL;
886 per_cpu(ici_index_kobject, cpu) = NULL;
887 free_cache_attributes(cpu);
890 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
892 int err;
894 if (num_cache_leaves == 0)
895 return -ENOENT;
897 err = detect_cache_attributes(cpu);
898 if (err)
899 return err;
901 /* Allocate all required memory */
902 per_cpu(ici_cache_kobject, cpu) =
903 kzalloc(sizeof(struct kobject), GFP_KERNEL);
904 if (unlikely(per_cpu(ici_cache_kobject, cpu) == NULL))
905 goto err_out;
907 per_cpu(ici_index_kobject, cpu) = kzalloc(
908 sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL);
909 if (unlikely(per_cpu(ici_index_kobject, cpu) == NULL))
910 goto err_out;
912 return 0;
914 err_out:
915 cpuid4_cache_sysfs_exit(cpu);
916 return -ENOMEM;
919 static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
921 /* Add/Remove cache interface for CPU device */
922 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
924 unsigned int cpu = sys_dev->id;
925 unsigned long i, j;
926 struct _index_kobject *this_object;
927 struct _cpuid4_info *this_leaf;
928 int retval;
930 retval = cpuid4_cache_sysfs_init(cpu);
931 if (unlikely(retval < 0))
932 return retval;
934 retval = kobject_init_and_add(per_cpu(ici_cache_kobject, cpu),
935 &ktype_percpu_entry,
936 &sys_dev->kobj, "%s", "cache");
937 if (retval < 0) {
938 cpuid4_cache_sysfs_exit(cpu);
939 return retval;
942 for (i = 0; i < num_cache_leaves; i++) {
943 this_object = INDEX_KOBJECT_PTR(cpu, i);
944 this_object->cpu = cpu;
945 this_object->index = i;
947 this_leaf = CPUID4_INFO_IDX(cpu, i);
949 if (this_leaf->can_disable)
950 ktype_cache.default_attrs = default_l3_attrs;
951 else
952 ktype_cache.default_attrs = default_attrs;
954 retval = kobject_init_and_add(&(this_object->kobj),
955 &ktype_cache,
956 per_cpu(ici_cache_kobject, cpu),
957 "index%1lu", i);
958 if (unlikely(retval)) {
959 for (j = 0; j < i; j++)
960 kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj));
961 kobject_put(per_cpu(ici_cache_kobject, cpu));
962 cpuid4_cache_sysfs_exit(cpu);
963 return retval;
965 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
967 cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
969 kobject_uevent(per_cpu(ici_cache_kobject, cpu), KOBJ_ADD);
970 return 0;
973 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
975 unsigned int cpu = sys_dev->id;
976 unsigned long i;
978 if (per_cpu(ici_cpuid4_info, cpu) == NULL)
979 return;
980 if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
981 return;
982 cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
984 for (i = 0; i < num_cache_leaves; i++)
985 kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj));
986 kobject_put(per_cpu(ici_cache_kobject, cpu));
987 cpuid4_cache_sysfs_exit(cpu);
990 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
991 unsigned long action, void *hcpu)
993 unsigned int cpu = (unsigned long)hcpu;
994 struct sys_device *sys_dev;
996 sys_dev = get_cpu_sysdev(cpu);
997 switch (action) {
998 case CPU_ONLINE:
999 case CPU_ONLINE_FROZEN:
1000 cache_add_dev(sys_dev);
1001 break;
1002 case CPU_DEAD:
1003 case CPU_DEAD_FROZEN:
1004 cache_remove_dev(sys_dev);
1005 break;
1007 return NOTIFY_OK;
1010 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
1011 .notifier_call = cacheinfo_cpu_callback,
1014 static int __cpuinit cache_sysfs_init(void)
1016 int i;
1018 if (num_cache_leaves == 0)
1019 return 0;
1021 for_each_online_cpu(i) {
1022 int err;
1023 struct sys_device *sys_dev = get_cpu_sysdev(i);
1025 err = cache_add_dev(sys_dev);
1026 if (err)
1027 return err;
1029 register_hotcpu_notifier(&cacheinfo_cpu_notifier);
1030 return 0;
1033 device_initcall(cache_sysfs_init);
1035 #endif