Pull novell-bugzilla-156426 into release branch
[pandora-kernel.git] / arch / x86_64 / kernel / mce_amd.c
1 /*
2  *  (c) 2005 Advanced Micro Devices, Inc.
3  *  Your use of this code is subject to the terms and conditions of the
4  *  GNU general public license version 2. See "COPYING" or
5  *  http://www.gnu.org/licenses/gpl.html
6  *
7  *  Written by Jacob Shin - AMD, Inc.
8  *
9  *  Support : jacob.shin@amd.com
10  *
11  *  MC4_MISC0 DRAM ECC Error Threshold available under AMD K8 Rev F.
12  *  MC4_MISC0 exists per physical processor.
13  *
14  */
15
16 #include <linux/cpu.h>
17 #include <linux/errno.h>
18 #include <linux/init.h>
19 #include <linux/interrupt.h>
20 #include <linux/kobject.h>
21 #include <linux/notifier.h>
22 #include <linux/sched.h>
23 #include <linux/smp.h>
24 #include <linux/sysdev.h>
25 #include <linux/sysfs.h>
26 #include <asm/apic.h>
27 #include <asm/mce.h>
28 #include <asm/msr.h>
29 #include <asm/percpu.h>
30 #include <asm/idle.h>
31
32 #define PFX "mce_threshold: "
33 #define VERSION "version 1.00.9"
34 #define NR_BANKS 5
35 #define THRESHOLD_MAX 0xFFF
36 #define INT_TYPE_APIC 0x00020000
37 #define MASK_VALID_HI 0x80000000
38 #define MASK_LVTOFF_HI 0x00F00000
39 #define MASK_COUNT_EN_HI 0x00080000
40 #define MASK_INT_TYPE_HI 0x00060000
41 #define MASK_OVERFLOW_HI 0x00010000
42 #define MASK_ERR_COUNT_HI 0x00000FFF
43 #define MASK_OVERFLOW 0x0001000000000000L
44
45 struct threshold_bank {
46         unsigned int cpu;
47         u8 bank;
48         u8 interrupt_enable;
49         u16 threshold_limit;
50         struct kobject kobj;
51 };
52
53 static struct threshold_bank threshold_defaults = {
54         .interrupt_enable = 0,
55         .threshold_limit = THRESHOLD_MAX,
56 };
57
58 #ifdef CONFIG_SMP
59 static unsigned char shared_bank[NR_BANKS] = {
60         0, 0, 0, 0, 1
61 };
62 #endif
63
64 static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */
65
66 /*
67  * CPU Initialization
68  */
69
70 /* must be called with correct cpu affinity */
71 static void threshold_restart_bank(struct threshold_bank *b,
72                                    int reset, u16 old_limit)
73 {
74         u32 mci_misc_hi, mci_misc_lo;
75
76         rdmsr(MSR_IA32_MC0_MISC + b->bank * 4, mci_misc_lo, mci_misc_hi);
77
78         if (b->threshold_limit < (mci_misc_hi & THRESHOLD_MAX))
79                 reset = 1;      /* limit cannot be lower than err count */
80
81         if (reset) {            /* reset err count and overflow bit */
82                 mci_misc_hi =
83                     (mci_misc_hi & ~(MASK_ERR_COUNT_HI | MASK_OVERFLOW_HI)) |
84                     (THRESHOLD_MAX - b->threshold_limit);
85         } else if (old_limit) { /* change limit w/o reset */
86                 int new_count = (mci_misc_hi & THRESHOLD_MAX) +
87                     (old_limit - b->threshold_limit);
88                 mci_misc_hi = (mci_misc_hi & ~MASK_ERR_COUNT_HI) |
89                     (new_count & THRESHOLD_MAX);
90         }
91
92         b->interrupt_enable ?
93             (mci_misc_hi = (mci_misc_hi & ~MASK_INT_TYPE_HI) | INT_TYPE_APIC) :
94             (mci_misc_hi &= ~MASK_INT_TYPE_HI);
95
96         mci_misc_hi |= MASK_COUNT_EN_HI;
97         wrmsr(MSR_IA32_MC0_MISC + b->bank * 4, mci_misc_lo, mci_misc_hi);
98 }
99
100 void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c)
101 {
102         int bank;
103         u32 mci_misc_lo, mci_misc_hi;
104         unsigned int cpu = smp_processor_id();
105
106         for (bank = 0; bank < NR_BANKS; ++bank) {
107                 rdmsr(MSR_IA32_MC0_MISC + bank * 4, mci_misc_lo, mci_misc_hi);
108
109                 /* !valid, !counter present, bios locked */
110                 if (!(mci_misc_hi & MASK_VALID_HI) ||
111                     !(mci_misc_hi & MASK_VALID_HI >> 1) ||
112                     (mci_misc_hi & MASK_VALID_HI >> 2))
113                         continue;
114
115                 per_cpu(bank_map, cpu) |= (1 << bank);
116
117 #ifdef CONFIG_SMP
118                 if (shared_bank[bank] && cpu_core_id[cpu])
119                         continue;
120 #endif
121
122                 setup_threshold_lvt((mci_misc_hi & MASK_LVTOFF_HI) >> 20);
123                 threshold_defaults.cpu = cpu;
124                 threshold_defaults.bank = bank;
125                 threshold_restart_bank(&threshold_defaults, 0, 0);
126         }
127 }
128
129 /*
130  * APIC Interrupt Handler
131  */
132
133 /*
134  * threshold interrupt handler will service THRESHOLD_APIC_VECTOR.
135  * the interrupt goes off when error_count reaches threshold_limit.
136  * the handler will simply log mcelog w/ software defined bank number.
137  */
138 asmlinkage void mce_threshold_interrupt(void)
139 {
140         int bank;
141         struct mce m;
142
143         ack_APIC_irq();
144         exit_idle();
145         irq_enter();
146
147         memset(&m, 0, sizeof(m));
148         rdtscll(m.tsc);
149         m.cpu = smp_processor_id();
150
151         /* assume first bank caused it */
152         for (bank = 0; bank < NR_BANKS; ++bank) {
153                 m.bank = MCE_THRESHOLD_BASE + bank;
154                 rdmsrl(MSR_IA32_MC0_MISC + bank * 4, m.misc);
155
156                 if (m.misc & MASK_OVERFLOW) {
157                         mce_log(&m);
158                         goto out;
159                 }
160         }
161       out:
162         irq_exit();
163 }
164
165 /*
166  * Sysfs Interface
167  */
168
169 static struct sysdev_class threshold_sysclass = {
170         set_kset_name("threshold"),
171 };
172
173 static DEFINE_PER_CPU(struct sys_device, device_threshold);
174
175 struct threshold_attr {
176         struct attribute attr;
177         ssize_t(*show) (struct threshold_bank *, char *);
178         ssize_t(*store) (struct threshold_bank *, const char *, size_t count);
179 };
180
181 static DEFINE_PER_CPU(struct threshold_bank *, threshold_banks[NR_BANKS]);
182
183 static cpumask_t affinity_set(unsigned int cpu)
184 {
185         cpumask_t oldmask = current->cpus_allowed;
186         cpumask_t newmask = CPU_MASK_NONE;
187         cpu_set(cpu, newmask);
188         set_cpus_allowed(current, newmask);
189         return oldmask;
190 }
191
192 static void affinity_restore(cpumask_t oldmask)
193 {
194         set_cpus_allowed(current, oldmask);
195 }
196
197 #define SHOW_FIELDS(name) \
198         static ssize_t show_ ## name(struct threshold_bank * b, char *buf) \
199         { \
200                 return sprintf(buf, "%lx\n", (unsigned long) b->name); \
201         }
202 SHOW_FIELDS(interrupt_enable)
203 SHOW_FIELDS(threshold_limit)
204
205 static ssize_t store_interrupt_enable(struct threshold_bank *b,
206                                       const char *buf, size_t count)
207 {
208         char *end;
209         cpumask_t oldmask;
210         unsigned long new = simple_strtoul(buf, &end, 0);
211         if (end == buf)
212                 return -EINVAL;
213         b->interrupt_enable = !!new;
214
215         oldmask = affinity_set(b->cpu);
216         threshold_restart_bank(b, 0, 0);
217         affinity_restore(oldmask);
218
219         return end - buf;
220 }
221
222 static ssize_t store_threshold_limit(struct threshold_bank *b,
223                                      const char *buf, size_t count)
224 {
225         char *end;
226         cpumask_t oldmask;
227         u16 old;
228         unsigned long new = simple_strtoul(buf, &end, 0);
229         if (end == buf)
230                 return -EINVAL;
231         if (new > THRESHOLD_MAX)
232                 new = THRESHOLD_MAX;
233         if (new < 1)
234                 new = 1;
235         old = b->threshold_limit;
236         b->threshold_limit = new;
237
238         oldmask = affinity_set(b->cpu);
239         threshold_restart_bank(b, 0, old);
240         affinity_restore(oldmask);
241
242         return end - buf;
243 }
244
245 static ssize_t show_error_count(struct threshold_bank *b, char *buf)
246 {
247         u32 high, low;
248         cpumask_t oldmask;
249         oldmask = affinity_set(b->cpu);
250         rdmsr(MSR_IA32_MC0_MISC + b->bank * 4, low, high); /* ignore low 32 */
251         affinity_restore(oldmask);
252         return sprintf(buf, "%x\n",
253                        (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit));
254 }
255
256 static ssize_t store_error_count(struct threshold_bank *b,
257                                  const char *buf, size_t count)
258 {
259         cpumask_t oldmask;
260         oldmask = affinity_set(b->cpu);
261         threshold_restart_bank(b, 1, 0);
262         affinity_restore(oldmask);
263         return 1;
264 }
265
266 #define THRESHOLD_ATTR(_name,_mode,_show,_store) {            \
267         .attr = {.name = __stringify(_name), .mode = _mode }, \
268         .show = _show,                                        \
269         .store = _store,                                      \
270 };
271
272 #define ATTR_FIELDS(name) \
273         static struct threshold_attr name = \
274         THRESHOLD_ATTR(name, 0644, show_## name, store_## name)
275
276 ATTR_FIELDS(interrupt_enable);
277 ATTR_FIELDS(threshold_limit);
278 ATTR_FIELDS(error_count);
279
280 static struct attribute *default_attrs[] = {
281         &interrupt_enable.attr,
282         &threshold_limit.attr,
283         &error_count.attr,
284         NULL
285 };
286
287 #define to_bank(k) container_of(k,struct threshold_bank,kobj)
288 #define to_attr(a) container_of(a,struct threshold_attr,attr)
289
290 static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
291 {
292         struct threshold_bank *b = to_bank(kobj);
293         struct threshold_attr *a = to_attr(attr);
294         ssize_t ret;
295         ret = a->show ? a->show(b, buf) : -EIO;
296         return ret;
297 }
298
299 static ssize_t store(struct kobject *kobj, struct attribute *attr,
300                      const char *buf, size_t count)
301 {
302         struct threshold_bank *b = to_bank(kobj);
303         struct threshold_attr *a = to_attr(attr);
304         ssize_t ret;
305         ret = a->store ? a->store(b, buf, count) : -EIO;
306         return ret;
307 }
308
309 static struct sysfs_ops threshold_ops = {
310         .show = show,
311         .store = store,
312 };
313
314 static struct kobj_type threshold_ktype = {
315         .sysfs_ops = &threshold_ops,
316         .default_attrs = default_attrs,
317 };
318
319 /* symlinks sibling shared banks to first core.  first core owns dir/files. */
320 static __cpuinit int threshold_create_bank(unsigned int cpu, int bank)
321 {
322         int err = 0;
323         struct threshold_bank *b = NULL;
324
325 #ifdef CONFIG_SMP
326         if (cpu_core_id[cpu] && shared_bank[bank]) {    /* symlink */
327                 char name[16];
328                 unsigned lcpu = first_cpu(cpu_core_map[cpu]);
329                 if (cpu_core_id[lcpu])
330                         goto out;       /* first core not up yet */
331
332                 b = per_cpu(threshold_banks, lcpu)[bank];
333                 if (!b)
334                         goto out;
335                 sprintf(name, "bank%i", bank);
336                 err = sysfs_create_link(&per_cpu(device_threshold, cpu).kobj,
337                                         &b->kobj, name);
338                 if (err)
339                         goto out;
340                 per_cpu(threshold_banks, cpu)[bank] = b;
341                 goto out;
342         }
343 #endif
344
345         b = kmalloc(sizeof(struct threshold_bank), GFP_KERNEL);
346         if (!b) {
347                 err = -ENOMEM;
348                 goto out;
349         }
350         memset(b, 0, sizeof(struct threshold_bank));
351
352         b->cpu = cpu;
353         b->bank = bank;
354         b->interrupt_enable = 0;
355         b->threshold_limit = THRESHOLD_MAX;
356         kobject_set_name(&b->kobj, "bank%i", bank);
357         b->kobj.parent = &per_cpu(device_threshold, cpu).kobj;
358         b->kobj.ktype = &threshold_ktype;
359
360         err = kobject_register(&b->kobj);
361         if (err) {
362                 kfree(b);
363                 goto out;
364         }
365         per_cpu(threshold_banks, cpu)[bank] = b;
366       out:
367         return err;
368 }
369
370 /* create dir/files for all valid threshold banks */
371 static __cpuinit int threshold_create_device(unsigned int cpu)
372 {
373         int bank;
374         int err = 0;
375
376         per_cpu(device_threshold, cpu).id = cpu;
377         per_cpu(device_threshold, cpu).cls = &threshold_sysclass;
378         err = sysdev_register(&per_cpu(device_threshold, cpu));
379         if (err)
380                 goto out;
381
382         for (bank = 0; bank < NR_BANKS; ++bank) {
383                 if (!(per_cpu(bank_map, cpu) & 1 << bank))
384                         continue;
385                 err = threshold_create_bank(cpu, bank);
386                 if (err)
387                         goto out;
388         }
389       out:
390         return err;
391 }
392
393 #ifdef CONFIG_HOTPLUG_CPU
394 /*
395  * let's be hotplug friendly.
396  * in case of multiple core processors, the first core always takes ownership
397  *   of shared sysfs dir/files, and rest of the cores will be symlinked to it.
398  */
399
400 /* cpu hotplug call removes all symlinks before first core dies */
401 static __cpuinit void threshold_remove_bank(unsigned int cpu, int bank)
402 {
403         struct threshold_bank *b;
404         char name[16];
405
406         b = per_cpu(threshold_banks, cpu)[bank];
407         if (!b)
408                 return;
409         if (shared_bank[bank] && atomic_read(&b->kobj.kref.refcount) > 2) {
410                 sprintf(name, "bank%i", bank);
411                 sysfs_remove_link(&per_cpu(device_threshold, cpu).kobj, name);
412                 per_cpu(threshold_banks, cpu)[bank] = NULL;
413         } else {
414                 kobject_unregister(&b->kobj);
415                 kfree(per_cpu(threshold_banks, cpu)[bank]);
416         }
417 }
418
419 static __cpuinit void threshold_remove_device(unsigned int cpu)
420 {
421         int bank;
422
423         for (bank = 0; bank < NR_BANKS; ++bank) {
424                 if (!(per_cpu(bank_map, cpu) & 1 << bank))
425                         continue;
426                 threshold_remove_bank(cpu, bank);
427         }
428         sysdev_unregister(&per_cpu(device_threshold, cpu));
429 }
430
431 /* link all existing siblings when first core comes up */
432 static __cpuinit int threshold_create_symlinks(unsigned int cpu)
433 {
434         int bank, err = 0;
435         unsigned int lcpu = 0;
436
437         if (cpu_core_id[cpu])
438                 return 0;
439         for_each_cpu_mask(lcpu, cpu_core_map[cpu]) {
440                 if (lcpu == cpu)
441                         continue;
442                 for (bank = 0; bank < NR_BANKS; ++bank) {
443                         if (!(per_cpu(bank_map, cpu) & 1 << bank))
444                                 continue;
445                         if (!shared_bank[bank])
446                                 continue;
447                         err = threshold_create_bank(lcpu, bank);
448                 }
449         }
450         return err;
451 }
452
453 /* remove all symlinks before first core dies. */
454 static __cpuinit void threshold_remove_symlinks(unsigned int cpu)
455 {
456         int bank;
457         unsigned int lcpu = 0;
458         if (cpu_core_id[cpu])
459                 return;
460         for_each_cpu_mask(lcpu, cpu_core_map[cpu]) {
461                 if (lcpu == cpu)
462                         continue;
463                 for (bank = 0; bank < NR_BANKS; ++bank) {
464                         if (!(per_cpu(bank_map, cpu) & 1 << bank))
465                                 continue;
466                         if (!shared_bank[bank])
467                                 continue;
468                         threshold_remove_bank(lcpu, bank);
469                 }
470         }
471 }
472 #else /* !CONFIG_HOTPLUG_CPU */
473 static __cpuinit void threshold_create_symlinks(unsigned int cpu)
474 {
475 }
476 static __cpuinit void threshold_remove_symlinks(unsigned int cpu)
477 {
478 }
479 static void threshold_remove_device(unsigned int cpu)
480 {
481 }
482 #endif
483
484 /* get notified when a cpu comes on/off */
485 static int threshold_cpu_callback(struct notifier_block *nfb,
486                                             unsigned long action, void *hcpu)
487 {
488         /* cpu was unsigned int to begin with */
489         unsigned int cpu = (unsigned long)hcpu;
490
491         if (cpu >= NR_CPUS)
492                 goto out;
493
494         switch (action) {
495         case CPU_ONLINE:
496                 threshold_create_device(cpu);
497                 threshold_create_symlinks(cpu);
498                 break;
499         case CPU_DOWN_PREPARE:
500                 threshold_remove_symlinks(cpu);
501                 break;
502         case CPU_DOWN_FAILED:
503                 threshold_create_symlinks(cpu);
504                 break;
505         case CPU_DEAD:
506                 threshold_remove_device(cpu);
507                 break;
508         default:
509                 break;
510         }
511       out:
512         return NOTIFY_OK;
513 }
514
515 static struct notifier_block threshold_cpu_notifier = {
516         .notifier_call = threshold_cpu_callback,
517 };
518
519 static __init int threshold_init_device(void)
520 {
521         int err;
522         int lcpu = 0;
523
524         err = sysdev_class_register(&threshold_sysclass);
525         if (err)
526                 goto out;
527
528         /* to hit CPUs online before the notifier is up */
529         for_each_online_cpu(lcpu) {
530                 err = threshold_create_device(lcpu);
531                 if (err)
532                         goto out;
533         }
534         register_cpu_notifier(&threshold_cpu_notifier);
535
536       out:
537         return err;
538 }
539
540 device_initcall(threshold_init_device);