aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel/trap.c
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2007-05-06 17:51:25 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-07 15:13:02 -0400
commit377fad3acbb7e94ab9942a74e0d9ede8eeb2f039 (patch)
tree0bf8046bb1fa6ccb51df76b56819dee6b6d7487b /arch/um/kernel/trap.c
parent5d86456d3852cb95a38d2b23fe01cede54984ba5 (diff)
uml: kernel segfaults should dump proper registers
If there's a segfault inside the kernel, we want a dump of the registers at the point of the segfault, not the registers at the point of calling panic or the last userspace registers. sig_handler_common_skas now uses a static register set in the case of a SIGSEGV to avoid messing up the process registers if the segfault turns out to be non-fatal. The architecture sigcontext-to-pt_regs copying code was repurposed to copy data out of the SEGV stack frame. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um/kernel/trap.c')
-rw-r--r--arch/um/kernel/trap.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index c3e62e634c0a..0c467fa08870 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -170,8 +170,10 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
170 flush_tlb_kernel_vm(); 170 flush_tlb_kernel_vm();
171 return 0; 171 return 0;
172 } 172 }
173 else if(current->mm == NULL) 173 else if(current->mm == NULL) {
174 panic("Segfault with no mm"); 174 show_regs(container_of(regs, struct pt_regs, regs));
175 panic("Segfault with no mm");
176 }
175 177
176 if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) 178 if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
177 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); 179 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
@@ -194,9 +196,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
194 else if(!is_user && arch_fixup(ip, regs)) 196 else if(!is_user && arch_fixup(ip, regs))
195 return 0; 197 return 0;
196 198
197 if(!is_user) 199 if(!is_user) {
200 show_regs(container_of(regs, struct pt_regs, regs));
198 panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", 201 panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
199 address, ip); 202 address, ip);
203 }
200 204
201 if (err == -EACCES) { 205 if (err == -EACCES) {
202 si.si_signo = SIGBUS; 206 si.si_signo = SIGBUS;