Commit 1f9961ab authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

[PATCH] uml: eliminate signal order delivery dependency

On 2.4 hosts signals are delivered in numeric order when there are multiple
pending at a given time.  UML developed a subtle dependency on this
ordering, which broke on 2.6 hosts and the separate process and thread
signal queues.

This patch eliminates that dependency.
Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8be1f786
...@@ -70,7 +70,7 @@ void init_new_thread_signals(int altstack) ...@@ -70,7 +70,7 @@ void init_new_thread_signals(int altstack)
set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags,
SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
set_handler(SIGUSR2, (__sighandler_t) sig_handler, set_handler(SIGUSR2, (__sighandler_t) sig_handler,
SA_NOMASK | flags, -1); flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
signal(SIGHUP, SIG_IGN); signal(SIGHUP, SIG_IGN);
init_irq_signals(altstack); init_irq_signals(altstack);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "kern_util.h" #include "kern_util.h"
#include "irq_user.h" #include "irq_user.h"
#include "time_user.h" #include "time_user.h"
#include "signal_user.h"
#include "mem_user.h" #include "mem_user.h"
#include "os.h" #include "os.h"
#include "tlb.h" #include "tlb.h"
...@@ -53,7 +54,9 @@ void flush_thread_tt(void) ...@@ -53,7 +54,9 @@ void flush_thread_tt(void)
current->thread.request.u.exec.pid = new_pid; current->thread.request.u.exec.pid = new_pid;
unprotect_stack((unsigned long) current_thread); unprotect_stack((unsigned long) current_thread);
os_usr1_process(os_getpid()); os_usr1_process(os_getpid());
change_sig(SIGUSR1, 1);
change_sig(SIGUSR1, 0);
enable_timer(); enable_timer();
free_page(stack); free_page(stack);
protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1); protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
......
...@@ -201,6 +201,7 @@ static int new_thread_proc(void *stack) ...@@ -201,6 +201,7 @@ static int new_thread_proc(void *stack)
local_irq_disable(); local_irq_disable();
init_new_thread_stack(stack, new_thread_handler); init_new_thread_stack(stack, new_thread_handler);
os_usr1_process(os_getpid()); os_usr1_process(os_getpid());
change_sig(SIGUSR1, 1);
return(0); return(0);
} }
...@@ -244,6 +245,7 @@ int fork_tramp(void *stack) ...@@ -244,6 +245,7 @@ int fork_tramp(void *stack)
init_new_thread_stack(stack, finish_fork_handler); init_new_thread_stack(stack, finish_fork_handler);
os_usr1_process(os_getpid()); os_usr1_process(os_getpid());
change_sig(SIGUSR1, 1);
return(0); return(0);
} }
...@@ -295,19 +297,30 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -295,19 +297,30 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
current->thread.request.op = OP_FORK; current->thread.request.op = OP_FORK;
current->thread.request.u.fork.pid = new_pid; current->thread.request.u.fork.pid = new_pid;
os_usr1_process(os_getpid()); os_usr1_process(os_getpid());
return(0);
/* Enable the signal and then disable it to ensure that it is handled
* here, and nowhere else.
*/
change_sig(SIGUSR1, 1);
change_sig(SIGUSR1, 0);
err = 0;
out:
return(err);
} }
void reboot_tt(void) void reboot_tt(void)
{ {
current->thread.request.op = OP_REBOOT; current->thread.request.op = OP_REBOOT;
os_usr1_process(os_getpid()); os_usr1_process(os_getpid());
change_sig(SIGUSR1, 1);
} }
void halt_tt(void) void halt_tt(void)
{ {
current->thread.request.op = OP_HALT; current->thread.request.op = OP_HALT;
os_usr1_process(os_getpid()); os_usr1_process(os_getpid());
change_sig(SIGUSR1, 1);
} }
void kill_off_processes_tt(void) void kill_off_processes_tt(void)
...@@ -334,6 +347,9 @@ void initial_thread_cb_tt(void (*proc)(void *), void *arg) ...@@ -334,6 +347,9 @@ void initial_thread_cb_tt(void (*proc)(void *), void *arg)
current->thread.request.u.cb.proc = proc; current->thread.request.u.cb.proc = proc;
current->thread.request.u.cb.arg = arg; current->thread.request.u.cb.arg = arg;
os_usr1_process(os_getpid()); os_usr1_process(os_getpid());
change_sig(SIGUSR1, 1);
change_sig(SIGUSR1, 0);
} }
} }
......
...@@ -37,7 +37,6 @@ void sig_handler_common_tt(int sig, void *sc_ptr) ...@@ -37,7 +37,6 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
if(sig != SIGUSR2) if(sig != SIGUSR2)
r->syscall = -1; r->syscall = -1;
change_sig(SIGUSR1, 1);
info = &sig_info[sig]; info = &sig_info[sig];
if(!info->is_irq) unblock_signals(); if(!info->is_irq) unblock_signals();
...@@ -46,7 +45,6 @@ void sig_handler_common_tt(int sig, void *sc_ptr) ...@@ -46,7 +45,6 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
if(is_user){ if(is_user){
interrupt_end(); interrupt_end();
block_signals(); block_signals();
change_sig(SIGUSR1, 0);
set_user_mode(NULL); set_user_mode(NULL);
} }
*r = save_regs; *r = save_regs;
......
...@@ -96,11 +96,7 @@ void os_kill_process(int pid, int reap_child) ...@@ -96,11 +96,7 @@ void os_kill_process(int pid, int reap_child)
void os_usr1_process(int pid) void os_usr1_process(int pid)
{ {
#ifdef __NR_tkill
syscall(__NR_tkill, pid, SIGUSR1);
#else
kill(pid, SIGUSR1); kill(pid, SIGUSR1);
#endif
} }
int os_getpid(void) int os_getpid(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment