aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel/trap.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel/trap.c')
-rw-r--r--arch/um/kernel/trap.c33
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
131static void segv_handler(int sig, struct uml_pt_regs *regs) 132void 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
144void 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
217void relay_signal(int sig, struct uml_pt_regs *regs) 230void 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
233static void bus_handler(int sig, struct uml_pt_regs *regs) 245void 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
240static void winch(int sig, struct uml_pt_regs *regs) 252void 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
245const 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
254void trap_init(void) 257void trap_init(void)
255{ 258{
256} 259}