aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/nmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/nmi.c')
-rw-r--r--arch/x86_64/kernel/nmi.c135
1 files changed, 99 insertions, 36 deletions
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 486f4c61a948..dfab9f167366 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -39,15 +39,17 @@ int panic_on_unrecovered_nmi;
39 * different subsystems this reservation system just tries to coordinate 39 * different subsystems this reservation system just tries to coordinate
40 * things a little 40 * things a little
41 */ 41 */
42static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner);
43static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[2]);
44
45static cpumask_t backtrace_mask = CPU_MASK_NONE;
46 42
47/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's 43/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's
48 * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) 44 * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now)
49 */ 45 */
50#define NMI_MAX_COUNTER_BITS 66 46#define NMI_MAX_COUNTER_BITS 66
47#define NMI_MAX_COUNTER_LONGS BITS_TO_LONGS(NMI_MAX_COUNTER_BITS)
48
49static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner[NMI_MAX_COUNTER_LONGS]);
50static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[NMI_MAX_COUNTER_LONGS]);
51
52static cpumask_t backtrace_mask = CPU_MASK_NONE;
51 53
52/* nmi_active: 54/* nmi_active:
53 * >0: the lapic NMI watchdog is active, but can be disabled 55 * >0: the lapic NMI watchdog is active, but can be disabled
@@ -108,64 +110,128 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr)
108/* checks for a bit availability (hack for oprofile) */ 110/* checks for a bit availability (hack for oprofile) */
109int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) 111int avail_to_resrv_perfctr_nmi_bit(unsigned int counter)
110{ 112{
113 int cpu;
111 BUG_ON(counter > NMI_MAX_COUNTER_BITS); 114 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
112 115 for_each_possible_cpu (cpu) {
113 return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); 116 if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
117 return 0;
118 }
119 return 1;
114} 120}
115 121
116/* checks the an msr for availability */ 122/* checks the an msr for availability */
117int avail_to_resrv_perfctr_nmi(unsigned int msr) 123int avail_to_resrv_perfctr_nmi(unsigned int msr)
118{ 124{
119 unsigned int counter; 125 unsigned int counter;
126 int cpu;
120 127
121 counter = nmi_perfctr_msr_to_bit(msr); 128 counter = nmi_perfctr_msr_to_bit(msr);
122 BUG_ON(counter > NMI_MAX_COUNTER_BITS); 129 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
123 130
124 return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); 131 for_each_possible_cpu (cpu) {
132 if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
133 return 0;
134 }
135 return 1;
125} 136}
126 137
127int reserve_perfctr_nmi(unsigned int msr) 138static int __reserve_perfctr_nmi(int cpu, unsigned int msr)
128{ 139{
129 unsigned int counter; 140 unsigned int counter;
141 if (cpu < 0)
142 cpu = smp_processor_id();
130 143
131 counter = nmi_perfctr_msr_to_bit(msr); 144 counter = nmi_perfctr_msr_to_bit(msr);
132 BUG_ON(counter > NMI_MAX_COUNTER_BITS); 145 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
133 146
134 if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner))) 147 if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
135 return 1; 148 return 1;
136 return 0; 149 return 0;
137} 150}
138 151
139void release_perfctr_nmi(unsigned int msr) 152static void __release_perfctr_nmi(int cpu, unsigned int msr)
140{ 153{
141 unsigned int counter; 154 unsigned int counter;
155 if (cpu < 0)
156 cpu = smp_processor_id();
142 157
143 counter = nmi_perfctr_msr_to_bit(msr); 158 counter = nmi_perfctr_msr_to_bit(msr);
144 BUG_ON(counter > NMI_MAX_COUNTER_BITS); 159 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
145 160
146 clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner)); 161 clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu));
147} 162}
148 163
149int reserve_evntsel_nmi(unsigned int msr) 164int reserve_perfctr_nmi(unsigned int msr)
165{
166 int cpu, i;
167 for_each_possible_cpu (cpu) {
168 if (!__reserve_perfctr_nmi(cpu, msr)) {
169 for_each_possible_cpu (i) {
170 if (i >= cpu)
171 break;
172 __release_perfctr_nmi(i, msr);
173 }
174 return 0;
175 }
176 }
177 return 1;
178}
179
180void release_perfctr_nmi(unsigned int msr)
181{
182 int cpu;
183 for_each_possible_cpu (cpu)
184 __release_perfctr_nmi(cpu, msr);
185}
186
187int __reserve_evntsel_nmi(int cpu, unsigned int msr)
150{ 188{
151 unsigned int counter; 189 unsigned int counter;
190 if (cpu < 0)
191 cpu = smp_processor_id();
152 192
153 counter = nmi_evntsel_msr_to_bit(msr); 193 counter = nmi_evntsel_msr_to_bit(msr);
154 BUG_ON(counter > NMI_MAX_COUNTER_BITS); 194 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
155 195
156 if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner))) 196 if (!test_and_set_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]))
157 return 1; 197 return 1;
158 return 0; 198 return 0;
159} 199}
160 200
161void release_evntsel_nmi(unsigned int msr) 201static void __release_evntsel_nmi(int cpu, unsigned int msr)
162{ 202{
163 unsigned int counter; 203 unsigned int counter;
204 if (cpu < 0)
205 cpu = smp_processor_id();
164 206
165 counter = nmi_evntsel_msr_to_bit(msr); 207 counter = nmi_evntsel_msr_to_bit(msr);
166 BUG_ON(counter > NMI_MAX_COUNTER_BITS); 208 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
167 209
168 clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner)); 210 clear_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]);
211}
212
213int reserve_evntsel_nmi(unsigned int msr)
214{
215 int cpu, i;
216 for_each_possible_cpu (cpu) {
217 if (!__reserve_evntsel_nmi(cpu, msr)) {
218 for_each_possible_cpu (i) {
219 if (i >= cpu)
220 break;
221 __release_evntsel_nmi(i, msr);
222 }
223 return 0;
224 }
225 }
226 return 1;
227}
228
229void release_evntsel_nmi(unsigned int msr)
230{
231 int cpu;
232 for_each_possible_cpu (cpu) {
233 __release_evntsel_nmi(cpu, msr);
234 }
169} 235}
170 236
171static __cpuinit inline int nmi_known_cpu(void) 237static __cpuinit inline int nmi_known_cpu(void)
@@ -187,10 +253,7 @@ void nmi_watchdog_default(void)
187{ 253{
188 if (nmi_watchdog != NMI_DEFAULT) 254 if (nmi_watchdog != NMI_DEFAULT)
189 return; 255 return;
190 if (nmi_known_cpu()) 256 nmi_watchdog = NMI_NONE;
191 nmi_watchdog = NMI_LOCAL_APIC;
192 else
193 nmi_watchdog = NMI_IO_APIC;
194} 257}
195 258
196static int endflag __initdata = 0; 259static int endflag __initdata = 0;
@@ -256,7 +319,7 @@ int __init check_nmi_watchdog (void)
256 for (cpu = 0; cpu < NR_CPUS; cpu++) 319 for (cpu = 0; cpu < NR_CPUS; cpu++)
257 counts[cpu] = cpu_pda(cpu)->__nmi_count; 320 counts[cpu] = cpu_pda(cpu)->__nmi_count;
258 local_irq_enable(); 321 local_irq_enable();
259 mdelay((10*1000)/nmi_hz); // wait 10 ticks 322 mdelay((20*1000)/nmi_hz); // wait 20 ticks
260 323
261 for_each_online_cpu(cpu) { 324 for_each_online_cpu(cpu) {
262 if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled) 325 if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled)
@@ -475,10 +538,10 @@ static int setup_k7_watchdog(void)
475 538
476 perfctr_msr = MSR_K7_PERFCTR0; 539 perfctr_msr = MSR_K7_PERFCTR0;
477 evntsel_msr = MSR_K7_EVNTSEL0; 540 evntsel_msr = MSR_K7_EVNTSEL0;
478 if (!reserve_perfctr_nmi(perfctr_msr)) 541 if (!__reserve_perfctr_nmi(-1, perfctr_msr))
479 goto fail; 542 goto fail;
480 543
481 if (!reserve_evntsel_nmi(evntsel_msr)) 544 if (!__reserve_evntsel_nmi(-1, evntsel_msr))
482 goto fail1; 545 goto fail1;
483 546
484 /* Simulator may not support it */ 547 /* Simulator may not support it */
@@ -504,9 +567,9 @@ static int setup_k7_watchdog(void)
504 wd->check_bit = 1ULL<<63; 567 wd->check_bit = 1ULL<<63;
505 return 1; 568 return 1;
506fail2: 569fail2:
507 release_evntsel_nmi(evntsel_msr); 570 __release_evntsel_nmi(-1, evntsel_msr);
508fail1: 571fail1:
509 release_perfctr_nmi(perfctr_msr); 572 __release_perfctr_nmi(-1, perfctr_msr);
510fail: 573fail:
511 return 0; 574 return 0;
512} 575}
@@ -517,8 +580,8 @@ static void stop_k7_watchdog(void)
517 580
518 wrmsr(wd->evntsel_msr, 0, 0); 581 wrmsr(wd->evntsel_msr, 0, 0);
519 582
520 release_evntsel_nmi(wd->evntsel_msr); 583 __release_evntsel_nmi(-1, wd->evntsel_msr);
521 release_perfctr_nmi(wd->perfctr_msr); 584 __release_perfctr_nmi(-1, wd->perfctr_msr);
522} 585}
523 586
524/* Note that these events don't tick when the CPU idles. This means 587/* Note that these events don't tick when the CPU idles. This means
@@ -584,10 +647,10 @@ static int setup_p4_watchdog(void)
584 cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); 647 cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4);
585 } 648 }
586 649
587 if (!reserve_perfctr_nmi(perfctr_msr)) 650 if (!__reserve_perfctr_nmi(-1, perfctr_msr))
588 goto fail; 651 goto fail;
589 652
590 if (!reserve_evntsel_nmi(evntsel_msr)) 653 if (!__reserve_evntsel_nmi(-1, evntsel_msr))
591 goto fail1; 654 goto fail1;
592 655
593 evntsel = P4_ESCR_EVENT_SELECT(0x3F) 656 evntsel = P4_ESCR_EVENT_SELECT(0x3F)
@@ -612,7 +675,7 @@ static int setup_p4_watchdog(void)
612 wd->check_bit = 1ULL<<39; 675 wd->check_bit = 1ULL<<39;
613 return 1; 676 return 1;
614fail1: 677fail1:
615 release_perfctr_nmi(perfctr_msr); 678 __release_perfctr_nmi(-1, perfctr_msr);
616fail: 679fail:
617 return 0; 680 return 0;
618} 681}
@@ -624,8 +687,8 @@ static void stop_p4_watchdog(void)
624 wrmsr(wd->cccr_msr, 0, 0); 687 wrmsr(wd->cccr_msr, 0, 0);
625 wrmsr(wd->evntsel_msr, 0, 0); 688 wrmsr(wd->evntsel_msr, 0, 0);
626 689
627 release_evntsel_nmi(wd->evntsel_msr); 690 __release_evntsel_nmi(-1, wd->evntsel_msr);
628 release_perfctr_nmi(wd->perfctr_msr); 691 __release_perfctr_nmi(-1, wd->perfctr_msr);
629} 692}
630 693
631#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 694#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL
@@ -653,10 +716,10 @@ static int setup_intel_arch_watchdog(void)
653 perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; 716 perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0;
654 evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0; 717 evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0;
655 718
656 if (!reserve_perfctr_nmi(perfctr_msr)) 719 if (!__reserve_perfctr_nmi(-1, perfctr_msr))
657 goto fail; 720 goto fail;
658 721
659 if (!reserve_evntsel_nmi(evntsel_msr)) 722 if (!__reserve_evntsel_nmi(-1, evntsel_msr))
660 goto fail1; 723 goto fail1;
661 724
662 wrmsrl(perfctr_msr, 0UL); 725 wrmsrl(perfctr_msr, 0UL);
@@ -683,7 +746,7 @@ static int setup_intel_arch_watchdog(void)
683 wd->check_bit = 1ULL << (eax.split.bit_width - 1); 746 wd->check_bit = 1ULL << (eax.split.bit_width - 1);
684 return 1; 747 return 1;
685fail1: 748fail1:
686 release_perfctr_nmi(perfctr_msr); 749 __release_perfctr_nmi(-1, perfctr_msr);
687fail: 750fail:
688 return 0; 751 return 0;
689} 752}
@@ -707,8 +770,8 @@ static void stop_intel_arch_watchdog(void)
707 770
708 wrmsr(wd->evntsel_msr, 0, 0); 771 wrmsr(wd->evntsel_msr, 0, 0);
709 772
710 release_evntsel_nmi(wd->evntsel_msr); 773 __release_evntsel_nmi(-1, wd->evntsel_msr);
711 release_perfctr_nmi(wd->perfctr_msr); 774 __release_perfctr_nmi(-1, wd->perfctr_msr);
712} 775}
713 776
714void setup_apic_nmi_watchdog(void *unused) 777void setup_apic_nmi_watchdog(void *unused)