diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/apic/hw_nmi.c | 18 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel.c | 9 | ||||
-rw-r--r-- | arch/x86/kernel/entry_32.S | 10 | ||||
-rw-r--r-- | arch/x86/kernel/signal.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/traps.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/tsc.c | 4 |
6 files changed, 38 insertions, 12 deletions
diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c index c3fcb5de5083..6a1e71bde323 100644 --- a/arch/x86/kernel/apic/hw_nmi.c +++ b/arch/x86/kernel/apic/hw_nmi.c | |||
@@ -33,31 +33,41 @@ static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly; | |||
33 | /* "in progress" flag of arch_trigger_all_cpu_backtrace */ | 33 | /* "in progress" flag of arch_trigger_all_cpu_backtrace */ |
34 | static unsigned long backtrace_flag; | 34 | static unsigned long backtrace_flag; |
35 | 35 | ||
36 | void arch_trigger_all_cpu_backtrace(void) | 36 | void arch_trigger_all_cpu_backtrace(bool include_self) |
37 | { | 37 | { |
38 | int i; | 38 | int i; |
39 | int cpu = get_cpu(); | ||
39 | 40 | ||
40 | if (test_and_set_bit(0, &backtrace_flag)) | 41 | if (test_and_set_bit(0, &backtrace_flag)) { |
41 | /* | 42 | /* |
42 | * If there is already a trigger_all_cpu_backtrace() in progress | 43 | * If there is already a trigger_all_cpu_backtrace() in progress |
43 | * (backtrace_flag == 1), don't output double cpu dump infos. | 44 | * (backtrace_flag == 1), don't output double cpu dump infos. |
44 | */ | 45 | */ |
46 | put_cpu(); | ||
45 | return; | 47 | return; |
48 | } | ||
46 | 49 | ||
47 | cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask); | 50 | cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask); |
51 | if (!include_self) | ||
52 | cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); | ||
48 | 53 | ||
49 | printk(KERN_INFO "sending NMI to all CPUs:\n"); | 54 | if (!cpumask_empty(to_cpumask(backtrace_mask))) { |
50 | apic->send_IPI_all(NMI_VECTOR); | 55 | pr_info("sending NMI to %s CPUs:\n", |
56 | (include_self ? "all" : "other")); | ||
57 | apic->send_IPI_mask(to_cpumask(backtrace_mask), NMI_VECTOR); | ||
58 | } | ||
51 | 59 | ||
52 | /* Wait for up to 10 seconds for all CPUs to do the backtrace */ | 60 | /* Wait for up to 10 seconds for all CPUs to do the backtrace */ |
53 | for (i = 0; i < 10 * 1000; i++) { | 61 | for (i = 0; i < 10 * 1000; i++) { |
54 | if (cpumask_empty(to_cpumask(backtrace_mask))) | 62 | if (cpumask_empty(to_cpumask(backtrace_mask))) |
55 | break; | 63 | break; |
56 | mdelay(1); | 64 | mdelay(1); |
65 | touch_softlockup_watchdog(); | ||
57 | } | 66 | } |
58 | 67 | ||
59 | clear_bit(0, &backtrace_flag); | 68 | clear_bit(0, &backtrace_flag); |
60 | smp_mb__after_atomic(); | 69 | smp_mb__after_atomic(); |
70 | put_cpu(); | ||
61 | } | 71 | } |
62 | 72 | ||
63 | static int | 73 | static int |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index adb02aa62af5..07846d738bdb 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -1382,6 +1382,15 @@ again: | |||
1382 | intel_pmu_lbr_read(); | 1382 | intel_pmu_lbr_read(); |
1383 | 1383 | ||
1384 | /* | 1384 | /* |
1385 | * CondChgd bit 63 doesn't mean any overflow status. Ignore | ||
1386 | * and clear the bit. | ||
1387 | */ | ||
1388 | if (__test_and_clear_bit(63, (unsigned long *)&status)) { | ||
1389 | if (!status) | ||
1390 | goto done; | ||
1391 | } | ||
1392 | |||
1393 | /* | ||
1385 | * PEBS overflow sets bit 62 in the global status register | 1394 | * PEBS overflow sets bit 62 in the global status register |
1386 | */ | 1395 | */ |
1387 | if (__test_and_clear_bit(62, (unsigned long *)&status)) { | 1396 | if (__test_and_clear_bit(62, (unsigned long *)&status)) { |
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index f0da82b8e634..dbaa23e78b36 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -423,9 +423,10 @@ sysenter_past_esp: | |||
423 | jnz sysenter_audit | 423 | jnz sysenter_audit |
424 | sysenter_do_call: | 424 | sysenter_do_call: |
425 | cmpl $(NR_syscalls), %eax | 425 | cmpl $(NR_syscalls), %eax |
426 | jae syscall_badsys | 426 | jae sysenter_badsys |
427 | call *sys_call_table(,%eax,4) | 427 | call *sys_call_table(,%eax,4) |
428 | movl %eax,PT_EAX(%esp) | 428 | movl %eax,PT_EAX(%esp) |
429 | sysenter_after_call: | ||
429 | LOCKDEP_SYS_EXIT | 430 | LOCKDEP_SYS_EXIT |
430 | DISABLE_INTERRUPTS(CLBR_ANY) | 431 | DISABLE_INTERRUPTS(CLBR_ANY) |
431 | TRACE_IRQS_OFF | 432 | TRACE_IRQS_OFF |
@@ -675,7 +676,12 @@ END(syscall_fault) | |||
675 | 676 | ||
676 | syscall_badsys: | 677 | syscall_badsys: |
677 | movl $-ENOSYS,PT_EAX(%esp) | 678 | movl $-ENOSYS,PT_EAX(%esp) |
678 | jmp resume_userspace | 679 | jmp syscall_exit |
680 | END(syscall_badsys) | ||
681 | |||
682 | sysenter_badsys: | ||
683 | movl $-ENOSYS,PT_EAX(%esp) | ||
684 | jmp sysenter_after_call | ||
679 | END(syscall_badsys) | 685 | END(syscall_badsys) |
680 | CFI_ENDPROC | 686 | CFI_ENDPROC |
681 | 687 | ||
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index a0da58db43a8..2851d63c1202 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -363,7 +363,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, | |||
363 | 363 | ||
364 | /* Set up to return from userspace. */ | 364 | /* Set up to return from userspace. */ |
365 | restorer = current->mm->context.vdso + | 365 | restorer = current->mm->context.vdso + |
366 | selected_vdso32->sym___kernel_sigreturn; | 366 | selected_vdso32->sym___kernel_rt_sigreturn; |
367 | if (ksig->ka.sa.sa_flags & SA_RESTORER) | 367 | if (ksig->ka.sa.sa_flags & SA_RESTORER) |
368 | restorer = ksig->ka.sa.sa_restorer; | 368 | restorer = ksig->ka.sa.sa_restorer; |
369 | put_user_ex(restorer, &frame->pretcode); | 369 | put_user_ex(restorer, &frame->pretcode); |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index c6eb418c5627..0d0e922fafc1 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -343,6 +343,7 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code) | |||
343 | if (poke_int3_handler(regs)) | 343 | if (poke_int3_handler(regs)) |
344 | return; | 344 | return; |
345 | 345 | ||
346 | prev_state = exception_enter(); | ||
346 | #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP | 347 | #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP |
347 | if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, | 348 | if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, |
348 | SIGTRAP) == NOTIFY_STOP) | 349 | SIGTRAP) == NOTIFY_STOP) |
@@ -351,9 +352,8 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code) | |||
351 | 352 | ||
352 | #ifdef CONFIG_KPROBES | 353 | #ifdef CONFIG_KPROBES |
353 | if (kprobe_int3_handler(regs)) | 354 | if (kprobe_int3_handler(regs)) |
354 | return; | 355 | goto exit; |
355 | #endif | 356 | #endif |
356 | prev_state = exception_enter(); | ||
357 | 357 | ||
358 | if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, | 358 | if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, |
359 | SIGTRAP) == NOTIFY_STOP) | 359 | SIGTRAP) == NOTIFY_STOP) |
@@ -433,6 +433,8 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) | |||
433 | unsigned long dr6; | 433 | unsigned long dr6; |
434 | int si_code; | 434 | int si_code; |
435 | 435 | ||
436 | prev_state = exception_enter(); | ||
437 | |||
436 | get_debugreg(dr6, 6); | 438 | get_debugreg(dr6, 6); |
437 | 439 | ||
438 | /* Filter out all the reserved bits which are preset to 1 */ | 440 | /* Filter out all the reserved bits which are preset to 1 */ |
@@ -465,7 +467,6 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) | |||
465 | if (kprobe_debug_handler(regs)) | 467 | if (kprobe_debug_handler(regs)) |
466 | goto exit; | 468 | goto exit; |
467 | #endif | 469 | #endif |
468 | prev_state = exception_enter(); | ||
469 | 470 | ||
470 | if (notify_die(DIE_DEBUG, "debug", regs, (long)&dr6, error_code, | 471 | if (notify_die(DIE_DEBUG, "debug", regs, (long)&dr6, error_code, |
471 | SIGTRAP) == NOTIFY_STOP) | 472 | SIGTRAP) == NOTIFY_STOP) |
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 57e5ce126d5a..ea030319b321 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -920,9 +920,9 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | |||
920 | tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); | 920 | tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); |
921 | if (!(freq->flags & CPUFREQ_CONST_LOOPS)) | 921 | if (!(freq->flags & CPUFREQ_CONST_LOOPS)) |
922 | mark_tsc_unstable("cpufreq changes"); | 922 | mark_tsc_unstable("cpufreq changes"); |
923 | } | ||
924 | 923 | ||
925 | set_cyc2ns_scale(tsc_khz, freq->cpu); | 924 | set_cyc2ns_scale(tsc_khz, freq->cpu); |
925 | } | ||
926 | 926 | ||
927 | return 0; | 927 | return 0; |
928 | } | 928 | } |