Messages in this thread Patch in this message | | | Date | Fri, 27 Feb 2004 14:40:31 -0700 | From | Tom Rini <> | Subject | [KGDB PATCH][4/7] Fix x86_64 hooks |
| |
Hello. The following is more complicated than it looks. This makes the x86_64 stub add kgdb to the die_chain, and then remove all of the now unneeded CHK_DEBUGGER statements, and other whitespace changes. In the end, the x86_64 patch looks like: arch/x86_64/Kconfig | 4 arch/x86_64/kernel/Makefile | 1 arch/x86_64/kernel/entry.S | 41 +++ arch/x86_64/kernel/irq.c | 2 arch/x86_64/kernel/kgdb.c | 478 +++++++++++++++++++++++++++++++++++++++++ arch/x86_64/kernel/traps.c | 3 include/asm-x86_64/kgdb.h | 54 ++++ include/asm-x86_64/processor.h | 1 8 files changed, 577 insertions(+), 7 deletions(-)
As an aside, I now know how to kill off user_schedule bits on i386/x86_64, so with more thought on how to do it cleanly for everyone, the entry.S changes can die.
diff -zrupN linux-2.6.3+config+serial/arch/x86_64/kernel/kgdb.c linux-2.6.3+config+serial+sysrq+arch_hooks/arch/x86_64/kernel/kgdb.c --- linux-2.6.3+config+serial/arch/x86_64/kernel/kgdb.c 2004-02-27 12:16:13.000000000 -0700 +++ linux-2.6.3+config+serial+sysrq+arch_hooks/arch/x86_64/kernel/kgdb.c 2004-02-27 12:16:14.000000000 -0700 @@ -41,6 +41,7 @@ #endif #include <linux/init.h> #include <linux/debugger.h> +#include <asm/kdebug.h> /* Put the error code here just in case the user cares. */ int gdb_x86_64errcode; @@ -443,6 +444,33 @@ struct pt_regs *kgdb_shadow_regs(struct return NULL; } +/* Register KGDB with the die_chain so that we hook into all of the right + * spots. */ +static int kgdb_notify(struct notifier_block *self, unsigned long cmd, + void *ptr) +{ + struct die_args *d = ptr; + + if (!kgdb_connected || (cmd == DIE_DEBUG && user_mode(d->regs))) + return NOTIFY_DONE; + if (cmd == DIE_NMI_IPI) { + if (atomic_read(debugger_active)) + return NOTIFY_BAD; + } else if ((*linux_debug_hook)(d->trapnr, d->signr, d->err, d->regs)) + return NOTIFY_BAD; /* skip */ + + return NOTIFY_DONE; +} + +static struct notifier_block kgdb_notifier = { + .notifier_call = kgdb_notify, +}; + +int kgdb_arch_init(void) +{ + notifier_chain_register(&die_chain, &kgdb_notifier); +} + struct kgdb_arch arch_kgdb_ops = { .gdb_bpt_instr = {0xcc}, .flags = KGDB_HW_BREAKPOINT, diff -zrupN linux-2.6.3+config+serial/arch/x86_64/kernel/nmi.c linux-2.6.3+config+serial+sysrq+arch_hooks/arch/x86_64/kernel/nmi.c --- linux-2.6.3+config+serial/arch/x86_64/kernel/nmi.c 2004-02-27 12:16:13.000000000 -0700 +++ linux-2.6.3+config+serial+sysrq+arch_hooks/arch/x86_64/kernel/nmi.c 2004-02-27 12:11:20.000000000 -0700 @@ -24,7 +24,6 @@ #include <linux/module.h> #include <linux/sysdev.h> #include <linux/nmi.h> -#include <linux/debugger.h> #include <asm/smp.h> #include <asm/mtrr.h> @@ -318,26 +317,13 @@ void nmi_watchdog_tick (struct pt_regs * return; sum = read_pda(apic_timer_irqs); - if (atomic_read(&debugger_active)) { - - /* - * The machine is in debugger, hold this cpu if already - * not held. - */ - debugger_nmihook(cpu, regs); - alert_counter[cpu] = 0; - - } else if (last_irq_sums[cpu] == sum) { - + if (last_irq_sums[cpu] == sum) { /* * Ayiee, looks like this CPU is stuck ... * wait a few IRQs (5 seconds) before doing the oops ... */ alert_counter[cpu]++; if (alert_counter[cpu] == 5*nmi_hz) { - - CHK_DEBUGGER(2,SIGSEGV,0,regs,) - if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_BAD) { alert_counter[cpu] = 0; return; diff -zrupN linux-2.6.3+config+serial/arch/x86_64/kernel/traps.c linux-2.6.3+config+serial+sysrq+arch_hooks/arch/x86_64/kernel/traps.c --- linux-2.6.3+config+serial/arch/x86_64/kernel/traps.c 2004-02-27 12:16:13.000000000 -0700 +++ linux-2.6.3+config+serial+sysrq+arch_hooks/arch/x86_64/kernel/traps.c 2004-02-27 12:16:14.000000000 -0700 @@ -364,7 +364,6 @@ void __die(const char * str, struct pt_r void die(const char * str, struct pt_regs * regs, long err) { - CHK_DEBUGGER(1,SIGTRAP,err,regs,) oops_begin(); handle_BUG(regs); __die(str, regs, err); @@ -438,7 +437,6 @@ static void do_trap(int trapnr, int sign #define DO_ERROR(trapnr, signr, str, name) \ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ { \ - CHK_DEBUGGER(1,SIGTRAP,error_code,regs,return) \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) == NOTIFY_BAD) \ return; \ do_trap(trapnr, signr, str, regs, error_code, NULL); \ @@ -646,7 +644,6 @@ asmlinkage void do_debug(struct pt_regs force_sig_info(SIGTRAP, &info, tsk); clear_dr7: asm volatile("movq %0,%%db7"::"r"(0UL)); - CHK_DEBUGGER(1,SIGTRAP,error_code,regs,return) notify_die(DIE_DEBUG, "debug", regs, error_code, 1, SIGTRAP); return; diff -zrupN linux-2.6.3+config+serial/arch/x86_64/mm/fault.c linux-2.6.3+config+serial+sysrq+arch_hooks/arch/x86_64/mm/fault.c --- linux-2.6.3+config+serial/arch/x86_64/mm/fault.c 2004-02-27 12:16:13.000000000 -0700 +++ linux-2.6.3+config+serial+sysrq+arch_hooks/arch/x86_64/mm/fault.c 2004-02-27 12:10:49.000000000 -0700 @@ -23,7 +23,6 @@ #include <linux/vt_kern.h> /* For unblank_screen() */ #include <linux/compiler.h> #include <linux/module.h> -#include <linux/debugger.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -408,7 +407,6 @@ no_context: if (is_prefetch(regs, address)) return; - CHK_DEBUGGER(14, SIGSEGV,error_code, regs,) if (is_errata93(regs, address)) return; diff -zrupN linux-2.6.3+config+serial/include/asm-x86_64/calling.h linux-2.6.3+config+serial+sysrq+arch_hooks/include/asm-x86_64/calling.h --- linux-2.6.3+config+serial/include/asm-x86_64/calling.h 2004-02-27 12:16:13.000000000 -0700 +++ linux-2.6.3+config+serial+sysrq+arch_hooks/include/asm-x86_64/calling.h 2004-02-27 12:12:03.000000000 -0700 @@ -12,7 +12,7 @@ #define RBX 40 /* arguments: interrupts/non tracing syscalls only save upto here*/ #define R11 48 -#define R10 56 +#define R10 56 #define R9 64 #define R8 72 #define RAX 80 -- Tom Rini http://gate.crashing.org/~trini/ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |