diff -Naur -X exclude-files ac_cur/arch/um/config.in ac/arch/um/config.in --- ac_cur/arch/um/config.in Sat Sep 15 16:46:07 2001 +++ ac/arch/um/config.in Sat Sep 15 19:20:55 2001 @@ -32,6 +32,7 @@ bool 'Virtual serial line' CONFIG_SSL tristate 'Host filesystem' CONFIG_HOSTFS bool 'Management console' CONFIG_MCONSOLE +dep_bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_MCONSOLE endmenu mainmenu_option next_comment diff -Naur -X exclude-files ac_cur/arch/um/defconfig ac/arch/um/defconfig --- ac_cur/arch/um/defconfig Sat Sep 15 16:52:59 2001 +++ ac/arch/um/defconfig Sat Sep 15 19:20:55 2001 @@ -29,6 +29,7 @@ CONFIG_SSL=y CONFIG_HOSTFS=m CONFIG_MCONSOLE=y +CONFIG_MAGIC_SYSRQ=y # # Loadable module support diff -Naur -X exclude-files ac_cur/arch/um/drivers/mconsole_kern.c ac/arch/um/drivers/mconsole_kern.c --- ac_cur/arch/um/drivers/mconsole_kern.c Sat Sep 15 15:56:11 2001 +++ ac/arch/um/drivers/mconsole_kern.c Sat Sep 15 19:21:19 2001 @@ -11,6 +11,7 @@ #include "linux/utsname.h" #include "linux/ctype.h" #include "linux/interrupt.h" +#include "linux/sysrq.h" #include "asm/irq.h" #include "user_util.h" #include "kern_util.h" @@ -175,6 +176,25 @@ else ok = "OK"; mconsole_reply(req, ok); } + +#ifdef CONFIG_MAGIC_SYSRQ +void mconsole_sysrq(struct mconsole_request *req) +{ + char *ptr = req->buf; + + ptr += strlen("sysrq"); + while(isspace(*ptr)) ptr++; + + handle_sysrq(*ptr, (struct pt_regs *) ¤t->thread.process_regs, + NULL, NULL); + mconsole_reply(req, "OK"); +} +#else +void mconsole_sysrq(struct mconsole_request *req) +{ + mconsole_reply(req, "ERR sysrq not compiled in"); +} +#endif int mconsole_init(void) { diff -Naur -X exclude-files ac_cur/arch/um/drivers/mconsole_user.c ac/arch/um/drivers/mconsole_user.c --- ac_cur/arch/um/drivers/mconsole_user.c Sat Sep 15 15:56:11 2001 +++ ac/arch/um/drivers/mconsole_user.c Sat Sep 15 19:20:55 2001 @@ -22,6 +22,7 @@ { "reboot", mconsole_reboot }, { "config", mconsole_config }, { "remove", mconsole_remove }, + { "sysrq", mconsole_sysrq }, { "help", mconsole_help }, }; diff -Naur -X exclude-files ac_cur/arch/um/include/mconsole.h ac/arch/um/include/mconsole.h --- ac_cur/arch/um/include/mconsole.h Sat Sep 15 15:56:11 2001 +++ ac/arch/um/include/mconsole.h Sat Sep 15 19:20:55 2001 @@ -33,6 +33,7 @@ extern void mconsole_reboot(struct mconsole_request *req); extern void mconsole_config(struct mconsole_request *req); extern void mconsole_remove(struct mconsole_request *req); +extern void mconsole_sysrq(struct mconsole_request *req); #endif diff -Naur -X exclude-files ac_cur/arch/um/include/sysrq.h ac/arch/um/include/sysrq.h --- ac_cur/arch/um/include/sysrq.h Wed Dec 31 19:00:00 1969 +++ ac/arch/um/include/sysrq.h Sat Sep 15 19:27:47 2001 @@ -0,0 +1,6 @@ +#ifndef __UM_SYSRQ_H +#define __UM_SYSRQ_H + +extern void show_trace(unsigned long *stack); + +#endif diff -Naur -X exclude-files ac_cur/arch/um/kernel/Makefile ac/arch/um/kernel/Makefile --- ac_cur/arch/um/kernel/Makefile Sat Sep 15 16:46:07 2001 +++ ac/arch/um/kernel/Makefile Sat Sep 15 19:27:47 2001 @@ -3,7 +3,7 @@ OBJS = process.o current.o exec_kern.o exec_user.o init_task.o irq.o \ irq_user.o mem.o mem_user.o ptrace.o reboot.o resource.o \ setup.o signal_user.o smp.o syscall_kern.o syscall_user.o \ - sys_call_table.o time.o time_kern.o tlb.o trap_kern.o \ + sysrq.o sys_call_table.o time.o time_kern.o tlb.o trap_kern.o \ trap_user.o uaccess_user.o um_arch.o umid.o user_util.o OX_OBJS = ksyms.o process_kern.o signal_kern.o user_syms.o diff -Naur -X exclude-files ac_cur/arch/um/kernel/mem.c ac/arch/um/kernel/mem.c --- ac_cur/arch/um/kernel/mem.c Sat Sep 15 15:56:11 2001 +++ ac/arch/um/kernel/mem.c Sat Sep 15 19:20:55 2001 @@ -146,6 +146,36 @@ return freed; } +void show_mem(void) +{ + int i, total = 0, reserved = 0; + int shared = 0, cached = 0; + int highmem = 0; + + printk("Mem-info:\n"); + show_free_areas(); + printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageHighMem(mem_map+i)) + highmem++; + if (PageReserved(mem_map+i)) + reserved++; + else if (PageSwapCache(mem_map+i)) + cached++; + else if (page_count(mem_map+i)) + shared += page_count(mem_map+i) - 1; + } + printk("%d pages of RAM\n", total); + printk("%d pages of HIGHMEM\n",highmem); + printk("%d reserved pages\n",reserved); + printk("%d pages shared\n",shared); + printk("%d pages swap cached\n",cached); + printk("%ld pages in page table cache\n",pgtable_cache_size); + show_buffers(); +} + /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff -Naur -X exclude-files ac_cur/arch/um/kernel/process_kern.c ac/arch/um/kernel/process_kern.c --- ac_cur/arch/um/kernel/process_kern.c Sat Sep 15 15:56:11 2001 +++ ac/arch/um/kernel/process_kern.c Sat Sep 15 19:23:51 2001 @@ -19,6 +19,7 @@ #include "asm/segment.h" #include "asm/stat.h" #include "asm/pgtable.h" +#include "asm/processor.h" #include "asm/pgalloc.h" #include "asm/spinlock.h" #include "asm/uaccess.h" diff -Naur -X exclude-files ac_cur/arch/um/kernel/sysrq.c ac/arch/um/kernel/sysrq.c --- ac_cur/arch/um/kernel/sysrq.c Wed Dec 31 19:00:00 1969 +++ ac/arch/um/kernel/sysrq.c Sat Sep 15 19:27:47 2001 @@ -0,0 +1,72 @@ +#include "linux/kernel.h" +#include "linux/module.h" +#include "asm/page.h" +#include "asm/processor.h" +#include "sysrq.h" + +extern int _stext, _etext; + + /* + * If the address is either in the .text section of the + * kernel, or in the vmalloc'ed module regions, it *may* + * be the address of a calling routine + */ + +#ifdef CONFIG_MODULES + +extern struct module *module_list; +extern struct module kernel_module; + +static inline int kernel_text_address(unsigned long addr) +{ + int retval = 0; + struct module *mod; + + if (addr >= (unsigned long) &_stext && + addr <= (unsigned long) &_etext) + return 1; + + for (mod = module_list; mod != &kernel_module; mod = mod->next) { + /* mod_bound tests for addr being inside the vmalloc'ed + * module area. Of course it'd be better to test only + * for the .text subset... */ + if (mod_bound(addr, 0, mod)) { + retval = 1; + break; + } + } + + return retval; +} + +#else + +static inline int kernel_text_address(unsigned long addr) +{ + return (addr >= (unsigned long) &_stext && + addr <= (unsigned long) &_etext); +} + +#endif + +void show_trace(unsigned long * stack) +{ + int i; + unsigned long addr; + + if (!stack) + stack = (unsigned long*) &stack; + + printk("Call Trace: "); + i = 1; + while (((long) stack & (THREAD_SIZE-1)) != 0) { + addr = *stack++; + if (kernel_text_address(addr)) { + if (i && ((i % 6) == 0)) + printk("\n "); + printk("[<%08lx>] ", addr); + i++; + } + } + printk("\n"); +} diff -Naur -X exclude-files ac_cur/arch/um/sys-i386/Makefile ac/arch/um/sys-i386/Makefile --- ac_cur/arch/um/sys-i386/Makefile Sat Sep 15 16:46:07 2001 +++ ac/arch/um/sys-i386/Makefile Sat Sep 15 19:27:47 2001 @@ -1,7 +1,7 @@ OBJ = sys.o OBJS = checksum.o ldt.o old-checksum.o ptrace.o ptrace_user.o semaphore.o \ - sigcontext.o syscalls.o + sigcontext.o syscalls.o sysrq.o OX_OBJS = ksyms.o SYMLINKS = semaphore.c old-checksum.c checksum.S diff -Naur -X exclude-files ac_cur/arch/um/sys-i386/sysrq.c ac/arch/um/sys-i386/sysrq.c --- ac_cur/arch/um/sys-i386/sysrq.c Wed Dec 31 19:00:00 1969 +++ ac/arch/um/sys-i386/sysrq.c Sat Sep 15 19:35:53 2001 @@ -0,0 +1,22 @@ +#include "linux/kernel.h" +#include "linux/smp.h" +#include "asm/ptrace.h" +#include "sysrq.h" + +void show_regs(struct pt_regs_subarch *regs) +{ + printk("\n"); + printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs, regs->eip, + smp_processor_id()); + if (regs->xcs & 3) + printk(" ESP: %04x:%08lx",0xffff & regs->xss, regs->esp); + printk(" EFLAGS: %08lx\n", regs->eflags); + printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", + regs->eax, regs->ebx, regs->ecx, regs->edx); + printk("ESI: %08lx EDI: %08lx EBP: %08lx", + regs->esi, regs->edi, regs->ebp); + printk(" DS: %04x ES: %04x\n", + 0xffff & regs->xds, 0xffff & regs->xes); + + show_trace(®s->esp); +}