The serial UML OS-abstraction layer patch (um/kernel dir).
This moves all systemcalls from trap_user.c file under os-Linux dir
Signed-off-by: Gennady Sharapov <Gennady.V.Sharapov@intel.com>
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-/* 
+/*
  * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
 #include "sysdep/ptrace.h"
 #include "sysdep/faultinfo.h"
 
+typedef void (*kern_hndl)(int, union uml_pt_regs *);
+
+struct kern_handlers {
+       kern_hndl relay_signal;
+       kern_hndl winch;
+       kern_hndl bus_handler;
+       kern_hndl page_fault;
+       kern_hndl sigio_handler;
+       kern_hndl timer_handler;
+};
+
+extern struct kern_handlers handlinfo_kern;
+
 extern int ncpus;
 extern char *linux_prog;
 extern char *gdb_init;
 extern void free_irq(unsigned int, void *);
 extern int um_in_interrupt(void);
 extern int cpu(void);
+extern void segv_handler(int sig, union uml_pt_regs *regs);
+extern void sigio_handler(int sig, union uml_pt_regs *regs);
 
 #endif
 
 
 #include "uml-config.h"
 #include "asm/types.h"
 #include "../os/include/file.h"
+#include "sysdep/ptrace.h"
+#include "kern_util.h"
 
 #define OS_TYPE_FILE 1 
 #define OS_TYPE_DIR 2 
 extern int get_signals(void);
 extern int set_signals(int enable);
 
+/* trap.c */
+extern void os_fill_handlinfo(struct kern_handlers h);
+extern void do_longjmp(void *p, int val);
+
 #endif
 
-/* 
+/*
  * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
 
 extern struct cpu_task cpu_tasks[];
 
-struct signal_info {
-       void (*handler)(int, union uml_pt_regs *);
-       int is_irq;
-};
-
-extern struct signal_info sig_info[];
+extern void (*sig_info[])(int, union uml_pt_regs *);
 
 extern unsigned long low_physmem;
 extern unsigned long high_physmem;
 extern void setup_hostinfo(void);
 extern void do_exec(int old_pid, int new_pid);
 extern void tracer_panic(char *msg, ...);
-extern void do_longjmp(void *p, int val);
 extern int detach(int pid, int sig);
 extern int attach(int pid);
 extern void kill_child_dead(int pid);
 
 #
 
 obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
-       syscall.o tlb.o trap_user.o uaccess.o
+       syscall.o tlb.o uaccess.o
 
 USER_OBJS := process.o clone.o
 
 
-/* 
+/*
  * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
 #ifdef CONFIG_MODE_SKAS
 #include "skas.h"
 #endif
+#include "os.h"
 
 /* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
 int handle_page_fault(unsigned long address, unsigned long ip, 
        goto out;
 }
 
+struct kern_handlers handlinfo_kern = {
+       .relay_signal = relay_signal,
+       .winch = winch,
+       .bus_handler = relay_signal,
+       .page_fault = segv_handler,
+       .sigio_handler = sigio_handler,
+       .timer_handler = timer_handler
+};
 /*
  * We give a *copy* of the faultinfo in the regs to segv.
  * This must be done, since nesting SEGVs could overwrite
 
-/* 
+/*
  * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
 #include "user_util.h"
 #include "os.h"
 
-void kill_child_dead(int pid)
-{
-       kill(pid, SIGKILL);
-       kill(pid, SIGCONT);
-       do {
-               int n;
-               CATCH_EINTR(n = waitpid(pid, NULL, 0));
-               if (n > 0)
-                       kill(pid, SIGCONT);
-               else
-                       break;
-       } while(1);
-}
-
 void segv_handler(int sig, union uml_pt_regs *regs)
 {
         struct faultinfo * fi = UPT_FAULTINFO(regs);
        CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
 }
 
-struct signal_info sig_info[] = {
-       [ SIGTRAP ] { .handler          = relay_signal,
-                     .is_irq           = 0 },
-       [ SIGFPE ] { .handler           = relay_signal,
-                    .is_irq            = 0 },
-       [ SIGILL ] { .handler           = relay_signal,
-                    .is_irq            = 0 },
-       [ SIGWINCH ] { .handler         = winch,
-                      .is_irq          = 1 },
-       [ SIGBUS ] { .handler           = bus_handler,
-                    .is_irq            = 0 },
-       [ SIGSEGV] { .handler           = segv_handler,
-                    .is_irq            = 0 },
-       [ SIGIO ] { .handler            = sigio_handler,
-                   .is_irq             = 1 },
-       [ SIGVTALRM ] { .handler        = timer_handler,
-                       .is_irq         = 1 },
-        [ SIGALRM ] { .handler          = timer_handler,
-                      .is_irq           = 1 },
-       [ SIGUSR2 ] { .handler          = usr2_handler,
-                     .is_irq           = 0 },
-};
+void (*sig_info[NSIG])(int, union uml_pt_regs *);
 
-void do_longjmp(void *b, int val)
+void os_fill_handlinfo(struct kern_handlers h)
 {
-       sigjmp_buf *buf = b;
-
-       siglongjmp(*buf, val);
+       sig_info[SIGTRAP] = h.relay_signal;
+       sig_info[SIGFPE] = h.relay_signal;
+       sig_info[SIGILL] = h.relay_signal;
+       sig_info[SIGWINCH] = h.winch;
+       sig_info[SIGBUS] = h.bus_handler;
+       sig_info[SIGSEGV] = h.page_fault;
+       sig_info[SIGIO] = h.sigio_handler;
+       sig_info[SIGVTALRM] = h.timer_handler;
+       sig_info[SIGALRM] = h.timer_handler;
+       sig_info[SIGUSR2] = usr2_handler;
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
 
-/* 
+/*
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
 {
        struct sigcontext *sc = sc_ptr;
        struct tt_regs save_regs, *r;
-       struct signal_info *info;
        int save_errno = errno, is_user;
+       void (*handler)(int, union uml_pt_regs *);
 
        /* This is done because to allow SIGSEGV to be delivered inside a SEGV
         * handler.  This can happen in copy_user, and if SEGV is disabled,
        if(sig != SIGUSR2) 
                r->syscall = -1;
 
-       info = &sig_info[sig];
-       if(!info->is_irq) unblock_signals();
+       handler = sig_info[sig];
+
+       /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */
+       if (sig != SIGIO && sig != SIGWINCH &&
+           sig != SIGVTALRM && sig != SIGALRM)
+               unblock_signals();
 
