diff options
author | jdike <jdike> | 2004-04-07 20:47:31 +0000 |
---|---|---|
committer | jdike <jdike> | 2004-04-07 20:47:31 +0000 |
commit | 566ae5880196a60a6effb1648adadad2d9c34d68 (patch) | |
tree | 51fa7a428ad7c4e359af9a2e1189ad72848c2156 | |
parent | 7deb82b91d5881af6ac48015bd5188e82a5a417c (diff) | |
download | uml-history-566ae5880196a60a6effb1648adadad2d9c34d68.tar.gz |
-rw-r--r-- | arch/um/kernel/tt/exec_kern.c | 3 | ||||
-rw-r--r-- | arch/um/kernel/tt/process_kern.c | 16 | ||||
-rw-r--r-- | arch/um/kernel/tt/trap_user.c | 9 |
3 files changed, 26 insertions, 2 deletions
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c index 12fbbd0..644d83b 100644 --- a/arch/um/kernel/tt/exec_kern.c +++ b/arch/um/kernel/tt/exec_kern.c @@ -14,6 +14,7 @@ #include "irq_user.h" #include "time_user.h" #include "mem_user.h" +#include "signal_user.h" #include "os.h" #include "tlb.h" #include "mode.h" @@ -53,7 +54,9 @@ void flush_thread_tt(void) current->thread.request.u.exec.pid = new_pid; unprotect_stack((unsigned long) current); os_usr1_process(os_getpid()); + change_sig(SIGUSR1, 1); + change_sig(SIGUSR1, 0); enable_timer(); free_page(stack); protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1); diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index dd8a55e..adfd077 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -142,6 +142,12 @@ static void new_thread_handler(int sig) sti(); if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf)) do_exit(0); + + /* XXX No set_user_mode here because a newly execed process will + * immediately segfault on its non-existent IP, coming straight back + * to the signal handler, which will call set_user_mode on its way + * out. This should probably change since it's confusing. + */ } static int new_thread_proc(void *stack) @@ -162,6 +168,7 @@ static int new_thread_proc(void *stack) cli(); init_new_thread_stack(stack, new_thread_handler); os_usr1_process(os_getpid()); + change_sig(SIGUSR1, 1); return(0); } @@ -204,6 +211,7 @@ int fork_tramp(void *stack) arch_init_thread(); init_new_thread_stack(stack, finish_fork_handler); os_usr1_process(os_getpid()); + change_sig(SIGUSR1, 1); return(0); } @@ -256,6 +264,9 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, current->thread.request.op = OP_FORK; current->thread.request.u.fork.pid = new_pid; os_usr1_process(os_getpid()); + change_sig(SIGUSR1, 1); + + change_sig(SIGUSR1, 0); return(0); } @@ -263,12 +274,14 @@ void reboot_tt(void) { current->thread.request.op = OP_REBOOT; os_usr1_process(os_getpid()); + change_sig(SIGUSR1, 1); } void halt_tt(void) { current->thread.request.op = OP_HALT; os_usr1_process(os_getpid()); + change_sig(SIGUSR1, 1); } void kill_off_processes_tt(void) @@ -297,6 +310,9 @@ void initial_thread_cb_tt(void (*proc)(void *), void *arg) current->thread.request.u.cb.proc = proc; current->thread.request.u.cb.arg = arg; os_usr1_process(os_getpid()); + change_sig(SIGUSR1, 1); + + change_sig(SIGUSR1, 0); } } diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c index 7a6dbf5..00bacac 100644 --- a/arch/um/kernel/tt/trap_user.c +++ b/arch/um/kernel/tt/trap_user.c @@ -23,6 +23,13 @@ void sig_handler_common_tt(int sig, void *sc_ptr) unprotect_kernel_mem(); + /* 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, + * the process will die. + */ + if(sig == SIGSEGV) + change_sig(SIGSEGV, 1); + r = &TASK_REGS(get_current())->tt; save_regs = *r; is_user = user_context(SC_SP(sc)); @@ -30,7 +37,6 @@ void sig_handler_common_tt(int sig, void *sc_ptr) if(sig != SIGUSR2) r->syscall = -1; - change_sig(SIGUSR1, 1); info = &sig_info[sig]; if(!info->is_irq) unblock_signals(); @@ -39,7 +45,6 @@ void sig_handler_common_tt(int sig, void *sc_ptr) if(is_user){ interrupt_end(); block_signals(); - change_sig(SIGUSR1, 0); set_user_mode(NULL); } *r = save_regs; |