aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/include/shared/os.h2
-rw-r--r--arch/um/os-Linux/process.c19
-rw-r--r--arch/um/os-Linux/signal.c22
-rw-r--r--arch/um/os-Linux/skas/process.c3
4 files changed, 19 insertions, 27 deletions
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 2e2663a8e910..598ca825ea9f 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -225,7 +225,7 @@ extern char *get_umid(void);
225extern void timer_init(void); 225extern void timer_init(void);
226extern void set_sigstack(void *sig_stack, int size); 226extern void set_sigstack(void *sig_stack, int size);
227extern void remove_sigstack(void); 227extern void remove_sigstack(void);
228extern void set_handler(int sig, void (*handler)(int), int flags, ...); 228extern void set_handler(int sig, void (*handler)(int));
229extern int change_sig(int signal, int on); 229extern int change_sig(int signal, int on);
230extern void block_signals(void); 230extern void block_signals(void);
231extern void unblock_signals(void); 231extern void unblock_signals(void);
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index c1a8fa74ebb9..075ae920143d 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -235,20 +235,13 @@ out:
235 235
236void init_new_thread_signals(void) 236void init_new_thread_signals(void)
237{ 237{
238 set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK, 238 set_handler(SIGSEGV, (__sighandler_t) sig_handler);
239 SIGIO, SIGWINCH, SIGVTALRM, -1); 239 set_handler(SIGTRAP, (__sighandler_t) sig_handler);
240 set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK, 240 set_handler(SIGFPE, (__sighandler_t) sig_handler);
241 SIGIO, SIGWINCH, SIGVTALRM, -1); 241 set_handler(SIGILL, (__sighandler_t) sig_handler);
242 set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK, 242 set_handler(SIGBUS, (__sighandler_t) sig_handler);
243 SIGIO, SIGWINCH, SIGVTALRM, -1);
244 set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK,
245 SIGIO, SIGWINCH, SIGVTALRM, -1);
246 set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK,
247 SIGIO, SIGWINCH, SIGVTALRM, -1);
248 signal(SIGHUP, SIG_IGN); 243 signal(SIGHUP, SIG_IGN);
249 244 set_handler(SIGIO, (__sighandler_t) sig_handler);
250 set_handler(SIGIO, (__sighandler_t) sig_handler,
251 SA_ONSTACK | SA_RESTART, SIGIO, SIGWINCH, SIGVTALRM, -1);
252 signal(SIGWINCH, SIG_IGN); 245 signal(SIGWINCH, SIG_IGN);
253 signal(SIGTERM, SIG_DFL); 246 signal(SIGTERM, SIG_DFL);
254} 247}
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 75c3e9c9cabb..f248fb2ab58c 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -111,8 +111,7 @@ void alarm_handler(int sig, struct sigcontext *sc)
111 111
112void timer_init(void) 112void timer_init(void)
113{ 113{
114 set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, 114 set_handler(SIGVTALRM, (__sighandler_t) alarm_handler);
115 SA_ONSTACK | SA_RESTART, SIGIO, SIGWINCH, -1);
116} 115}
117 116
118void set_sigstack(void *sig_stack, int size) 117void set_sigstack(void *sig_stack, int size)
@@ -174,27 +173,28 @@ static void hard_handler(int sig, siginfo_t *info, void *p)
174 handle_signal(sig, (struct sigcontext *) &uc->uc_mcontext); 173 handle_signal(sig, (struct sigcontext *) &uc->uc_mcontext);
175} 174}
176 175
177void set_handler(int sig, void (*handler)(int), int flags, ...) 176void set_handler(int sig, void (*handler)(int))
178{ 177{
179 struct sigaction action; 178 struct sigaction action;
180 va_list ap; 179 int flags = SA_SIGINFO | SA_ONSTACK;
181 sigset_t sig_mask; 180 sigset_t sig_mask;
182 int mask;
183 181
184 handlers[sig] = (void (*)(int, struct sigcontext *)) handler; 182 handlers[sig] = (void (*)(int, struct sigcontext *)) handler;
185 action.sa_sigaction = hard_handler; 183 action.sa_sigaction = hard_handler;
186 184
185 /* block irq ones */
187 sigemptyset(&action.sa_mask); 186 sigemptyset(&action.sa_mask);
188 187 sigaddset(&action.sa_mask, SIGVTALRM);
189 va_start(ap, flags); 188 sigaddset(&action.sa_mask, SIGIO);
190 while ((mask = va_arg(ap, int)) != -1) 189 sigaddset(&action.sa_mask, SIGWINCH);
191 sigaddset(&action.sa_mask, mask);
192 va_end(ap);
193 190
194 if (sig == SIGSEGV) 191 if (sig == SIGSEGV)
195 flags |= SA_NODEFER; 192 flags |= SA_NODEFER;
196 193
197 action.sa_flags = flags | SA_SIGINFO; 194 if (sigismember(&action.sa_mask, sig))
195 flags |= SA_RESTART; /* if it's an irq signal */
196
197 action.sa_flags = flags;
198 action.sa_restorer = NULL; 198 action.sa_restorer = NULL;
199 if (sigaction(sig, &action, NULL) < 0) 199 if (sigaction(sig, &action, NULL) < 0)
200 panic("sigaction failed - errno = %d\n", errno); 200 panic("sigaction failed - errno = %d\n", errno);
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 20b34dcb0906..31743f1d1195 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -659,8 +659,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
659{ 659{
660 int n; 660 int n;
661 661
662 set_handler(SIGWINCH, (__sighandler_t) sig_handler, 662 set_handler(SIGWINCH, (__sighandler_t) sig_handler);
663 SA_ONSTACK | SA_RESTART, SIGIO, SIGVTALRM, -1);
664 663
665 /* 664 /*
666 * Can't use UML_SETJMP or UML_LONGJMP here because they save 665 * Can't use UML_SETJMP or UML_LONGJMP here because they save