patch-2.4.19 linux-2.4.19/arch/m68k/kernel/traps.c

Next file: linux-2.4.19/arch/m68k/mac/config.c
Previous file: linux-2.4.19/arch/m68k/kernel/sun3-head.S
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/arch/m68k/kernel/traps.c linux-2.4.19/arch/m68k/kernel/traps.c
@@ -23,7 +23,7 @@
 #include <linux/signal.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/types.h>
+#include <linux/module.h>
 #include <linux/a.out.h>
 #include <linux/user.h>
 #include <linux/string.h>
@@ -224,7 +224,7 @@
 		unsigned long addr = fp->un.fmt4.effaddr;
 
 		if (fslw & MMU060_MA)
-			addr = (addr + 7) & -8;
+			addr = (addr + PAGE_SIZE - 1) & PAGE_MASK;
 
 		errorcode = 1;
 		if (fslw & MMU060_DESC_ERR) {
@@ -258,16 +258,12 @@
 
 	set_fs(MAKE_MM_SEG(wbs));
 
-	asm volatile (".chip 68040");
-
 	if (iswrite)
-		asm volatile ("ptestw (%0)" : : "a" (addr));
+                asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));
 	else
-		asm volatile ("ptestr (%0)" : : "a" (addr));
+                asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr));
 
-	asm volatile ("movec %%mmusr,%0" : "=r" (mmusr));
-
-	asm volatile (".chip 68k");
+        asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));
 
 	set_fs(old_fs); 
 
@@ -816,15 +812,71 @@
 
 
 int kstack_depth_to_print = 48;
+extern struct module kernel_module;
+
+static inline int kernel_text_address(unsigned long addr)
+{
+	struct module *mod;
+	int retval = 0;
+	extern char _stext, _etext;
+
+	if (addr >= (unsigned long) &_stext &&
+	    addr <= (unsigned long) &_etext)
+		return 1;
+
+#ifdef CONFIG_MODULES
+	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;
+		}
+	}
+#endif
+
+	return retval;
+}
+
+void show_trace(unsigned long *stack)
+{
+	unsigned long *endstack;
+	unsigned long addr;
+	int i;
+
+	printk("Call Trace:");
+	addr = (unsigned long)stack + THREAD_SIZE - 1;
+	endstack = (unsigned long *)(addr & -THREAD_SIZE);
+	i = 0;
+	while (stack + 1 <= endstack) {
+		addr = *stack++;
+		/*
+		 * If the address is either in the text segment of the
+		 * kernel, or in the region which contains vmalloc'ed
+		 * memory, it *may* be the address of a calling
+		 * routine; if so, print it so that someone tracing
+		 * down the cause of the crash will be able to figure
+		 * out the call path that was taken.
+		 */
+		if (kernel_text_address(addr)) {
+			if (i % 4 == 0)
+				printk("\n       ");
+			printk(" [<%08lx>]", addr);
+			i++;
+		}
+	}
+	printk("\n");
+}
 
-/* MODULE_RANGE is a guess of how much space is likely to be
-   vmalloced.  */
-#define MODULE_RANGE (8*1024*1024)
+void show_trace_task(struct task_struct *tsk)
+{
+	show_trace((unsigned long *)tsk->thread.esp0);
+}
 
 static void dump_stack(struct frame *fp)
 {
-	unsigned long *stack, *endstack, addr, module_start, module_end;
-	extern char _start, _etext;
+	unsigned long *stack, *endstack, addr;
 	int i;
 
 	addr = (unsigned long)&fp->un;
@@ -881,7 +933,7 @@
 	}
 
 	stack = (unsigned long *)addr;
-	endstack = (unsigned long *)PAGE_ALIGN(addr);
+	endstack = (unsigned long *)((addr + THREAD_SIZE - 1) & -THREAD_SIZE);
 
 	printk("Stack from %08lx:", (unsigned long)stack);
 	for (i = 0; i < kstack_depth_to_print; i++) {
@@ -891,32 +943,10 @@
 			printk("\n       ");
 		printk(" %08lx", *stack++);
 	}
+	printk("\n");
+	show_trace((unsigned long *)addr);
 
-	printk ("\nCall Trace:");
-	stack = (unsigned long *) addr;
-	i = 0;
-	module_start = VMALLOC_START;
-	module_end = module_start + MODULE_RANGE;
-	while (stack + 1 <= endstack) {
-		addr = *stack++;
-		/*
-		 * If the address is either in the text segment of the
-		 * kernel, or in the region which contains vmalloc'ed
-		 * memory, it *may* be the address of a calling
-		 * routine; if so, print it so that someone tracing
-		 * down the cause of the crash will be able to figure
-		 * out the call path that was taken.
-		 */
-		if (((addr >= (unsigned long) &_start) &&
-		     (addr <= (unsigned long) &_etext)) ||
-		    ((addr >= module_start) && (addr <= module_end))) {
-			if (i % 4 == 0)
-				printk("\n       ");
-			printk(" [<%08lx>]", addr);
-			i++;
-		}
-	}
-	printk("\nCode: ");
+	printk("Code: ");
 	for (i = 0; i < 10; i++)
 		printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]);
 	printk ("\n");

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)