aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/skas/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/skas/process.c')
-rw-r--r--arch/um/os-Linux/skas/process.c316
1 files changed, 168 insertions, 148 deletions
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index ba9af8d62055..d77c81d7068a 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -1,48 +1,38 @@
1/* 1/*
2 * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2002- 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdlib.h> 6#include <stdlib.h>
7#include <string.h>
8#include <unistd.h> 7#include <unistd.h>
9#include <errno.h>
10#include <signal.h>
11#include <sched.h> 8#include <sched.h>
12#include "ptrace_user.h" 9#include <errno.h>
13#include <sys/wait.h> 10#include <string.h>
14#include <sys/mman.h> 11#include <sys/mman.h>
15#include <sys/user.h> 12#include <sys/ptrace.h>
16#include <sys/time.h> 13#include <sys/wait.h>
17#include <sys/syscall.h> 14#include <asm/unistd.h>
18#include <asm/types.h> 15#include "as-layout.h"
19#include "user.h"
20#include "sysdep/ptrace.h"
21#include "kern_util.h"
22#include "skas.h"
23#include "stub-data.h"
24#include "mm_id.h"
25#include "sysdep/sigcontext.h"
26#include "sysdep/stub.h"
27#include "os.h"
28#include "proc_mm.h"
29#include "skas_ptrace.h"
30#include "chan_user.h" 16#include "chan_user.h"
31#include "registers.h" 17#include "kern_constants.h"
32#include "mem.h" 18#include "mem.h"
33#include "uml-config.h" 19#include "os.h"
34#include "process.h" 20#include "process.h"
35#include "longjmp.h" 21#include "proc_mm.h"
36#include "kern_constants.h" 22#include "ptrace_user.h"
37#include "as-layout.h" 23#include "registers.h"
24#include "skas.h"
25#include "skas_ptrace.h"
26#include "user.h"
27#include "sysdep/stub.h"
38 28
39int is_skas_winch(int pid, int fd, void *data) 29int is_skas_winch(int pid, int fd, void *data)
40{ 30{
41 if(pid != os_getpgrp()) 31 if (pid != getpgrp())
42 return(0); 32 return 0;
43 33
44 register_winch_irq(-1, fd, -1, data, 0); 34 register_winch_irq(-1, fd, -1, data, 0);
45 return(1); 35 return 1;
46} 36}
47 37
48static int ptrace_dump_regs(int pid) 38static int ptrace_dump_regs(int pid)
@@ -50,13 +40,12 @@ static int ptrace_dump_regs(int pid)
50 unsigned long regs[MAX_REG_NR]; 40 unsigned long regs[MAX_REG_NR];
51 int i; 41 int i;
52 42
53 if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) 43 if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
54 return -errno; 44 return -errno;
55 else { 45
56 printk("Stub registers -\n"); 46 printk(UM_KERN_ERR "Stub registers -\n");
57 for(i = 0; i < ARRAY_SIZE(regs); i++) 47 for (i = 0; i < ARRAY_SIZE(regs); i++)
58 printk("\t%d - %lx\n", i, regs[i]); 48 printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]);
59 }
60 49
61 return 0; 50 return 0;
62} 51}
@@ -74,27 +63,28 @@ void wait_stub_done(int pid)
74{ 63{
75 int n, status, err; 64 int n, status, err;
76 65
77 while(1){ 66 while (1) {
78 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 67 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
79 if((n < 0) || !WIFSTOPPED(status)) 68 if ((n < 0) || !WIFSTOPPED(status))
80 goto bad_wait; 69 goto bad_wait;
81 70
82 if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0) 71 if (((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0)
83 break; 72 break;
84 73
85 err = ptrace(PTRACE_CONT, pid, 0, 0); 74 err = ptrace(PTRACE_CONT, pid, 0, 0);
86 if(err) 75 if (err)
87 panic("wait_stub_done : continue failed, errno = %d\n", 76 panic("wait_stub_done : continue failed, errno = %d\n",
88 errno); 77 errno);
89 } 78 }
90 79
91 if(((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) 80 if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
92 return; 81 return;
93 82
94bad_wait: 83bad_wait:
95 err = ptrace_dump_regs(pid); 84 err = ptrace_dump_regs(pid);
96 if(err) 85 if (err)
97 printk("Failed to get registers from stub, errno = %d\n", -err); 86 printk(UM_KERN_ERR "Failed to get registers from stub, "
87 "errno = %d\n", -err);
98 panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, " 88 panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, "
99 "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status); 89 "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status);
100} 90}
@@ -105,9 +95,9 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
105{ 95{
106 int err; 96 int err;
107 97
108 if(ptrace_faultinfo){ 98 if (ptrace_faultinfo) {
109 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); 99 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
110 if(err) 100 if (err)
111 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " 101 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
112 "errno = %d\n", errno); 102 "errno = %d\n", errno);
113 103
@@ -119,52 +109,57 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
119 } 109 }
120 else { 110 else {
121 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); 111 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
122 if(err) 112 if (err)
123 panic("Failed to continue stub, pid = %d, errno = %d\n", 113 panic("Failed to continue stub, pid = %d, errno = %d\n",
124 pid, errno); 114 pid, errno);
125 wait_stub_done(pid); 115 wait_stub_done(pid);
126 116
127 /* faultinfo is prepared by the stub-segv-handler at start of 117 /*
118 * faultinfo is prepared by the stub-segv-handler at start of
128 * the stub stack page. We just have to copy it. 119 * the stub stack page. We just have to copy it.
129 */ 120 */
130 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); 121 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
131 } 122 }
132} 123}
133 124
134static void handle_segv(int pid, union uml_pt_regs * regs) 125static void handle_segv(int pid, struct uml_pt_regs * regs)
135{ 126{
136 get_skas_faultinfo(pid, &regs->skas.faultinfo); 127 get_skas_faultinfo(pid, &regs->faultinfo);
137 segv(regs->skas.faultinfo, 0, 1, NULL); 128 segv(regs->faultinfo, 0, 1, NULL);
138} 129}
139 130
140/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ 131/*
141static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu) 132 * To use the same value of using_sysemu as the caller, ask it that value
133 * (in local_using_sysemu
134 */
135static void handle_trap(int pid, struct uml_pt_regs *regs,
136 int local_using_sysemu)
142{ 137{
143 int err, status; 138 int err, status;
144 139
145 /* Mark this as a syscall */ 140 /* Mark this as a syscall */
146 UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs); 141 UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp);
147 142
148 if (!local_using_sysemu) 143 if (!local_using_sysemu)
149 { 144 {
150 err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, 145 err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
151 __NR_getpid); 146 __NR_getpid);
152 if(err < 0) 147 if (err < 0)
153 panic("handle_trap - nullifying syscall failed errno = %d\n", 148 panic("handle_trap - nullifying syscall failed, "
154 errno); 149 "errno = %d\n", errno);
155 150
156 err = ptrace(PTRACE_SYSCALL, pid, 0, 0); 151 err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
157 if(err < 0) 152 if (err < 0)
158 panic("handle_trap - continuing to end of syscall failed, " 153 panic("handle_trap - continuing to end of syscall "
159 "errno = %d\n", errno); 154 "failed, errno = %d\n", errno);
160 155
161 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); 156 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
162 if((err < 0) || !WIFSTOPPED(status) || 157 if ((err < 0) || !WIFSTOPPED(status) ||
163 (WSTOPSIG(status) != SIGTRAP + 0x80)){ 158 (WSTOPSIG(status) != SIGTRAP + 0x80)) {
164 err = ptrace_dump_regs(pid); 159 err = ptrace_dump_regs(pid);
165 if(err) 160 if (err)
166 printk("Failed to get registers from process, " 161 printk(UM_KERN_ERR "Failed to get registers "
167 "errno = %d\n", -err); 162 "from process, errno = %d\n", -err);
168 panic("handle_trap - failed to wait at end of syscall, " 163 panic("handle_trap - failed to wait at end of syscall, "
169 "errno = %d, status = %d\n", errno, status); 164 "errno = %d, status = %d\n", errno, status);
170 } 165 }
@@ -182,63 +177,64 @@ static int userspace_tramp(void *stack)
182 177
183 ptrace(PTRACE_TRACEME, 0, 0, 0); 178 ptrace(PTRACE_TRACEME, 0, 0, 0);
184 179
185 init_new_thread_signals(); 180 signal(SIGTERM, SIG_DFL);
186 err = set_interval(1); 181 err = set_interval();
187 if(err) 182 if (err)
188 panic("userspace_tramp - setting timer failed, errno = %d\n", 183 panic("userspace_tramp - setting timer failed, errno = %d\n",
189 err); 184 err);
190 185
191 if(!proc_mm){ 186 if (!proc_mm) {
192 /* This has a pte, but it can't be mapped in with the usual 187 /*
188 * This has a pte, but it can't be mapped in with the usual
193 * tlb_flush mechanism because this is part of that mechanism 189 * tlb_flush mechanism because this is part of that mechanism
194 */ 190 */
195 int fd; 191 int fd;
196 __u64 offset; 192 unsigned long long offset;
197 fd = phys_mapping(to_phys(&__syscall_stub_start), &offset); 193 fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
198 addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE, 194 addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE,
199 PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); 195 PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
200 if(addr == MAP_FAILED){ 196 if (addr == MAP_FAILED) {
201 printk("mapping mmap stub failed, errno = %d\n", 197 printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, "
202 errno); 198 "errno = %d\n", STUB_CODE, errno);
203 exit(1); 199 exit(1);
204 } 200 }
205 201
206 if(stack != NULL){ 202 if (stack != NULL) {
207 fd = phys_mapping(to_phys(stack), &offset); 203 fd = phys_mapping(to_phys(stack), &offset);
208 addr = mmap((void *) UML_CONFIG_STUB_DATA, 204 addr = mmap((void *) STUB_DATA,
209 UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, 205 UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
210 MAP_FIXED | MAP_SHARED, fd, offset); 206 MAP_FIXED | MAP_SHARED, fd, offset);
211 if(addr == MAP_FAILED){ 207 if (addr == MAP_FAILED) {
212 printk("mapping segfault stack failed, " 208 printk(UM_KERN_ERR "mapping segfault stack "
213 "errno = %d\n", errno); 209 "at 0x%lx failed, errno = %d\n",
210 STUB_DATA, errno);
214 exit(1); 211 exit(1);
215 } 212 }
216 } 213 }
217 } 214 }
218 if(!ptrace_faultinfo && (stack != NULL)){ 215 if (!ptrace_faultinfo && (stack != NULL)) {
219 struct sigaction sa; 216 struct sigaction sa;
220 217
221 unsigned long v = UML_CONFIG_STUB_CODE + 218 unsigned long v = STUB_CODE +
222 (unsigned long) stub_segv_handler - 219 (unsigned long) stub_segv_handler -
223 (unsigned long) &__syscall_stub_start; 220 (unsigned long) &__syscall_stub_start;
224 221
225 set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE); 222 set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
226 sigemptyset(&sa.sa_mask); 223 sigemptyset(&sa.sa_mask);
227 sigaddset(&sa.sa_mask, SIGIO); 224 sigaddset(&sa.sa_mask, SIGIO);
228 sigaddset(&sa.sa_mask, SIGWINCH); 225 sigaddset(&sa.sa_mask, SIGWINCH);
229 sigaddset(&sa.sa_mask, SIGALRM);
230 sigaddset(&sa.sa_mask, SIGVTALRM); 226 sigaddset(&sa.sa_mask, SIGVTALRM);
231 sigaddset(&sa.sa_mask, SIGUSR1); 227 sigaddset(&sa.sa_mask, SIGUSR1);
232 sa.sa_flags = SA_ONSTACK; 228 sa.sa_flags = SA_ONSTACK;
233 sa.sa_handler = (void *) v; 229 sa.sa_handler = (void *) v;
234 sa.sa_restorer = NULL; 230 sa.sa_restorer = NULL;
235 if(sigaction(SIGSEGV, &sa, NULL) < 0) 231 if (sigaction(SIGSEGV, &sa, NULL) < 0)
236 panic("userspace_tramp - setting SIGSEGV handler " 232 panic("userspace_tramp - setting SIGSEGV handler "
237 "failed - errno = %d\n", errno); 233 "failed - errno = %d\n", errno);
238 } 234 }
239 235
240 os_stop_process(os_getpid()); 236 kill(os_getpid(), SIGSTOP);
241 return(0); 237 return 0;
242} 238}
243 239
244/* Each element set once, and only accessed by a single processor anyway */ 240/* Each element set once, and only accessed by a single processor anyway */
@@ -255,44 +251,55 @@ int start_userspace(unsigned long stub_stack)
255 stack = mmap(NULL, UM_KERN_PAGE_SIZE, 251 stack = mmap(NULL, UM_KERN_PAGE_SIZE,
256 PROT_READ | PROT_WRITE | PROT_EXEC, 252 PROT_READ | PROT_WRITE | PROT_EXEC,
257 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 253 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
258 if(stack == MAP_FAILED) 254 if (stack == MAP_FAILED)
259 panic("start_userspace : mmap failed, errno = %d", errno); 255 panic("start_userspace : mmap failed, errno = %d", errno);
260 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); 256 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
261 257
262 flags = CLONE_FILES | SIGCHLD; 258 flags = CLONE_FILES | SIGCHLD;
263 if(proc_mm) flags |= CLONE_VM; 259 if (proc_mm)
260 flags |= CLONE_VM;
261
264 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); 262 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
265 if(pid < 0) 263 if (pid < 0)
266 panic("start_userspace : clone failed, errno = %d", errno); 264 panic("start_userspace : clone failed, errno = %d", errno);
267 265
268 do { 266 do {
269 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 267 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
270 if(n < 0) 268 if (n < 0)
271 panic("start_userspace : wait failed, errno = %d", 269 panic("start_userspace : wait failed, errno = %d",
272 errno); 270 errno);
273 } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM)); 271 } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
274 272
275 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) 273 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
276 panic("start_userspace : expected SIGSTOP, got status = %d", 274 panic("start_userspace : expected SIGSTOP, got status = %d",
277 status); 275 status);
278 276
279 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0) 277 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
280 panic("start_userspace : PTRACE_OLDSETOPTIONS failed, errno=%d\n", 278 (void *) PTRACE_O_TRACESYSGOOD) < 0)
281 errno); 279 panic("start_userspace : PTRACE_OLDSETOPTIONS failed, "
280 "errno = %d\n", errno);
282 281
283 if(munmap(stack, UM_KERN_PAGE_SIZE) < 0) 282 if (munmap(stack, UM_KERN_PAGE_SIZE) < 0)
284 panic("start_userspace : munmap failed, errno = %d\n", errno); 283 panic("start_userspace : munmap failed, errno = %d\n", errno);
285 284
286 return(pid); 285 return pid;
287} 286}
288 287
289void userspace(union uml_pt_regs *regs) 288void userspace(struct uml_pt_regs *regs)
290{ 289{
290 struct itimerval timer;
291 unsigned long long nsecs, now;
291 int err, status, op, pid = userspace_pid[0]; 292 int err, status, op, pid = userspace_pid[0];
292 /* To prevent races if using_sysemu changes under us.*/ 293 /* To prevent races if using_sysemu changes under us.*/
293 int local_using_sysemu; 294 int local_using_sysemu;
294 295
295 while(1){ 296 if (getitimer(ITIMER_VIRTUAL, &timer))
297 printk("Failed to get itimer, errno = %d\n", errno);
298 nsecs = timer.it_value.tv_sec * UM_NSEC_PER_SEC +
299 timer.it_value.tv_usec * UM_NSEC_PER_USEC;
300 nsecs += os_nsecs();
301
302 while (1) {
296 restore_registers(pid, regs); 303 restore_registers(pid, regs);
297 304
298 /* Now we set local_using_sysemu to be used for one loop */ 305 /* Now we set local_using_sysemu to be used for one loop */
@@ -302,26 +309,28 @@ void userspace(union uml_pt_regs *regs)
302 singlestepping(NULL)); 309 singlestepping(NULL));
303 310
304 err = ptrace(op, pid, 0, 0); 311 err = ptrace(op, pid, 0, 0);
305 if(err) 312 if (err)
306 panic("userspace - could not resume userspace process, " 313 panic("userspace - could not resume userspace process, "
307 "pid=%d, ptrace operation = %d, errno = %d\n", 314 "pid=%d, ptrace operation = %d, errno = %d\n",
308 pid, op, errno); 315 pid, op, errno);
309 316
310 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); 317 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
311 if(err < 0) 318 if (err < 0)
312 panic("userspace - waitpid failed, errno = %d\n", 319 panic("userspace - waitpid failed, errno = %d\n",
313 errno); 320 errno);
314 321
315 regs->skas.is_user = 1; 322 regs->is_user = 1;
316 save_registers(pid, regs); 323 save_registers(pid, regs);
317 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ 324 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
318 325
319 if(WIFSTOPPED(status)){ 326 if (WIFSTOPPED(status)) {
320 int sig = WSTOPSIG(status); 327 int sig = WSTOPSIG(status);
321 switch(sig){ 328 switch(sig) {
322 case SIGSEGV: 329 case SIGSEGV:
323 if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){ 330 if (PTRACE_FULL_FAULTINFO ||
324 get_skas_faultinfo(pid, &regs->skas.faultinfo); 331 !ptrace_faultinfo) {
332 get_skas_faultinfo(pid,
333 &regs->faultinfo);
325 (*sig_info[SIGSEGV])(SIGSEGV, regs); 334 (*sig_info[SIGSEGV])(SIGSEGV, regs);
326 } 335 }
327 else handle_segv(pid, regs); 336 else handle_segv(pid, regs);
@@ -332,8 +341,20 @@ void userspace(union uml_pt_regs *regs)
332 case SIGTRAP: 341 case SIGTRAP:
333 relay_signal(SIGTRAP, regs); 342 relay_signal(SIGTRAP, regs);
334 break; 343 break;
335 case SIGIO:
336 case SIGVTALRM: 344 case SIGVTALRM:
345 now = os_nsecs();
346 if(now < nsecs)
347 break;
348 block_signals();
349 (*sig_info[sig])(sig, regs);
350 unblock_signals();
351 nsecs = timer.it_value.tv_sec *
352 UM_NSEC_PER_SEC +
353 timer.it_value.tv_usec *
354 UM_NSEC_PER_USEC;
355 nsecs += os_nsecs();
356 break;
357 case SIGIO:
337 case SIGILL: 358 case SIGILL:
338 case SIGBUS: 359 case SIGBUS:
339 case SIGFPE: 360 case SIGFPE:
@@ -343,30 +364,29 @@ void userspace(union uml_pt_regs *regs)
343 unblock_signals(); 364 unblock_signals();
344 break; 365 break;
345 default: 366 default:
346 printk("userspace - child stopped with signal " 367 printk(UM_KERN_ERR "userspace - child stopped "
347 "%d\n", sig); 368 "with signal %d\n", sig);
348 } 369 }
349 pid = userspace_pid[0]; 370 pid = userspace_pid[0];
350 interrupt_end(); 371 interrupt_end();
351 372
352 /* Avoid -ERESTARTSYS handling in host */ 373 /* Avoid -ERESTARTSYS handling in host */
353 if(PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET) 374 if (PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET)
354 PT_SYSCALL_NR(regs->skas.regs) = -1; 375 PT_SYSCALL_NR(regs->gp) = -1;
355 } 376 }
356 } 377 }
357} 378}
358 379
359static unsigned long thread_regs[MAX_REG_NR]; 380static unsigned long thread_regs[MAX_REG_NR];
360static unsigned long thread_fp_regs[HOST_FP_SIZE];
361 381
362static int __init init_thread_regs(void) 382static int __init init_thread_regs(void)
363{ 383{
364 get_safe_registers(thread_regs, thread_fp_regs); 384 get_safe_registers(thread_regs);
365 /* Set parent's instruction pointer to start of clone-stub */ 385 /* Set parent's instruction pointer to start of clone-stub */
366 thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + 386 thread_regs[REGS_IP_INDEX] = STUB_CODE +
367 (unsigned long) stub_clone_handler - 387 (unsigned long) stub_clone_handler -
368 (unsigned long) &__syscall_stub_start; 388 (unsigned long) &__syscall_stub_start;
369 thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + UM_KERN_PAGE_SIZE - 389 thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE -
370 sizeof(void *); 390 sizeof(void *);
371#ifdef __SIGNAL_FRAMESIZE 391#ifdef __SIGNAL_FRAMESIZE
372 thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE; 392 thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
@@ -378,53 +398,53 @@ __initcall(init_thread_regs);
378 398
379int copy_context_skas0(unsigned long new_stack, int pid) 399int copy_context_skas0(unsigned long new_stack, int pid)
380{ 400{
401 struct timeval tv = { .tv_sec = 0, .tv_usec = UM_USEC_PER_SEC / UM_HZ };
381 int err; 402 int err;
382 unsigned long current_stack = current_stub_stack(); 403 unsigned long current_stack = current_stub_stack();
383 struct stub_data *data = (struct stub_data *) current_stack; 404 struct stub_data *data = (struct stub_data *) current_stack;
384 struct stub_data *child_data = (struct stub_data *) new_stack; 405 struct stub_data *child_data = (struct stub_data *) new_stack;
385 __u64 new_offset; 406 unsigned long long new_offset;
386 int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset); 407 int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
387 408
388 /* prepare offset and fd of child's stack as argument for parent's 409 /*
410 * prepare offset and fd of child's stack as argument for parent's
389 * and child's mmap2 calls 411 * and child's mmap2 calls
390 */ 412 */
391 *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset), 413 *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset),
392 .fd = new_fd, 414 .fd = new_fd,
393 .timer = ((struct itimerval) 415 .timer = ((struct itimerval)
394 { { 0, 1000000 / hz() }, 416 { .it_value = tv,
395 { 0, 1000000 / hz() }})}); 417 .it_interval = tv }) });
418
396 err = ptrace_setregs(pid, thread_regs); 419 err = ptrace_setregs(pid, thread_regs);
397 if(err < 0) 420 if (err < 0)
398 panic("copy_context_skas0 : PTRACE_SETREGS failed, " 421 panic("copy_context_skas0 : PTRACE_SETREGS failed, "
399 "pid = %d, errno = %d\n", pid, -err); 422 "pid = %d, errno = %d\n", pid, -err);
400 423
401 err = ptrace_setfpregs(pid, thread_fp_regs);
402 if(err < 0)
403 panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
404 "pid = %d, errno = %d\n", pid, -err);
405
406 /* set a well known return code for detection of child write failure */ 424 /* set a well known return code for detection of child write failure */
407 child_data->err = 12345678; 425 child_data->err = 12345678;
408 426
409 /* Wait, until parent has finished its work: read child's pid from 427 /*
428 * Wait, until parent has finished its work: read child's pid from
410 * parent's stack, and check, if bad result. 429 * parent's stack, and check, if bad result.
411 */ 430 */
412 err = ptrace(PTRACE_CONT, pid, 0, 0); 431 err = ptrace(PTRACE_CONT, pid, 0, 0);
413 if(err) 432 if (err)
414 panic("Failed to continue new process, pid = %d, " 433 panic("Failed to continue new process, pid = %d, "
415 "errno = %d\n", pid, errno); 434 "errno = %d\n", pid, errno);
416 wait_stub_done(pid); 435 wait_stub_done(pid);
417 436
418 pid = data->err; 437 pid = data->err;
419 if(pid < 0) 438 if (pid < 0)
420 panic("copy_context_skas0 - stub-parent reports error %d\n", 439 panic("copy_context_skas0 - stub-parent reports error %d\n",
421 -pid); 440 -pid);
422 441
423 /* Wait, until child has finished too: read child's result from 442 /*
443 * Wait, until child has finished too: read child's result from
424 * child's stack and check it. 444 * child's stack and check it.
425 */ 445 */
426 wait_stub_done(pid); 446 wait_stub_done(pid);
427 if (child_data->err != UML_CONFIG_STUB_DATA) 447 if (child_data->err != STUB_DATA)
428 panic("copy_context_skas0 - stub-child reports error %ld\n", 448 panic("copy_context_skas0 - stub-child reports error %ld\n",
429 child_data->err); 449 child_data->err);
430 450
@@ -446,7 +466,7 @@ void map_stub_pages(int fd, unsigned long code,
446{ 466{
447 struct proc_mm_op mmop; 467 struct proc_mm_op mmop;
448 int n; 468 int n;
449 __u64 code_offset; 469 unsigned long long code_offset;
450 int code_fd = phys_mapping(to_phys((void *) &__syscall_stub_start), 470 int code_fd = phys_mapping(to_phys((void *) &__syscall_stub_start),
451 &code_offset); 471 &code_offset);
452 472
@@ -461,16 +481,17 @@ void map_stub_pages(int fd, unsigned long code,
461 .offset = code_offset 481 .offset = code_offset
462 } } }); 482 } } });
463 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); 483 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
464 if(n != sizeof(mmop)){ 484 if (n != sizeof(mmop)) {
465 n = errno; 485 n = errno;
466 printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n", 486 printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, "
467 code, code_fd, (unsigned long long) code_offset); 487 "offset = %llx\n", code, code_fd,
488 (unsigned long long) code_offset);
468 panic("map_stub_pages : /proc/mm map for code failed, " 489 panic("map_stub_pages : /proc/mm map for code failed, "
469 "err = %d\n", n); 490 "err = %d\n", n);
470 } 491 }
471 492
472 if ( stack ) { 493 if (stack) {
473 __u64 map_offset; 494 unsigned long long map_offset;
474 int map_fd = phys_mapping(to_phys((void *)stack), &map_offset); 495 int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);
475 mmop = ((struct proc_mm_op) 496 mmop = ((struct proc_mm_op)
476 { .op = MM_MMAP, 497 { .op = MM_MMAP,
@@ -484,7 +505,7 @@ void map_stub_pages(int fd, unsigned long code,
484 .offset = map_offset 505 .offset = map_offset
485 } } }); 506 } } });
486 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); 507 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
487 if(n != sizeof(mmop)) 508 if (n != sizeof(mmop))
488 panic("map_stub_pages : /proc/mm map for data failed, " 509 panic("map_stub_pages : /proc/mm map for data failed, "
489 "err = %d\n", errno); 510 "err = %d\n", errno);
490 } 511 }
@@ -504,7 +525,7 @@ void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
504 525
505void switch_threads(jmp_buf *me, jmp_buf *you) 526void switch_threads(jmp_buf *me, jmp_buf *you)
506{ 527{
507 if(UML_SETJMP(me) == 0) 528 if (UML_SETJMP(me) == 0)
508 UML_LONGJMP(you, 1); 529 UML_LONGJMP(you, 1);
509} 530}
510 531
@@ -520,8 +541,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
520 int n; 541 int n;
521 542
522 set_handler(SIGWINCH, (__sighandler_t) sig_handler, 543 set_handler(SIGWINCH, (__sighandler_t) sig_handler,
523 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, 544 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGVTALRM, -1);
524 SIGVTALRM, -1);
525 545
526 /* 546 /*
527 * Can't use UML_SETJMP or UML_LONGJMP here because they save 547 * Can't use UML_SETJMP or UML_LONGJMP here because they save
@@ -532,7 +552,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
532 * after returning to the jumper. 552 * after returning to the jumper.
533 */ 553 */
534 n = setjmp(initial_jmpbuf); 554 n = setjmp(initial_jmpbuf);
535 switch(n){ 555 switch(n) {
536 case INIT_JMP_NEW_THREAD: 556 case INIT_JMP_NEW_THREAD:
537 (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler; 557 (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;
538 (*switch_buf)[0].JB_SP = (unsigned long) stack + 558 (*switch_buf)[0].JB_SP = (unsigned long) stack +
@@ -544,10 +564,10 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
544 break; 564 break;
545 case INIT_JMP_HALT: 565 case INIT_JMP_HALT:
546 kmalloc_ok = 0; 566 kmalloc_ok = 0;
547 return(0); 567 return 0;
548 case INIT_JMP_REBOOT: 568 case INIT_JMP_REBOOT:
549 kmalloc_ok = 0; 569 kmalloc_ok = 0;
550 return(1); 570 return 1;
551 default: 571 default:
552 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); 572 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
553 } 573 }
@@ -563,7 +583,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
563 cb_back = &here; 583 cb_back = &here;
564 584
565 block_signals(); 585 block_signals();
566 if(UML_SETJMP(&here) == 0) 586 if (UML_SETJMP(&here) == 0)
567 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); 587 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
568 unblock_signals(); 588 unblock_signals();
569 589
@@ -584,16 +604,16 @@ void reboot_skas(void)
584 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); 604 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT);
585} 605}
586 606
587void switch_mm_skas(struct mm_id *mm_idp) 607void __switch_mm(struct mm_id *mm_idp)
588{ 608{
589 int err; 609 int err;
590 610
591 /* FIXME: need cpu pid in switch_mm_skas */ 611 /* FIXME: need cpu pid in __switch_mm */
592 if(proc_mm){ 612 if (proc_mm) {
593 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, 613 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
594 mm_idp->u.mm_fd); 614 mm_idp->u.mm_fd);
595 if(err) 615 if (err)
596 panic("switch_mm_skas - PTRACE_SWITCH_MM failed, " 616 panic("__switch_mm - PTRACE_SWITCH_MM failed, "
597 "errno = %d\n", errno); 617 "errno = %d\n", errno);
598 } 618 }
599 else userspace_pid[0] = mm_idp->u.pid; 619 else userspace_pid[0] = mm_idp->u.pid;