diff options
-rw-r--r-- | arch/um/include/longjmp.h | 19 | ||||
-rw-r--r-- | arch/um/os-Linux/main.c | 12 | ||||
-rw-r--r-- | arch/um/os-Linux/process.c | 30 | ||||
-rw-r--r-- | arch/um/os-Linux/signal.c | 203 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 29 | ||||
-rw-r--r-- | arch/um/os-Linux/trap.c | 3 | ||||
-rw-r--r-- | arch/um/os-Linux/uaccess.c | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/util.c | 1 |
8 files changed, 183 insertions, 118 deletions
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h new file mode 100644 index 000000000000..50f5df18e46d --- /dev/null +++ b/arch/um/include/longjmp.h | |||
@@ -0,0 +1,19 @@ | |||
1 | #ifndef __UML_LONGJMP_H | ||
2 | #define __UML_LONGJMP_H | ||
3 | |||
4 | #include <setjmp.h> | ||
5 | #include "os.h" | ||
6 | |||
7 | #define UML_SIGLONGJMP(buf, val) do { \ | ||
8 | siglongjmp(*buf, val); \ | ||
9 | } while(0) | ||
10 | |||
11 | #define UML_SIGSETJMP(buf, enable) ({ \ | ||
12 | int n; \ | ||
13 | enable = get_signals(); \ | ||
14 | n = sigsetjmp(*buf, 1); \ | ||
15 | if(n != 0) \ | ||
16 | set_signals(enable); \ | ||
17 | n; }) | ||
18 | |||
19 | #endif | ||
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 98becd18f211..2878e89a674f 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c | |||
@@ -81,20 +81,8 @@ extern void scan_elf_aux( char **envp); | |||
81 | int main(int argc, char **argv, char **envp) | 81 | int main(int argc, char **argv, char **envp) |
82 | { | 82 | { |
83 | char **new_argv; | 83 | char **new_argv; |
84 | sigset_t mask; | ||
85 | int ret, i, err; | 84 | int ret, i, err; |
86 | 85 | ||
87 | /* Enable all signals except SIGIO - in some environments, we can | ||
88 | * enter with some signals blocked | ||
89 | */ | ||
90 | |||
91 | sigemptyset(&mask); | ||
92 | sigaddset(&mask, SIGIO); | ||
93 | if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){ | ||
94 | perror("sigprocmask"); | ||
95 | exit(1); | ||
96 | } | ||
97 | |||
98 | #ifdef UML_CONFIG_CMDLINE_ON_HOST | 86 | #ifdef UML_CONFIG_CMDLINE_ON_HOST |
99 | /* Allocate memory for thread command lines */ | 87 | /* Allocate memory for thread command lines */ |
100 | if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){ | 88 | if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){ |
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 39815c6b5e45..7f5e2dac2a35 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "process.h" | 18 | #include "process.h" |
19 | #include "irq_user.h" | 19 | #include "irq_user.h" |
20 | #include "kern_util.h" | 20 | #include "kern_util.h" |
21 | #include "longjmp.h" | ||
21 | 22 | ||
22 | #define ARBITRARY_ADDR -1 | 23 | #define ARBITRARY_ADDR -1 |
23 | #define FAILURE_PID -1 | 24 | #define FAILURE_PID -1 |
@@ -205,24 +206,13 @@ void init_new_thread_signals(int altstack) | |||
205 | 206 | ||
206 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) | 207 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) |
207 | { | 208 | { |
208 | sigjmp_buf buf; | 209 | sigjmp_buf buf; |
209 | int n; | 210 | int n, enable; |
210 | 211 | ||
211 | *jmp_ptr = &buf; | 212 | *jmp_ptr = &buf; |
212 | n = sigsetjmp(buf, 1); | 213 | n = UML_SIGSETJMP(&buf, enable); |
213 | if(n != 0) | 214 | if(n != 0) |
214 | return(n); | 215 | return(n); |
215 | (*fn)(arg); | 216 | (*fn)(arg); |
216 | return(0); | 217 | return(0); |
217 | } | 218 | } |
218 | |||
219 | /* | ||
220 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
221 | * Emacs will notice this stuff at the end of the file and automatically | ||
222 | * adjust the settings for this buffer only. This must remain at the end | ||
223 | * of the file. | ||
224 | * --------------------------------------------------------------------------- | ||
225 | * Local variables: | ||
226 | * c-file-style: "linux" | ||
227 | * End: | ||
228 | */ | ||
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 56ca95931b41..f11b3124a0c8 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
@@ -20,23 +20,58 @@ | |||
20 | #include "mode.h" | 20 | #include "mode.h" |
21 | #include "os.h" | 21 | #include "os.h" |
22 | 22 | ||
23 | /* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled | ||
24 | * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to | ||
25 | * be able to profile all of UML, not just the non-critical sections. If | ||
26 | * profiling is not thread-safe, then that is not my problem. We can disable | ||
27 | * profiling when SMP is enabled in that case. | ||
28 | */ | ||
29 | #define SIGIO_BIT 0 | ||
30 | #define SIGIO_MASK (1 << SIGIO_BIT) | ||
31 | |||
32 | #define SIGVTALRM_BIT 1 | ||
33 | #define SIGVTALRM_MASK (1 << SIGVTALRM_BIT) | ||
34 | |||
35 | #define SIGALRM_BIT 2 | ||
36 | #define SIGALRM_MASK (1 << SIGALRM_BIT) | ||
37 | |||
38 | static int signals_enabled = 1; | ||
39 | static int pending = 0; | ||
40 | |||
23 | void sig_handler(ARCH_SIGHDLR_PARAM) | 41 | void sig_handler(ARCH_SIGHDLR_PARAM) |
24 | { | 42 | { |
25 | struct sigcontext *sc; | 43 | struct sigcontext *sc; |
44 | int enabled; | ||
45 | |||
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 | */ | ||
26 | 50 | ||
27 | ARCH_GET_SIGCONTEXT(sc, sig); | 51 | ARCH_GET_SIGCONTEXT(sc, sig); |
52 | |||
53 | enabled = signals_enabled; | ||
54 | if(!enabled && (sig == SIGIO)){ | ||
55 | pending |= SIGIO_MASK; | ||
56 | return; | ||
57 | } | ||
58 | |||
59 | block_signals(); | ||
60 | |||
28 | CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas, | 61 | CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas, |
29 | sig, sc); | 62 | sig, sc); |
63 | |||
64 | set_signals(enabled); | ||
30 | } | 65 | } |
31 | 66 | ||
32 | extern int timer_irq_inited; | 67 | extern int timer_irq_inited; |
33 | 68 | ||
34 | void alarm_handler(ARCH_SIGHDLR_PARAM) | 69 | static void real_alarm_handler(int sig, struct sigcontext *sc) |
35 | { | 70 | { |
36 | struct sigcontext *sc; | 71 | if(!timer_irq_inited){ |
37 | 72 | signals_enabled = 1; | |
38 | ARCH_GET_SIGCONTEXT(sc, sig); | 73 | return; |
39 | if(!timer_irq_inited) return; | 74 | } |
40 | 75 | ||
41 | if(sig == SIGALRM) | 76 | if(sig == SIGALRM) |
42 | switch_timers(0); | 77 | switch_timers(0); |
@@ -46,6 +81,29 @@ void alarm_handler(ARCH_SIGHDLR_PARAM) | |||
46 | 81 | ||
47 | if(sig == SIGALRM) | 82 | if(sig == SIGALRM) |
48 | switch_timers(1); | 83 | switch_timers(1); |
84 | |||
85 | } | ||
86 | |||
87 | void alarm_handler(ARCH_SIGHDLR_PARAM) | ||
88 | { | ||
89 | struct sigcontext *sc; | ||
90 | int enabled; | ||
91 | |||
92 | ARCH_GET_SIGCONTEXT(sc, sig); | ||
93 | |||
94 | enabled = signals_enabled; | ||
95 | if(!signals_enabled){ | ||
96 | if(sig == SIGVTALRM) | ||
97 | pending |= SIGVTALRM_MASK; | ||
98 | else pending |= SIGALRM_MASK; | ||
99 | |||
100 | return; | ||
101 | } | ||
102 | |||
103 | block_signals(); | ||
104 | |||
105 | real_alarm_handler(sig, sc); | ||
106 | set_signals(enabled); | ||
49 | } | 107 | } |
50 | 108 | ||
51 | extern void do_boot_timer_handler(struct sigcontext * sc); | 109 | extern void do_boot_timer_handler(struct sigcontext * sc); |
@@ -53,10 +111,22 @@ extern void do_boot_timer_handler(struct sigcontext * sc); | |||
53 | void boot_timer_handler(ARCH_SIGHDLR_PARAM) | 111 | void boot_timer_handler(ARCH_SIGHDLR_PARAM) |
54 | { | 112 | { |
55 | struct sigcontext *sc; | 113 | struct sigcontext *sc; |
114 | int enabled; | ||
56 | 115 | ||
57 | ARCH_GET_SIGCONTEXT(sc, sig); | 116 | ARCH_GET_SIGCONTEXT(sc, sig); |
58 | 117 | ||
118 | enabled = signals_enabled; | ||
119 | if(!enabled){ | ||
120 | if(sig == SIGVTALRM) | ||
121 | pending |= SIGVTALRM_MASK; | ||
122 | else pending |= SIGALRM_MASK; | ||
123 | return; | ||
124 | } | ||
125 | |||
126 | block_signals(); | ||
127 | |||
59 | do_boot_timer_handler(sc); | 128 | do_boot_timer_handler(sc); |
129 | set_signals(enabled); | ||
60 | } | 130 | } |
61 | 131 | ||
62 | void set_sigstack(void *sig_stack, int size) | 132 | void set_sigstack(void *sig_stack, int size) |
@@ -83,6 +153,7 @@ void set_handler(int sig, void (*handler)(int), int flags, ...) | |||
83 | { | 153 | { |
84 | struct sigaction action; | 154 | struct sigaction action; |
85 | va_list ap; | 155 | va_list ap; |
156 | sigset_t sig_mask; | ||
86 | int mask; | 157 | int mask; |
87 | 158 | ||
88 | va_start(ap, flags); | 159 | va_start(ap, flags); |
@@ -95,7 +166,12 @@ void set_handler(int sig, void (*handler)(int), int flags, ...) | |||
95 | action.sa_flags = flags; | 166 | action.sa_flags = flags; |
96 | action.sa_restorer = NULL; | 167 | action.sa_restorer = NULL; |
97 | if(sigaction(sig, &action, NULL) < 0) | 168 | if(sigaction(sig, &action, NULL) < 0) |
98 | panic("sigaction failed"); | 169 | panic("sigaction failed - errno = %d\n", errno); |
170 | |||
171 | sigemptyset(&sig_mask); | ||
172 | sigaddset(&sig_mask, sig); | ||
173 | if(sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0) | ||
174 | panic("sigprocmask failed - errno = %d\n", errno); | ||
99 | } | 175 | } |
100 | 176 | ||
101 | int change_sig(int signal, int on) | 177 | int change_sig(int signal, int on) |
@@ -108,91 +184,74 @@ int change_sig(int signal, int on) | |||
108 | return(!sigismember(&old, signal)); | 184 | return(!sigismember(&old, signal)); |
109 | } | 185 | } |
110 | 186 | ||
111 | /* Both here and in set/get_signal we don't touch SIGPROF, because we must not | ||
112 | * disable profiling; it's safe because the profiling code does not interact | ||
113 | * with the kernel code at all.*/ | ||
114 | |||
115 | static void change_signals(int type) | ||
116 | { | ||
117 | sigset_t mask; | ||
118 | |||
119 | sigemptyset(&mask); | ||
120 | sigaddset(&mask, SIGVTALRM); | ||
121 | sigaddset(&mask, SIGALRM); | ||
122 | sigaddset(&mask, SIGIO); | ||
123 | if(sigprocmask(type, &mask, NULL) < 0) | ||
124 | panic("Failed to change signal mask - errno = %d", errno); | ||
125 | } | ||
126 | |||
127 | void block_signals(void) | 187 | void block_signals(void) |
128 | { | 188 | { |
129 | change_signals(SIG_BLOCK); | 189 | signals_enabled = 0; |
130 | } | 190 | } |
131 | 191 | ||
132 | void unblock_signals(void) | 192 | void unblock_signals(void) |
133 | { | 193 | { |
134 | change_signals(SIG_UNBLOCK); | 194 | int save_pending; |
135 | } | ||
136 | 195 | ||
137 | /* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled | 196 | if(signals_enabled == 1) |
138 | * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to | 197 | return; |
139 | * be able to profile all of UML, not just the non-critical sections. If | ||
140 | * profiling is not thread-safe, then that is not my problem. We can disable | ||
141 | * profiling when SMP is enabled in that case. | ||
142 | */ | ||
143 | #define SIGIO_BIT 0 | ||
144 | #define SIGVTALRM_BIT 1 | ||
145 | |||
146 | static int enable_mask(sigset_t *mask) | ||
147 | { | ||
148 | int sigs; | ||
149 | 198 | ||
150 | sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT; | 199 | /* We loop because the IRQ handler returns with interrupts off. So, |
151 | sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT; | 200 | * interrupts may have arrived and we need to re-enable them and |
152 | sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT; | 201 | * recheck pending. |
153 | return(sigs); | 202 | */ |
203 | while(1){ | ||
204 | /* Save and reset save_pending after enabling signals. This | ||
205 | * way, pending won't be changed while we're reading it. | ||
206 | */ | ||
207 | signals_enabled = 1; | ||
208 | |||
209 | save_pending = pending; | ||
210 | if(save_pending == 0) | ||
211 | return; | ||
212 | |||
213 | pending = 0; | ||
214 | |||
215 | /* We have pending interrupts, so disable signals, as the | ||
216 | * handlers expect them off when they are called. They will | ||
217 | * be enabled again above. | ||
218 | */ | ||
219 | |||
220 | signals_enabled = 0; | ||
221 | |||
222 | /* Deal with SIGIO first because the alarm handler might | ||
223 | * schedule, leaving the pending SIGIO stranded until we come | ||
224 | * back here. | ||
225 | */ | ||
226 | if(save_pending & SIGIO_MASK) | ||
227 | CHOOSE_MODE_PROC(sig_handler_common_tt, | ||
228 | sig_handler_common_skas, SIGIO, NULL); | ||
229 | |||
230 | if(save_pending & SIGALRM_MASK) | ||
231 | real_alarm_handler(SIGALRM, NULL); | ||
232 | |||
233 | if(save_pending & SIGVTALRM_MASK) | ||
234 | real_alarm_handler(SIGVTALRM, NULL); | ||
235 | } | ||
154 | } | 236 | } |
155 | 237 | ||
156 | int get_signals(void) | 238 | int get_signals(void) |
157 | { | 239 | { |
158 | sigset_t mask; | 240 | return signals_enabled; |
159 | |||
160 | if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0) | ||
161 | panic("Failed to get signal mask"); | ||
162 | return(enable_mask(&mask)); | ||
163 | } | 241 | } |
164 | 242 | ||
165 | int set_signals(int enable) | 243 | int set_signals(int enable) |
166 | { | 244 | { |
167 | sigset_t mask; | ||
168 | int ret; | 245 | int ret; |
246 | if(signals_enabled == enable) | ||
247 | return enable; | ||
169 | 248 | ||
170 | sigemptyset(&mask); | 249 | ret = signals_enabled; |
171 | if(enable & (1 << SIGIO_BIT)) | 250 | if(enable) |
172 | sigaddset(&mask, SIGIO); | 251 | unblock_signals(); |
173 | if(enable & (1 << SIGVTALRM_BIT)){ | 252 | else block_signals(); |
174 | sigaddset(&mask, SIGVTALRM); | ||
175 | sigaddset(&mask, SIGALRM); | ||
176 | } | ||
177 | |||
178 | /* This is safe - sigprocmask is guaranteed to copy locally the | ||
179 | * value of new_set, do his work and then, at the end, write to | ||
180 | * old_set. | ||
181 | */ | ||
182 | if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0) | ||
183 | panic("Failed to enable signals"); | ||
184 | ret = enable_mask(&mask); | ||
185 | sigemptyset(&mask); | ||
186 | if((enable & (1 << SIGIO_BIT)) == 0) | ||
187 | sigaddset(&mask, SIGIO); | ||
188 | if((enable & (1 << SIGVTALRM_BIT)) == 0){ | ||
189 | sigaddset(&mask, SIGVTALRM); | ||
190 | sigaddset(&mask, SIGALRM); | ||
191 | } | ||
192 | if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0) | ||
193 | panic("Failed to block signals"); | ||
194 | 253 | ||
195 | return(ret); | 254 | return ret; |
196 | } | 255 | } |
197 | 256 | ||
198 | void os_usr1_signal(int on) | 257 | void os_usr1_signal(int on) |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index b959b2618b7f..120a21c5883f 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "mem.h" | 34 | #include "mem.h" |
35 | #include "uml-config.h" | 35 | #include "uml-config.h" |
36 | #include "process.h" | 36 | #include "process.h" |
37 | #include "longjmp.h" | ||
37 | 38 | ||
38 | int is_skas_winch(int pid, int fd, void *data) | 39 | int is_skas_winch(int pid, int fd, void *data) |
39 | { | 40 | { |
@@ -433,6 +434,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
433 | { | 434 | { |
434 | unsigned long flags; | 435 | unsigned long flags; |
435 | sigjmp_buf switch_buf, fork_buf; | 436 | sigjmp_buf switch_buf, fork_buf; |
437 | int enable; | ||
436 | 438 | ||
437 | *switch_buf_ptr = &switch_buf; | 439 | *switch_buf_ptr = &switch_buf; |
438 | *fork_buf_ptr = &fork_buf; | 440 | *fork_buf_ptr = &fork_buf; |
@@ -447,7 +449,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
447 | */ | 449 | */ |
448 | flags = get_signals(); | 450 | flags = get_signals(); |
449 | block_signals(); | 451 | block_signals(); |
450 | if(sigsetjmp(fork_buf, 1) == 0) | 452 | if(UML_SIGSETJMP(&fork_buf, enable) == 0) |
451 | new_thread_proc(stack, handler); | 453 | new_thread_proc(stack, handler); |
452 | 454 | ||
453 | remove_sigstack(); | 455 | remove_sigstack(); |
@@ -458,20 +460,22 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
458 | void thread_wait(void *sw, void *fb) | 460 | void thread_wait(void *sw, void *fb) |
459 | { | 461 | { |
460 | sigjmp_buf buf, **switch_buf = sw, *fork_buf; | 462 | sigjmp_buf buf, **switch_buf = sw, *fork_buf; |
463 | int enable; | ||
461 | 464 | ||
462 | *switch_buf = &buf; | 465 | *switch_buf = &buf; |
463 | fork_buf = fb; | 466 | fork_buf = fb; |
464 | if(sigsetjmp(buf, 1) == 0) | 467 | if(UML_SIGSETJMP(&buf, enable) == 0) |
465 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); | 468 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); |
466 | } | 469 | } |
467 | 470 | ||
468 | void switch_threads(void *me, void *next) | 471 | void switch_threads(void *me, void *next) |
469 | { | 472 | { |
470 | sigjmp_buf my_buf, **me_ptr = me, *next_buf = next; | 473 | sigjmp_buf my_buf, **me_ptr = me, *next_buf = next; |
474 | int enable; | ||
471 | 475 | ||
472 | *me_ptr = &my_buf; | 476 | *me_ptr = &my_buf; |
473 | if(sigsetjmp(my_buf, 1) == 0) | 477 | if(UML_SIGSETJMP(&my_buf, enable) == 0) |
474 | siglongjmp(*next_buf, 1); | 478 | UML_SIGLONGJMP(next_buf, 1); |
475 | } | 479 | } |
476 | 480 | ||
477 | static sigjmp_buf initial_jmpbuf; | 481 | static sigjmp_buf initial_jmpbuf; |
@@ -484,14 +488,14 @@ static sigjmp_buf *cb_back; | |||
484 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | 488 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) |
485 | { | 489 | { |
486 | sigjmp_buf **switch_buf = switch_buf_ptr; | 490 | sigjmp_buf **switch_buf = switch_buf_ptr; |
487 | int n; | 491 | int n, enable; |
488 | 492 | ||
489 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, | 493 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, |
490 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, | 494 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, |
491 | SIGVTALRM, -1); | 495 | SIGVTALRM, -1); |
492 | 496 | ||
493 | *fork_buf_ptr = &initial_jmpbuf; | 497 | *fork_buf_ptr = &initial_jmpbuf; |
494 | n = sigsetjmp(initial_jmpbuf, 1); | 498 | n = UML_SIGSETJMP(&initial_jmpbuf, enable); |
495 | switch(n){ | 499 | switch(n){ |
496 | case INIT_JMP_NEW_THREAD: | 500 | case INIT_JMP_NEW_THREAD: |
497 | new_thread_proc((void *) stack, new_thread_handler); | 501 | new_thread_proc((void *) stack, new_thread_handler); |
@@ -501,7 +505,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
501 | break; | 505 | break; |
502 | case INIT_JMP_CALLBACK: | 506 | case INIT_JMP_CALLBACK: |
503 | (*cb_proc)(cb_arg); | 507 | (*cb_proc)(cb_arg); |
504 | siglongjmp(*cb_back, 1); | 508 | UML_SIGLONGJMP(cb_back, 1); |
505 | break; | 509 | break; |
506 | case INIT_JMP_HALT: | 510 | case INIT_JMP_HALT: |
507 | kmalloc_ok = 0; | 511 | kmalloc_ok = 0; |
@@ -512,20 +516,21 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
512 | default: | 516 | default: |
513 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); | 517 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); |
514 | } | 518 | } |
515 | siglongjmp(**switch_buf, 1); | 519 | UML_SIGLONGJMP(*switch_buf, 1); |
516 | } | 520 | } |
517 | 521 | ||
518 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) | 522 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) |
519 | { | 523 | { |
520 | sigjmp_buf here; | 524 | sigjmp_buf here; |
525 | int enable; | ||
521 | 526 | ||
522 | cb_proc = proc; | 527 | cb_proc = proc; |
523 | cb_arg = arg; | 528 | cb_arg = arg; |
524 | cb_back = &here; | 529 | cb_back = &here; |
525 | 530 | ||
526 | block_signals(); | 531 | block_signals(); |
527 | if(sigsetjmp(here, 1) == 0) | 532 | if(UML_SIGSETJMP(&here, enable) == 0) |
528 | siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK); | 533 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); |
529 | unblock_signals(); | 534 | unblock_signals(); |
530 | 535 | ||
531 | cb_proc = NULL; | 536 | cb_proc = NULL; |
@@ -536,13 +541,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
536 | void halt_skas(void) | 541 | void halt_skas(void) |
537 | { | 542 | { |
538 | block_signals(); | 543 | block_signals(); |
539 | siglongjmp(initial_jmpbuf, INIT_JMP_HALT); | 544 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_HALT); |
540 | } | 545 | } |
541 | 546 | ||
542 | void reboot_skas(void) | 547 | void reboot_skas(void) |
543 | { | 548 | { |
544 | block_signals(); | 549 | block_signals(); |
545 | siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT); | 550 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); |
546 | } | 551 | } |
547 | 552 | ||
548 | void switch_mm_skas(struct mm_id *mm_idp) | 553 | void switch_mm_skas(struct mm_id *mm_idp) |
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c index 321e1c8e227d..a9f6b26f9828 100644 --- a/arch/um/os-Linux/trap.c +++ b/arch/um/os-Linux/trap.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include "user_util.h" | 10 | #include "user_util.h" |
11 | #include "os.h" | 11 | #include "os.h" |
12 | #include "mode.h" | 12 | #include "mode.h" |
13 | #include "longjmp.h" | ||
13 | 14 | ||
14 | void usr2_handler(int sig, union uml_pt_regs *regs) | 15 | void usr2_handler(int sig, union uml_pt_regs *regs) |
15 | { | 16 | { |
@@ -36,5 +37,5 @@ void do_longjmp(void *b, int val) | |||
36 | { | 37 | { |
37 | sigjmp_buf *buf = b; | 38 | sigjmp_buf *buf = b; |
38 | 39 | ||
39 | siglongjmp(*buf, val); | 40 | UML_SIGLONGJMP(buf, val); |
40 | } | 41 | } |
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c index 38d710158c3d..166fb66995df 100644 --- a/arch/um/os-Linux/uaccess.c +++ b/arch/um/os-Linux/uaccess.c | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | #include <setjmp.h> | 7 | #include <setjmp.h> |
8 | #include <string.h> | 8 | #include <string.h> |
9 | #include "longjmp.h" | ||
9 | 10 | ||
10 | unsigned long __do_user_copy(void *to, const void *from, int n, | 11 | unsigned long __do_user_copy(void *to, const void *from, int n, |
11 | void **fault_addr, void **fault_catcher, | 12 | void **fault_addr, void **fault_catcher, |
@@ -13,10 +14,11 @@ unsigned long __do_user_copy(void *to, const void *from, int n, | |||
13 | int n), int *faulted_out) | 14 | int n), int *faulted_out) |
14 | { | 15 | { |
15 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; | 16 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; |
17 | int enable; | ||
16 | 18 | ||
17 | sigjmp_buf jbuf; | 19 | sigjmp_buf jbuf; |
18 | *fault_catcher = &jbuf; | 20 | *fault_catcher = &jbuf; |
19 | if(sigsetjmp(jbuf, 1) == 0){ | 21 | if(UML_SIGSETJMP(&jbuf, enable) == 0){ |
20 | (*op)(to, from, n); | 22 | (*op)(to, from, n); |
21 | ret = 0; | 23 | ret = 0; |
22 | *faulted_out = 0; | 24 | *faulted_out = 0; |
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index d224434d5610..e32065e2fdc8 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "ptrace_user.h" | 30 | #include "ptrace_user.h" |
31 | #include "uml-config.h" | 31 | #include "uml-config.h" |
32 | #include "os.h" | 32 | #include "os.h" |
33 | #include "longjmp.h" | ||
33 | 34 | ||
34 | void stack_protections(unsigned long address) | 35 | void stack_protections(unsigned long address) |
35 | { | 36 | { |