Re: [PATCH] [31/50] x86_64: honor notify_die() returning NOTIFY_STOP
On Sat, 2007-09-22 at 00:32 +0200, Andi Kleen wrote: > - 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) 80 chars please. tglx - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [31/50] x86_64: honor notify_die() returning NOTIFY_STOP
On Sat, 2007-09-22 at 00:32 +0200, Andi Kleen wrote: - 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) 80 chars please. tglx - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [31/50] x86_64: honor notify_die() returning NOTIFY_STOP
From: "Jan Beulich" <[EMAIL PROTECTED]> If a debugger or other low level code resolves a kernel exception, don't send signals, kill the kernel, or do anything the like. Signed-off-by: Jan Beulich <[EMAIL PROTECTED]> Signed-off-by: Andi Kleen <[EMAIL PROTECTED]> arch/x86_64/kernel/mce.c|7 --- arch/x86_64/kernel/traps.c | 23 +++ arch/x86_64/mm/fault.c | 12 ++-- include/asm-x86_64/kdebug.h |4 ++-- 4 files changed, 27 insertions(+), 19 deletions(-) Index: linux/arch/x86_64/kernel/mce.c === --- linux.orig/arch/x86_64/kernel/mce.c +++ linux/arch/x86_64/kernel/mce.c @@ -196,9 +196,10 @@ void do_machine_check(struct pt_regs * r atomic_inc(_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(, 0, sizeof(struct mce)); Index: linux/arch/x86_64/kernel/traps.c === --- linux.orig/arch/x86_64/kernel/traps.c +++ linux/arch/x86_64/kernel/traps.c @@ -557,7 +557,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); @@ -568,12 +568,17 @@ void __kprobes oops_end(unsigned long fl else /* Nest count reaches zero, release the lock. */ spin_unlock_irqrestore(_lock, 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 & 0x,++die_counter); @@ -587,7 +592,8 @@ void __kprobes __die(const char * str, s 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 */ @@ -596,6 +602,7 @@ void __kprobes __die(const char * str, s printk(" RSP <%016lx>\n", regs->rsp); if (kexec_should_crash(current)) crash_kexec(regs); + return 0; } void die(const char * str, struct pt_regs * regs, long err) @@ -605,9 +612,9 @@ void die(const char * str, struct pt_reg if (!user_mode(regs)) report_bug(regs->rip, 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) @@ -624,10 +631,10 @@ void __kprobes die_nmi(char *str, struct 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, Index: linux/arch/x86_64/mm/fault.c === --- linux.orig/arch/x86_64/mm/fault.c +++ linux/arch/x86_64/mm/fault.c @@ -234,9 +234,9 @@ static noinline void pgtable_bad(unsigne 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 Index: linux/include/asm-x86_64/kdebug.h
[PATCH] [31/50] x86_64: honor notify_die() returning NOTIFY_STOP
From: Jan Beulich [EMAIL PROTECTED] If a debugger or other low level code resolves a kernel exception, don't send signals, kill the kernel, or do anything the like. Signed-off-by: Jan Beulich [EMAIL PROTECTED] Signed-off-by: Andi Kleen [EMAIL PROTECTED] arch/x86_64/kernel/mce.c|7 --- arch/x86_64/kernel/traps.c | 23 +++ arch/x86_64/mm/fault.c | 12 ++-- include/asm-x86_64/kdebug.h |4 ++-- 4 files changed, 27 insertions(+), 19 deletions(-) Index: linux/arch/x86_64/kernel/mce.c === --- linux.orig/arch/x86_64/kernel/mce.c +++ linux/arch/x86_64/kernel/mce.c @@ -196,9 +196,10 @@ void do_machine_check(struct pt_regs * r 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)); Index: linux/arch/x86_64/kernel/traps.c === --- linux.orig/arch/x86_64/kernel/traps.c +++ linux/arch/x86_64/kernel/traps.c @@ -557,7 +557,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); @@ -568,12 +568,17 @@ void __kprobes oops_end(unsigned long fl else /* Nest count reaches zero, release the lock. */ spin_unlock_irqrestore(die_lock, 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 0x,++die_counter); @@ -587,7 +592,8 @@ void __kprobes __die(const char * str, s 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 */ @@ -596,6 +602,7 @@ void __kprobes __die(const char * str, s printk( RSP %016lx\n, regs-rsp); if (kexec_should_crash(current)) crash_kexec(regs); + return 0; } void die(const char * str, struct pt_regs * regs, long err) @@ -605,9 +612,9 @@ void die(const char * str, struct pt_reg if (!user_mode(regs)) report_bug(regs-rip, 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) @@ -624,10 +631,10 @@ void __kprobes die_nmi(char *str, struct 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, Index: linux/arch/x86_64/mm/fault.c === --- linux.orig/arch/x86_64/mm/fault.c +++ linux/arch/x86_64/mm/fault.c @@ -234,9 +234,9 @@ static noinline void pgtable_bad(unsigne 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 Index: linux/include/asm-x86_64/kdebug.h