diff options
Diffstat (limited to 'arch/um/kernel/trap.c')
-rw-r--r-- | arch/um/kernel/trap.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index cb3321f8e0a9..44e490419495 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include "as-layout.h" | 13 | #include "as-layout.h" |
14 | #include "kern_util.h" | 14 | #include "kern_util.h" |
15 | #include "os.h" | 15 | #include "os.h" |
16 | #include "skas.h" | ||
16 | #include "sysdep/sigcontext.h" | 17 | #include "sysdep/sigcontext.h" |
17 | 18 | ||
18 | /* | 19 | /* |
@@ -128,7 +129,19 @@ static void bad_segv(struct faultinfo fi, unsigned long ip) | |||
128 | force_sig_info(SIGSEGV, &si, current); | 129 | force_sig_info(SIGSEGV, &si, current); |
129 | } | 130 | } |
130 | 131 | ||
131 | static void segv_handler(int sig, struct uml_pt_regs *regs) | 132 | void fatal_sigsegv(void) |
133 | { | ||
134 | force_sigsegv(SIGSEGV, current); | ||
135 | do_signal(); | ||
136 | /* | ||
137 | * This is to tell gcc that we're not returning - do_signal | ||
138 | * can, in general, return, but in this case, it's not, since | ||
139 | * we just got a fatal SIGSEGV queued. | ||
140 | */ | ||
141 | os_dump_core(); | ||
142 | } | ||
143 | |||
144 | void segv_handler(int sig, struct uml_pt_regs *regs) | ||
132 | { | 145 | { |
133 | struct faultinfo * fi = UPT_FAULTINFO(regs); | 146 | struct faultinfo * fi = UPT_FAULTINFO(regs); |
134 | 147 | ||
@@ -216,9 +229,6 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, | |||
216 | 229 | ||
217 | void relay_signal(int sig, struct uml_pt_regs *regs) | 230 | void relay_signal(int sig, struct uml_pt_regs *regs) |
218 | { | 231 | { |
219 | if (arch_handle_signal(sig, regs)) | ||
220 | return; | ||
221 | |||
222 | if (!UPT_IS_USER(regs)) { | 232 | if (!UPT_IS_USER(regs)) { |
223 | if (sig == SIGBUS) | 233 | if (sig == SIGBUS) |
224 | printk(KERN_ERR "Bus error - the host /dev/shm or /tmp " | 234 | printk(KERN_ERR "Bus error - the host /dev/shm or /tmp " |
@@ -226,31 +236,24 @@ void relay_signal(int sig, struct uml_pt_regs *regs) | |||
226 | panic("Kernel mode signal %d", sig); | 236 | panic("Kernel mode signal %d", sig); |
227 | } | 237 | } |
228 | 238 | ||
239 | arch_examine_signal(sig, regs); | ||
240 | |||
229 | current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); | 241 | current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); |
230 | force_sig(sig, current); | 242 | force_sig(sig, current); |
231 | } | 243 | } |
232 | 244 | ||
233 | static void bus_handler(int sig, struct uml_pt_regs *regs) | 245 | void bus_handler(int sig, struct uml_pt_regs *regs) |
234 | { | 246 | { |
235 | if (current->thread.fault_catcher != NULL) | 247 | if (current->thread.fault_catcher != NULL) |
236 | UML_LONGJMP(current->thread.fault_catcher, 1); | 248 | UML_LONGJMP(current->thread.fault_catcher, 1); |
237 | else relay_signal(sig, regs); | 249 | else relay_signal(sig, regs); |
238 | } | 250 | } |
239 | 251 | ||
240 | static void winch(int sig, struct uml_pt_regs *regs) | 252 | void winch(int sig, struct uml_pt_regs *regs) |
241 | { | 253 | { |
242 | do_IRQ(WINCH_IRQ, regs); | 254 | do_IRQ(WINCH_IRQ, regs); |
243 | } | 255 | } |
244 | 256 | ||
245 | const struct kern_handlers handlinfo_kern = { | ||
246 | .relay_signal = relay_signal, | ||
247 | .winch = winch, | ||
248 | .bus_handler = bus_handler, | ||
249 | .page_fault = segv_handler, | ||
250 | .sigio_handler = sigio_handler, | ||
251 | .timer_handler = timer_handler | ||
252 | }; | ||
253 | |||
254 | void trap_init(void) | 257 | void trap_init(void) |
255 | { | 258 | { |
256 | } | 259 | } |