diff options
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r-- | arch/i386/kernel/traps.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index cd2d5d5514fe..09a58cb6daa7 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -210,7 +210,7 @@ void show_registers(struct pt_regs *regs) | |||
210 | unsigned short ss; | 210 | unsigned short ss; |
211 | 211 | ||
212 | esp = (unsigned long) (®s->esp); | 212 | esp = (unsigned long) (®s->esp); |
213 | ss = __KERNEL_DS; | 213 | savesegment(ss, ss); |
214 | if (user_mode(regs)) { | 214 | if (user_mode(regs)) { |
215 | in_kernel = 0; | 215 | in_kernel = 0; |
216 | esp = regs->esp; | 216 | esp = regs->esp; |
@@ -267,9 +267,6 @@ static void handle_BUG(struct pt_regs *regs) | |||
267 | char c; | 267 | char c; |
268 | unsigned long eip; | 268 | unsigned long eip; |
269 | 269 | ||
270 | if (user_mode(regs)) | ||
271 | goto no_bug; /* Not in kernel */ | ||
272 | |||
273 | eip = regs->eip; | 270 | eip = regs->eip; |
274 | 271 | ||
275 | if (eip < PAGE_OFFSET) | 272 | if (eip < PAGE_OFFSET) |
@@ -366,8 +363,9 @@ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long e | |||
366 | die(str, regs, err); | 363 | die(str, regs, err); |
367 | } | 364 | } |
368 | 365 | ||
369 | static void do_trap(int trapnr, int signr, char *str, int vm86, | 366 | static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86, |
370 | struct pt_regs * regs, long error_code, siginfo_t *info) | 367 | struct pt_regs * regs, long error_code, |
368 | siginfo_t *info) | ||
371 | { | 369 | { |
372 | struct task_struct *tsk = current; | 370 | struct task_struct *tsk = current; |
373 | tsk->thread.error_code = error_code; | 371 | tsk->thread.error_code = error_code; |
@@ -463,7 +461,8 @@ DO_ERROR(12, SIGBUS, "stack segment", stack_segment) | |||
463 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) | 461 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) |
464 | DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0) | 462 | DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0) |
465 | 463 | ||
466 | fastcall void do_general_protection(struct pt_regs * regs, long error_code) | 464 | fastcall void __kprobes do_general_protection(struct pt_regs * regs, |
465 | long error_code) | ||
467 | { | 466 | { |
468 | int cpu = get_cpu(); | 467 | int cpu = get_cpu(); |
469 | struct tss_struct *tss = &per_cpu(init_tss, cpu); | 468 | struct tss_struct *tss = &per_cpu(init_tss, cpu); |
@@ -568,6 +567,10 @@ static DEFINE_SPINLOCK(nmi_print_lock); | |||
568 | 567 | ||
569 | void die_nmi (struct pt_regs *regs, const char *msg) | 568 | void die_nmi (struct pt_regs *regs, const char *msg) |
570 | { | 569 | { |
570 | if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 0, SIGINT) == | ||
571 | NOTIFY_STOP) | ||
572 | return; | ||
573 | |||
571 | spin_lock(&nmi_print_lock); | 574 | spin_lock(&nmi_print_lock); |
572 | /* | 575 | /* |
573 | * We are in trouble anyway, lets at least try | 576 | * We are in trouble anyway, lets at least try |
@@ -656,7 +659,7 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code) | |||
656 | 659 | ||
657 | ++nmi_count(cpu); | 660 | ++nmi_count(cpu); |
658 | 661 | ||
659 | if (!nmi_callback(regs, cpu)) | 662 | if (!rcu_dereference(nmi_callback)(regs, cpu)) |
660 | default_do_nmi(regs); | 663 | default_do_nmi(regs); |
661 | 664 | ||
662 | nmi_exit(); | 665 | nmi_exit(); |
@@ -664,7 +667,7 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code) | |||
664 | 667 | ||
665 | void set_nmi_callback(nmi_callback_t callback) | 668 | void set_nmi_callback(nmi_callback_t callback) |
666 | { | 669 | { |
667 | nmi_callback = callback; | 670 | rcu_assign_pointer(nmi_callback, callback); |
668 | } | 671 | } |
669 | EXPORT_SYMBOL_GPL(set_nmi_callback); | 672 | EXPORT_SYMBOL_GPL(set_nmi_callback); |
670 | 673 | ||
@@ -675,7 +678,7 @@ void unset_nmi_callback(void) | |||
675 | EXPORT_SYMBOL_GPL(unset_nmi_callback); | 678 | EXPORT_SYMBOL_GPL(unset_nmi_callback); |
676 | 679 | ||
677 | #ifdef CONFIG_KPROBES | 680 | #ifdef CONFIG_KPROBES |
678 | fastcall void do_int3(struct pt_regs *regs, long error_code) | 681 | fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) |
679 | { | 682 | { |
680 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) | 683 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) |
681 | == NOTIFY_STOP) | 684 | == NOTIFY_STOP) |
@@ -709,7 +712,7 @@ fastcall void do_int3(struct pt_regs *regs, long error_code) | |||
709 | * find every occurrence of the TF bit that could be saved away even | 712 | * find every occurrence of the TF bit that could be saved away even |
710 | * by user code) | 713 | * by user code) |
711 | */ | 714 | */ |
712 | fastcall void do_debug(struct pt_regs * regs, long error_code) | 715 | fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code) |
713 | { | 716 | { |
714 | unsigned int condition; | 717 | unsigned int condition; |
715 | struct task_struct *tsk = current; | 718 | struct task_struct *tsk = current; |
@@ -1008,7 +1011,7 @@ void __init trap_init_f00f_bug(void) | |||
1008 | * it uses the read-only mapped virtual address. | 1011 | * it uses the read-only mapped virtual address. |
1009 | */ | 1012 | */ |
1010 | idt_descr.address = fix_to_virt(FIX_F00F_IDT); | 1013 | idt_descr.address = fix_to_virt(FIX_F00F_IDT); |
1011 | __asm__ __volatile__("lidt %0" : : "m" (idt_descr)); | 1014 | load_idt(&idt_descr); |
1012 | } | 1015 | } |
1013 | #endif | 1016 | #endif |
1014 | 1017 | ||