diff options
author | Bodo Stroesser <bstroesser@fujitsu-siemens.com> | 2005-05-05 19:15:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-05 19:36:36 -0400 |
commit | c578455a3eccf4dd7bd111e77129c301d6d67914 (patch) | |
tree | b52def020bd10e1b8bffcf90e1e2a3c1b35010c8 /arch/um/kernel/skas/trap_user.c | |
parent | ea66e8a3b6c4760e8fbf59b1becb6bd8e3dd5376 (diff) |
[PATCH] uml: S390 preparation, abstract host page fault data
This patch removes the arch-specific fault/trap-infos from thread and
skas-regs.
It adds a new struct faultinfo, that is arch-specific defined in
sysdep/faultinfo.h.
The structure is inserted in thread.arch and thread.regs.skas and
thread.regs.tt
Now, segv and other trap-handlers can copy the contents from regs.X.faultinfo
to thread.arch.faultinfo with one simple assignment.
Also, the number of macros necessary is reduced to
FAULT_ADDRESS(struct faultinfo)
extracts the faulting address from faultinfo
FAULT_WRITE(struct faultinfo)
extracts the "is_write" flag
SEGV_IS_FIXABLE(struct faultinfo)
is true for the fixable segvs, i.e. (TRAP == 14)
on i386
UPT_FAULTINFO(regs)
result is (struct faultinfo *) to the faultinfo
in regs->skas.faultinfo
GET_FAULTINFO_FROM_SC(struct faultinfo, struct sigcontext *)
copies the relevant parts of the sigcontext to
struct faultinfo.
On SIGSEGV, call user_signal() instead of handle_segv(), if the architecture
provides the information needed in PTRACE_FAULTINFO, or if PTRACE_FAULTINFO is
missing, because segv-stub will provide the info.
The benefit of the change is, that in case of a non-fixable SIGSEGV, we can
give user processes a SIGSEGV, instead of possibly looping on pagefault
handling.
Since handle_segv() sikked arch_fixup() implicitly by passing ip==0 to segv(),
I changed segv() to call arch_fixup() only, if !is_user.
Signed-off-by: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um/kernel/skas/trap_user.c')
-rw-r--r-- | arch/um/kernel/skas/trap_user.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c index 8e9b46d4702e..0dee1d95c806 100644 --- a/arch/um/kernel/skas/trap_user.c +++ b/arch/um/kernel/skas/trap_user.c | |||
@@ -5,12 +5,15 @@ | |||
5 | 5 | ||
6 | #include <signal.h> | 6 | #include <signal.h> |
7 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include "sysdep/ptrace.h" | ||
9 | #include "signal_user.h" | 8 | #include "signal_user.h" |
10 | #include "user_util.h" | 9 | #include "user_util.h" |
11 | #include "kern_util.h" | 10 | #include "kern_util.h" |
12 | #include "task.h" | 11 | #include "task.h" |
13 | #include "sigcontext.h" | 12 | #include "sigcontext.h" |
13 | #include "skas.h" | ||
14 | #include "ptrace_user.h" | ||
15 | #include "sysdep/ptrace.h" | ||
16 | #include "sysdep/ptrace_user.h" | ||
14 | 17 | ||
15 | void sig_handler_common_skas(int sig, void *sc_ptr) | 18 | void sig_handler_common_skas(int sig, void *sc_ptr) |
16 | { | 19 | { |
@@ -31,9 +34,11 @@ void sig_handler_common_skas(int sig, void *sc_ptr) | |||
31 | r = &TASK_REGS(get_current())->skas; | 34 | r = &TASK_REGS(get_current())->skas; |
32 | save_user = r->is_user; | 35 | save_user = r->is_user; |
33 | r->is_user = 0; | 36 | r->is_user = 0; |
34 | r->fault_addr = SC_FAULT_ADDR(sc); | 37 | if ( sig == SIGFPE || sig == SIGSEGV || |
35 | r->fault_type = SC_FAULT_TYPE(sc); | 38 | sig == SIGBUS || sig == SIGILL || |
36 | r->trap_type = SC_TRAP_TYPE(sc); | 39 | sig == SIGTRAP ) { |
40 | GET_FAULTINFO_FROM_SC(r->faultinfo, sc); | ||
41 | } | ||
37 | 42 | ||
38 | change_sig(SIGUSR1, 1); | 43 | change_sig(SIGUSR1, 1); |
39 | info = &sig_info[sig]; | 44 | info = &sig_info[sig]; |
@@ -45,14 +50,17 @@ void sig_handler_common_skas(int sig, void *sc_ptr) | |||
45 | r->is_user = save_user; | 50 | r->is_user = save_user; |
46 | } | 51 | } |
47 | 52 | ||
48 | void user_signal(int sig, union uml_pt_regs *regs) | 53 | extern int ptrace_faultinfo; |
54 | |||
55 | void user_signal(int sig, union uml_pt_regs *regs, int pid) | ||
49 | { | 56 | { |
50 | struct signal_info *info; | 57 | struct signal_info *info; |
58 | int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || | ||
59 | (sig == SIGILL) || (sig == SIGTRAP)); | ||
51 | 60 | ||
52 | regs->skas.is_user = 1; | 61 | regs->skas.is_user = 1; |
53 | regs->skas.fault_addr = 0; | 62 | if (segv) |
54 | regs->skas.fault_type = 0; | 63 | get_skas_faultinfo(pid, ®s->skas.faultinfo); |
55 | regs->skas.trap_type = 0; | ||
56 | info = &sig_info[sig]; | 64 | info = &sig_info[sig]; |
57 | (*info->handler)(sig, regs); | 65 | (*info->handler)(sig, regs); |
58 | 66 | ||