summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdike <jdike>2004-04-07 20:47:31 +0000
committerjdike <jdike>2004-04-07 20:47:31 +0000
commit566ae5880196a60a6effb1648adadad2d9c34d68 (patch)
tree51fa7a428ad7c4e359af9a2e1189ad72848c2156
parent7deb82b91d5881af6ac48015bd5188e82a5a417c (diff)
downloaduml-history-master.tar.gz
Properly fixed the tracing myself bug on 2.6 hosts.HEADmaster
-rw-r--r--arch/um/kernel/tt/exec_kern.c3
-rw-r--r--arch/um/kernel/tt/process_kern.c16
-rw-r--r--arch/um/kernel/tt/trap_user.c9
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, &current->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;