aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/kernel/mce_amd.c112
1 files changed, 29 insertions, 83 deletions
diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86_64/kernel/mce_amd.c
index 10ffbe52939c..3f967d4fe199 100644
--- a/arch/x86_64/kernel/mce_amd.c
+++ b/arch/x86_64/kernel/mce_amd.c
@@ -30,17 +30,17 @@
30#include <asm/percpu.h> 30#include <asm/percpu.h>
31#include <asm/idle.h> 31#include <asm/idle.h>
32 32
33#define PFX "mce_threshold: " 33#define PFX "mce_threshold: "
34#define VERSION "version 1.1.0" 34#define VERSION "version 1.1.1"
35#define NR_BANKS 6 35#define NR_BANKS 6
36#define NR_BLOCKS 9 36#define NR_BLOCKS 9
37#define THRESHOLD_MAX 0xFFF 37#define THRESHOLD_MAX 0xFFF
38#define INT_TYPE_APIC 0x00020000 38#define INT_TYPE_APIC 0x00020000
39#define MASK_VALID_HI 0x80000000 39#define MASK_VALID_HI 0x80000000
40#define MASK_LVTOFF_HI 0x00F00000 40#define MASK_LVTOFF_HI 0x00F00000
41#define MASK_COUNT_EN_HI 0x00080000 41#define MASK_COUNT_EN_HI 0x00080000
42#define MASK_INT_TYPE_HI 0x00060000 42#define MASK_INT_TYPE_HI 0x00060000
43#define MASK_OVERFLOW_HI 0x00010000 43#define MASK_OVERFLOW_HI 0x00010000
44#define MASK_ERR_COUNT_HI 0x00000FFF 44#define MASK_ERR_COUNT_HI 0x00000FFF
45#define MASK_BLKPTR_LO 0xFF000000 45#define MASK_BLKPTR_LO 0xFF000000
46#define MCG_XBLK_ADDR 0xC0000400 46#define MCG_XBLK_ADDR 0xC0000400
@@ -222,7 +222,7 @@ asmlinkage void mce_threshold_interrupt(void)
222 } 222 }
223 } 223 }
224 } 224 }
225 out: 225out:
226 irq_exit(); 226 irq_exit();
227} 227}
228 228
@@ -231,7 +231,7 @@ asmlinkage void mce_threshold_interrupt(void)
231 */ 231 */
232 232
233struct threshold_attr { 233struct threshold_attr {
234 struct attribute attr; 234 struct attribute attr;
235 ssize_t(*show) (struct threshold_block *, char *); 235 ssize_t(*show) (struct threshold_block *, char *);
236 ssize_t(*store) (struct threshold_block *, const char *, size_t count); 236 ssize_t(*store) (struct threshold_block *, const char *, size_t count);
237}; 237};
@@ -250,11 +250,11 @@ static void affinity_restore(cpumask_t oldmask)
250 set_cpus_allowed(current, oldmask); 250 set_cpus_allowed(current, oldmask);
251} 251}
252 252
253#define SHOW_FIELDS(name) \ 253#define SHOW_FIELDS(name) \
254 static ssize_t show_ ## name(struct threshold_block * b, char *buf) \ 254static ssize_t show_ ## name(struct threshold_block * b, char *buf) \
255 { \ 255{ \
256 return sprintf(buf, "%lx\n", (unsigned long) b->name); \ 256 return sprintf(buf, "%lx\n", (unsigned long) b->name); \
257 } 257}
258SHOW_FIELDS(interrupt_enable) 258SHOW_FIELDS(interrupt_enable)
259SHOW_FIELDS(threshold_limit) 259SHOW_FIELDS(threshold_limit)
260 260
@@ -325,13 +325,13 @@ static ssize_t store_error_count(struct threshold_block *b,
325 .store = _store, \ 325 .store = _store, \
326}; 326};
327 327
328#define ATTR_FIELDS(name) \ 328#define RW_ATTR(name) \
329 static struct threshold_attr name = \ 329static struct threshold_attr name = \
330 THRESHOLD_ATTR(name, 0644, show_## name, store_## name) 330 THRESHOLD_ATTR(name, 0644, show_## name, store_## name)
331 331
332ATTR_FIELDS(interrupt_enable); 332RW_ATTR(interrupt_enable);
333ATTR_FIELDS(threshold_limit); 333RW_ATTR(threshold_limit);
334ATTR_FIELDS(error_count); 334RW_ATTR(error_count);
335 335
336static struct attribute *default_attrs[] = { 336static struct attribute *default_attrs[] = {
337 &interrupt_enable.attr, 337 &interrupt_enable.attr,
@@ -341,7 +341,7 @@ static struct attribute *default_attrs[] = {
341}; 341};
342 342
343#define to_block(k) container_of(k, struct threshold_block, kobj) 343#define to_block(k) container_of(k, struct threshold_block, kobj)
344#define to_attr(a) container_of(a,struct threshold_attr,attr) 344#define to_attr(a) container_of(a, struct threshold_attr, attr)
345 345
346static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) 346static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
347{ 347{
@@ -530,14 +530,14 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
530out_free: 530out_free:
531 per_cpu(threshold_banks, cpu)[bank] = NULL; 531 per_cpu(threshold_banks, cpu)[bank] = NULL;
532 kfree(b); 532 kfree(b);
533 out: 533out:
534 return err; 534 return err;
535} 535}
536 536
537/* create dir/files for all valid threshold banks */ 537/* create dir/files for all valid threshold banks */
538static __cpuinit int threshold_create_device(unsigned int cpu) 538static __cpuinit int threshold_create_device(unsigned int cpu)
539{ 539{
540 int bank; 540 unsigned int bank;
541 int err = 0; 541 int err = 0;
542 542
543 for (bank = 0; bank < NR_BANKS; ++bank) { 543 for (bank = 0; bank < NR_BANKS; ++bank) {
@@ -547,7 +547,7 @@ static __cpuinit int threshold_create_device(unsigned int cpu)
547 if (err) 547 if (err)
548 goto out; 548 goto out;
549 } 549 }
550 out: 550out:
551 return err; 551 return err;
552} 552}
553 553
@@ -620,7 +620,7 @@ free_out:
620 620
621static __cpuinit void threshold_remove_device(unsigned int cpu) 621static __cpuinit void threshold_remove_device(unsigned int cpu)
622{ 622{
623 int bank; 623 unsigned int bank;
624 624
625 for (bank = 0; bank < NR_BANKS; ++bank) { 625 for (bank = 0; bank < NR_BANKS; ++bank) {
626 if (!(per_cpu(bank_map, cpu) & 1 << bank)) 626 if (!(per_cpu(bank_map, cpu) & 1 << bank))
@@ -629,54 +629,7 @@ static __cpuinit void threshold_remove_device(unsigned int cpu)
629 } 629 }
630} 630}
631 631
632/* link all existing siblings when first core comes up */
633static __cpuinit int threshold_create_symlinks(unsigned int cpu)
634{
635 int bank, err = 0;
636 unsigned int lcpu = 0;
637
638 if (cpu_data[cpu].cpu_core_id)
639 return 0;
640 for_each_cpu_mask(lcpu, cpu_core_map[cpu]) {
641 if (lcpu == cpu)
642 continue;
643 for (bank = 0; bank < NR_BANKS; ++bank) {
644 if (!(per_cpu(bank_map, cpu) & 1 << bank))
645 continue;
646 if (!shared_bank[bank])
647 continue;
648 err = threshold_create_bank(lcpu, bank);
649 }
650 }
651 return err;
652}
653
654/* remove all symlinks before first core dies. */
655static __cpuinit void threshold_remove_symlinks(unsigned int cpu)
656{
657 int bank;
658 unsigned int lcpu = 0;
659 if (cpu_data[cpu].cpu_core_id)
660 return;
661 for_each_cpu_mask(lcpu, cpu_core_map[cpu]) {
662 if (lcpu == cpu)
663 continue;
664 for (bank = 0; bank < NR_BANKS; ++bank) {
665 if (!(per_cpu(bank_map, cpu) & 1 << bank))
666 continue;
667 if (!shared_bank[bank])
668 continue;
669 threshold_remove_bank(lcpu, bank);
670 }
671 }
672}
673#else /* !CONFIG_HOTPLUG_CPU */ 632#else /* !CONFIG_HOTPLUG_CPU */
674static __cpuinit void threshold_create_symlinks(unsigned int cpu)
675{
676}
677static __cpuinit void threshold_remove_symlinks(unsigned int cpu)
678{
679}
680static void threshold_remove_device(unsigned int cpu) 633static void threshold_remove_device(unsigned int cpu)
681{ 634{
682} 635}
@@ -695,13 +648,6 @@ static int threshold_cpu_callback(struct notifier_block *nfb,
695 switch (action) { 648 switch (action) {
696 case CPU_ONLINE: 649 case CPU_ONLINE:
697 threshold_create_device(cpu); 650 threshold_create_device(cpu);
698 threshold_create_symlinks(cpu);
699 break;
700 case CPU_DOWN_PREPARE:
701 threshold_remove_symlinks(cpu);
702 break;
703 case CPU_DOWN_FAILED:
704 threshold_create_symlinks(cpu);
705 break; 651 break;
706 case CPU_DEAD: 652 case CPU_DEAD:
707 threshold_remove_device(cpu); 653 threshold_remove_device(cpu);
@@ -719,7 +665,7 @@ static struct notifier_block threshold_cpu_notifier = {
719 665
720static __init int threshold_init_device(void) 666static __init int threshold_init_device(void)
721{ 667{
722 int lcpu = 0; 668 unsigned lcpu = 0;
723 669
724 /* to hit CPUs online before the notifier is up */ 670 /* to hit CPUs online before the notifier is up */
725 for_each_online_cpu(lcpu) { 671 for_each_online_cpu(lcpu) {