aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel/skas/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel/skas/process.c')
-rw-r--r--arch/um/kernel/skas/process.c68
1 files changed, 46 insertions, 22 deletions
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index b4ffaaa81241..773cd2b525fc 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include <stdlib.h> 6#include <stdlib.h>
7#include <string.h>
7#include <unistd.h> 8#include <unistd.h>
8#include <errno.h> 9#include <errno.h>
9#include <signal.h> 10#include <signal.h>
@@ -27,27 +28,37 @@
27#include "chan_user.h" 28#include "chan_user.h"
28#include "signal_user.h" 29#include "signal_user.h"
29#include "registers.h" 30#include "registers.h"
31#include "process.h"
30 32
31int is_skas_winch(int pid, int fd, void *data) 33int is_skas_winch(int pid, int fd, void *data)
32{ 34{
33 if(pid != os_getpid()) 35 if(pid != os_getpgrp())
34 return(0); 36 return(0);
35 37
36 register_winch_irq(-1, fd, -1, data); 38 register_winch_irq(-1, fd, -1, data);
37 return(1); 39 return(1);
38} 40}
39 41
40static void handle_segv(int pid) 42void get_skas_faultinfo(int pid, struct faultinfo * fi)
41{ 43{
42 struct ptrace_faultinfo fault;
43 int err; 44 int err;
44 45
45 err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault); 46 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
46 if(err) 47 if(err)
47 panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n", 48 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
48 errno); 49 "errno = %d\n", errno);
50
51 /* Special handling for i386, which has different structs */
52 if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
53 memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
54 sizeof(struct faultinfo) -
55 sizeof(struct ptrace_faultinfo));
56}
49 57
50 segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL); 58static void handle_segv(int pid, union uml_pt_regs * regs)
59{
60 get_skas_faultinfo(pid, &regs->skas.faultinfo);
61 segv(regs->skas.faultinfo, 0, 1, NULL);
51} 62}
52 63
53/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ 64/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
@@ -163,7 +174,7 @@ void userspace(union uml_pt_regs *regs)
163 if(WIFSTOPPED(status)){ 174 if(WIFSTOPPED(status)){
164 switch(WSTOPSIG(status)){ 175 switch(WSTOPSIG(status)){
165 case SIGSEGV: 176 case SIGSEGV:
166 handle_segv(pid); 177 handle_segv(pid, regs);
167 break; 178 break;
168 case SIGTRAP + 0x80: 179 case SIGTRAP + 0x80:
169 handle_trap(pid, regs, local_using_sysemu); 180 handle_trap(pid, regs, local_using_sysemu);
@@ -177,7 +188,7 @@ void userspace(union uml_pt_regs *regs)
177 case SIGBUS: 188 case SIGBUS:
178 case SIGFPE: 189 case SIGFPE:
179 case SIGWINCH: 190 case SIGWINCH:
180 user_signal(WSTOPSIG(status), regs); 191 user_signal(WSTOPSIG(status), regs, pid);
181 break; 192 break;
182 default: 193 default:
183 printk("userspace - child stopped with signal " 194 printk("userspace - child stopped with signal "
@@ -190,6 +201,11 @@ void userspace(union uml_pt_regs *regs)
190 } 201 }
191 } 202 }
192} 203}
204#define INIT_JMP_NEW_THREAD 0
205#define INIT_JMP_REMOVE_SIGSTACK 1
206#define INIT_JMP_CALLBACK 2
207#define INIT_JMP_HALT 3
208#define INIT_JMP_REBOOT 4
193 209
194void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, 210void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
195 void (*handler)(int)) 211 void (*handler)(int))
@@ -225,7 +241,7 @@ void thread_wait(void *sw, void *fb)
225 *switch_buf = &buf; 241 *switch_buf = &buf;
226 fork_buf = fb; 242 fork_buf = fb;
227 if(sigsetjmp(buf, 1) == 0) 243 if(sigsetjmp(buf, 1) == 0)
228 siglongjmp(*fork_buf, 1); 244 siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
229} 245}
230 246
231void switch_threads(void *me, void *next) 247void switch_threads(void *me, void *next)
@@ -249,23 +265,31 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
249 sigjmp_buf **switch_buf = switch_buf_ptr; 265 sigjmp_buf **switch_buf = switch_buf_ptr;
250 int n; 266 int n;
251 267
268 set_handler(SIGWINCH, (__sighandler_t) sig_handler,
269 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
270 SIGVTALRM, -1);
271
252 *fork_buf_ptr = &initial_jmpbuf; 272 *fork_buf_ptr = &initial_jmpbuf;
253 n = sigsetjmp(initial_jmpbuf, 1); 273 n = sigsetjmp(initial_jmpbuf, 1);
254 if(n == 0) 274 switch(n){
255 new_thread_proc((void *) stack, new_thread_handler); 275 case INIT_JMP_NEW_THREAD:
256 else if(n == 1) 276 new_thread_proc((void *) stack, new_thread_handler);
257 remove_sigstack(); 277 break;
258 else if(n == 2){ 278 case INIT_JMP_REMOVE_SIGSTACK:
279 remove_sigstack();
280 break;
281 case INIT_JMP_CALLBACK:
259 (*cb_proc)(cb_arg); 282 (*cb_proc)(cb_arg);
260 siglongjmp(*cb_back, 1); 283 siglongjmp(*cb_back, 1);
261 } 284 break;
262 else if(n == 3){ 285 case INIT_JMP_HALT:
263 kmalloc_ok = 0; 286 kmalloc_ok = 0;
264 return(0); 287 return(0);
265 } 288 case INIT_JMP_REBOOT:
266 else if(n == 4){
267 kmalloc_ok = 0; 289 kmalloc_ok = 0;
268 return(1); 290 return(1);
291 default:
292 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
269 } 293 }
270 siglongjmp(**switch_buf, 1); 294 siglongjmp(**switch_buf, 1);
271} 295}
@@ -290,7 +314,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
290 314
291 block_signals(); 315 block_signals();
292 if(sigsetjmp(here, 1) == 0) 316 if(sigsetjmp(here, 1) == 0)
293 siglongjmp(initial_jmpbuf, 2); 317 siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK);
294 unblock_signals(); 318 unblock_signals();
295 319
296 cb_proc = NULL; 320 cb_proc = NULL;
@@ -301,13 +325,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
301void halt_skas(void) 325void halt_skas(void)
302{ 326{
303 block_signals(); 327 block_signals();
304 siglongjmp(initial_jmpbuf, 3); 328 siglongjmp(initial_jmpbuf, INIT_JMP_HALT);
305} 329}
306 330
307void reboot_skas(void) 331void reboot_skas(void)
308{ 332{
309 block_signals(); 333 block_signals();
310 siglongjmp(initial_jmpbuf, 4); 334 siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
311} 335}
312 336
313void switch_mm_skas(int mm_fd) 337void switch_mm_skas(int mm_fd)