diff options
| -rw-r--r-- | arch/um/include/sysdep-i386/signal.h | 27 | ||||
| -rw-r--r-- | arch/um/include/sysdep-x86_64/signal.h | 29 | ||||
| -rw-r--r-- | arch/um/os-Linux/irq.c | 2 | ||||
| -rw-r--r-- | arch/um/os-Linux/main.c | 34 | ||||
| -rw-r--r-- | arch/um/os-Linux/process.c | 12 | ||||
| -rw-r--r-- | arch/um/os-Linux/signal.c | 31 | ||||
| -rw-r--r-- | arch/um/os-Linux/skas/process.c | 17 | ||||
| -rw-r--r-- | arch/um/os-Linux/sys-i386/Makefile | 2 | ||||
| -rw-r--r-- | arch/um/os-Linux/sys-i386/signal.c | 15 | ||||
| -rw-r--r-- | arch/um/os-Linux/sys-x86_64/Makefile | 2 | ||||
| -rw-r--r-- | arch/um/os-Linux/sys-x86_64/signal.c | 16 | ||||
| -rw-r--r-- | arch/um/os-Linux/time.c | 4 |
12 files changed, 102 insertions, 89 deletions
diff --git a/arch/um/include/sysdep-i386/signal.h b/arch/um/include/sysdep-i386/signal.h deleted file mode 100644 index 07518b162136..000000000000 --- a/arch/um/include/sysdep-i386/signal.h +++ /dev/null | |||
| @@ -1,27 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2004 PathScale, Inc | ||
| 3 | * Licensed under the GPL | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef __I386_SIGNAL_H_ | ||
| 7 | #define __I386_SIGNAL_H_ | ||
| 8 | |||
| 9 | #include <signal.h> | ||
| 10 | |||
| 11 | #define ARCH_SIGHDLR_PARAM int sig | ||
| 12 | |||
| 13 | #define ARCH_GET_SIGCONTEXT(sc, sig) \ | ||
| 14 | do sc = (struct sigcontext *) (&sig + 1); while(0) | ||
| 15 | |||
| 16 | #endif | ||
| 17 | |||
| 18 | /* | ||
| 19 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
| 20 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 21 | * adjust the settings for this buffer only. This must remain at the end | ||
| 22 | * of the file. | ||
| 23 | * --------------------------------------------------------------------------- | ||
| 24 | * Local variables: | ||
| 25 | * c-file-style: "linux" | ||
| 26 | * End: | ||
| 27 | */ | ||
diff --git a/arch/um/include/sysdep-x86_64/signal.h b/arch/um/include/sysdep-x86_64/signal.h deleted file mode 100644 index 6142897af3d1..000000000000 --- a/arch/um/include/sysdep-x86_64/signal.h +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2004 PathScale, Inc | ||
| 3 | * Licensed under the GPL | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef __X86_64_SIGNAL_H_ | ||
| 7 | #define __X86_64_SIGNAL_H_ | ||
| 8 | |||
| 9 | #define ARCH_SIGHDLR_PARAM int sig | ||
| 10 | |||
| 11 | #define ARCH_GET_SIGCONTEXT(sc, sig_addr) \ | ||
| 12 | do { \ | ||
| 13 | struct ucontext *__uc; \ | ||
| 14 | asm("movq %%rdx, %0" : "=r" (__uc)); \ | ||
| 15 | sc = (struct sigcontext *) &__uc->uc_mcontext; \ | ||
| 16 | } while(0) | ||
| 17 | |||
| 18 | #endif | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
| 22 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 23 | * adjust the settings for this buffer only. This must remain at the end | ||
| 24 | * of the file. | ||
| 25 | * --------------------------------------------------------------------------- | ||
| 26 | * Local variables: | ||
| 27 | * c-file-style: "linux" | ||
| 28 | * End: | ||
| 29 | */ | ||
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index 7555bf9c33d9..a97206df5b52 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c | |||
| @@ -132,7 +132,7 @@ void os_set_pollfd(int i, int fd) | |||
| 132 | 132 | ||
| 133 | void os_set_ioignore(void) | 133 | void os_set_ioignore(void) |
| 134 | { | 134 | { |
| 135 | set_handler(SIGIO, SIG_IGN, 0, -1); | 135 | signal(SIGIO, SIG_IGN); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | void init_irq_signals(int on_sigstack) | 138 | void init_irq_signals(int on_sigstack) |
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 90912aaca7aa..d1c5670787dc 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c | |||
| @@ -67,13 +67,32 @@ static __init void do_uml_initcalls(void) | |||
| 67 | 67 | ||
| 68 | static void last_ditch_exit(int sig) | 68 | static void last_ditch_exit(int sig) |
| 69 | { | 69 | { |
| 70 | signal(SIGINT, SIG_DFL); | ||
| 71 | signal(SIGTERM, SIG_DFL); | ||
| 72 | signal(SIGHUP, SIG_DFL); | ||
| 73 | uml_cleanup(); | 70 | uml_cleanup(); |
| 74 | exit(1); | 71 | exit(1); |
| 75 | } | 72 | } |
| 76 | 73 | ||
| 74 | static void install_fatal_handler(int sig) | ||
| 75 | { | ||
| 76 | struct sigaction action; | ||
| 77 | |||
| 78 | /* All signals are enabled in this handler ... */ | ||
| 79 | sigemptyset(&action.sa_mask); | ||
| 80 | |||
| 81 | /* ... including the signal being handled, plus we want the | ||
| 82 | * handler reset to the default behavior, so that if an exit | ||
| 83 | * handler is hanging for some reason, the UML will just die | ||
| 84 | * after this signal is sent a second time. | ||
| 85 | */ | ||
| 86 | action.sa_flags = SA_RESETHAND | SA_NODEFER; | ||
| 87 | action.sa_restorer = NULL; | ||
| 88 | action.sa_handler = last_ditch_exit; | ||
| 89 | if(sigaction(sig, &action, NULL) < 0){ | ||
| 90 | printf("failed to install handler for signal %d - errno = %d\n", | ||
| 91 | errno); | ||
| 92 | exit(1); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 77 | #define UML_LIB_PATH ":/usr/lib/uml" | 96 | #define UML_LIB_PATH ":/usr/lib/uml" |
| 78 | 97 | ||
| 79 | static void setup_env_path(void) | 98 | static void setup_env_path(void) |
| @@ -158,9 +177,12 @@ int main(int argc, char **argv, char **envp) | |||
| 158 | } | 177 | } |
| 159 | new_argv[argc] = NULL; | 178 | new_argv[argc] = NULL; |
| 160 | 179 | ||
| 161 | set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); | 180 | /* Allow these signals to bring down a UML if all other |
| 162 | set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); | 181 | * methods of control fail. |
| 163 | set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); | 182 | */ |
| 183 | install_fatal_handler(SIGINT); | ||
| 184 | install_fatal_handler(SIGTERM); | ||
| 185 | install_fatal_handler(SIGHUP); | ||
| 164 | 186 | ||
| 165 | scan_elf_aux( envp); | 187 | scan_elf_aux( envp); |
| 166 | 188 | ||
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 3afde92ad2c0..ff203625a4bd 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
| @@ -246,7 +246,17 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) | |||
| 246 | set_sigstack(sig_stack, pages * page_size()); | 246 | set_sigstack(sig_stack, pages * page_size()); |
| 247 | flags = SA_ONSTACK; | 247 | flags = SA_ONSTACK; |
| 248 | } | 248 | } |
| 249 | if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1); | 249 | if(usr1_handler){ |
| 250 | struct sigaction sa; | ||
| 251 | |||
| 252 | sa.sa_handler = usr1_handler; | ||
| 253 | sigemptyset(&sa.sa_mask); | ||
| 254 | sa.sa_flags = flags; | ||
| 255 | sa.sa_restorer = NULL; | ||
| 256 | if(sigaction(SIGUSR1, &sa, NULL) < 0) | ||
| 257 | panic("init_new_thread_stack - sigaction failed - " | ||
| 258 | "errno = %d\n", errno); | ||
| 259 | } | ||
| 250 | } | 260 | } |
| 251 | 261 | ||
| 252 | void init_new_thread_signals(void) | 262 | void init_new_thread_signals(void) |
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 60e4faedf254..55b62e2b8f41 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include "user.h" | 15 | #include "user.h" |
| 16 | #include "signal_kern.h" | 16 | #include "signal_kern.h" |
| 17 | #include "sysdep/sigcontext.h" | 17 | #include "sysdep/sigcontext.h" |
| 18 | #include "sysdep/signal.h" | ||
| 19 | #include "sigcontext.h" | 18 | #include "sigcontext.h" |
| 20 | #include "mode.h" | 19 | #include "mode.h" |
| 21 | #include "os.h" | 20 | #include "os.h" |
| @@ -38,18 +37,10 @@ | |||
| 38 | static int signals_enabled = 1; | 37 | static int signals_enabled = 1; |
| 39 | static int pending = 0; | 38 | static int pending = 0; |
| 40 | 39 | ||
| 41 | void sig_handler(ARCH_SIGHDLR_PARAM) | 40 | void sig_handler(int sig, struct sigcontext *sc) |
| 42 | { | 41 | { |
| 43 | struct sigcontext *sc; | ||
| 44 | int enabled; | 42 | int enabled; |
| 45 | 43 | ||
| 46 | /* Must be the first thing that this handler does - x86_64 stores | ||
| 47 | * the sigcontext in %rdx, and we need to save it before it has a | ||
| 48 | * chance to get trashed. | ||
| 49 | */ | ||
| 50 | |||
| 51 | ARCH_GET_SIGCONTEXT(sc, sig); | ||
| 52 | |||
| 53 | enabled = signals_enabled; | 44 | enabled = signals_enabled; |
| 54 | if(!enabled && (sig == SIGIO)){ | 45 | if(!enabled && (sig == SIGIO)){ |
| 55 | pending |= SIGIO_MASK; | 46 | pending |= SIGIO_MASK; |
| @@ -84,13 +75,10 @@ static void real_alarm_handler(int sig, struct sigcontext *sc) | |||
| 84 | 75 | ||
| 85 | } | 76 | } |
| 86 | 77 | ||
| 87 | void alarm_handler(ARCH_SIGHDLR_PARAM) | 78 | void alarm_handler(int sig, struct sigcontext *sc) |
| 88 | { | 79 | { |
| 89 | struct sigcontext *sc; | ||
| 90 | int enabled; | 80 | int enabled; |
| 91 | 81 | ||
| 92 | ARCH_GET_SIGCONTEXT(sc, sig); | ||
| 93 | |||
| 94 | enabled = signals_enabled; | 82 | enabled = signals_enabled; |
| 95 | if(!signals_enabled){ | 83 | if(!signals_enabled){ |
| 96 | if(sig == SIGVTALRM) | 84 | if(sig == SIGVTALRM) |
| @@ -126,6 +114,10 @@ void remove_sigstack(void) | |||
| 126 | panic("disabling signal stack failed, errno = %d\n", errno); | 114 | panic("disabling signal stack failed, errno = %d\n", errno); |
| 127 | } | 115 | } |
| 128 | 116 | ||
| 117 | void (*handlers[_NSIG])(int sig, struct sigcontext *sc); | ||
| 118 | |||
| 119 | extern void hard_handler(int sig); | ||
| 120 | |||
| 129 | void set_handler(int sig, void (*handler)(int), int flags, ...) | 121 | void set_handler(int sig, void (*handler)(int), int flags, ...) |
| 130 | { | 122 | { |
| 131 | struct sigaction action; | 123 | struct sigaction action; |
| @@ -133,13 +125,16 @@ void set_handler(int sig, void (*handler)(int), int flags, ...) | |||
| 133 | sigset_t sig_mask; | 125 | sigset_t sig_mask; |
| 134 | int mask; | 126 | int mask; |
| 135 | 127 | ||
| 136 | va_start(ap, flags); | 128 | handlers[sig] = (void (*)(int, struct sigcontext *)) handler; |
| 137 | action.sa_handler = handler; | 129 | action.sa_handler = hard_handler; |
| 130 | |||
| 138 | sigemptyset(&action.sa_mask); | 131 | sigemptyset(&action.sa_mask); |
| 139 | while((mask = va_arg(ap, int)) != -1){ | 132 | |
| 133 | va_start(ap, flags); | ||
| 134 | while((mask = va_arg(ap, int)) != -1) | ||
| 140 | sigaddset(&action.sa_mask, mask); | 135 | sigaddset(&action.sa_mask, mask); |
| 141 | } | ||
| 142 | va_end(ap); | 136 | va_end(ap); |
| 137 | |||
| 143 | action.sa_flags = flags; | 138 | action.sa_flags = flags; |
| 144 | action.sa_restorer = NULL; | 139 | action.sa_restorer = NULL; |
| 145 | if(sigaction(sig, &action, NULL) < 0) | 140 | if(sigaction(sig, &action, NULL) < 0) |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 50418a5e7134..88ff0de95cd3 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
| @@ -189,14 +189,25 @@ static int userspace_tramp(void *stack) | |||
| 189 | } | 189 | } |
| 190 | } | 190 | } |
| 191 | if(!ptrace_faultinfo && (stack != NULL)){ | 191 | if(!ptrace_faultinfo && (stack != NULL)){ |
| 192 | struct sigaction sa; | ||
| 193 | |||
| 192 | unsigned long v = UML_CONFIG_STUB_CODE + | 194 | unsigned long v = UML_CONFIG_STUB_CODE + |
| 193 | (unsigned long) stub_segv_handler - | 195 | (unsigned long) stub_segv_handler - |
| 194 | (unsigned long) &__syscall_stub_start; | 196 | (unsigned long) &__syscall_stub_start; |
| 195 | 197 | ||
| 196 | set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size()); | 198 | set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size()); |
| 197 | set_handler(SIGSEGV, (void *) v, SA_ONSTACK, | 199 | sigemptyset(&sa.sa_mask); |
| 198 | SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, | 200 | sigaddset(&sa.sa_mask, SIGIO); |
| 199 | SIGUSR1, -1); | 201 | sigaddset(&sa.sa_mask, SIGWINCH); |
| 202 | sigaddset(&sa.sa_mask, SIGALRM); | ||
| 203 | sigaddset(&sa.sa_mask, SIGVTALRM); | ||
| 204 | sigaddset(&sa.sa_mask, SIGUSR1); | ||
| 205 | sa.sa_flags = SA_ONSTACK; | ||
| 206 | sa.sa_handler = (void *) v; | ||
| 207 | sa.sa_restorer = NULL; | ||
| 208 | if(sigaction(SIGSEGV, &sa, NULL) < 0) | ||
| 209 | panic("userspace_tramp - setting SIGSEGV handler " | ||
| 210 | "failed - errno = %d\n", errno); | ||
| 200 | } | 211 | } |
| 201 | 212 | ||
| 202 | os_stop_process(os_getpid()); | 213 | os_stop_process(os_getpid()); |
diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile index b3213613c41c..37806621b25d 100644 --- a/arch/um/os-Linux/sys-i386/Makefile +++ b/arch/um/os-Linux/sys-i386/Makefile | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # Licensed under the GPL | 3 | # Licensed under the GPL |
| 4 | # | 4 | # |
| 5 | 5 | ||
| 6 | obj-$(CONFIG_MODE_SKAS) = registers.o tls.o | 6 | obj-$(CONFIG_MODE_SKAS) = registers.o signal.o tls.o |
| 7 | 7 | ||
| 8 | USER_OBJS := $(obj-y) | 8 | USER_OBJS := $(obj-y) |
| 9 | 9 | ||
diff --git a/arch/um/os-Linux/sys-i386/signal.c b/arch/um/os-Linux/sys-i386/signal.c new file mode 100644 index 000000000000..0d3eae518352 --- /dev/null +++ b/arch/um/os-Linux/sys-i386/signal.c | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) | ||
| 3 | * Licensed under the GPL | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <signal.h> | ||
| 7 | |||
| 8 | extern void (*handlers[])(int sig, struct sigcontext *sc); | ||
| 9 | |||
| 10 | void hard_handler(int sig) | ||
| 11 | { | ||
| 12 | struct sigcontext *sc = (struct sigcontext *) (&sig + 1); | ||
| 13 | |||
| 14 | (*handlers[sig])(sig, sc); | ||
| 15 | } | ||
diff --git a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile index 340ef26f5944..f67842a7735b 100644 --- a/arch/um/os-Linux/sys-x86_64/Makefile +++ b/arch/um/os-Linux/sys-x86_64/Makefile | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # Licensed under the GPL | 3 | # Licensed under the GPL |
| 4 | # | 4 | # |
| 5 | 5 | ||
| 6 | obj-$(CONFIG_MODE_SKAS) = registers.o | 6 | obj-$(CONFIG_MODE_SKAS) = registers.o signal.o |
| 7 | 7 | ||
| 8 | USER_OBJS := $(obj-y) | 8 | USER_OBJS := $(obj-y) |
| 9 | 9 | ||
diff --git a/arch/um/os-Linux/sys-x86_64/signal.c b/arch/um/os-Linux/sys-x86_64/signal.c new file mode 100644 index 000000000000..3f369e5f976b --- /dev/null +++ b/arch/um/os-Linux/sys-x86_64/signal.c | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) | ||
| 3 | * Licensed under the GPL | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <signal.h> | ||
| 7 | |||
| 8 | extern void (*handlers[])(int sig, struct sigcontext *sc); | ||
| 9 | |||
| 10 | void hard_handler(int sig) | ||
| 11 | { | ||
| 12 | struct ucontext *uc; | ||
| 13 | asm("movq %%rdx, %0" : "=r" (uc)); | ||
| 14 | |||
| 15 | (*handlers[sig])(sig, (struct sigcontext *) &uc->uc_mcontext); | ||
| 16 | } | ||
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 4ae73c0e5485..7f5ebbadca63 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c | |||
| @@ -40,8 +40,8 @@ void disable_timer(void) | |||
| 40 | printk("disnable_timer - setitimer failed, errno = %d\n", | 40 | printk("disnable_timer - setitimer failed, errno = %d\n", |
| 41 | errno); | 41 | errno); |
| 42 | /* If there are signals already queued, after unblocking ignore them */ | 42 | /* If there are signals already queued, after unblocking ignore them */ |
| 43 | set_handler(SIGALRM, SIG_IGN, 0, -1); | 43 | signal(SIGALRM, SIG_IGN); |
| 44 | set_handler(SIGVTALRM, SIG_IGN, 0, -1); | 44 | signal(SIGVTALRM, SIG_IGN); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | void switch_timers(int to_real) | 47 | void switch_timers(int to_real) |
