diff options
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/kernel/mce_amd.c | 112 |
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: | 225 | out: |
226 | irq_exit(); | 226 | irq_exit(); |
227 | } | 227 | } |
228 | 228 | ||
@@ -231,7 +231,7 @@ asmlinkage void mce_threshold_interrupt(void) | |||
231 | */ | 231 | */ |
232 | 232 | ||
233 | struct threshold_attr { | 233 | struct 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) \ | 254 | static 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 | } |
258 | SHOW_FIELDS(interrupt_enable) | 258 | SHOW_FIELDS(interrupt_enable) |
259 | SHOW_FIELDS(threshold_limit) | 259 | SHOW_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 = \ | 329 | static struct threshold_attr name = \ |
330 | THRESHOLD_ATTR(name, 0644, show_## name, store_## name) | 330 | THRESHOLD_ATTR(name, 0644, show_## name, store_## name) |
331 | 331 | ||
332 | ATTR_FIELDS(interrupt_enable); | 332 | RW_ATTR(interrupt_enable); |
333 | ATTR_FIELDS(threshold_limit); | 333 | RW_ATTR(threshold_limit); |
334 | ATTR_FIELDS(error_count); | 334 | RW_ATTR(error_count); |
335 | 335 | ||
336 | static struct attribute *default_attrs[] = { | 336 | static 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 | ||
346 | static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) | 346 | static 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) | |||
530 | out_free: | 530 | out_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: | 533 | out: |
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 */ |
538 | static __cpuinit int threshold_create_device(unsigned int cpu) | 538 | static __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: | 550 | out: |
551 | return err; | 551 | return err; |
552 | } | 552 | } |
553 | 553 | ||
@@ -620,7 +620,7 @@ free_out: | |||
620 | 620 | ||
621 | static __cpuinit void threshold_remove_device(unsigned int cpu) | 621 | static __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 */ | ||
633 | static __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. */ | ||
655 | static __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 */ |
674 | static __cpuinit void threshold_create_symlinks(unsigned int cpu) | ||
675 | { | ||
676 | } | ||
677 | static __cpuinit void threshold_remove_symlinks(unsigned int cpu) | ||
678 | { | ||
679 | } | ||
680 | static void threshold_remove_device(unsigned int cpu) | 633 | static 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 | ||
720 | static __init int threshold_init_device(void) | 666 | static __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) { |