diff options
author | Jeff Dike <jdike@addtoit.com> | 2007-05-06 17:51:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-07 15:13:02 -0400 |
commit | 377fad3acbb7e94ab9942a74e0d9ede8eeb2f039 (patch) | |
tree | 0bf8046bb1fa6ccb51df76b56819dee6b6d7487b /arch/um/kernel/trap.c | |
parent | 5d86456d3852cb95a38d2b23fe01cede54984ba5 (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.c | 10 |
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; |