]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/um/kernel/trap.c
Merge branch 'linus' into x86/i8259
[linux-2.6-omap-h63xx.git] / arch / um / kernel / trap.c
index eac63fb6183c16df3b12140b90e33a7c0db264b5..44e4904194951f680f187fd4f6137ca289b9cab8 100644 (file)
@@ -13,6 +13,7 @@
 #include "as-layout.h"
 #include "kern_util.h"
 #include "os.h"
+#include "skas.h"
 #include "sysdep/sigcontext.h"
 
 /*
@@ -108,7 +109,7 @@ out_nosemaphore:
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-       if (is_init(current)) {
+       if (is_global_init(current)) {
                up_read(&mm->mmap_sem);
                yield();
                down_read(&mm->mmap_sem);
@@ -128,7 +129,19 @@ static void bad_segv(struct faultinfo fi, unsigned long ip)
        force_sig_info(SIGSEGV, &si, current);
 }
 
-static void segv_handler(int sig, struct uml_pt_regs *regs)
+void fatal_sigsegv(void)
+{
+       force_sigsegv(SIGSEGV, current);
+       do_signal();
+       /*
+        * This is to tell gcc that we're not returning - do_signal
+        * can, in general, return, but in this case, it's not, since
+        * we just got a fatal SIGSEGV queued.
+        */
+       os_dump_core();
+}
+
+void segv_handler(int sig, struct uml_pt_regs *regs)
 {
        struct faultinfo * fi = UPT_FAULTINFO(regs);
 
@@ -149,7 +162,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
                   struct uml_pt_regs *regs)
 {
        struct siginfo si;
-       void *catcher;
+       jmp_buf *catcher;
        int err;
        int is_write = FAULT_WRITE(fi);
        unsigned long address = FAULT_ADDRESS(fi);
@@ -181,7 +194,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
                return 0;
        else if (catcher != NULL) {
                current->thread.fault_addr = (void *) address;
-               do_longjmp(catcher, 1);
+               UML_LONGJMP(catcher, 1);
        }
        else if (current->thread.fault_addr != NULL)
                panic("fault_addr set but no fault catcher");
@@ -216,9 +229,6 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
 
 void relay_signal(int sig, struct uml_pt_regs *regs)
 {
-       if (arch_handle_signal(sig, regs))
-               return;
-
        if (!UPT_IS_USER(regs)) {
                if (sig == SIGBUS)
                        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)
                panic("Kernel mode signal %d", sig);
        }
 
+       arch_examine_signal(sig, regs);
+
        current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
        force_sig(sig, current);
 }
 
-static void bus_handler(int sig, struct uml_pt_regs *regs)
+void bus_handler(int sig, struct uml_pt_regs *regs)
 {
        if (current->thread.fault_catcher != NULL)
-               do_longjmp(current->thread.fault_catcher, 1);
+               UML_LONGJMP(current->thread.fault_catcher, 1);
        else relay_signal(sig, regs);
 }
 
-static void winch(int sig, struct uml_pt_regs *regs)
+void winch(int sig, struct uml_pt_regs *regs)
 {
        do_IRQ(WINCH_IRQ, regs);
 }
 
-const struct kern_handlers handlinfo_kern = {
-       .relay_signal = relay_signal,
-       .winch = winch,
-       .bus_handler = bus_handler,
-       .page_fault = segv_handler,
-       .sigio_handler = sigio_handler,
-       .timer_handler = timer_handler
-};
-
 void trap_init(void)
 {
 }