perf_event: x86: Allocate the fake_cpuc
[linux-2.6/libata-dev.git] / arch / x86 / kernel / cpu / intel_cacheinfo.c
blobfc6c8ef92dcc5f0bd9c846b2597f0463e50209af
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>
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
28 struct _cache_table {
29 unsigned char descriptor;
30 char cache_type;
31 short size;
34 /* All the cache descriptor types we care about (no TLB or
35 trace cache entries) */
37 static const struct _cache_table __cpuinitconst cache_table[] =
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}
112 enum _cache_type {
113 CACHE_TYPE_NULL = 0,
114 CACHE_TYPE_DATA = 1,
115 CACHE_TYPE_INST = 2,
116 CACHE_TYPE_UNIFIED = 3
119 union _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;
132 union _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;
141 union _cpuid4_leaf_ecx {
142 struct {
143 unsigned int number_of_sets:32;
144 } split;
145 u32 full;
148 struct _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);
157 /* subset of above _cpuid4_info w/o shared_cpu_map */
158 struct _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;
166 unsigned short num_cache_leaves;
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.
172 In theory the TLBs could be reported as fake type (they are in "dummy").
173 Maybe later */
174 union 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;
181 unsigned val;
184 union 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;
191 unsigned val;
194 union 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;
202 unsigned val;
205 static 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 */
219 static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 };
220 static const unsigned char __cpuinitconst types[] = { 1, 2, 3, 3 };
222 static void __cpuinit
223 amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
224 union _cpuid4_leaf_ebx *ebx,
225 union _cpuid4_leaf_ecx *ecx)
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;
234 eax->full = 0;
235 ebx->full = 0;
236 ecx->full = 0;
238 cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
239 cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
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;
272 break;
273 default:
274 return;
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;
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;
293 static void __cpuinit
294 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
296 if (index < 3)
297 return;
299 if (boot_cpu_data.x86 == 0x11)
300 return;
302 /* see erratum #382 */
303 if ((boot_cpu_data.x86 == 0x10) && (boot_cpu_data.x86_model < 0x8))
304 return;
306 this_leaf->can_disable = 1;
309 static int
310 __cpuinit cpuid4_cache_lookup_regs(int index,
311 struct _cpuid4_info_regs *this_leaf)
313 union _cpuid4_leaf_eax eax;
314 union _cpuid4_leaf_ebx ebx;
315 union _cpuid4_leaf_ecx ecx;
316 unsigned edx;
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);
326 if (eax.split.type == CACHE_TYPE_NULL)
327 return -EIO; /* better error ? */
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;
339 static int __cpuinit find_num_cache_leaves(void)
341 unsigned int eax, ebx, ecx, edx;
342 union _cpuid4_leaf_eax cache_eax;
343 int i = -1;
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;
354 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
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
365 if (c->cpuid_level > 3) {
366 static int is_initialized;
368 if (is_initialized == 0) {
369 /* Init num_cache_leaves from boot CPU */
370 num_cache_leaves = find_num_cache_leaves();
371 is_initialized++;
375 * Whenever possible use cpuid(4), deterministic cache
376 * parameters cpuid leaf to find the cache details
378 for (i = 0; i < num_cache_leaves; i++) {
379 struct _cpuid4_info_regs this_leaf;
380 int retval;
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;
413 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
414 * trace cache
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;
423 if (num_cache_leaves != 0 && c->x86 == 15)
424 only_trace = 1;
426 /* Number of times to iterate */
427 n = cpuid_eax(2) & 0xFF;
429 for (i = 0 ; i < n ; i++) {
430 cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
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;
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;
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;
465 break;
468 k++;
474 if (new_l1d)
475 l1d = new_l1d;
477 if (new_l1i)
478 l1i = new_l1i;
480 if (new_l2) {
481 l2 = new_l2;
482 #ifdef CONFIG_X86_HT
483 per_cpu(cpu_llc_id, cpu) = l2_id;
484 #endif
487 if (new_l3) {
488 l3 = new_l3;
489 #ifdef CONFIG_X86_HT
490 per_cpu(cpu_llc_id, cpu) = l3_id;
491 #endif
494 c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
496 return l2;
499 #ifdef CONFIG_SYSFS
501 /* pointer to _cpuid4_info array (for each cache leaf) */
502 static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
503 #define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))
505 #ifdef CONFIG_SMP
506 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
508 struct _cpuid4_info *this_leaf, *sibling_leaf;
509 unsigned long num_threads_sharing;
510 int index_msb, i, sibling;
511 struct cpuinfo_x86 *c = &cpu_data(cpu);
513 if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
514 for_each_cpu(i, c->llc_shared_map) {
515 if (!per_cpu(ici_cpuid4_info, i))
516 continue;
517 this_leaf = CPUID4_INFO_IDX(i, index);
518 for_each_cpu(sibling, c->llc_shared_map) {
519 if (!cpu_online(sibling))
520 continue;
521 set_bit(sibling, this_leaf->shared_cpu_map);
524 return;
526 this_leaf = CPUID4_INFO_IDX(cpu, index);
527 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
529 if (num_threads_sharing == 1)
530 cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
531 else {
532 index_msb = get_count_order(num_threads_sharing);
534 for_each_online_cpu(i) {
535 if (cpu_data(i).apicid >> index_msb ==
536 c->apicid >> index_msb) {
537 cpumask_set_cpu(i,
538 to_cpumask(this_leaf->shared_cpu_map));
539 if (i != cpu && per_cpu(ici_cpuid4_info, i)) {
540 sibling_leaf =
541 CPUID4_INFO_IDX(i, index);
542 cpumask_set_cpu(cpu, to_cpumask(
543 sibling_leaf->shared_cpu_map));
549 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
551 struct _cpuid4_info *this_leaf, *sibling_leaf;
552 int sibling;
554 this_leaf = CPUID4_INFO_IDX(cpu, index);
555 for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) {
556 sibling_leaf = CPUID4_INFO_IDX(sibling, index);
557 cpumask_clear_cpu(cpu,
558 to_cpumask(sibling_leaf->shared_cpu_map));
561 #else
562 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
566 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
569 #endif
571 static void __cpuinit free_cache_attributes(unsigned int cpu)
573 int i;
575 for (i = 0; i < num_cache_leaves; i++)
576 cache_remove_shared_cpu_map(cpu, i);
578 kfree(per_cpu(ici_cpuid4_info, cpu));
579 per_cpu(ici_cpuid4_info, cpu) = NULL;
582 static int
583 __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
585 struct _cpuid4_info_regs *leaf_regs =
586 (struct _cpuid4_info_regs *)this_leaf;
588 return cpuid4_cache_lookup_regs(index, leaf_regs);
591 static void __cpuinit get_cpu_leaves(void *_retval)
593 int j, *retval = _retval, cpu = smp_processor_id();
595 /* Do cpuid and store the results */
596 for (j = 0; j < num_cache_leaves; j++) {
597 struct _cpuid4_info *this_leaf;
598 this_leaf = CPUID4_INFO_IDX(cpu, j);
599 *retval = cpuid4_cache_lookup(j, this_leaf);
600 if (unlikely(*retval < 0)) {
601 int i;
603 for (i = 0; i < j; i++)
604 cache_remove_shared_cpu_map(cpu, i);
605 break;
607 cache_shared_cpu_map_setup(cpu, j);
611 static int __cpuinit detect_cache_attributes(unsigned int cpu)
613 int retval;
615 if (num_cache_leaves == 0)
616 return -ENOENT;
618 per_cpu(ici_cpuid4_info, cpu) = kzalloc(
619 sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
620 if (per_cpu(ici_cpuid4_info, cpu) == NULL)
621 return -ENOMEM;
623 smp_call_function_single(cpu, get_cpu_leaves, &retval, true);
624 if (retval) {
625 kfree(per_cpu(ici_cpuid4_info, cpu));
626 per_cpu(ici_cpuid4_info, cpu) = NULL;
629 return retval;
632 #include <linux/kobject.h>
633 #include <linux/sysfs.h>
635 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
637 /* pointer to kobject for cpuX/cache */
638 static DEFINE_PER_CPU(struct kobject *, ici_cache_kobject);
640 struct _index_kobject {
641 struct kobject kobj;
642 unsigned int cpu;
643 unsigned short index;
646 /* pointer to array of kobjects for cpuX/cache/indexY */
647 static DEFINE_PER_CPU(struct _index_kobject *, ici_index_kobject);
648 #define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(ici_index_kobject, x))[y]))
650 #define show_one_plus(file_name, object, val) \
651 static ssize_t show_##file_name \
652 (struct _cpuid4_info *this_leaf, char *buf) \
654 return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
657 show_one_plus(level, eax.split.level, 0);
658 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
659 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
660 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
661 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
663 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
665 return sprintf(buf, "%luK\n", this_leaf->size / 1024);
668 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
669 int type, char *buf)
671 ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
672 int n = 0;
674 if (len > 1) {
675 const struct cpumask *mask;
677 mask = to_cpumask(this_leaf->shared_cpu_map);
678 n = type ?
679 cpulist_scnprintf(buf, len-2, mask) :
680 cpumask_scnprintf(buf, len-2, mask);
681 buf[n++] = '\n';
682 buf[n] = '\0';
684 return n;
687 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
689 return show_shared_cpu_map_func(leaf, 0, buf);
692 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
694 return show_shared_cpu_map_func(leaf, 1, buf);
697 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf)
699 switch (this_leaf->eax.split.type) {
700 case CACHE_TYPE_DATA:
701 return sprintf(buf, "Data\n");
702 case CACHE_TYPE_INST:
703 return sprintf(buf, "Instruction\n");
704 case CACHE_TYPE_UNIFIED:
705 return sprintf(buf, "Unified\n");
706 default:
707 return sprintf(buf, "Unknown\n");
711 #define to_object(k) container_of(k, struct _index_kobject, kobj)
712 #define to_attr(a) container_of(a, struct _cache_attr, attr)
714 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
715 unsigned int index)
717 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
718 int node = cpu_to_node(cpu);
719 struct pci_dev *dev = node_to_k8_nb_misc(node);
720 unsigned int reg = 0;
722 if (!this_leaf->can_disable)
723 return -EINVAL;
725 if (!dev)
726 return -EINVAL;
728 pci_read_config_dword(dev, 0x1BC + index * 4, &reg);
729 return sprintf(buf, "%x\n", reg);
732 #define SHOW_CACHE_DISABLE(index) \
733 static ssize_t \
734 show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \
736 return show_cache_disable(this_leaf, buf, index); \
738 SHOW_CACHE_DISABLE(0)
739 SHOW_CACHE_DISABLE(1)
741 static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
742 const char *buf, size_t count, unsigned int index)
744 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
745 int node = cpu_to_node(cpu);
746 struct pci_dev *dev = node_to_k8_nb_misc(node);
747 unsigned long val = 0;
748 unsigned int scrubber = 0;
750 if (!this_leaf->can_disable)
751 return -EINVAL;
753 if (!capable(CAP_SYS_ADMIN))
754 return -EPERM;
756 if (!dev)
757 return -EINVAL;
759 if (strict_strtoul(buf, 10, &val) < 0)
760 return -EINVAL;
762 val |= 0xc0000000;
764 pci_read_config_dword(dev, 0x58, &scrubber);
765 scrubber &= ~0x1f000000;
766 pci_write_config_dword(dev, 0x58, scrubber);
768 pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000);
769 wbinvd();
770 pci_write_config_dword(dev, 0x1BC + index * 4, val);
771 return count;
774 #define STORE_CACHE_DISABLE(index) \
775 static ssize_t \
776 store_cache_disable_##index(struct _cpuid4_info *this_leaf, \
777 const char *buf, size_t count) \
779 return store_cache_disable(this_leaf, buf, count, index); \
781 STORE_CACHE_DISABLE(0)
782 STORE_CACHE_DISABLE(1)
784 struct _cache_attr {
785 struct attribute attr;
786 ssize_t (*show)(struct _cpuid4_info *, char *);
787 ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
790 #define define_one_ro(_name) \
791 static struct _cache_attr _name = \
792 __ATTR(_name, 0444, show_##_name, NULL)
794 define_one_ro(level);
795 define_one_ro(type);
796 define_one_ro(coherency_line_size);
797 define_one_ro(physical_line_partition);
798 define_one_ro(ways_of_associativity);
799 define_one_ro(number_of_sets);
800 define_one_ro(size);
801 define_one_ro(shared_cpu_map);
802 define_one_ro(shared_cpu_list);
804 static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
805 show_cache_disable_0, store_cache_disable_0);
806 static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
807 show_cache_disable_1, store_cache_disable_1);
809 static struct attribute *default_attrs[] = {
810 &type.attr,
811 &level.attr,
812 &coherency_line_size.attr,
813 &physical_line_partition.attr,
814 &ways_of_associativity.attr,
815 &number_of_sets.attr,
816 &size.attr,
817 &shared_cpu_map.attr,
818 &shared_cpu_list.attr,
819 &cache_disable_0.attr,
820 &cache_disable_1.attr,
821 NULL
824 static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
826 struct _cache_attr *fattr = to_attr(attr);
827 struct _index_kobject *this_leaf = to_object(kobj);
828 ssize_t ret;
830 ret = fattr->show ?
831 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
832 buf) :
834 return ret;
837 static ssize_t store(struct kobject *kobj, struct attribute *attr,
838 const char *buf, size_t count)
840 struct _cache_attr *fattr = to_attr(attr);
841 struct _index_kobject *this_leaf = to_object(kobj);
842 ssize_t ret;
844 ret = fattr->store ?
845 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
846 buf, count) :
848 return ret;
851 static struct sysfs_ops sysfs_ops = {
852 .show = show,
853 .store = store,
856 static struct kobj_type ktype_cache = {
857 .sysfs_ops = &sysfs_ops,
858 .default_attrs = default_attrs,
861 static struct kobj_type ktype_percpu_entry = {
862 .sysfs_ops = &sysfs_ops,
865 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
867 kfree(per_cpu(ici_cache_kobject, cpu));
868 kfree(per_cpu(ici_index_kobject, cpu));
869 per_cpu(ici_cache_kobject, cpu) = NULL;
870 per_cpu(ici_index_kobject, cpu) = NULL;
871 free_cache_attributes(cpu);
874 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
876 int err;
878 if (num_cache_leaves == 0)
879 return -ENOENT;
881 err = detect_cache_attributes(cpu);
882 if (err)
883 return err;
885 /* Allocate all required memory */
886 per_cpu(ici_cache_kobject, cpu) =
887 kzalloc(sizeof(struct kobject), GFP_KERNEL);
888 if (unlikely(per_cpu(ici_cache_kobject, cpu) == NULL))
889 goto err_out;
891 per_cpu(ici_index_kobject, cpu) = kzalloc(
892 sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL);
893 if (unlikely(per_cpu(ici_index_kobject, cpu) == NULL))
894 goto err_out;
896 return 0;
898 err_out:
899 cpuid4_cache_sysfs_exit(cpu);
900 return -ENOMEM;
903 static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
905 /* Add/Remove cache interface for CPU device */
906 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
908 unsigned int cpu = sys_dev->id;
909 unsigned long i, j;
910 struct _index_kobject *this_object;
911 int retval;
913 retval = cpuid4_cache_sysfs_init(cpu);
914 if (unlikely(retval < 0))
915 return retval;
917 retval = kobject_init_and_add(per_cpu(ici_cache_kobject, cpu),
918 &ktype_percpu_entry,
919 &sys_dev->kobj, "%s", "cache");
920 if (retval < 0) {
921 cpuid4_cache_sysfs_exit(cpu);
922 return retval;
925 for (i = 0; i < num_cache_leaves; i++) {
926 this_object = INDEX_KOBJECT_PTR(cpu, i);
927 this_object->cpu = cpu;
928 this_object->index = i;
929 retval = kobject_init_and_add(&(this_object->kobj),
930 &ktype_cache,
931 per_cpu(ici_cache_kobject, cpu),
932 "index%1lu", i);
933 if (unlikely(retval)) {
934 for (j = 0; j < i; j++)
935 kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj));
936 kobject_put(per_cpu(ici_cache_kobject, cpu));
937 cpuid4_cache_sysfs_exit(cpu);
938 return retval;
940 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
942 cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
944 kobject_uevent(per_cpu(ici_cache_kobject, cpu), KOBJ_ADD);
945 return 0;
948 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
950 unsigned int cpu = sys_dev->id;
951 unsigned long i;
953 if (per_cpu(ici_cpuid4_info, cpu) == NULL)
954 return;
955 if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
956 return;
957 cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
959 for (i = 0; i < num_cache_leaves; i++)
960 kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj));
961 kobject_put(per_cpu(ici_cache_kobject, cpu));
962 cpuid4_cache_sysfs_exit(cpu);
965 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
966 unsigned long action, void *hcpu)
968 unsigned int cpu = (unsigned long)hcpu;
969 struct sys_device *sys_dev;
971 sys_dev = get_cpu_sysdev(cpu);
972 switch (action) {
973 case CPU_ONLINE:
974 case CPU_ONLINE_FROZEN:
975 cache_add_dev(sys_dev);
976 break;
977 case CPU_DEAD:
978 case CPU_DEAD_FROZEN:
979 cache_remove_dev(sys_dev);
980 break;
982 return NOTIFY_OK;
985 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
986 .notifier_call = cacheinfo_cpu_callback,
989 static int __cpuinit cache_sysfs_init(void)
991 int i;
993 if (num_cache_leaves == 0)
994 return 0;
996 for_each_online_cpu(i) {
997 int err;
998 struct sys_device *sys_dev = get_cpu_sysdev(i);
1000 err = cache_add_dev(sys_dev);
1001 if (err)
1002 return err;
1004 register_hotcpu_notifier(&cacheinfo_cpu_notifier);
1005 return 0;
1008 device_initcall(cache_sysfs_init);
1010 #endif