diff options
Diffstat (limited to 'arch/x86/kernel/cpu')
| -rw-r--r-- | arch/x86/kernel/cpu/amd.c | 26 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/bugs.c | 41 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/common.c | 14 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/intel.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/intel_cacheinfo.c | 75 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-internal.h | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-severity.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 209 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_amd.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_intel.c | 39 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mtrr/main.c | 11 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 121 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.h | 5 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_amd.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_uncore.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_p6.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/proc.c | 7 |
18 files changed, 365 insertions, 221 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f7e98a2c0d12..15239fffd6fe 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
| @@ -304,7 +304,7 @@ static void __cpuinit amd_get_topology(struct cpuinfo_x86 *c) | |||
| 304 | int cpu = smp_processor_id(); | 304 | int cpu = smp_processor_id(); |
| 305 | 305 | ||
| 306 | /* get information required for multi-node processors */ | 306 | /* get information required for multi-node processors */ |
| 307 | if (cpu_has(c, X86_FEATURE_TOPOEXT)) { | 307 | if (cpu_has_topoext) { |
| 308 | u32 eax, ebx, ecx, edx; | 308 | u32 eax, ebx, ecx, edx; |
| 309 | 309 | ||
| 310 | cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); | 310 | cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); |
| @@ -631,6 +631,20 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
| 631 | } | 631 | } |
| 632 | } | 632 | } |
| 633 | 633 | ||
| 634 | /* | ||
| 635 | * The way access filter has a performance penalty on some workloads. | ||
| 636 | * Disable it on the affected CPUs. | ||
| 637 | */ | ||
| 638 | if ((c->x86 == 0x15) && | ||
| 639 | (c->x86_model >= 0x02) && (c->x86_model < 0x20)) { | ||
| 640 | u64 val; | ||
| 641 | |||
| 642 | if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) { | ||
| 643 | val |= 0x1E; | ||
| 644 | wrmsrl_safe(0xc0011021, val); | ||
| 645 | } | ||
| 646 | } | ||
| 647 | |||
| 634 | cpu_detect_cache_sizes(c); | 648 | cpu_detect_cache_sizes(c); |
| 635 | 649 | ||
| 636 | /* Multi core CPU? */ | 650 | /* Multi core CPU? */ |
| @@ -643,12 +657,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
| 643 | detect_ht(c); | 657 | detect_ht(c); |
| 644 | #endif | 658 | #endif |
| 645 | 659 | ||
| 646 | if (c->extended_cpuid_level >= 0x80000006) { | 660 | init_amd_cacheinfo(c); |
| 647 | if (cpuid_edx(0x80000006) & 0xf000) | ||
| 648 | num_cache_leaves = 4; | ||
| 649 | else | ||
| 650 | num_cache_leaves = 3; | ||
| 651 | } | ||
| 652 | 661 | ||
| 653 | if (c->x86 >= 0xf) | 662 | if (c->x86 >= 0xf) |
| 654 | set_cpu_cap(c, X86_FEATURE_K8); | 663 | set_cpu_cap(c, X86_FEATURE_K8); |
| @@ -739,9 +748,6 @@ static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, | |||
| 739 | 748 | ||
| 740 | static void __cpuinit cpu_set_tlb_flushall_shift(struct cpuinfo_x86 *c) | 749 | static void __cpuinit cpu_set_tlb_flushall_shift(struct cpuinfo_x86 *c) |
| 741 | { | 750 | { |
| 742 | if (!cpu_has_invlpg) | ||
| 743 | return; | ||
| 744 | |||
| 745 | tlb_flushall_shift = 5; | 751 | tlb_flushall_shift = 5; |
| 746 | 752 | ||
| 747 | if (c->x86 <= 0x11) | 753 | if (c->x86 <= 0x11) |
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index d0e910da16c5..92dfec986a48 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
| @@ -107,53 +107,17 @@ static void __init check_hlt(void) | |||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | /* | 109 | /* |
| 110 | * Most 386 processors have a bug where a POPAD can lock the | ||
| 111 | * machine even from user space. | ||
| 112 | */ | ||
| 113 | |||
| 114 | static void __init check_popad(void) | ||
| 115 | { | ||
| 116 | #ifndef CONFIG_X86_POPAD_OK | ||
| 117 | int res, inp = (int) &res; | ||
| 118 | |||
| 119 | pr_info("Checking for popad bug... "); | ||
| 120 | __asm__ __volatile__( | ||
| 121 | "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx " | ||
| 122 | : "=&a" (res) | ||
| 123 | : "d" (inp) | ||
| 124 | : "ecx", "edi"); | ||
| 125 | /* | ||
| 126 | * If this fails, it means that any user program may lock the | ||
| 127 | * CPU hard. Too bad. | ||
| 128 | */ | ||
| 129 | if (res != 12345678) | ||
| 130 | pr_cont("Buggy\n"); | ||
| 131 | else | ||
| 132 | pr_cont("OK\n"); | ||
| 133 | #endif | ||
| 134 | } | ||
| 135 | |||
| 136 | /* | ||
| 137 | * Check whether we are able to run this kernel safely on SMP. | 110 | * Check whether we are able to run this kernel safely on SMP. |
| 138 | * | 111 | * |
| 139 | * - In order to run on a i386, we need to be compiled for i386 | 112 | * - i386 is no longer supported. |
| 140 | * (for due to lack of "invlpg" and working WP on a i386) | ||
| 141 | * - In order to run on anything without a TSC, we need to be | 113 | * - In order to run on anything without a TSC, we need to be |
| 142 | * compiled for a i486. | 114 | * compiled for a i486. |
| 143 | */ | 115 | */ |
| 144 | 116 | ||
| 145 | static void __init check_config(void) | 117 | static void __init check_config(void) |
| 146 | { | 118 | { |
| 147 | /* | 119 | if (boot_cpu_data.x86 < 4) |
| 148 | * We'd better not be a i386 if we're configured to use some | ||
| 149 | * i486+ only features! (WP works in supervisor mode and the | ||
| 150 | * new "invlpg" and "bswap" instructions) | ||
| 151 | */ | ||
| 152 | #if defined(CONFIG_X86_WP_WORKS_OK) || defined(CONFIG_X86_INVLPG) || \ | ||
| 153 | defined(CONFIG_X86_BSWAP) | ||
| 154 | if (boot_cpu_data.x86 == 3) | ||
| 155 | panic("Kernel requires i486+ for 'invlpg' and other features"); | 120 | panic("Kernel requires i486+ for 'invlpg' and other features"); |
| 156 | #endif | ||
| 157 | } | 121 | } |
| 158 | 122 | ||
| 159 | 123 | ||
| @@ -166,7 +130,6 @@ void __init check_bugs(void) | |||
| 166 | #endif | 130 | #endif |
| 167 | check_config(); | 131 | check_config(); |
| 168 | check_hlt(); | 132 | check_hlt(); |
| 169 | check_popad(); | ||
| 170 | init_utsname()->machine[1] = | 133 | init_utsname()->machine[1] = |
| 171 | '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); | 134 | '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); |
| 172 | alternative_instructions(); | 135 | alternative_instructions(); |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 7505f7b13e71..9c3ab43a6954 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -1173,15 +1173,6 @@ DEFINE_PER_CPU(struct task_struct *, fpu_owner_task); | |||
| 1173 | DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary); | 1173 | DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary); |
| 1174 | #endif | 1174 | #endif |
| 1175 | 1175 | ||
| 1176 | /* Make sure %fs and %gs are initialized properly in idle threads */ | ||
| 1177 | struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs) | ||
| 1178 | { | ||
| 1179 | memset(regs, 0, sizeof(struct pt_regs)); | ||
| 1180 | regs->fs = __KERNEL_PERCPU; | ||
| 1181 | regs->gs = __KERNEL_STACK_CANARY; | ||
| 1182 | |||
| 1183 | return regs; | ||
| 1184 | } | ||
| 1185 | #endif /* CONFIG_X86_64 */ | 1176 | #endif /* CONFIG_X86_64 */ |
| 1186 | 1177 | ||
| 1187 | /* | 1178 | /* |
| @@ -1237,7 +1228,7 @@ void __cpuinit cpu_init(void) | |||
| 1237 | oist = &per_cpu(orig_ist, cpu); | 1228 | oist = &per_cpu(orig_ist, cpu); |
| 1238 | 1229 | ||
| 1239 | #ifdef CONFIG_NUMA | 1230 | #ifdef CONFIG_NUMA |
| 1240 | if (cpu != 0 && this_cpu_read(numa_node) == 0 && | 1231 | if (this_cpu_read(numa_node) == 0 && |
| 1241 | early_cpu_to_node(cpu) != NUMA_NO_NODE) | 1232 | early_cpu_to_node(cpu) != NUMA_NO_NODE) |
| 1242 | set_numa_node(early_cpu_to_node(cpu)); | 1233 | set_numa_node(early_cpu_to_node(cpu)); |
| 1243 | #endif | 1234 | #endif |
| @@ -1269,8 +1260,7 @@ void __cpuinit cpu_init(void) | |||
| 1269 | barrier(); | 1260 | barrier(); |
| 1270 | 1261 | ||
| 1271 | x86_configure_nx(); | 1262 | x86_configure_nx(); |
| 1272 | if (cpu != 0) | 1263 | enable_x2apic(); |
| 1273 | enable_x2apic(); | ||
| 1274 | 1264 | ||
| 1275 | /* | 1265 | /* |
| 1276 | * set up and load the per-CPU TSS | 1266 | * set up and load the per-CPU TSS |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 198e019a531a..fcaabd0432c5 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
| @@ -612,10 +612,6 @@ static void __cpuinit intel_tlb_lookup(const unsigned char desc) | |||
| 612 | 612 | ||
| 613 | static void __cpuinit intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c) | 613 | static void __cpuinit intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c) |
| 614 | { | 614 | { |
| 615 | if (!cpu_has_invlpg) { | ||
| 616 | tlb_flushall_shift = -1; | ||
| 617 | return; | ||
| 618 | } | ||
| 619 | switch ((c->x86 << 8) + c->x86_model) { | 615 | switch ((c->x86 << 8) + c->x86_model) { |
| 620 | case 0x60f: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */ | 616 | case 0x60f: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */ |
| 621 | case 0x616: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */ | 617 | case 0x616: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */ |
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 93c5451bdd52..fe9edec6698a 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
| @@ -538,7 +538,11 @@ __cpuinit cpuid4_cache_lookup_regs(int index, | |||
| 538 | unsigned edx; | 538 | unsigned edx; |
| 539 | 539 | ||
| 540 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { | 540 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { |
| 541 | amd_cpuid4(index, &eax, &ebx, &ecx); | 541 | if (cpu_has_topoext) |
| 542 | cpuid_count(0x8000001d, index, &eax.full, | ||
| 543 | &ebx.full, &ecx.full, &edx); | ||
| 544 | else | ||
| 545 | amd_cpuid4(index, &eax, &ebx, &ecx); | ||
| 542 | amd_init_l3_cache(this_leaf, index); | 546 | amd_init_l3_cache(this_leaf, index); |
| 543 | } else { | 547 | } else { |
| 544 | cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); | 548 | cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); |
| @@ -557,21 +561,39 @@ __cpuinit cpuid4_cache_lookup_regs(int index, | |||
| 557 | return 0; | 561 | return 0; |
| 558 | } | 562 | } |
| 559 | 563 | ||
| 560 | static int __cpuinit find_num_cache_leaves(void) | 564 | static int __cpuinit find_num_cache_leaves(struct cpuinfo_x86 *c) |
| 561 | { | 565 | { |
| 562 | unsigned int eax, ebx, ecx, edx; | 566 | unsigned int eax, ebx, ecx, edx, op; |
| 563 | union _cpuid4_leaf_eax cache_eax; | 567 | union _cpuid4_leaf_eax cache_eax; |
| 564 | int i = -1; | 568 | int i = -1; |
| 565 | 569 | ||
| 570 | if (c->x86_vendor == X86_VENDOR_AMD) | ||
| 571 | op = 0x8000001d; | ||
| 572 | else | ||
| 573 | op = 4; | ||
| 574 | |||
| 566 | do { | 575 | do { |
| 567 | ++i; | 576 | ++i; |
| 568 | /* Do cpuid(4) loop to find out num_cache_leaves */ | 577 | /* Do cpuid(op) loop to find out num_cache_leaves */ |
| 569 | cpuid_count(4, i, &eax, &ebx, &ecx, &edx); | 578 | cpuid_count(op, i, &eax, &ebx, &ecx, &edx); |
| 570 | cache_eax.full = eax; | 579 | cache_eax.full = eax; |
| 571 | } while (cache_eax.split.type != CACHE_TYPE_NULL); | 580 | } while (cache_eax.split.type != CACHE_TYPE_NULL); |
| 572 | return i; | 581 | return i; |
| 573 | } | 582 | } |
| 574 | 583 | ||
| 584 | void __cpuinit init_amd_cacheinfo(struct cpuinfo_x86 *c) | ||
| 585 | { | ||
| 586 | |||
| 587 | if (cpu_has_topoext) { | ||
| 588 | num_cache_leaves = find_num_cache_leaves(c); | ||
| 589 | } else if (c->extended_cpuid_level >= 0x80000006) { | ||
| 590 | if (cpuid_edx(0x80000006) & 0xf000) | ||
| 591 | num_cache_leaves = 4; | ||
| 592 | else | ||
| 593 | num_cache_leaves = 3; | ||
| 594 | } | ||
| 595 | } | ||
| 596 | |||
| 575 | unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | 597 | unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) |
| 576 | { | 598 | { |
| 577 | /* Cache sizes */ | 599 | /* Cache sizes */ |
| @@ -588,7 +610,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
| 588 | 610 | ||
| 589 | if (is_initialized == 0) { | 611 | if (is_initialized == 0) { |
| 590 | /* Init num_cache_leaves from boot CPU */ | 612 | /* Init num_cache_leaves from boot CPU */ |
| 591 | num_cache_leaves = find_num_cache_leaves(); | 613 | num_cache_leaves = find_num_cache_leaves(c); |
| 592 | is_initialized++; | 614 | is_initialized++; |
| 593 | } | 615 | } |
| 594 | 616 | ||
| @@ -728,37 +750,50 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info); | |||
| 728 | static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) | 750 | static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) |
| 729 | { | 751 | { |
| 730 | struct _cpuid4_info *this_leaf; | 752 | struct _cpuid4_info *this_leaf; |
| 731 | int ret, i, sibling; | 753 | int i, sibling; |
| 732 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
| 733 | 754 | ||
| 734 | ret = 0; | 755 | if (cpu_has_topoext) { |
| 735 | if (index == 3) { | 756 | unsigned int apicid, nshared, first, last; |
| 736 | ret = 1; | 757 | |
| 737 | for_each_cpu(i, cpu_llc_shared_mask(cpu)) { | 758 | if (!per_cpu(ici_cpuid4_info, cpu)) |
| 759 | return 0; | ||
| 760 | |||
| 761 | this_leaf = CPUID4_INFO_IDX(cpu, index); | ||
| 762 | nshared = this_leaf->base.eax.split.num_threads_sharing + 1; | ||
| 763 | apicid = cpu_data(cpu).apicid; | ||
| 764 | first = apicid - (apicid % nshared); | ||
| 765 | last = first + nshared - 1; | ||
| 766 | |||
| 767 | for_each_online_cpu(i) { | ||
| 768 | apicid = cpu_data(i).apicid; | ||
| 769 | if ((apicid < first) || (apicid > last)) | ||
| 770 | continue; | ||
| 738 | if (!per_cpu(ici_cpuid4_info, i)) | 771 | if (!per_cpu(ici_cpuid4_info, i)) |
| 739 | continue; | 772 | continue; |
| 740 | this_leaf = CPUID4_INFO_IDX(i, index); | 773 | this_leaf = CPUID4_INFO_IDX(i, index); |
| 741 | for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) { | 774 | |
| 742 | if (!cpu_online(sibling)) | 775 | for_each_online_cpu(sibling) { |
| 776 | apicid = cpu_data(sibling).apicid; | ||
| 777 | if ((apicid < first) || (apicid > last)) | ||
| 743 | continue; | 778 | continue; |
| 744 | set_bit(sibling, this_leaf->shared_cpu_map); | 779 | set_bit(sibling, this_leaf->shared_cpu_map); |
| 745 | } | 780 | } |
| 746 | } | 781 | } |
| 747 | } else if ((c->x86 == 0x15) && ((index == 1) || (index == 2))) { | 782 | } else if (index == 3) { |
| 748 | ret = 1; | 783 | for_each_cpu(i, cpu_llc_shared_mask(cpu)) { |
| 749 | for_each_cpu(i, cpu_sibling_mask(cpu)) { | ||
| 750 | if (!per_cpu(ici_cpuid4_info, i)) | 784 | if (!per_cpu(ici_cpuid4_info, i)) |
| 751 | continue; | 785 | continue; |
| 752 | this_leaf = CPUID4_INFO_IDX(i, index); | 786 | this_leaf = CPUID4_INFO_IDX(i, index); |
| 753 | for_each_cpu(sibling, cpu_sibling_mask(cpu)) { | 787 | for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) { |
| 754 | if (!cpu_online(sibling)) | 788 | if (!cpu_online(sibling)) |
| 755 | continue; | 789 | continue; |
| 756 | set_bit(sibling, this_leaf->shared_cpu_map); | 790 | set_bit(sibling, this_leaf->shared_cpu_map); |
| 757 | } | 791 | } |
| 758 | } | 792 | } |
| 759 | } | 793 | } else |
| 794 | return 0; | ||
| 760 | 795 | ||
| 761 | return ret; | 796 | return 1; |
| 762 | } | 797 | } |
| 763 | 798 | ||
| 764 | static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) | 799 | static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) |
diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h index 6a05c1d327a9..5b7d4fa5d3b7 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-internal.h +++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h | |||
| @@ -24,8 +24,6 @@ struct mce_bank { | |||
| 24 | int mce_severity(struct mce *a, int tolerant, char **msg); | 24 | int mce_severity(struct mce *a, int tolerant, char **msg); |
| 25 | struct dentry *mce_get_debugfs_dir(void); | 25 | struct dentry *mce_get_debugfs_dir(void); |
| 26 | 26 | ||
| 27 | extern int mce_ser; | ||
| 28 | |||
| 29 | extern struct mce_bank *mce_banks; | 27 | extern struct mce_bank *mce_banks; |
| 30 | 28 | ||
| 31 | #ifdef CONFIG_X86_MCE_INTEL | 29 | #ifdef CONFIG_X86_MCE_INTEL |
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c index 13017626f9a8..beb1f1689e52 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-severity.c +++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c | |||
| @@ -193,9 +193,9 @@ int mce_severity(struct mce *m, int tolerant, char **msg) | |||
| 193 | continue; | 193 | continue; |
| 194 | if ((m->mcgstatus & s->mcgmask) != s->mcgres) | 194 | if ((m->mcgstatus & s->mcgmask) != s->mcgres) |
| 195 | continue; | 195 | continue; |
| 196 | if (s->ser == SER_REQUIRED && !mce_ser) | 196 | if (s->ser == SER_REQUIRED && !mca_cfg.ser) |
| 197 | continue; | 197 | continue; |
| 198 | if (s->ser == NO_SER && mce_ser) | 198 | if (s->ser == NO_SER && mca_cfg.ser) |
| 199 | continue; | 199 | continue; |
| 200 | if (s->context && ctx != s->context) | 200 | if (s->context && ctx != s->context) |
| 201 | continue; | 201 | continue; |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 46cbf8689692..80dbda84f1c3 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -58,34 +58,26 @@ static DEFINE_MUTEX(mce_chrdev_read_mutex); | |||
| 58 | #define CREATE_TRACE_POINTS | 58 | #define CREATE_TRACE_POINTS |
| 59 | #include <trace/events/mce.h> | 59 | #include <trace/events/mce.h> |
| 60 | 60 | ||
| 61 | int mce_disabled __read_mostly; | ||
| 62 | |||
| 63 | #define SPINUNIT 100 /* 100ns */ | 61 | #define SPINUNIT 100 /* 100ns */ |
| 64 | 62 | ||
| 65 | atomic_t mce_entry; | 63 | atomic_t mce_entry; |
| 66 | 64 | ||
| 67 | DEFINE_PER_CPU(unsigned, mce_exception_count); | 65 | DEFINE_PER_CPU(unsigned, mce_exception_count); |
| 68 | 66 | ||
| 69 | /* | 67 | struct mce_bank *mce_banks __read_mostly; |
| 70 | * Tolerant levels: | 68 | |
| 71 | * 0: always panic on uncorrected errors, log corrected errors | 69 | struct mca_config mca_cfg __read_mostly = { |
| 72 | * 1: panic or SIGBUS on uncorrected errors, log corrected errors | 70 | .bootlog = -1, |
| 73 | * 2: SIGBUS or log uncorrected errors (if possible), log corrected errors | 71 | /* |
| 74 | * 3: never panic or SIGBUS, log all errors (for testing only) | 72 | * Tolerant levels: |
| 75 | */ | 73 | * 0: always panic on uncorrected errors, log corrected errors |
| 76 | static int tolerant __read_mostly = 1; | 74 | * 1: panic or SIGBUS on uncorrected errors, log corrected errors |
| 77 | static int banks __read_mostly; | 75 | * 2: SIGBUS or log uncorrected errors (if possible), log corr. errors |
| 78 | static int rip_msr __read_mostly; | 76 | * 3: never panic or SIGBUS, log all errors (for testing only) |
| 79 | static int mce_bootlog __read_mostly = -1; | 77 | */ |
| 80 | static int monarch_timeout __read_mostly = -1; | 78 | .tolerant = 1, |
| 81 | static int mce_panic_timeout __read_mostly; | 79 | .monarch_timeout = -1 |
| 82 | static int mce_dont_log_ce __read_mostly; | 80 | }; |
| 83 | int mce_cmci_disabled __read_mostly; | ||
| 84 | int mce_ignore_ce __read_mostly; | ||
| 85 | int mce_ser __read_mostly; | ||
| 86 | int mce_bios_cmci_threshold __read_mostly; | ||
| 87 | |||
| 88 | struct mce_bank *mce_banks __read_mostly; | ||
| 89 | 81 | ||
| 90 | /* User mode helper program triggered by machine check event */ | 82 | /* User mode helper program triggered by machine check event */ |
| 91 | static unsigned long mce_need_notify; | 83 | static unsigned long mce_need_notify; |
| @@ -302,7 +294,7 @@ static void wait_for_panic(void) | |||
| 302 | while (timeout-- > 0) | 294 | while (timeout-- > 0) |
| 303 | udelay(1); | 295 | udelay(1); |
| 304 | if (panic_timeout == 0) | 296 | if (panic_timeout == 0) |
| 305 | panic_timeout = mce_panic_timeout; | 297 | panic_timeout = mca_cfg.panic_timeout; |
| 306 | panic("Panicing machine check CPU died"); | 298 | panic("Panicing machine check CPU died"); |
| 307 | } | 299 | } |
| 308 | 300 | ||
| @@ -360,7 +352,7 @@ static void mce_panic(char *msg, struct mce *final, char *exp) | |||
| 360 | pr_emerg(HW_ERR "Machine check: %s\n", exp); | 352 | pr_emerg(HW_ERR "Machine check: %s\n", exp); |
| 361 | if (!fake_panic) { | 353 | if (!fake_panic) { |
| 362 | if (panic_timeout == 0) | 354 | if (panic_timeout == 0) |
| 363 | panic_timeout = mce_panic_timeout; | 355 | panic_timeout = mca_cfg.panic_timeout; |
| 364 | panic(msg); | 356 | panic(msg); |
| 365 | } else | 357 | } else |
| 366 | pr_emerg(HW_ERR "Fake kernel panic: %s\n", msg); | 358 | pr_emerg(HW_ERR "Fake kernel panic: %s\n", msg); |
| @@ -372,7 +364,7 @@ static int msr_to_offset(u32 msr) | |||
| 372 | { | 364 | { |
| 373 | unsigned bank = __this_cpu_read(injectm.bank); | 365 | unsigned bank = __this_cpu_read(injectm.bank); |
| 374 | 366 | ||
| 375 | if (msr == rip_msr) | 367 | if (msr == mca_cfg.rip_msr) |
| 376 | return offsetof(struct mce, ip); | 368 | return offsetof(struct mce, ip); |
| 377 | if (msr == MSR_IA32_MCx_STATUS(bank)) | 369 | if (msr == MSR_IA32_MCx_STATUS(bank)) |
| 378 | return offsetof(struct mce, status); | 370 | return offsetof(struct mce, status); |
| @@ -451,8 +443,8 @@ static inline void mce_gather_info(struct mce *m, struct pt_regs *regs) | |||
| 451 | m->cs |= 3; | 443 | m->cs |= 3; |
| 452 | } | 444 | } |
| 453 | /* Use accurate RIP reporting if available. */ | 445 | /* Use accurate RIP reporting if available. */ |
| 454 | if (rip_msr) | 446 | if (mca_cfg.rip_msr) |
| 455 | m->ip = mce_rdmsrl(rip_msr); | 447 | m->ip = mce_rdmsrl(mca_cfg.rip_msr); |
| 456 | } | 448 | } |
| 457 | } | 449 | } |
| 458 | 450 | ||
| @@ -513,7 +505,7 @@ static int mce_ring_add(unsigned long pfn) | |||
| 513 | 505 | ||
| 514 | int mce_available(struct cpuinfo_x86 *c) | 506 | int mce_available(struct cpuinfo_x86 *c) |
| 515 | { | 507 | { |
| 516 | if (mce_disabled) | 508 | if (mca_cfg.disabled) |
| 517 | return 0; | 509 | return 0; |
| 518 | return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA); | 510 | return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA); |
| 519 | } | 511 | } |
| @@ -565,7 +557,7 @@ static void mce_read_aux(struct mce *m, int i) | |||
| 565 | /* | 557 | /* |
| 566 | * Mask the reported address by the reported granularity. | 558 | * Mask the reported address by the reported granularity. |
| 567 | */ | 559 | */ |
| 568 | if (mce_ser && (m->status & MCI_STATUS_MISCV)) { | 560 | if (mca_cfg.ser && (m->status & MCI_STATUS_MISCV)) { |
| 569 | u8 shift = MCI_MISC_ADDR_LSB(m->misc); | 561 | u8 shift = MCI_MISC_ADDR_LSB(m->misc); |
| 570 | m->addr >>= shift; | 562 | m->addr >>= shift; |
| 571 | m->addr <<= shift; | 563 | m->addr <<= shift; |
| @@ -599,7 +591,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) | |||
| 599 | 591 | ||
| 600 | mce_gather_info(&m, NULL); | 592 | mce_gather_info(&m, NULL); |
| 601 | 593 | ||
| 602 | for (i = 0; i < banks; i++) { | 594 | for (i = 0; i < mca_cfg.banks; i++) { |
| 603 | if (!mce_banks[i].ctl || !test_bit(i, *b)) | 595 | if (!mce_banks[i].ctl || !test_bit(i, *b)) |
| 604 | continue; | 596 | continue; |
| 605 | 597 | ||
| @@ -620,7 +612,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) | |||
| 620 | * TBD do the same check for MCI_STATUS_EN here? | 612 | * TBD do the same check for MCI_STATUS_EN here? |
| 621 | */ | 613 | */ |
| 622 | if (!(flags & MCP_UC) && | 614 | if (!(flags & MCP_UC) && |
| 623 | (m.status & (mce_ser ? MCI_STATUS_S : MCI_STATUS_UC))) | 615 | (m.status & (mca_cfg.ser ? MCI_STATUS_S : MCI_STATUS_UC))) |
| 624 | continue; | 616 | continue; |
| 625 | 617 | ||
| 626 | mce_read_aux(&m, i); | 618 | mce_read_aux(&m, i); |
| @@ -631,7 +623,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) | |||
| 631 | * Don't get the IP here because it's unlikely to | 623 | * Don't get the IP here because it's unlikely to |
| 632 | * have anything to do with the actual error location. | 624 | * have anything to do with the actual error location. |
| 633 | */ | 625 | */ |
| 634 | if (!(flags & MCP_DONTLOG) && !mce_dont_log_ce) | 626 | if (!(flags & MCP_DONTLOG) && !mca_cfg.dont_log_ce) |
| 635 | mce_log(&m); | 627 | mce_log(&m); |
| 636 | 628 | ||
| 637 | /* | 629 | /* |
| @@ -658,14 +650,14 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp, | |||
| 658 | { | 650 | { |
| 659 | int i, ret = 0; | 651 | int i, ret = 0; |
| 660 | 652 | ||
| 661 | for (i = 0; i < banks; i++) { | 653 | for (i = 0; i < mca_cfg.banks; i++) { |
| 662 | m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i)); | 654 | m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i)); |
| 663 | if (m->status & MCI_STATUS_VAL) { | 655 | if (m->status & MCI_STATUS_VAL) { |
| 664 | __set_bit(i, validp); | 656 | __set_bit(i, validp); |
| 665 | if (quirk_no_way_out) | 657 | if (quirk_no_way_out) |
| 666 | quirk_no_way_out(i, m, regs); | 658 | quirk_no_way_out(i, m, regs); |
| 667 | } | 659 | } |
| 668 | if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY) | 660 | if (mce_severity(m, mca_cfg.tolerant, msg) >= MCE_PANIC_SEVERITY) |
| 669 | ret = 1; | 661 | ret = 1; |
| 670 | } | 662 | } |
| 671 | return ret; | 663 | return ret; |
| @@ -696,11 +688,11 @@ static int mce_timed_out(u64 *t) | |||
| 696 | rmb(); | 688 | rmb(); |
| 697 | if (atomic_read(&mce_paniced)) | 689 | if (atomic_read(&mce_paniced)) |
| 698 | wait_for_panic(); | 690 | wait_for_panic(); |
| 699 | if (!monarch_timeout) | 691 | if (!mca_cfg.monarch_timeout) |
| 700 | goto out; | 692 | goto out; |
| 701 | if ((s64)*t < SPINUNIT) { | 693 | if ((s64)*t < SPINUNIT) { |
| 702 | /* CHECKME: Make panic default for 1 too? */ | 694 | /* CHECKME: Make panic default for 1 too? */ |
| 703 | if (tolerant < 1) | 695 | if (mca_cfg.tolerant < 1) |
| 704 | mce_panic("Timeout synchronizing machine check over CPUs", | 696 | mce_panic("Timeout synchronizing machine check over CPUs", |
| 705 | NULL, NULL); | 697 | NULL, NULL); |
| 706 | cpu_missing = 1; | 698 | cpu_missing = 1; |
| @@ -750,7 +742,8 @@ static void mce_reign(void) | |||
| 750 | * Grade the severity of the errors of all the CPUs. | 742 | * Grade the severity of the errors of all the CPUs. |
| 751 | */ | 743 | */ |
| 752 | for_each_possible_cpu(cpu) { | 744 | for_each_possible_cpu(cpu) { |
| 753 | int severity = mce_severity(&per_cpu(mces_seen, cpu), tolerant, | 745 | int severity = mce_severity(&per_cpu(mces_seen, cpu), |
| 746 | mca_cfg.tolerant, | ||
| 754 | &nmsg); | 747 | &nmsg); |
| 755 | if (severity > global_worst) { | 748 | if (severity > global_worst) { |
| 756 | msg = nmsg; | 749 | msg = nmsg; |
| @@ -764,7 +757,7 @@ static void mce_reign(void) | |||
| 764 | * This dumps all the mces in the log buffer and stops the | 757 | * This dumps all the mces in the log buffer and stops the |
| 765 | * other CPUs. | 758 | * other CPUs. |
| 766 | */ | 759 | */ |
| 767 | if (m && global_worst >= MCE_PANIC_SEVERITY && tolerant < 3) | 760 | if (m && global_worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) |
| 768 | mce_panic("Fatal Machine check", m, msg); | 761 | mce_panic("Fatal Machine check", m, msg); |
| 769 | 762 | ||
| 770 | /* | 763 | /* |
| @@ -777,7 +770,7 @@ static void mce_reign(void) | |||
| 777 | * No machine check event found. Must be some external | 770 | * No machine check event found. Must be some external |
| 778 | * source or one CPU is hung. Panic. | 771 | * source or one CPU is hung. Panic. |
| 779 | */ | 772 | */ |
| 780 | if (global_worst <= MCE_KEEP_SEVERITY && tolerant < 3) | 773 | if (global_worst <= MCE_KEEP_SEVERITY && mca_cfg.tolerant < 3) |
| 781 | mce_panic("Machine check from unknown source", NULL, NULL); | 774 | mce_panic("Machine check from unknown source", NULL, NULL); |
| 782 | 775 | ||
| 783 | /* | 776 | /* |
| @@ -801,7 +794,7 @@ static int mce_start(int *no_way_out) | |||
| 801 | { | 794 | { |
| 802 | int order; | 795 | int order; |
| 803 | int cpus = num_online_cpus(); | 796 | int cpus = num_online_cpus(); |
| 804 | u64 timeout = (u64)monarch_timeout * NSEC_PER_USEC; | 797 | u64 timeout = (u64)mca_cfg.monarch_timeout * NSEC_PER_USEC; |
| 805 | 798 | ||
| 806 | if (!timeout) | 799 | if (!timeout) |
| 807 | return -1; | 800 | return -1; |
| @@ -865,7 +858,7 @@ static int mce_start(int *no_way_out) | |||
| 865 | static int mce_end(int order) | 858 | static int mce_end(int order) |
| 866 | { | 859 | { |
| 867 | int ret = -1; | 860 | int ret = -1; |
| 868 | u64 timeout = (u64)monarch_timeout * NSEC_PER_USEC; | 861 | u64 timeout = (u64)mca_cfg.monarch_timeout * NSEC_PER_USEC; |
| 869 | 862 | ||
| 870 | if (!timeout) | 863 | if (!timeout) |
| 871 | goto reset; | 864 | goto reset; |
| @@ -946,7 +939,7 @@ static void mce_clear_state(unsigned long *toclear) | |||
| 946 | { | 939 | { |
| 947 | int i; | 940 | int i; |
| 948 | 941 | ||
| 949 | for (i = 0; i < banks; i++) { | 942 | for (i = 0; i < mca_cfg.banks; i++) { |
| 950 | if (test_bit(i, toclear)) | 943 | if (test_bit(i, toclear)) |
| 951 | mce_wrmsrl(MSR_IA32_MCx_STATUS(i), 0); | 944 | mce_wrmsrl(MSR_IA32_MCx_STATUS(i), 0); |
| 952 | } | 945 | } |
| @@ -1011,6 +1004,7 @@ static void mce_clear_info(struct mce_info *mi) | |||
| 1011 | */ | 1004 | */ |
| 1012 | void do_machine_check(struct pt_regs *regs, long error_code) | 1005 | void do_machine_check(struct pt_regs *regs, long error_code) |
| 1013 | { | 1006 | { |
| 1007 | struct mca_config *cfg = &mca_cfg; | ||
| 1014 | struct mce m, *final; | 1008 | struct mce m, *final; |
| 1015 | int i; | 1009 | int i; |
| 1016 | int worst = 0; | 1010 | int worst = 0; |
| @@ -1022,7 +1016,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) | |||
| 1022 | int order; | 1016 | int order; |
| 1023 | /* | 1017 | /* |
| 1024 | * If no_way_out gets set, there is no safe way to recover from this | 1018 | * If no_way_out gets set, there is no safe way to recover from this |
| 1025 | * MCE. If tolerant is cranked up, we'll try anyway. | 1019 | * MCE. If mca_cfg.tolerant is cranked up, we'll try anyway. |
| 1026 | */ | 1020 | */ |
| 1027 | int no_way_out = 0; | 1021 | int no_way_out = 0; |
| 1028 | /* | 1022 | /* |
| @@ -1038,7 +1032,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) | |||
| 1038 | 1032 | ||
| 1039 | this_cpu_inc(mce_exception_count); | 1033 | this_cpu_inc(mce_exception_count); |
| 1040 | 1034 | ||
| 1041 | if (!banks) | 1035 | if (!cfg->banks) |
| 1042 | goto out; | 1036 | goto out; |
| 1043 | 1037 | ||
| 1044 | mce_gather_info(&m, regs); | 1038 | mce_gather_info(&m, regs); |
| @@ -1065,7 +1059,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) | |||
| 1065 | * because the first one to see it will clear it. | 1059 | * because the first one to see it will clear it. |
| 1066 | */ | 1060 | */ |
| 1067 | order = mce_start(&no_way_out); | 1061 | order = mce_start(&no_way_out); |
| 1068 | for (i = 0; i < banks; i++) { | 1062 | for (i = 0; i < cfg->banks; i++) { |
| 1069 | __clear_bit(i, toclear); | 1063 | __clear_bit(i, toclear); |
| 1070 | if (!test_bit(i, valid_banks)) | 1064 | if (!test_bit(i, valid_banks)) |
| 1071 | continue; | 1065 | continue; |
| @@ -1084,7 +1078,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) | |||
| 1084 | * Non uncorrected or non signaled errors are handled by | 1078 | * Non uncorrected or non signaled errors are handled by |
| 1085 | * machine_check_poll. Leave them alone, unless this panics. | 1079 | * machine_check_poll. Leave them alone, unless this panics. |
| 1086 | */ | 1080 | */ |
| 1087 | if (!(m.status & (mce_ser ? MCI_STATUS_S : MCI_STATUS_UC)) && | 1081 | if (!(m.status & (cfg->ser ? MCI_STATUS_S : MCI_STATUS_UC)) && |
| 1088 | !no_way_out) | 1082 | !no_way_out) |
| 1089 | continue; | 1083 | continue; |
| 1090 | 1084 | ||
| @@ -1093,7 +1087,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) | |||
| 1093 | */ | 1087 | */ |
| 1094 | add_taint(TAINT_MACHINE_CHECK); | 1088 | add_taint(TAINT_MACHINE_CHECK); |
| 1095 | 1089 | ||
| 1096 | severity = mce_severity(&m, tolerant, NULL); | 1090 | severity = mce_severity(&m, cfg->tolerant, NULL); |
| 1097 | 1091 | ||
| 1098 | /* | 1092 | /* |
| 1099 | * When machine check was for corrected handler don't touch, | 1093 | * When machine check was for corrected handler don't touch, |
| @@ -1117,7 +1111,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) | |||
| 1117 | * When the ring overflows we just ignore the AO error. | 1111 | * When the ring overflows we just ignore the AO error. |
| 1118 | * RED-PEN add some logging mechanism when | 1112 | * RED-PEN add some logging mechanism when |
| 1119 | * usable_address or mce_add_ring fails. | 1113 | * usable_address or mce_add_ring fails. |
| 1120 | * RED-PEN don't ignore overflow for tolerant == 0 | 1114 | * RED-PEN don't ignore overflow for mca_cfg.tolerant == 0 |
| 1121 | */ | 1115 | */ |
| 1122 | if (severity == MCE_AO_SEVERITY && mce_usable_address(&m)) | 1116 | if (severity == MCE_AO_SEVERITY && mce_usable_address(&m)) |
| 1123 | mce_ring_add(m.addr >> PAGE_SHIFT); | 1117 | mce_ring_add(m.addr >> PAGE_SHIFT); |
| @@ -1149,7 +1143,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) | |||
| 1149 | * issues we try to recover, or limit damage to the current | 1143 | * issues we try to recover, or limit damage to the current |
| 1150 | * process. | 1144 | * process. |
| 1151 | */ | 1145 | */ |
| 1152 | if (tolerant < 3) { | 1146 | if (cfg->tolerant < 3) { |
| 1153 | if (no_way_out) | 1147 | if (no_way_out) |
| 1154 | mce_panic("Fatal machine check on current CPU", &m, msg); | 1148 | mce_panic("Fatal machine check on current CPU", &m, msg); |
| 1155 | if (worst == MCE_AR_SEVERITY) { | 1149 | if (worst == MCE_AR_SEVERITY) { |
| @@ -1377,11 +1371,13 @@ EXPORT_SYMBOL_GPL(mce_notify_irq); | |||
| 1377 | static int __cpuinit __mcheck_cpu_mce_banks_init(void) | 1371 | static int __cpuinit __mcheck_cpu_mce_banks_init(void) |
| 1378 | { | 1372 | { |
| 1379 | int i; | 1373 | int i; |
| 1374 | u8 num_banks = mca_cfg.banks; | ||
| 1380 | 1375 | ||
| 1381 | mce_banks = kzalloc(banks * sizeof(struct mce_bank), GFP_KERNEL); | 1376 | mce_banks = kzalloc(num_banks * sizeof(struct mce_bank), GFP_KERNEL); |
| 1382 | if (!mce_banks) | 1377 | if (!mce_banks) |
| 1383 | return -ENOMEM; | 1378 | return -ENOMEM; |
| 1384 | for (i = 0; i < banks; i++) { | 1379 | |
| 1380 | for (i = 0; i < num_banks; i++) { | ||
| 1385 | struct mce_bank *b = &mce_banks[i]; | 1381 | struct mce_bank *b = &mce_banks[i]; |
| 1386 | 1382 | ||
| 1387 | b->ctl = -1ULL; | 1383 | b->ctl = -1ULL; |
| @@ -1401,7 +1397,7 @@ static int __cpuinit __mcheck_cpu_cap_init(void) | |||
| 1401 | rdmsrl(MSR_IA32_MCG_CAP, cap); | 1397 | rdmsrl(MSR_IA32_MCG_CAP, cap); |
| 1402 | 1398 | ||
| 1403 | b = cap & MCG_BANKCNT_MASK; | 1399 | b = cap & MCG_BANKCNT_MASK; |
| 1404 | if (!banks) | 1400 | if (!mca_cfg.banks) |
| 1405 | pr_info("CPU supports %d MCE banks\n", b); | 1401 | pr_info("CPU supports %d MCE banks\n", b); |
| 1406 | 1402 | ||
| 1407 | if (b > MAX_NR_BANKS) { | 1403 | if (b > MAX_NR_BANKS) { |
| @@ -1411,8 +1407,9 @@ static int __cpuinit __mcheck_cpu_cap_init(void) | |||
| 1411 | } | 1407 | } |
| 1412 | 1408 | ||
| 1413 | /* Don't support asymmetric configurations today */ | 1409 | /* Don't support asymmetric configurations today */ |
| 1414 | WARN_ON(banks != 0 && b != banks); | 1410 | WARN_ON(mca_cfg.banks != 0 && b != mca_cfg.banks); |
| 1415 | banks = b; | 1411 | mca_cfg.banks = b; |
| 1412 | |||
| 1416 | if (!mce_banks) { | 1413 | if (!mce_banks) { |
| 1417 | int err = __mcheck_cpu_mce_banks_init(); | 1414 | int err = __mcheck_cpu_mce_banks_init(); |
| 1418 | 1415 | ||
| @@ -1422,25 +1419,29 @@ static int __cpuinit __mcheck_cpu_cap_init(void) | |||
| 1422 | 1419 | ||
| 1423 | /* Use accurate RIP reporting if available. */ | 1420 | /* Use accurate RIP reporting if available. */ |
| 1424 | if ((cap & MCG_EXT_P) && MCG_EXT_CNT(cap) >= 9) | 1421 | if ((cap & MCG_EXT_P) && MCG_EXT_CNT(cap) >= 9) |
| 1425 | rip_msr = MSR_IA32_MCG_EIP; | 1422 | mca_cfg.rip_msr = MSR_IA32_MCG_EIP; |
| 1426 | 1423 | ||
| 1427 | if (cap & MCG_SER_P) | 1424 | if (cap & MCG_SER_P) |
| 1428 | mce_ser = 1; | 1425 | mca_cfg.ser = true; |
| 1429 | 1426 | ||
| 1430 | return 0; | 1427 | return 0; |
| 1431 | } | 1428 | } |
| 1432 | 1429 | ||
| 1433 | static void __mcheck_cpu_init_generic(void) | 1430 | static void __mcheck_cpu_init_generic(void) |
| 1434 | { | 1431 | { |
| 1432 | enum mcp_flags m_fl = 0; | ||
| 1435 | mce_banks_t all_banks; | 1433 | mce_banks_t all_banks; |
| 1436 | u64 cap; | 1434 | u64 cap; |
| 1437 | int i; | 1435 | int i; |
| 1438 | 1436 | ||
| 1437 | if (!mca_cfg.bootlog) | ||
| 1438 | m_fl = MCP_DONTLOG; | ||
| 1439 | |||
| 1439 | /* | 1440 | /* |
| 1440 | * Log the machine checks left over from the previous reset. | 1441 | * Log the machine checks left over from the previous reset. |
| 1441 | */ | 1442 | */ |
| 1442 | bitmap_fill(all_banks, MAX_NR_BANKS); | 1443 | bitmap_fill(all_banks, MAX_NR_BANKS); |
| 1443 | machine_check_poll(MCP_UC|(!mce_bootlog ? MCP_DONTLOG : 0), &all_banks); | 1444 | machine_check_poll(MCP_UC | m_fl, &all_banks); |
| 1444 | 1445 | ||
| 1445 | set_in_cr4(X86_CR4_MCE); | 1446 | set_in_cr4(X86_CR4_MCE); |
| 1446 | 1447 | ||
| @@ -1448,7 +1449,7 @@ static void __mcheck_cpu_init_generic(void) | |||
| 1448 | if (cap & MCG_CTL_P) | 1449 | if (cap & MCG_CTL_P) |
| 1449 | wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff); | 1450 | wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff); |
| 1450 | 1451 | ||
| 1451 | for (i = 0; i < banks; i++) { | 1452 | for (i = 0; i < mca_cfg.banks; i++) { |
| 1452 | struct mce_bank *b = &mce_banks[i]; | 1453 | struct mce_bank *b = &mce_banks[i]; |
| 1453 | 1454 | ||
| 1454 | if (!b->init) | 1455 | if (!b->init) |
| @@ -1489,6 +1490,8 @@ static void quirk_sandybridge_ifu(int bank, struct mce *m, struct pt_regs *regs) | |||
| 1489 | /* Add per CPU specific workarounds here */ | 1490 | /* Add per CPU specific workarounds here */ |
| 1490 | static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) | 1491 | static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) |
| 1491 | { | 1492 | { |
| 1493 | struct mca_config *cfg = &mca_cfg; | ||
| 1494 | |||
| 1492 | if (c->x86_vendor == X86_VENDOR_UNKNOWN) { | 1495 | if (c->x86_vendor == X86_VENDOR_UNKNOWN) { |
| 1493 | pr_info("unknown CPU type - not enabling MCE support\n"); | 1496 | pr_info("unknown CPU type - not enabling MCE support\n"); |
| 1494 | return -EOPNOTSUPP; | 1497 | return -EOPNOTSUPP; |
| @@ -1496,7 +1499,7 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) | |||
| 1496 | 1499 | ||
| 1497 | /* This should be disabled by the BIOS, but isn't always */ | 1500 | /* This should be disabled by the BIOS, but isn't always */ |
| 1498 | if (c->x86_vendor == X86_VENDOR_AMD) { | 1501 | if (c->x86_vendor == X86_VENDOR_AMD) { |
| 1499 | if (c->x86 == 15 && banks > 4) { | 1502 | if (c->x86 == 15 && cfg->banks > 4) { |
| 1500 | /* | 1503 | /* |
| 1501 | * disable GART TBL walk error reporting, which | 1504 | * disable GART TBL walk error reporting, which |
| 1502 | * trips off incorrectly with the IOMMU & 3ware | 1505 | * trips off incorrectly with the IOMMU & 3ware |
| @@ -1504,18 +1507,18 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) | |||
| 1504 | */ | 1507 | */ |
| 1505 | clear_bit(10, (unsigned long *)&mce_banks[4].ctl); | 1508 | clear_bit(10, (unsigned long *)&mce_banks[4].ctl); |
| 1506 | } | 1509 | } |
| 1507 | if (c->x86 <= 17 && mce_bootlog < 0) { | 1510 | if (c->x86 <= 17 && cfg->bootlog < 0) { |
| 1508 | /* | 1511 | /* |
| 1509 | * Lots of broken BIOS around that don't clear them | 1512 | * Lots of broken BIOS around that don't clear them |
| 1510 | * by default and leave crap in there. Don't log: | 1513 | * by default and leave crap in there. Don't log: |
| 1511 | */ | 1514 | */ |
| 1512 | mce_bootlog = 0; | 1515 | cfg->bootlog = 0; |
| 1513 | } | 1516 | } |
| 1514 | /* | 1517 | /* |
| 1515 | * Various K7s with broken bank 0 around. Always disable | 1518 | * Various K7s with broken bank 0 around. Always disable |
| 1516 | * by default. | 1519 | * by default. |
| 1517 | */ | 1520 | */ |
| 1518 | if (c->x86 == 6 && banks > 0) | 1521 | if (c->x86 == 6 && cfg->banks > 0) |
| 1519 | mce_banks[0].ctl = 0; | 1522 | mce_banks[0].ctl = 0; |
| 1520 | 1523 | ||
| 1521 | /* | 1524 | /* |
| @@ -1566,7 +1569,7 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) | |||
| 1566 | * valid event later, merely don't write CTL0. | 1569 | * valid event later, merely don't write CTL0. |
| 1567 | */ | 1570 | */ |
| 1568 | 1571 | ||
| 1569 | if (c->x86 == 6 && c->x86_model < 0x1A && banks > 0) | 1572 | if (c->x86 == 6 && c->x86_model < 0x1A && cfg->banks > 0) |
| 1570 | mce_banks[0].init = 0; | 1573 | mce_banks[0].init = 0; |
| 1571 | 1574 | ||
| 1572 | /* | 1575 | /* |
| @@ -1574,23 +1577,23 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) | |||
| 1574 | * synchronization with a one second timeout. | 1577 | * synchronization with a one second timeout. |
| 1575 | */ | 1578 | */ |
| 1576 | if ((c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xe)) && | 1579 | if ((c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xe)) && |
| 1577 | monarch_timeout < 0) | 1580 | cfg->monarch_timeout < 0) |
| 1578 | monarch_timeout = USEC_PER_SEC; | 1581 | cfg->monarch_timeout = USEC_PER_SEC; |
| 1579 | 1582 | ||
| 1580 | /* | 1583 | /* |
| 1581 | * There are also broken BIOSes on some Pentium M and | 1584 | * There are also broken BIOSes on some Pentium M and |
| 1582 | * earlier systems: | 1585 | * earlier systems: |
| 1583 | */ | 1586 | */ |
| 1584 | if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0) | 1587 | if (c->x86 == 6 && c->x86_model <= 13 && cfg->bootlog < 0) |
| 1585 | mce_bootlog = 0; | 1588 | cfg->bootlog = 0; |
| 1586 | 1589 | ||
| 1587 | if (c->x86 == 6 && c->x86_model == 45) | 1590 | if (c->x86 == 6 && c->x86_model == 45) |
| 1588 | quirk_no_way_out = quirk_sandybridge_ifu; | 1591 | quirk_no_way_out = quirk_sandybridge_ifu; |
| 1589 | } | 1592 | } |
| 1590 | if (monarch_timeout < 0) | 1593 | if (cfg->monarch_timeout < 0) |
| 1591 | monarch_timeout = 0; | 1594 | cfg->monarch_timeout = 0; |
| 1592 | if (mce_bootlog != 0) | 1595 | if (cfg->bootlog != 0) |
| 1593 | mce_panic_timeout = 30; | 1596 | cfg->panic_timeout = 30; |
| 1594 | 1597 | ||
| 1595 | return 0; | 1598 | return 0; |
| 1596 | } | 1599 | } |
| @@ -1635,7 +1638,7 @@ static void mce_start_timer(unsigned int cpu, struct timer_list *t) | |||
| 1635 | 1638 | ||
| 1636 | __this_cpu_write(mce_next_interval, iv); | 1639 | __this_cpu_write(mce_next_interval, iv); |
| 1637 | 1640 | ||
| 1638 | if (mce_ignore_ce || !iv) | 1641 | if (mca_cfg.ignore_ce || !iv) |
| 1639 | return; | 1642 | return; |
| 1640 | 1643 | ||
| 1641 | t->expires = round_jiffies(jiffies + iv); | 1644 | t->expires = round_jiffies(jiffies + iv); |
| @@ -1668,7 +1671,7 @@ void (*machine_check_vector)(struct pt_regs *, long error_code) = | |||
| 1668 | */ | 1671 | */ |
| 1669 | void __cpuinit mcheck_cpu_init(struct cpuinfo_x86 *c) | 1672 | void __cpuinit mcheck_cpu_init(struct cpuinfo_x86 *c) |
| 1670 | { | 1673 | { |
| 1671 | if (mce_disabled) | 1674 | if (mca_cfg.disabled) |
| 1672 | return; | 1675 | return; |
| 1673 | 1676 | ||
| 1674 | if (__mcheck_cpu_ancient_init(c)) | 1677 | if (__mcheck_cpu_ancient_init(c)) |
| @@ -1678,7 +1681,7 @@ void __cpuinit mcheck_cpu_init(struct cpuinfo_x86 *c) | |||
| 1678 | return; | 1681 | return; |
| 1679 | 1682 | ||
| 1680 | if (__mcheck_cpu_cap_init() < 0 || __mcheck_cpu_apply_quirks(c) < 0) { | 1683 | if (__mcheck_cpu_cap_init() < 0 || __mcheck_cpu_apply_quirks(c) < 0) { |
| 1681 | mce_disabled = 1; | 1684 | mca_cfg.disabled = true; |
| 1682 | return; | 1685 | return; |
| 1683 | } | 1686 | } |
| 1684 | 1687 | ||
| @@ -1951,6 +1954,8 @@ static struct miscdevice mce_chrdev_device = { | |||
| 1951 | */ | 1954 | */ |
| 1952 | static int __init mcheck_enable(char *str) | 1955 | static int __init mcheck_enable(char *str) |
| 1953 | { | 1956 | { |
| 1957 | struct mca_config *cfg = &mca_cfg; | ||
| 1958 | |||
| 1954 | if (*str == 0) { | 1959 | if (*str == 0) { |
| 1955 | enable_p5_mce(); | 1960 | enable_p5_mce(); |
| 1956 | return 1; | 1961 | return 1; |
| @@ -1958,22 +1963,22 @@ static int __init mcheck_enable(char *str) | |||
| 1958 | if (*str == '=') | 1963 | if (*str == '=') |
| 1959 | str++; | 1964 | str++; |
| 1960 | if (!strcmp(str, "off")) | 1965 | if (!strcmp(str, "off")) |
| 1961 | mce_disabled = 1; | 1966 | cfg->disabled = true; |
| 1962 | else if (!strcmp(str, "no_cmci")) | 1967 | else if (!strcmp(str, "no_cmci")) |
| 1963 | mce_cmci_disabled = 1; | 1968 | cfg->cmci_disabled = true; |
| 1964 | else if (!strcmp(str, "dont_log_ce")) | 1969 | else if (!strcmp(str, "dont_log_ce")) |
| 1965 | mce_dont_log_ce = 1; | 1970 | cfg->dont_log_ce = true; |
| 1966 | else if (!strcmp(str, "ignore_ce")) | 1971 | else if (!strcmp(str, "ignore_ce")) |
| 1967 | mce_ignore_ce = 1; | 1972 | cfg->ignore_ce = true; |
| 1968 | else if (!strcmp(str, "bootlog") || !strcmp(str, "nobootlog")) | 1973 | else if (!strcmp(str, "bootlog") || !strcmp(str, "nobootlog")) |
| 1969 | mce_bootlog = (str[0] == 'b'); | 1974 | cfg->bootlog = (str[0] == 'b'); |
| 1970 | else if (!strcmp(str, "bios_cmci_threshold")) | 1975 | else if (!strcmp(str, "bios_cmci_threshold")) |
| 1971 | mce_bios_cmci_threshold = 1; | 1976 | cfg->bios_cmci_threshold = true; |
| 1972 | else if (isdigit(str[0])) { | 1977 | else if (isdigit(str[0])) { |
| 1973 | get_option(&str, &tolerant); | 1978 | get_option(&str, &(cfg->tolerant)); |
| 1974 | if (*str == ',') { | 1979 | if (*str == ',') { |
| 1975 | ++str; | 1980 | ++str; |
| 1976 | get_option(&str, &monarch_timeout); | 1981 | get_option(&str, &(cfg->monarch_timeout)); |
| 1977 | } | 1982 | } |
| 1978 | } else { | 1983 | } else { |
| 1979 | pr_info("mce argument %s ignored. Please use /sys\n", str); | 1984 | pr_info("mce argument %s ignored. Please use /sys\n", str); |
| @@ -2002,7 +2007,7 @@ static int mce_disable_error_reporting(void) | |||
| 2002 | { | 2007 | { |
| 2003 | int i; | 2008 | int i; |
| 2004 | 2009 | ||
| 2005 | for (i = 0; i < banks; i++) { | 2010 | for (i = 0; i < mca_cfg.banks; i++) { |
| 2006 | struct mce_bank *b = &mce_banks[i]; | 2011 | struct mce_bank *b = &mce_banks[i]; |
| 2007 | 2012 | ||
| 2008 | if (b->init) | 2013 | if (b->init) |
| @@ -2142,15 +2147,15 @@ static ssize_t set_ignore_ce(struct device *s, | |||
| 2142 | if (strict_strtoull(buf, 0, &new) < 0) | 2147 | if (strict_strtoull(buf, 0, &new) < 0) |
| 2143 | return -EINVAL; | 2148 | return -EINVAL; |
| 2144 | 2149 | ||
| 2145 | if (mce_ignore_ce ^ !!new) { | 2150 | if (mca_cfg.ignore_ce ^ !!new) { |
| 2146 | if (new) { | 2151 | if (new) { |
| 2147 | /* disable ce features */ | 2152 | /* disable ce features */ |
| 2148 | mce_timer_delete_all(); | 2153 | mce_timer_delete_all(); |
| 2149 | on_each_cpu(mce_disable_cmci, NULL, 1); | 2154 | on_each_cpu(mce_disable_cmci, NULL, 1); |
| 2150 | mce_ignore_ce = 1; | 2155 | mca_cfg.ignore_ce = true; |
| 2151 | } else { | 2156 | } else { |
| 2152 | /* enable ce features */ | 2157 | /* enable ce features */ |
| 2153 | mce_ignore_ce = 0; | 2158 | mca_cfg.ignore_ce = false; |
| 2154 | on_each_cpu(mce_enable_ce, (void *)1, 1); | 2159 | on_each_cpu(mce_enable_ce, (void *)1, 1); |
| 2155 | } | 2160 | } |
| 2156 | } | 2161 | } |
| @@ -2166,14 +2171,14 @@ static ssize_t set_cmci_disabled(struct device *s, | |||
| 2166 | if (strict_strtoull(buf, 0, &new) < 0) | 2171 | if (strict_strtoull(buf, 0, &new) < 0) |
| 2167 | return -EINVAL; | 2172 | return -EINVAL; |
| 2168 | 2173 | ||
| 2169 | if (mce_cmci_disabled ^ !!new) { | 2174 | if (mca_cfg.cmci_disabled ^ !!new) { |
| 2170 | if (new) { | 2175 | if (new) { |
| 2171 | /* disable cmci */ | 2176 | /* disable cmci */ |
| 2172 | on_each_cpu(mce_disable_cmci, NULL, 1); | 2177 | on_each_cpu(mce_disable_cmci, NULL, 1); |
| 2173 | mce_cmci_disabled = 1; | 2178 | mca_cfg.cmci_disabled = true; |
| 2174 | } else { | 2179 | } else { |
| 2175 | /* enable cmci */ | 2180 | /* enable cmci */ |
| 2176 | mce_cmci_disabled = 0; | 2181 | mca_cfg.cmci_disabled = false; |
| 2177 | on_each_cpu(mce_enable_ce, NULL, 1); | 2182 | on_each_cpu(mce_enable_ce, NULL, 1); |
| 2178 | } | 2183 | } |
| 2179 | } | 2184 | } |
| @@ -2190,9 +2195,9 @@ static ssize_t store_int_with_restart(struct device *s, | |||
| 2190 | } | 2195 | } |
| 2191 | 2196 | ||
| 2192 | static DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger); | 2197 | static DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger); |
| 2193 | static DEVICE_INT_ATTR(tolerant, 0644, tolerant); | 2198 | static DEVICE_INT_ATTR(tolerant, 0644, mca_cfg.tolerant); |
| 2194 | static DEVICE_INT_ATTR(monarch_timeout, 0644, monarch_timeout); | 2199 | static DEVICE_INT_ATTR(monarch_timeout, 0644, mca_cfg.monarch_timeout); |
| 2195 | static DEVICE_INT_ATTR(dont_log_ce, 0644, mce_dont_log_ce); | 2200 | static DEVICE_BOOL_ATTR(dont_log_ce, 0644, mca_cfg.dont_log_ce); |
| 2196 | 2201 | ||
| 2197 | static struct dev_ext_attribute dev_attr_check_interval = { | 2202 | static struct dev_ext_attribute dev_attr_check_interval = { |
| 2198 | __ATTR(check_interval, 0644, device_show_int, store_int_with_restart), | 2203 | __ATTR(check_interval, 0644, device_show_int, store_int_with_restart), |
| @@ -2200,13 +2205,13 @@ static struct dev_ext_attribute dev_attr_check_interval = { | |||
| 2200 | }; | 2205 | }; |
| 2201 | 2206 | ||
| 2202 | static struct dev_ext_attribute dev_attr_ignore_ce = { | 2207 | static struct dev_ext_attribute dev_attr_ignore_ce = { |
| 2203 | __ATTR(ignore_ce, 0644, device_show_int, set_ignore_ce), | 2208 | __ATTR(ignore_ce, 0644, device_show_bool, set_ignore_ce), |
| 2204 | &mce_ignore_ce | 2209 | &mca_cfg.ignore_ce |
| 2205 | }; | 2210 | }; |
| 2206 | 2211 | ||
| 2207 | static struct dev_ext_attribute dev_attr_cmci_disabled = { | 2212 | static struct dev_ext_attribute dev_attr_cmci_disabled = { |
| 2208 | __ATTR(cmci_disabled, 0644, device_show_int, set_cmci_disabled), | 2213 | __ATTR(cmci_disabled, 0644, device_show_bool, set_cmci_disabled), |
| 2209 | &mce_cmci_disabled | 2214 | &mca_cfg.cmci_disabled |
| 2210 | }; | 2215 | }; |
| 2211 | 2216 | ||
| 2212 | static struct device_attribute *mce_device_attrs[] = { | 2217 | static struct device_attribute *mce_device_attrs[] = { |
| @@ -2253,7 +2258,7 @@ static __cpuinit int mce_device_create(unsigned int cpu) | |||
| 2253 | if (err) | 2258 | if (err) |
| 2254 | goto error; | 2259 | goto error; |
| 2255 | } | 2260 | } |
| 2256 | for (j = 0; j < banks; j++) { | 2261 | for (j = 0; j < mca_cfg.banks; j++) { |
| 2257 | err = device_create_file(dev, &mce_banks[j].attr); | 2262 | err = device_create_file(dev, &mce_banks[j].attr); |
| 2258 | if (err) | 2263 | if (err) |
| 2259 | goto error2; | 2264 | goto error2; |
| @@ -2285,7 +2290,7 @@ static __cpuinit void mce_device_remove(unsigned int cpu) | |||
| 2285 | for (i = 0; mce_device_attrs[i]; i++) | 2290 | for (i = 0; mce_device_attrs[i]; i++) |
| 2286 | device_remove_file(dev, mce_device_attrs[i]); | 2291 | device_remove_file(dev, mce_device_attrs[i]); |
| 2287 | 2292 | ||
| 2288 | for (i = 0; i < banks; i++) | 2293 | for (i = 0; i < mca_cfg.banks; i++) |
| 2289 | device_remove_file(dev, &mce_banks[i].attr); | 2294 | device_remove_file(dev, &mce_banks[i].attr); |
| 2290 | 2295 | ||
| 2291 | device_unregister(dev); | 2296 | device_unregister(dev); |
| @@ -2304,7 +2309,7 @@ static void __cpuinit mce_disable_cpu(void *h) | |||
| 2304 | 2309 | ||
| 2305 | if (!(action & CPU_TASKS_FROZEN)) | 2310 | if (!(action & CPU_TASKS_FROZEN)) |
| 2306 | cmci_clear(); | 2311 | cmci_clear(); |
| 2307 | for (i = 0; i < banks; i++) { | 2312 | for (i = 0; i < mca_cfg.banks; i++) { |
| 2308 | struct mce_bank *b = &mce_banks[i]; | 2313 | struct mce_bank *b = &mce_banks[i]; |
| 2309 | 2314 | ||
| 2310 | if (b->init) | 2315 | if (b->init) |
| @@ -2322,7 +2327,7 @@ static void __cpuinit mce_reenable_cpu(void *h) | |||
| 2322 | 2327 | ||
| 2323 | if (!(action & CPU_TASKS_FROZEN)) | 2328 | if (!(action & CPU_TASKS_FROZEN)) |
| 2324 | cmci_reenable(); | 2329 | cmci_reenable(); |
| 2325 | for (i = 0; i < banks; i++) { | 2330 | for (i = 0; i < mca_cfg.banks; i++) { |
| 2326 | struct mce_bank *b = &mce_banks[i]; | 2331 | struct mce_bank *b = &mce_banks[i]; |
| 2327 | 2332 | ||
| 2328 | if (b->init) | 2333 | if (b->init) |
| @@ -2375,7 +2380,7 @@ static __init void mce_init_banks(void) | |||
| 2375 | { | 2380 | { |
| 2376 | int i; | 2381 | int i; |
| 2377 | 2382 | ||
| 2378 | for (i = 0; i < banks; i++) { | 2383 | for (i = 0; i < mca_cfg.banks; i++) { |
| 2379 | struct mce_bank *b = &mce_banks[i]; | 2384 | struct mce_bank *b = &mce_banks[i]; |
| 2380 | struct device_attribute *a = &b->attr; | 2385 | struct device_attribute *a = &b->attr; |
| 2381 | 2386 | ||
| @@ -2426,7 +2431,7 @@ device_initcall_sync(mcheck_init_device); | |||
| 2426 | */ | 2431 | */ |
| 2427 | static int __init mcheck_disable(char *str) | 2432 | static int __init mcheck_disable(char *str) |
| 2428 | { | 2433 | { |
| 2429 | mce_disabled = 1; | 2434 | mca_cfg.disabled = true; |
| 2430 | return 1; | 2435 | return 1; |
| 2431 | } | 2436 | } |
| 2432 | __setup("nomce", mcheck_disable); | 2437 | __setup("nomce", mcheck_disable); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 698b6ec12e0f..1ac581f38dfa 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * | 6 | * |
| 7 | * Written by Jacob Shin - AMD, Inc. | 7 | * Written by Jacob Shin - AMD, Inc. |
| 8 | * | 8 | * |
| 9 | * Support: borislav.petkov@amd.com | 9 | * Maintained by: Borislav Petkov <bp@alien8.de> |
| 10 | * | 10 | * |
| 11 | * April 2006 | 11 | * April 2006 |
| 12 | * - added support for AMD Family 0x10 processors | 12 | * - added support for AMD Family 0x10 processors |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index 5f88abf07e9c..402c454fbff0 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c | |||
| @@ -53,7 +53,7 @@ static int cmci_supported(int *banks) | |||
| 53 | { | 53 | { |
| 54 | u64 cap; | 54 | u64 cap; |
| 55 | 55 | ||
| 56 | if (mce_cmci_disabled || mce_ignore_ce) | 56 | if (mca_cfg.cmci_disabled || mca_cfg.ignore_ce) |
| 57 | return 0; | 57 | return 0; |
| 58 | 58 | ||
| 59 | /* | 59 | /* |
| @@ -200,7 +200,7 @@ static void cmci_discover(int banks) | |||
| 200 | continue; | 200 | continue; |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | if (!mce_bios_cmci_threshold) { | 203 | if (!mca_cfg.bios_cmci_threshold) { |
| 204 | val &= ~MCI_CTL2_CMCI_THRESHOLD_MASK; | 204 | val &= ~MCI_CTL2_CMCI_THRESHOLD_MASK; |
| 205 | val |= CMCI_THRESHOLD; | 205 | val |= CMCI_THRESHOLD; |
| 206 | } else if (!(val & MCI_CTL2_CMCI_THRESHOLD_MASK)) { | 206 | } else if (!(val & MCI_CTL2_CMCI_THRESHOLD_MASK)) { |
| @@ -227,7 +227,7 @@ static void cmci_discover(int banks) | |||
| 227 | * set the thresholds properly or does not work with | 227 | * set the thresholds properly or does not work with |
| 228 | * this boot option. Note down now and report later. | 228 | * this boot option. Note down now and report later. |
| 229 | */ | 229 | */ |
| 230 | if (mce_bios_cmci_threshold && bios_zero_thresh && | 230 | if (mca_cfg.bios_cmci_threshold && bios_zero_thresh && |
| 231 | (val & MCI_CTL2_CMCI_THRESHOLD_MASK)) | 231 | (val & MCI_CTL2_CMCI_THRESHOLD_MASK)) |
| 232 | bios_wrong_thresh = 1; | 232 | bios_wrong_thresh = 1; |
| 233 | } else { | 233 | } else { |
| @@ -235,7 +235,7 @@ static void cmci_discover(int banks) | |||
| 235 | } | 235 | } |
| 236 | } | 236 | } |
| 237 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | 237 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); |
| 238 | if (mce_bios_cmci_threshold && bios_wrong_thresh) { | 238 | if (mca_cfg.bios_cmci_threshold && bios_wrong_thresh) { |
| 239 | pr_info_once( | 239 | pr_info_once( |
| 240 | "bios_cmci_threshold: Some banks do not have valid thresholds set\n"); | 240 | "bios_cmci_threshold: Some banks do not have valid thresholds set\n"); |
| 241 | pr_info_once( | 241 | pr_info_once( |
| @@ -285,34 +285,39 @@ void cmci_clear(void) | |||
| 285 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | 285 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); |
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | static long cmci_rediscover_work_func(void *arg) | ||
| 289 | { | ||
| 290 | int banks; | ||
| 291 | |||
| 292 | /* Recheck banks in case CPUs don't all have the same */ | ||
| 293 | if (cmci_supported(&banks)) | ||
| 294 | cmci_discover(banks); | ||
| 295 | |||
| 296 | return 0; | ||
| 297 | } | ||
| 298 | |||
| 288 | /* | 299 | /* |
| 289 | * After a CPU went down cycle through all the others and rediscover | 300 | * After a CPU went down cycle through all the others and rediscover |
| 290 | * Must run in process context. | 301 | * Must run in process context. |
| 291 | */ | 302 | */ |
| 292 | void cmci_rediscover(int dying) | 303 | void cmci_rediscover(int dying) |
| 293 | { | 304 | { |
| 294 | int banks; | 305 | int cpu, banks; |
| 295 | int cpu; | ||
| 296 | cpumask_var_t old; | ||
| 297 | 306 | ||
| 298 | if (!cmci_supported(&banks)) | 307 | if (!cmci_supported(&banks)) |
| 299 | return; | 308 | return; |
| 300 | if (!alloc_cpumask_var(&old, GFP_KERNEL)) | ||
| 301 | return; | ||
| 302 | cpumask_copy(old, ¤t->cpus_allowed); | ||
| 303 | 309 | ||
| 304 | for_each_online_cpu(cpu) { | 310 | for_each_online_cpu(cpu) { |
| 305 | if (cpu == dying) | 311 | if (cpu == dying) |
| 306 | continue; | 312 | continue; |
| 307 | if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) | 313 | |
| 314 | if (cpu == smp_processor_id()) { | ||
| 315 | cmci_rediscover_work_func(NULL); | ||
| 308 | continue; | 316 | continue; |
| 309 | /* Recheck banks in case CPUs don't all have the same */ | 317 | } |
| 310 | if (cmci_supported(&banks)) | ||
| 311 | cmci_discover(banks); | ||
| 312 | } | ||
| 313 | 318 | ||
| 314 | set_cpus_allowed_ptr(current, old); | 319 | work_on_cpu(cpu, cmci_rediscover_work_func, NULL); |
| 315 | free_cpumask_var(old); | 320 | } |
| 316 | } | 321 | } |
| 317 | 322 | ||
| 318 | /* | 323 | /* |
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 6b96110bb0c3..726bf963c227 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c | |||
| @@ -606,7 +606,7 @@ void __init mtrr_bp_init(void) | |||
| 606 | 606 | ||
| 607 | /* | 607 | /* |
| 608 | * This is an AMD specific MSR, but we assume(hope?) that | 608 | * This is an AMD specific MSR, but we assume(hope?) that |
| 609 | * Intel will implement it to when they extend the address | 609 | * Intel will implement it too when they extend the address |
| 610 | * bus of the Xeon. | 610 | * bus of the Xeon. |
| 611 | */ | 611 | */ |
| 612 | if (cpuid_eax(0x80000000) >= 0x80000008) { | 612 | if (cpuid_eax(0x80000000) >= 0x80000008) { |
| @@ -695,11 +695,16 @@ void mtrr_ap_init(void) | |||
| 695 | } | 695 | } |
| 696 | 696 | ||
| 697 | /** | 697 | /** |
| 698 | * Save current fixed-range MTRR state of the BSP | 698 | * Save current fixed-range MTRR state of the first cpu in cpu_online_mask. |
| 699 | */ | 699 | */ |
| 700 | void mtrr_save_state(void) | 700 | void mtrr_save_state(void) |
| 701 | { | 701 | { |
| 702 | smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1); | 702 | int first_cpu; |
| 703 | |||
| 704 | get_online_cpus(); | ||
| 705 | first_cpu = cpumask_first(cpu_online_mask); | ||
| 706 | smp_call_function_single(first_cpu, mtrr_save_fixed_ranges, NULL, 1); | ||
| 707 | put_online_cpus(); | ||
| 703 | } | 708 | } |
| 704 | 709 | ||
| 705 | void set_mtrr_aps_delayed_init(void) | 710 | void set_mtrr_aps_delayed_init(void) |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 4a3374e61a93..4428fd178bce 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
| @@ -1316,6 +1316,121 @@ static struct attribute_group x86_pmu_format_group = { | |||
| 1316 | .attrs = NULL, | 1316 | .attrs = NULL, |
| 1317 | }; | 1317 | }; |
| 1318 | 1318 | ||
| 1319 | struct perf_pmu_events_attr { | ||
| 1320 | struct device_attribute attr; | ||
| 1321 | u64 id; | ||
| 1322 | }; | ||
| 1323 | |||
| 1324 | /* | ||
| 1325 | * Remove all undefined events (x86_pmu.event_map(id) == 0) | ||
| 1326 | * out of events_attr attributes. | ||
| 1327 | */ | ||
| 1328 | static void __init filter_events(struct attribute **attrs) | ||
| 1329 | { | ||
| 1330 | int i, j; | ||
| 1331 | |||
| 1332 | for (i = 0; attrs[i]; i++) { | ||
| 1333 | if (x86_pmu.event_map(i)) | ||
| 1334 | continue; | ||
| 1335 | |||
| 1336 | for (j = i; attrs[j]; j++) | ||
| 1337 | attrs[j] = attrs[j + 1]; | ||
| 1338 | |||
| 1339 | /* Check the shifted attr. */ | ||
| 1340 | i--; | ||
| 1341 | } | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | static ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, | ||
| 1345 | char *page) | ||
| 1346 | { | ||
| 1347 | struct perf_pmu_events_attr *pmu_attr = \ | ||
| 1348 | container_of(attr, struct perf_pmu_events_attr, attr); | ||
| 1349 | |||
| 1350 | u64 config = x86_pmu.event_map(pmu_attr->id); | ||
| 1351 | return x86_pmu.events_sysfs_show(page, config); | ||
| 1352 | } | ||
| 1353 | |||
| 1354 | #define EVENT_VAR(_id) event_attr_##_id | ||
| 1355 | #define EVENT_PTR(_id) &event_attr_##_id.attr.attr | ||
| 1356 | |||
| 1357 | #define EVENT_ATTR(_name, _id) \ | ||
| 1358 | static struct perf_pmu_events_attr EVENT_VAR(_id) = { \ | ||
| 1359 | .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \ | ||
| 1360 | .id = PERF_COUNT_HW_##_id, \ | ||
| 1361 | }; | ||
| 1362 | |||
| 1363 | EVENT_ATTR(cpu-cycles, CPU_CYCLES ); | ||
| 1364 | EVENT_ATTR(instructions, INSTRUCTIONS ); | ||
| 1365 | EVENT_ATTR(cache-references, CACHE_REFERENCES ); | ||
| 1366 | EVENT_ATTR(cache-misses, CACHE_MISSES ); | ||
| 1367 | EVENT_ATTR(branch-instructions, BRANCH_INSTRUCTIONS ); | ||
| 1368 | EVENT_ATTR(branch-misses, BRANCH_MISSES ); | ||
| 1369 | EVENT_ATTR(bus-cycles, BUS_CYCLES ); | ||
| 1370 | EVENT_ATTR(stalled-cycles-frontend, STALLED_CYCLES_FRONTEND ); | ||
| 1371 | EVENT_ATTR(stalled-cycles-backend, STALLED_CYCLES_BACKEND ); | ||
| 1372 | EVENT_ATTR(ref-cycles, REF_CPU_CYCLES ); | ||
| 1373 | |||
| 1374 | static struct attribute *empty_attrs; | ||
| 1375 | |||
| 1376 | static struct attribute *events_attr[] = { | ||
| 1377 | EVENT_PTR(CPU_CYCLES), | ||
| 1378 | EVENT_PTR(INSTRUCTIONS), | ||
| 1379 | EVENT_PTR(CACHE_REFERENCES), | ||
| 1380 | EVENT_PTR(CACHE_MISSES), | ||
| 1381 | EVENT_PTR(BRANCH_INSTRUCTIONS), | ||
| 1382 | EVENT_PTR(BRANCH_MISSES), | ||
| 1383 | EVENT_PTR(BUS_CYCLES), | ||
| 1384 | EVENT_PTR(STALLED_CYCLES_FRONTEND), | ||
| 1385 | EVENT_PTR(STALLED_CYCLES_BACKEND), | ||
| 1386 | EVENT_PTR(REF_CPU_CYCLES), | ||
| 1387 | NULL, | ||
| 1388 | }; | ||
| 1389 | |||
| 1390 | static struct attribute_group x86_pmu_events_group = { | ||
| 1391 | .name = "events", | ||
| 1392 | .attrs = events_attr, | ||
| 1393 | }; | ||
| 1394 | |||
| 1395 | ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event) | ||
| 1396 | { | ||
| 1397 | u64 umask = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8; | ||
| 1398 | u64 cmask = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24; | ||
| 1399 | bool edge = (config & ARCH_PERFMON_EVENTSEL_EDGE); | ||
| 1400 | bool pc = (config & ARCH_PERFMON_EVENTSEL_PIN_CONTROL); | ||
| 1401 | bool any = (config & ARCH_PERFMON_EVENTSEL_ANY); | ||
| 1402 | bool inv = (config & ARCH_PERFMON_EVENTSEL_INV); | ||
| 1403 | ssize_t ret; | ||
| 1404 | |||
| 1405 | /* | ||
| 1406 | * We have whole page size to spend and just little data | ||
| 1407 | * to write, so we can safely use sprintf. | ||
| 1408 | */ | ||
| 1409 | ret = sprintf(page, "event=0x%02llx", event); | ||
| 1410 | |||
| 1411 | if (umask) | ||
| 1412 | ret += sprintf(page + ret, ",umask=0x%02llx", umask); | ||
| 1413 | |||
| 1414 | if (edge) | ||
| 1415 | ret += sprintf(page + ret, ",edge"); | ||
| 1416 | |||
| 1417 | if (pc) | ||
| 1418 | ret += sprintf(page + ret, ",pc"); | ||
| 1419 | |||
| 1420 | if (any) | ||
| 1421 | ret += sprintf(page + ret, ",any"); | ||
| 1422 | |||
| 1423 | if (inv) | ||
| 1424 | ret += sprintf(page + ret, ",inv"); | ||
| 1425 | |||
| 1426 | if (cmask) | ||
| 1427 | ret += sprintf(page + ret, ",cmask=0x%02llx", cmask); | ||
| 1428 | |||
| 1429 | ret += sprintf(page + ret, "\n"); | ||
| 1430 | |||
| 1431 | return ret; | ||
| 1432 | } | ||
| 1433 | |||
| 1319 | static int __init init_hw_perf_events(void) | 1434 | static int __init init_hw_perf_events(void) |
| 1320 | { | 1435 | { |
| 1321 | struct x86_pmu_quirk *quirk; | 1436 | struct x86_pmu_quirk *quirk; |
| @@ -1362,6 +1477,11 @@ static int __init init_hw_perf_events(void) | |||
| 1362 | x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ | 1477 | x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ |
| 1363 | x86_pmu_format_group.attrs = x86_pmu.format_attrs; | 1478 | x86_pmu_format_group.attrs = x86_pmu.format_attrs; |
| 1364 | 1479 | ||
| 1480 | if (!x86_pmu.events_sysfs_show) | ||
| 1481 | x86_pmu_events_group.attrs = &empty_attrs; | ||
| 1482 | else | ||
| 1483 | filter_events(x86_pmu_events_group.attrs); | ||
| 1484 | |||
| 1365 | pr_info("... version: %d\n", x86_pmu.version); | 1485 | pr_info("... version: %d\n", x86_pmu.version); |
| 1366 | pr_info("... bit width: %d\n", x86_pmu.cntval_bits); | 1486 | pr_info("... bit width: %d\n", x86_pmu.cntval_bits); |
| 1367 | pr_info("... generic registers: %d\n", x86_pmu.num_counters); | 1487 | pr_info("... generic registers: %d\n", x86_pmu.num_counters); |
| @@ -1651,6 +1771,7 @@ static struct attribute_group x86_pmu_attr_group = { | |||
| 1651 | static const struct attribute_group *x86_pmu_attr_groups[] = { | 1771 | static const struct attribute_group *x86_pmu_attr_groups[] = { |
| 1652 | &x86_pmu_attr_group, | 1772 | &x86_pmu_attr_group, |
| 1653 | &x86_pmu_format_group, | 1773 | &x86_pmu_format_group, |
| 1774 | &x86_pmu_events_group, | ||
| 1654 | NULL, | 1775 | NULL, |
| 1655 | }; | 1776 | }; |
| 1656 | 1777 | ||
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 271d25700297..115c1ea97746 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
| @@ -354,6 +354,8 @@ struct x86_pmu { | |||
| 354 | int attr_rdpmc; | 354 | int attr_rdpmc; |
| 355 | struct attribute **format_attrs; | 355 | struct attribute **format_attrs; |
| 356 | 356 | ||
| 357 | ssize_t (*events_sysfs_show)(char *page, u64 config); | ||
| 358 | |||
| 357 | /* | 359 | /* |
| 358 | * CPU Hotplug hooks | 360 | * CPU Hotplug hooks |
| 359 | */ | 361 | */ |
| @@ -536,6 +538,9 @@ static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip) | |||
| 536 | regs->ip = ip; | 538 | regs->ip = ip; |
| 537 | } | 539 | } |
| 538 | 540 | ||
| 541 | ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event); | ||
| 542 | ssize_t intel_event_sysfs_show(char *page, u64 config); | ||
| 543 | |||
| 539 | #ifdef CONFIG_CPU_SUP_AMD | 544 | #ifdef CONFIG_CPU_SUP_AMD |
| 540 | 545 | ||
| 541 | int amd_pmu_init(void); | 546 | int amd_pmu_init(void); |
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 4528ae7b6ec4..c93bc4e813a0 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c | |||
| @@ -568,6 +568,14 @@ amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *ev | |||
| 568 | } | 568 | } |
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | static ssize_t amd_event_sysfs_show(char *page, u64 config) | ||
| 572 | { | ||
| 573 | u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT) | | ||
| 574 | (config & AMD64_EVENTSEL_EVENT) >> 24; | ||
| 575 | |||
| 576 | return x86_event_sysfs_show(page, config, event); | ||
| 577 | } | ||
| 578 | |||
| 571 | static __initconst const struct x86_pmu amd_pmu = { | 579 | static __initconst const struct x86_pmu amd_pmu = { |
| 572 | .name = "AMD", | 580 | .name = "AMD", |
| 573 | .handle_irq = x86_pmu_handle_irq, | 581 | .handle_irq = x86_pmu_handle_irq, |
| @@ -591,6 +599,7 @@ static __initconst const struct x86_pmu amd_pmu = { | |||
| 591 | .put_event_constraints = amd_put_event_constraints, | 599 | .put_event_constraints = amd_put_event_constraints, |
| 592 | 600 | ||
| 593 | .format_attrs = amd_format_attr, | 601 | .format_attrs = amd_format_attr, |
| 602 | .events_sysfs_show = amd_event_sysfs_show, | ||
| 594 | 603 | ||
| 595 | .cpu_prepare = amd_pmu_cpu_prepare, | 604 | .cpu_prepare = amd_pmu_cpu_prepare, |
| 596 | .cpu_starting = amd_pmu_cpu_starting, | 605 | .cpu_starting = amd_pmu_cpu_starting, |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 324bb523d9d9..93b9e1181f83 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
| @@ -1603,6 +1603,13 @@ static struct attribute *intel_arch_formats_attr[] = { | |||
| 1603 | NULL, | 1603 | NULL, |
| 1604 | }; | 1604 | }; |
| 1605 | 1605 | ||
| 1606 | ssize_t intel_event_sysfs_show(char *page, u64 config) | ||
| 1607 | { | ||
| 1608 | u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT); | ||
| 1609 | |||
| 1610 | return x86_event_sysfs_show(page, config, event); | ||
| 1611 | } | ||
| 1612 | |||
| 1606 | static __initconst const struct x86_pmu core_pmu = { | 1613 | static __initconst const struct x86_pmu core_pmu = { |
| 1607 | .name = "core", | 1614 | .name = "core", |
| 1608 | .handle_irq = x86_pmu_handle_irq, | 1615 | .handle_irq = x86_pmu_handle_irq, |
| @@ -1628,6 +1635,7 @@ static __initconst const struct x86_pmu core_pmu = { | |||
| 1628 | .event_constraints = intel_core_event_constraints, | 1635 | .event_constraints = intel_core_event_constraints, |
| 1629 | .guest_get_msrs = core_guest_get_msrs, | 1636 | .guest_get_msrs = core_guest_get_msrs, |
| 1630 | .format_attrs = intel_arch_formats_attr, | 1637 | .format_attrs = intel_arch_formats_attr, |
| 1638 | .events_sysfs_show = intel_event_sysfs_show, | ||
| 1631 | }; | 1639 | }; |
| 1632 | 1640 | ||
| 1633 | struct intel_shared_regs *allocate_shared_regs(int cpu) | 1641 | struct intel_shared_regs *allocate_shared_regs(int cpu) |
| @@ -1766,6 +1774,7 @@ static __initconst const struct x86_pmu intel_pmu = { | |||
| 1766 | .pebs_aliases = intel_pebs_aliases_core2, | 1774 | .pebs_aliases = intel_pebs_aliases_core2, |
| 1767 | 1775 | ||
| 1768 | .format_attrs = intel_arch3_formats_attr, | 1776 | .format_attrs = intel_arch3_formats_attr, |
| 1777 | .events_sysfs_show = intel_event_sysfs_show, | ||
| 1769 | 1778 | ||
| 1770 | .cpu_prepare = intel_pmu_cpu_prepare, | 1779 | .cpu_prepare = intel_pmu_cpu_prepare, |
| 1771 | .cpu_starting = intel_pmu_cpu_starting, | 1780 | .cpu_starting = intel_pmu_cpu_starting, |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 3cf3d97cce3a..b43200dbfe7e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
| @@ -2500,7 +2500,7 @@ static bool pcidrv_registered; | |||
| 2500 | /* | 2500 | /* |
| 2501 | * add a pci uncore device | 2501 | * add a pci uncore device |
| 2502 | */ | 2502 | */ |
| 2503 | static int __devinit uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev) | 2503 | static int uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev) |
| 2504 | { | 2504 | { |
| 2505 | struct intel_uncore_pmu *pmu; | 2505 | struct intel_uncore_pmu *pmu; |
| 2506 | struct intel_uncore_box *box; | 2506 | struct intel_uncore_box *box; |
| @@ -2571,8 +2571,8 @@ static void uncore_pci_remove(struct pci_dev *pdev) | |||
| 2571 | kfree(box); | 2571 | kfree(box); |
| 2572 | } | 2572 | } |
| 2573 | 2573 | ||
| 2574 | static int __devinit uncore_pci_probe(struct pci_dev *pdev, | 2574 | static int uncore_pci_probe(struct pci_dev *pdev, |
| 2575 | const struct pci_device_id *id) | 2575 | const struct pci_device_id *id) |
| 2576 | { | 2576 | { |
| 2577 | struct intel_uncore_type *type; | 2577 | struct intel_uncore_type *type; |
| 2578 | 2578 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index 7d0270bd793e..f2af39f5dc3d 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c | |||
| @@ -227,6 +227,8 @@ static __initconst const struct x86_pmu p6_pmu = { | |||
| 227 | .event_constraints = p6_event_constraints, | 227 | .event_constraints = p6_event_constraints, |
| 228 | 228 | ||
| 229 | .format_attrs = intel_p6_formats_attr, | 229 | .format_attrs = intel_p6_formats_attr, |
| 230 | .events_sysfs_show = intel_event_sysfs_show, | ||
| 231 | |||
| 230 | }; | 232 | }; |
| 231 | 233 | ||
| 232 | __init int p6_pmu_init(void) | 234 | __init int p6_pmu_init(void) |
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index fbd895562292..3286a92e662a 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c | |||
| @@ -26,11 +26,6 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c, | |||
| 26 | #ifdef CONFIG_X86_32 | 26 | #ifdef CONFIG_X86_32 |
| 27 | static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) | 27 | static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) |
| 28 | { | 28 | { |
| 29 | /* | ||
| 30 | * We use exception 16 if we have hardware math and we've either seen | ||
| 31 | * it or the CPU claims it is internal | ||
| 32 | */ | ||
| 33 | int fpu_exception = c->hard_math && (ignore_fpu_irq || cpu_has_fpu); | ||
| 34 | seq_printf(m, | 29 | seq_printf(m, |
| 35 | "fdiv_bug\t: %s\n" | 30 | "fdiv_bug\t: %s\n" |
| 36 | "hlt_bug\t\t: %s\n" | 31 | "hlt_bug\t\t: %s\n" |
| @@ -45,7 +40,7 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) | |||
| 45 | c->f00f_bug ? "yes" : "no", | 40 | c->f00f_bug ? "yes" : "no", |
| 46 | c->coma_bug ? "yes" : "no", | 41 | c->coma_bug ? "yes" : "no", |
| 47 | c->hard_math ? "yes" : "no", | 42 | c->hard_math ? "yes" : "no", |
| 48 | fpu_exception ? "yes" : "no", | 43 | c->hard_math ? "yes" : "no", |
| 49 | c->cpuid_level, | 44 | c->cpuid_level, |
| 50 | c->wp_works_ok ? "yes" : "no"); | 45 | c->wp_works_ok ? "yes" : "no"); |
| 51 | } | 46 | } |
