--- linux-mm/include/linux/sched.h 2004-02-16 23:18:56.000000000 +0100 +++ clean-mm/include/linux/sched.h 2004-02-16 23:00:15.000000000 +0100 @@ -173,7 +173,9 @@ #define MAX_SCHEDULE_TIMEOUT LONG_MAX extern signed long FASTCALL(schedule_timeout(signed long timeout)); -asmlinkage void schedule(void); +asmlinkage void do_schedule(void); +asmlinkage void kern_schedule(void); +asmlinkage void kern_do_schedule(struct pt_regs); struct namespace; @@ -906,6 +908,15 @@ #endif /* CONFIG_SMP */ +static inline void schedule(void) +{ +#ifdef CONFIG_KGDB_THREAD + kern_schedule(); +#else + do_schedule(); +#endif +} + #endif /* __KERNEL__ */ #endif --- linux-mm/kernel/kgdbstub.c 2004-02-17 23:23:05.000000000 +0100 +++ clean-mm/kernel/kgdbstub.c 2004-02-16 23:00:15.000000000 +0100 @@ -48,6 +48,9 @@ #include #include #include +#ifdef CONFIG_KGDB_CONSOLE +#include +#endif #include extern int pid_max; @@ -1160,7 +1163,68 @@ printk("Connected.\n"); } +#ifdef CONFIG_KGDB_CONSOLE +char kgdbconbuf[BUFMAX]; + +void kgdb_console_write(struct console *co, const char *s, unsigned count) +{ + int i; + int wcount; + char *bufptr; + unsigned long flags; + + if (!kgdb_connected) { + return; + } + local_irq_save(flags); + + kgdbconbuf[0] = 'O'; + bufptr = kgdbconbuf + 1; + while (count > 0) { + if ((count << 1) > (BUFMAX - 2)) { + wcount = (BUFMAX - 2) >> 1; + } else { + wcount = count; + } + count -= wcount; + for (i = 0; i < wcount; i++) { + bufptr = pack_hex_byte(bufptr, s[i]); + } + *bufptr = '\0'; + s += wcount; + + putpacket(kgdbconbuf, 1); + + } + local_irq_restore(flags); +} + +/* Always fail so that kgdb console doesn't become the default console */ +static int __init kgdb_console_setup(struct console *co, char *options) +{ + return -1; +} + +static struct console kgdbcons = { + .name = "kgdb", + .write = kgdb_console_write, + .setup = kgdb_console_setup, + .flags = CON_PRINTBUFFER | CON_ENABLED, + .index = -1, +}; + +static int __init kgdb_console_init(void) +{ + register_console(&kgdbcons); + return 0; +} +console_initcall(kgdb_console_init); +#endif + EXPORT_SYMBOL(breakpoint); +#ifdef CONFIG_KGDB_THREAD +EXPORT_SYMBOL(kern_schedule); +#endif static int __init opt_kgdb_enter(char *str) { --- linux-mm/kernel/sched.c 2004-02-16 23:09:06.000000000 +0100 +++ clean-mm/kernel/sched.c 2004-02-16 23:00:15.000000000 +0100 @@ -1589,7 +1589,7 @@ /* * schedule() is the main scheduler function. */ -asmlinkage void schedule(void) +asmlinkage void do_schedule(void) { long *switch_count; task_t *prev, *next; @@ -1761,6 +1761,23 @@ EXPORT_SYMBOL(default_wake_function); +asmlinkage void user_schedule(void) +{ +#ifdef CONFIG_KGDB_THREAD + current->thread.debuggerinfo = NULL; +#endif + do_schedule(); +} + +#ifdef CONFIG_KGDB_THREAD +asmlinkage void kern_do_schedule(struct pt_regs regs) +{ + current->thread.debuggerinfo = ®s; + do_schedule(); + current->thread.debuggerinfo = NULL; +} +#endif + /* * The core wakeup function. Non-exclusive wakeups (nr_exclusive == 0) just * wake everything up. If it's an exclusive wakeup (nr_exclusive == small +ve