-       (*info->handler)(sig, (union uml_pt_regs *) r);
+       handler(sig, (union uml_pt_regs *) r);
 
        if(is_user){
                interrupt_end();
 
-/* 
+/*
  * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
        uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
                                     &host_task_size, &task_size);
 
+       /*
+        * Setting up handlers to 'sig_info' struct
+        */
+       os_fill_handlinfo(handlinfo_kern);
+
        brk_start = (unsigned long) sbrk(0);
        CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
        /* Increase physical memory size for exec-shield users
 
 #
 
 obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
-       start_up.o time.o tt.o tty.o uaccess.o umid.o user_syms.o drivers/ \
-       sys-$(SUBARCH)/
+       start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o user_syms.o \
+       drivers/ sys-$(SUBARCH)/
+
+obj-$(CONFIG_MODE_SKAS) += skas/
 
 USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
-       start_up.o time.o tt.o tty.o uaccess.o umid.o
+       start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o
 
 elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
 CFLAGS_elf_aux.o += -I$(objtree)/arch/um
 
--- /dev/null
+#
+# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
+# Licensed under the GPL
+#
+
+obj-y := trap.o
+
+USER_OBJS := trap.o
+
+include arch/um/scripts/Makefile.rules
 
-/* 
+/*
  * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
  * Licensed under the GPL
  */
 {
        struct sigcontext *sc = sc_ptr;
        struct skas_regs *r;
-       struct signal_info *info;
+       void (*handler)(int, union uml_pt_regs *);
        int save_errno = errno;
        int save_user;
 
         }
 
        change_sig(SIGUSR1, 1);
-       info = &sig_info[sig];
-       if(!info->is_irq) unblock_signals();
 
-       (*info->handler)(sig, (union uml_pt_regs *) r);
+       handler = sig_info[sig];
+
+       /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */
+       if (sig != SIGIO && sig != SIGWINCH &&
+           sig != SIGVTALRM && sig != SIGALRM)
+               unblock_signals();
+
+       handler(sig, (union uml_pt_regs *) r);
 
        errno = save_errno;
        r->is_user = save_user;
 
 void user_signal(int sig, union uml_pt_regs *regs, int pid)
 {
-       struct signal_info *info;
+       void (*handler)(int, union uml_pt_regs *);
         int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
                     (sig == SIGILL) || (sig == SIGTRAP));
 
        if (segv)
                get_skas_faultinfo(pid, ®s->skas.faultinfo);
-       info = &sig_info[sig];
-       (*info->handler)(sig, regs);
+
+       handler = sig_info[sig];
+       handler(sig, (union uml_pt_regs *) regs);
 
        unblock_signals();
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
 
--- /dev/null
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <setjmp.h>
+#include <signal.h>
+#include "kern_util.h"
+#include "user_util.h"
+#include "os.h"
+
+void do_longjmp(void *b, int val)
+{
+       sigjmp_buf *buf = b;
+
+       siglongjmp(*buf, val);
+}
 
        return(0);
 }
 
+void kill_child_dead(int pid)
+{
+       kill(pid, SIGKILL);
+       kill(pid, SIGCONT);
+       do {
+               int n;
+               CATCH_EINTR(n = waitpid(pid, NULL, 0));
+               if (n > 0)
+                       kill(pid, SIGCONT);
+               else
+                       break;
+       } while(1);
+}
+
 /*
  *-------------------------
  * only for tt mode (will be deleted in future...)