diff options
author | Alexander van Heukelum <heukelum@fastmail.fm> | 2008-10-22 06:00:09 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-22 08:00:23 -0400 |
commit | 874d93d11823b2b861addac6a5dc31162e924ab2 (patch) | |
tree | 6d84df0b35ca810ea5871be766934b0b20ad70b7 /arch | |
parent | b4b8f87bf4958cbad620654efc0882ac46c19846 (diff) |
x86, dumpstack: let signr=0 signal no do_exit
Change oops_end such that signr=0 signals that do_exit
is not to be called.
Currently, each use of __die is soon followed by a call
to oops_end and 'regs' is set to NULL if oops_end is expected
not to call do_exit. Change all such pairs to set signr=0
instead. On x86_64 oops_end is used 'bare' in die_nmi; use
signr=0 instead of regs=NULL there, too.
Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/dumpstack_32.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/dumpstack_64.c | 9 | ||||
-rw-r--r-- | arch/x86/mm/fault.c | 11 |
3 files changed, 16 insertions, 11 deletions
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index 5493d31be4e5..7c22f99f0efb 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
@@ -318,7 +318,7 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) | |||
318 | __raw_spin_unlock(&die_lock); | 318 | __raw_spin_unlock(&die_lock); |
319 | raw_local_irq_restore(flags); | 319 | raw_local_irq_restore(flags); |
320 | 320 | ||
321 | if (!regs) | 321 | if (!signr) |
322 | return; | 322 | return; |
323 | 323 | ||
324 | if (in_interrupt()) | 324 | if (in_interrupt()) |
@@ -371,17 +371,18 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) | |||
371 | void die(const char *str, struct pt_regs *regs, long err) | 371 | void die(const char *str, struct pt_regs *regs, long err) |
372 | { | 372 | { |
373 | unsigned long flags = oops_begin(); | 373 | unsigned long flags = oops_begin(); |
374 | int sig = SIGSEGV; | ||
374 | 375 | ||
375 | if (die_nest_count < 3) { | 376 | if (die_nest_count < 3) { |
376 | report_bug(regs->ip, regs); | 377 | report_bug(regs->ip, regs); |
377 | 378 | ||
378 | if (__die(str, regs, err)) | 379 | if (__die(str, regs, err)) |
379 | regs = NULL; | 380 | sig = 0; |
380 | } else { | 381 | } else { |
381 | printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); | 382 | printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); |
382 | } | 383 | } |
383 | 384 | ||
384 | oops_end(flags, regs, SIGSEGV); | 385 | oops_end(flags, regs, sig); |
385 | } | 386 | } |
386 | 387 | ||
387 | static DEFINE_SPINLOCK(nmi_print_lock); | 388 | static DEFINE_SPINLOCK(nmi_print_lock); |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 96a5db7da8a7..ffefea611ba3 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -465,7 +465,7 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) | |||
465 | /* Nest count reaches zero, release the lock. */ | 465 | /* Nest count reaches zero, release the lock. */ |
466 | __raw_spin_unlock(&die_lock); | 466 | __raw_spin_unlock(&die_lock); |
467 | raw_local_irq_restore(flags); | 467 | raw_local_irq_restore(flags); |
468 | if (!regs) { | 468 | if (!signr) { |
469 | oops_exit(); | 469 | oops_exit(); |
470 | return; | 470 | return; |
471 | } | 471 | } |
@@ -509,13 +509,14 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) | |||
509 | void die(const char *str, struct pt_regs *regs, long err) | 509 | void die(const char *str, struct pt_regs *regs, long err) |
510 | { | 510 | { |
511 | unsigned long flags = oops_begin(); | 511 | unsigned long flags = oops_begin(); |
512 | int sig = SIGSEGV; | ||
512 | 513 | ||
513 | if (!user_mode(regs)) | 514 | if (!user_mode(regs)) |
514 | report_bug(regs->ip, regs); | 515 | report_bug(regs->ip, regs); |
515 | 516 | ||
516 | if (__die(str, regs, err)) | 517 | if (__die(str, regs, err)) |
517 | regs = NULL; | 518 | sig = 0; |
518 | oops_end(flags, regs, SIGSEGV); | 519 | oops_end(flags, regs, sig); |
519 | } | 520 | } |
520 | 521 | ||
521 | notrace __kprobes void | 522 | notrace __kprobes void |
@@ -539,7 +540,7 @@ die_nmi(char *str, struct pt_regs *regs, int do_panic) | |||
539 | crash_kexec(regs); | 540 | crash_kexec(regs); |
540 | if (do_panic || panic_on_oops) | 541 | if (do_panic || panic_on_oops) |
541 | panic("Non maskable interrupt"); | 542 | panic("Non maskable interrupt"); |
542 | oops_end(flags, NULL, SIGBUS); | 543 | oops_end(flags, regs, 0); |
543 | nmi_exit(); | 544 | nmi_exit(); |
544 | local_irq_enable(); | 545 | local_irq_enable(); |
545 | do_exit(SIGBUS); | 546 | do_exit(SIGBUS); |
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 31e8730fa246..20ef272c412c 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -413,6 +413,7 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs, | |||
413 | unsigned long error_code) | 413 | unsigned long error_code) |
414 | { | 414 | { |
415 | unsigned long flags = oops_begin(); | 415 | unsigned long flags = oops_begin(); |
416 | int sig = SIGKILL; | ||
416 | struct task_struct *tsk; | 417 | struct task_struct *tsk; |
417 | 418 | ||
418 | printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", | 419 | printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", |
@@ -423,8 +424,8 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs, | |||
423 | tsk->thread.trap_no = 14; | 424 | tsk->thread.trap_no = 14; |
424 | tsk->thread.error_code = error_code; | 425 | tsk->thread.error_code = error_code; |
425 | if (__die("Bad pagetable", regs, error_code)) | 426 | if (__die("Bad pagetable", regs, error_code)) |
426 | regs = NULL; | 427 | sig = 0; |
427 | oops_end(flags, regs, SIGKILL); | 428 | oops_end(flags, regs, sig); |
428 | } | 429 | } |
429 | #endif | 430 | #endif |
430 | 431 | ||
@@ -590,6 +591,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
590 | int fault; | 591 | int fault; |
591 | #ifdef CONFIG_X86_64 | 592 | #ifdef CONFIG_X86_64 |
592 | unsigned long flags; | 593 | unsigned long flags; |
594 | int sig; | ||
593 | #endif | 595 | #endif |
594 | 596 | ||
595 | tsk = current; | 597 | tsk = current; |
@@ -849,11 +851,12 @@ no_context: | |||
849 | bust_spinlocks(0); | 851 | bust_spinlocks(0); |
850 | do_exit(SIGKILL); | 852 | do_exit(SIGKILL); |
851 | #else | 853 | #else |
854 | sig = SIGKILL; | ||
852 | if (__die("Oops", regs, error_code)) | 855 | if (__die("Oops", regs, error_code)) |
853 | regs = NULL; | 856 | sig = 0; |
854 | /* Executive summary in case the body of the oops scrolled away */ | 857 | /* Executive summary in case the body of the oops scrolled away */ |
855 | printk(KERN_EMERG "CR2: %016lx\n", address); | 858 | printk(KERN_EMERG "CR2: %016lx\n", address); |
856 | oops_end(flags, regs, SIGKILL); | 859 | oops_end(flags, regs, sig); |
857 | #endif | 860 | #endif |
858 | 861 | ||
859 | /* | 862 | /* |