Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=22f5991c85dec1281cce5c8df9ee92b43b1738c8
Commit:     22f5991c85dec1281cce5c8df9ee92b43b1738c8
Parent:     d88879b2d0225da3ba460bbdb8361bb049653671
Author:     Jan Beulich <[EMAIL PROTECTED]>
AuthorDate: Wed Jan 30 13:31:23 2008 +0100
Committer:  Ingo Molnar <[EMAIL PROTECTED]>
CommitDate: Wed Jan 30 13:31:23 2008 +0100

    x86-64: honor notify_die() returning NOTIFY_STOP
    
    This requires making die() return a value, making its callers honor
    this (and be prepared that it may return), and making oops_end() have
    two additional parameters.
    
    Signed-off-by: Jan Beulich <[EMAIL PROTECTED]>
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
---
 arch/x86/kernel/cpu/mcheck/mce_64.c |    8 ++++----
 arch/x86/kernel/traps_64.c          |   23 +++++++++++++++--------
 arch/x86/mm/fault_64.c              |   12 ++++++------
 include/asm-x86/kdebug.h            |    4 ++--
 4 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c 
b/arch/x86/kernel/cpu/mcheck/mce_64.c
index 8cd47fe..bc6e351 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
@@ -192,10 +192,10 @@ void do_machine_check(struct pt_regs * regs, long 
error_code)
 
        atomic_inc(&mce_entry);
 
-       if (regs)
-               notify_die(DIE_NMI, "machine check", regs, error_code, 18,
-                          SIGKILL);
-       if (!banks)
+       if ((regs
+            && notify_die(DIE_NMI, "machine check", regs, error_code,
+                          18, SIGKILL) == NOTIFY_STOP)
+           || !banks)
                goto out2;
 
        memset(&m, 0, sizeof(struct mce));
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index 1a12a81..cf90ceb 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -488,7 +488,7 @@ unsigned __kprobes long oops_begin(void)
        return flags;
 }
 
-void __kprobes oops_end(unsigned long flags)
+void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
 { 
        die_owner = -1;
        bust_spinlocks(0);
@@ -497,12 +497,17 @@ void __kprobes oops_end(unsigned long flags)
                /* Nest count reaches zero, release the lock. */
                __raw_spin_unlock(&die_lock);
        raw_local_irq_restore(flags);
+       if (!regs) {
+               oops_exit();
+               return;
+       }
        if (panic_on_oops)
                panic("Fatal exception");
        oops_exit();
+       do_exit(signr);
 }
 
-void __kprobes __die(const char * str, struct pt_regs * regs, long err)
+int __kprobes __die(const char * str, struct pt_regs * regs, long err)
 {
        static int die_counter;
        printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter);
@@ -516,7 +521,8 @@ void __kprobes __die(const char * str, struct pt_regs * 
regs, long err)
        printk("DEBUG_PAGEALLOC");
 #endif
        printk("\n");
-       notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
+       if (notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, 
SIGSEGV) == NOTIFY_STOP)
+               return 1;
        show_registers(regs);
        add_taint(TAINT_DIE);
        /* Executive summary in case the oops scrolled away */
@@ -525,6 +531,7 @@ void __kprobes __die(const char * str, struct pt_regs * 
regs, long err)
        printk(" RSP <%016lx>\n", regs->sp);
        if (kexec_should_crash(current))
                crash_kexec(regs);
+       return 0;
 }
 
 void die(const char * str, struct pt_regs * regs, long err)
@@ -534,9 +541,9 @@ void die(const char * str, struct pt_regs * regs, long err)
        if (!user_mode(regs))
                report_bug(regs->ip, regs);
 
-       __die(str, regs, err);
-       oops_end(flags);
-       do_exit(SIGSEGV); 
+       if (__die(str, regs, err))
+               regs = NULL;
+       oops_end(flags, regs, SIGSEGV);
 }
 
 void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic)
@@ -553,10 +560,10 @@ void __kprobes die_nmi(char *str, struct pt_regs *regs, 
int do_panic)
                crash_kexec(regs);
        if (do_panic || panic_on_oops)
                panic("Non maskable interrupt");
-       oops_end(flags);
+       oops_end(flags, NULL, SIGBUS);
        nmi_exit();
        local_irq_enable();
-       do_exit(SIGSEGV);
+       do_exit(SIGBUS);
 }
 
 static void __kprobes do_trap(int trapnr, int signr, char *str,
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c
index 162050d..121c7bd 100644
--- a/arch/x86/mm/fault_64.c
+++ b/arch/x86/mm/fault_64.c
@@ -227,9 +227,9 @@ static noinline void pgtable_bad(unsigned long address, 
struct pt_regs *regs,
        tsk->thread.cr2 = address;
        tsk->thread.trap_no = 14;
        tsk->thread.error_code = error_code;
-       __die("Bad pagetable", regs, error_code);
-       oops_end(flags);
-       do_exit(SIGKILL);
+       if (__die("Bad pagetable", regs, error_code))
+               regs = NULL;
+       oops_end(flags, regs, SIGKILL);
 }
 
 /*
@@ -541,11 +541,11 @@ no_context:
        tsk->thread.cr2 = address;
        tsk->thread.trap_no = 14;
        tsk->thread.error_code = error_code;
-       __die("Oops", regs, error_code);
+       if (__die("Oops", regs, error_code))
+               regs = NULL;
        /* Executive summary in case the body of the oops scrolled away */
        printk(KERN_EMERG "CR2: %016lx\n", address);
-       oops_end(flags);
-       do_exit(SIGKILL);
+       oops_end(flags, regs, SIGKILL);
 
 /*
  * We ran out of memory, or some other thing happened to us that made
diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h
index 49e5c91..a5e5e3b 100644
--- a/include/asm-x86/kdebug.h
+++ b/include/asm-x86/kdebug.h
@@ -25,7 +25,7 @@ enum die_val {
 extern void early_printk(const char *fmt, ...) 
__attribute__((format(printf,1,2)));
 extern void printk_address(unsigned long address);
 extern void die(const char *,struct pt_regs *,long);
-extern void __die(const char *,struct pt_regs *,long);
+extern int __must_check __die(const char *, struct pt_regs *, long);
 extern void show_registers(struct pt_regs *regs);
 extern void __show_registers(struct pt_regs *, int all);
 extern void show_trace(struct task_struct *, struct pt_regs *, unsigned long 
*);
@@ -33,6 +33,6 @@ extern void __show_regs(struct pt_regs *regs);
 extern void show_regs(struct pt_regs *regs);
 extern void dump_pagetable(unsigned long);
 extern unsigned long oops_begin(void);
-extern void oops_end(unsigned long);
+extern void oops_end(unsigned long, struct pt_regs *, int signr);
 
 #endif
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to