aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/skas
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/skas')
-rw-r--r--arch/um/os-Linux/skas/mem.c94
-rw-r--r--arch/um/os-Linux/skas/process.c229
-rw-r--r--arch/um/os-Linux/skas/trap.c32
3 files changed, 182 insertions, 173 deletions
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index ae7685710c46..d58d11179bb7 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -1,30 +1,25 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.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 <signal.h> 6#include <stddef.h>
7#include <unistd.h>
7#include <errno.h> 8#include <errno.h>
8#include <string.h> 9#include <string.h>
9#include <unistd.h>
10#include <sys/mman.h> 10#include <sys/mman.h>
11#include <sys/wait.h> 11#include "init.h"
12#include <asm/unistd.h> 12#include "kern_constants.h"
13#include "mem_user.h" 13#include "mm_id.h"
14#include "mem.h"
15#include "skas.h"
16#include "user.h"
17#include "os.h" 14#include "os.h"
18#include "proc_mm.h" 15#include "proc_mm.h"
19#include "ptrace_user.h" 16#include "ptrace_user.h"
20#include "kern_util.h"
21#include "task.h"
22#include "registers.h" 17#include "registers.h"
23#include "uml-config.h" 18#include "skas.h"
19#include "user.h"
24#include "sysdep/ptrace.h" 20#include "sysdep/ptrace.h"
25#include "sysdep/stub.h" 21#include "sysdep/stub.h"
26#include "init.h" 22#include "uml-config.h"
27#include "kern_constants.h"
28 23
29extern unsigned long batch_syscall_stub, __syscall_stub_start; 24extern unsigned long batch_syscall_stub, __syscall_stub_start;
30 25
@@ -33,7 +28,7 @@ extern void wait_stub_done(int pid);
33static inline unsigned long *check_init_stack(struct mm_id * mm_idp, 28static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
34 unsigned long *stack) 29 unsigned long *stack)
35{ 30{
36 if(stack == NULL) { 31 if (stack == NULL) {
37 stack = (unsigned long *) mm_idp->stack + 2; 32 stack = (unsigned long *) mm_idp->stack + 2;
38 *stack = 0; 33 *stack = 0;
39 } 34 }
@@ -67,29 +62,30 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
67 unsigned long * syscall; 62 unsigned long * syscall;
68 int err, pid = mm_idp->u.pid; 63 int err, pid = mm_idp->u.pid;
69 64
70 if(proc_mm) 65 if (proc_mm)
71 /* FIXME: Need to look up userspace_pid by cpu */ 66 /* FIXME: Need to look up userspace_pid by cpu */
72 pid = userspace_pid[0]; 67 pid = userspace_pid[0];
73 68
74 multi_count++; 69 multi_count++;
75 70
76 n = ptrace_setregs(pid, syscall_regs); 71 n = ptrace_setregs(pid, syscall_regs);
77 if(n < 0){ 72 if (n < 0) {
78 printk("Registers - \n"); 73 printk(UM_KERN_ERR "Registers - \n");
79 for(i = 0; i < MAX_REG_NR; i++) 74 for (i = 0; i < MAX_REG_NR; i++)
80 printk("\t%d\t0x%lx\n", i, syscall_regs[i]); 75 printk(UM_KERN_ERR "\t%d\t0x%lx\n", i, syscall_regs[i]);
81 panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", 76 panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
82 -n); 77 -n);
83 } 78 }
84 79
85 err = ptrace(PTRACE_CONT, pid, 0, 0); 80 err = ptrace(PTRACE_CONT, pid, 0, 0);
86 if(err) 81 if (err)
87 panic("Failed to continue stub, pid = %d, errno = %d\n", pid, 82 panic("Failed to continue stub, pid = %d, errno = %d\n", pid,
88 errno); 83 errno);
89 84
90 wait_stub_done(pid); 85 wait_stub_done(pid);
91 86
92 /* When the stub stops, we find the following values on the 87 /*
88 * When the stub stops, we find the following values on the
93 * beginning of the stack: 89 * beginning of the stack:
94 * (long )return_value 90 * (long )return_value
95 * (long )offset to failed sycall-data (0, if no error) 91 * (long )offset to failed sycall-data (0, if no error)
@@ -99,24 +95,25 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
99 if (offset) { 95 if (offset) {
100 data = (unsigned long *)(mm_idp->stack + 96 data = (unsigned long *)(mm_idp->stack +
101 offset - UML_CONFIG_STUB_DATA); 97 offset - UML_CONFIG_STUB_DATA);
102 printk("do_syscall_stub : ret = %ld, offset = %ld, " 98 printk(UM_KERN_ERR "do_syscall_stub : ret = %ld, offset = %ld, "
103 "data = %p\n", ret, offset, data); 99 "data = %p\n", ret, offset, data);
104 syscall = (unsigned long *)((unsigned long)data + data[0]); 100 syscall = (unsigned long *)((unsigned long)data + data[0]);
105 printk("do_syscall_stub: syscall %ld failed, return value = " 101 printk(UM_KERN_ERR "do_syscall_stub: syscall %ld failed, "
106 "0x%lx, expected return value = 0x%lx\n", 102 "return value = 0x%lx, expected return value = 0x%lx\n",
107 syscall[0], ret, syscall[7]); 103 syscall[0], ret, syscall[7]);
108 printk(" syscall parameters: " 104 printk(UM_KERN_ERR " syscall parameters: "
109 "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", 105 "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
110 syscall[1], syscall[2], syscall[3], 106 syscall[1], syscall[2], syscall[3],
111 syscall[4], syscall[5], syscall[6]); 107 syscall[4], syscall[5], syscall[6]);
112 for(n = 1; n < data[0]/sizeof(long); n++) { 108 for (n = 1; n < data[0]/sizeof(long); n++) {
113 if(n == 1) 109 if (n == 1)
114 printk(" additional syscall data:"); 110 printk(UM_KERN_ERR " additional syscall "
115 if(n % 4 == 1) 111 "data:");
116 printk("\n "); 112 if (n % 4 == 1)
113 printk("\n" UM_KERN_ERR " ");
117 printk(" 0x%lx", data[n]); 114 printk(" 0x%lx", data[n]);
118 } 115 }
119 if(n > 1) 116 if (n > 1)
120 printk("\n"); 117 printk("\n");
121 } 118 }
122 else ret = 0; 119 else ret = 0;
@@ -132,7 +129,7 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall,
132{ 129{
133 unsigned long *stack = check_init_stack(mm_idp, *addr); 130 unsigned long *stack = check_init_stack(mm_idp, *addr);
134 131
135 if(done && *addr == NULL) 132 if (done && *addr == NULL)
136 single_count++; 133 single_count++;
137 134
138 *stack += sizeof(long); 135 *stack += sizeof(long);
@@ -149,8 +146,8 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall,
149 *stack = 0; 146 *stack = 0;
150 multi_op_count++; 147 multi_op_count++;
151 148
152 if(!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) < 149 if (!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) <
153 UM_KERN_PAGE_SIZE - 10 * sizeof(long))){ 150 UM_KERN_PAGE_SIZE - 10 * sizeof(long))) {
154 *addr = stack; 151 *addr = stack;
155 return 0; 152 return 0;
156 } 153 }
@@ -165,14 +162,15 @@ long syscall_stub_data(struct mm_id * mm_idp,
165 unsigned long *stack; 162 unsigned long *stack;
166 int ret = 0; 163 int ret = 0;
167 164
168 /* If *addr still is uninitialized, it *must* contain NULL. 165 /*
166 * If *addr still is uninitialized, it *must* contain NULL.
169 * Thus in this case do_syscall_stub correctly won't be called. 167 * Thus in this case do_syscall_stub correctly won't be called.
170 */ 168 */
171 if((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >= 169 if ((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >=
172 UM_KERN_PAGE_SIZE - (10 + data_count) * sizeof(long)) { 170 UM_KERN_PAGE_SIZE - (10 + data_count) * sizeof(long)) {
173 ret = do_syscall_stub(mm_idp, addr); 171 ret = do_syscall_stub(mm_idp, addr);
174 /* in case of error, don't overwrite data on stack */ 172 /* in case of error, don't overwrite data on stack */
175 if(ret) 173 if (ret)
176 return ret; 174 return ret;
177 } 175 }
178 176
@@ -194,7 +192,7 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
194{ 192{
195 int ret; 193 int ret;
196 194
197 if(proc_mm){ 195 if (proc_mm) {
198 struct proc_mm_op map; 196 struct proc_mm_op map;
199 int fd = mm_idp->u.mm_fd; 197 int fd = mm_idp->u.mm_fd;
200 198
@@ -210,9 +208,10 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
210 .offset= offset 208 .offset= offset
211 } } } ); 209 } } } );
212 CATCH_EINTR(ret = write(fd, &map, sizeof(map))); 210 CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
213 if(ret != sizeof(map)){ 211 if (ret != sizeof(map)) {
214 ret = -errno; 212 ret = -errno;
215 printk("map : /proc/mm map failed, err = %d\n", -ret); 213 printk(UM_KERN_ERR "map : /proc/mm map failed, "
214 "err = %d\n", -ret);
216 } 215 }
217 else ret = 0; 216 else ret = 0;
218 } 217 }
@@ -233,7 +232,7 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
233{ 232{
234 int ret; 233 int ret;
235 234
236 if(proc_mm){ 235 if (proc_mm) {
237 struct proc_mm_op unmap; 236 struct proc_mm_op unmap;
238 int fd = mm_idp->u.mm_fd; 237 int fd = mm_idp->u.mm_fd;
239 238
@@ -244,9 +243,10 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
244 (unsigned long) addr, 243 (unsigned long) addr,
245 .len = len } } } ); 244 .len = len } } } );
246 CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap))); 245 CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
247 if(ret != sizeof(unmap)){ 246 if (ret != sizeof(unmap)) {
248 ret = -errno; 247 ret = -errno;
249 printk("unmap - proc_mm write returned %d\n", ret); 248 printk(UM_KERN_ERR "unmap - proc_mm write returned "
249 "%d\n", ret);
250 } 250 }
251 else ret = 0; 251 else ret = 0;
252 } 252 }
@@ -267,7 +267,7 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
267 struct proc_mm_op protect; 267 struct proc_mm_op protect;
268 int ret; 268 int ret;
269 269
270 if(proc_mm){ 270 if (proc_mm) {
271 int fd = mm_idp->u.mm_fd; 271 int fd = mm_idp->u.mm_fd;
272 272
273 protect = ((struct proc_mm_op) { .op = MM_MPROTECT, 273 protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
@@ -279,9 +279,9 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
279 .prot = prot } } } ); 279 .prot = prot } } } );
280 280
281 CATCH_EINTR(ret = write(fd, &protect, sizeof(protect))); 281 CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
282 if(ret != sizeof(protect)){ 282 if (ret != sizeof(protect)) {
283 ret = -errno; 283 ret = -errno;
284 printk("protect failed, err = %d", -ret); 284 printk(UM_KERN_ERR "protect failed, err = %d", -ret);
285 } 285 }
286 else ret = 0; 286 else ret = 0;
287 } 287 }
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index eb027673f357..e12d18cc77da 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 != os_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,12 +109,13 @@ 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));
@@ -137,8 +128,12 @@ static void handle_segv(int pid, struct uml_pt_regs * regs)
137 segv(regs->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, struct 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
@@ -149,22 +144,22 @@ static void handle_trap(int pid, struct uml_pt_regs *regs, int local_using_sysem
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 }
@@ -184,38 +179,39 @@ static int userspace_tramp(void *stack)
184 179
185 init_new_thread_signals(); 180 init_new_thread_signals();
186 err = set_interval(1); 181 err = set_interval(1);
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 *) UML_CONFIG_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 failed, "
202 errno); 198 "errno = %d\n", 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 *) UML_CONFIG_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 "failed, errno = %d\n", errno);
214 exit(1); 210 exit(1);
215 } 211 }
216 } 212 }
217 } 213 }
218 if(!ptrace_faultinfo && (stack != NULL)){ 214 if (!ptrace_faultinfo && (stack != NULL)) {
219 struct sigaction sa; 215 struct sigaction sa;
220 216
221 unsigned long v = UML_CONFIG_STUB_CODE + 217 unsigned long v = UML_CONFIG_STUB_CODE +
@@ -232,13 +228,13 @@ static int userspace_tramp(void *stack)
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 os_stop_process(os_getpid());
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,35 +251,38 @@ 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(struct uml_pt_regs *regs) 288void userspace(struct uml_pt_regs *regs)
@@ -292,7 +291,7 @@ void userspace(struct uml_pt_regs *regs)
292 /* To prevent races if using_sysemu changes under us.*/ 291 /* To prevent races if using_sysemu changes under us.*/
293 int local_using_sysemu; 292 int local_using_sysemu;
294 293
295 while(1){ 294 while (1) {
296 restore_registers(pid, regs); 295 restore_registers(pid, regs);
297 296
298 /* Now we set local_using_sysemu to be used for one loop */ 297 /* Now we set local_using_sysemu to be used for one loop */
@@ -302,13 +301,13 @@ void userspace(struct uml_pt_regs *regs)
302 singlestepping(NULL)); 301 singlestepping(NULL));
303 302
304 err = ptrace(op, pid, 0, 0); 303 err = ptrace(op, pid, 0, 0);
305 if(err) 304 if (err)
306 panic("userspace - could not resume userspace process, " 305 panic("userspace - could not resume userspace process, "
307 "pid=%d, ptrace operation = %d, errno = %d\n", 306 "pid=%d, ptrace operation = %d, errno = %d\n",
308 pid, op, errno); 307 pid, op, errno);
309 308
310 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); 309 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
311 if(err < 0) 310 if (err < 0)
312 panic("userspace - waitpid failed, errno = %d\n", 311 panic("userspace - waitpid failed, errno = %d\n",
313 errno); 312 errno);
314 313
@@ -316,12 +315,14 @@ void userspace(struct uml_pt_regs *regs)
316 save_registers(pid, regs); 315 save_registers(pid, regs);
317 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ 316 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
318 317
319 if(WIFSTOPPED(status)){ 318 if (WIFSTOPPED(status)) {
320 int sig = WSTOPSIG(status); 319 int sig = WSTOPSIG(status);
321 switch(sig){ 320 switch(sig) {
322 case SIGSEGV: 321 case SIGSEGV:
323 if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){ 322 if (PTRACE_FULL_FAULTINFO ||
324 get_skas_faultinfo(pid, &regs->faultinfo); 323 !ptrace_faultinfo) {
324 get_skas_faultinfo(pid,
325 &regs->faultinfo);
325 (*sig_info[SIGSEGV])(SIGSEGV, regs); 326 (*sig_info[SIGSEGV])(SIGSEGV, regs);
326 } 327 }
327 else handle_segv(pid, regs); 328 else handle_segv(pid, regs);
@@ -343,14 +344,14 @@ void userspace(struct uml_pt_regs *regs)
343 unblock_signals(); 344 unblock_signals();
344 break; 345 break;
345 default: 346 default:
346 printk("userspace - child stopped with signal " 347 printk(UM_KERN_ERR "userspace - child stopped "
347 "%d\n", sig); 348 "with signal %d\n", sig);
348 } 349 }
349 pid = userspace_pid[0]; 350 pid = userspace_pid[0];
350 interrupt_end(); 351 interrupt_end();
351 352
352 /* Avoid -ERESTARTSYS handling in host */ 353 /* Avoid -ERESTARTSYS handling in host */
353 if(PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET) 354 if (PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET)
354 PT_SYSCALL_NR(regs->regs) = -1; 355 PT_SYSCALL_NR(regs->regs) = -1;
355 } 356 }
356 } 357 }
@@ -384,7 +385,8 @@ int copy_context_skas0(unsigned long new_stack, int pid)
384 __u64 new_offset; 385 __u64 new_offset;
385 int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset); 386 int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
386 387
387 /* prepare offset and fd of child's stack as argument for parent's 388 /*
389 * prepare offset and fd of child's stack as argument for parent's
388 * and child's mmap2 calls 390 * and child's mmap2 calls
389 */ 391 */
390 *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset), 392 *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset),
@@ -393,28 +395,30 @@ int copy_context_skas0(unsigned long new_stack, int pid)
393 { { 0, 1000000 / hz() }, 395 { { 0, 1000000 / hz() },
394 { 0, 1000000 / hz() }})}); 396 { 0, 1000000 / hz() }})});
395 err = ptrace_setregs(pid, thread_regs); 397 err = ptrace_setregs(pid, thread_regs);
396 if(err < 0) 398 if (err < 0)
397 panic("copy_context_skas0 : PTRACE_SETREGS failed, " 399 panic("copy_context_skas0 : PTRACE_SETREGS failed, "
398 "pid = %d, errno = %d\n", pid, -err); 400 "pid = %d, errno = %d\n", pid, -err);
399 401
400 /* set a well known return code for detection of child write failure */ 402 /* set a well known return code for detection of child write failure */
401 child_data->err = 12345678; 403 child_data->err = 12345678;
402 404
403 /* Wait, until parent has finished its work: read child's pid from 405 /*
406 * Wait, until parent has finished its work: read child's pid from
404 * parent's stack, and check, if bad result. 407 * parent's stack, and check, if bad result.
405 */ 408 */
406 err = ptrace(PTRACE_CONT, pid, 0, 0); 409 err = ptrace(PTRACE_CONT, pid, 0, 0);
407 if(err) 410 if (err)
408 panic("Failed to continue new process, pid = %d, " 411 panic("Failed to continue new process, pid = %d, "
409 "errno = %d\n", pid, errno); 412 "errno = %d\n", pid, errno);
410 wait_stub_done(pid); 413 wait_stub_done(pid);
411 414
412 pid = data->err; 415 pid = data->err;
413 if(pid < 0) 416 if (pid < 0)
414 panic("copy_context_skas0 - stub-parent reports error %d\n", 417 panic("copy_context_skas0 - stub-parent reports error %d\n",
415 -pid); 418 -pid);
416 419
417 /* Wait, until child has finished too: read child's result from 420 /*
421 * Wait, until child has finished too: read child's result from
418 * child's stack and check it. 422 * child's stack and check it.
419 */ 423 */
420 wait_stub_done(pid); 424 wait_stub_done(pid);
@@ -455,15 +459,16 @@ void map_stub_pages(int fd, unsigned long code,
455 .offset = code_offset 459 .offset = code_offset
456 } } }); 460 } } });
457 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); 461 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
458 if(n != sizeof(mmop)){ 462 if (n != sizeof(mmop)) {
459 n = errno; 463 n = errno;
460 printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n", 464 printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, "
461 code, code_fd, (unsigned long long) code_offset); 465 "offset = %llx\n", code, code_fd,
466 (unsigned long long) code_offset);
462 panic("map_stub_pages : /proc/mm map for code failed, " 467 panic("map_stub_pages : /proc/mm map for code failed, "
463 "err = %d\n", n); 468 "err = %d\n", n);
464 } 469 }
465 470
466 if ( stack ) { 471 if (stack) {
467 __u64 map_offset; 472 __u64 map_offset;
468 int map_fd = phys_mapping(to_phys((void *)stack), &map_offset); 473 int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);
469 mmop = ((struct proc_mm_op) 474 mmop = ((struct proc_mm_op)
@@ -478,7 +483,7 @@ void map_stub_pages(int fd, unsigned long code,
478 .offset = map_offset 483 .offset = map_offset
479 } } }); 484 } } });
480 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); 485 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
481 if(n != sizeof(mmop)) 486 if (n != sizeof(mmop))
482 panic("map_stub_pages : /proc/mm map for data failed, " 487 panic("map_stub_pages : /proc/mm map for data failed, "
483 "err = %d\n", errno); 488 "err = %d\n", errno);
484 } 489 }
@@ -498,7 +503,7 @@ void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
498 503
499void switch_threads(jmp_buf *me, jmp_buf *you) 504void switch_threads(jmp_buf *me, jmp_buf *you)
500{ 505{
501 if(UML_SETJMP(me) == 0) 506 if (UML_SETJMP(me) == 0)
502 UML_LONGJMP(you, 1); 507 UML_LONGJMP(you, 1);
503} 508}
504 509
@@ -526,7 +531,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
526 * after returning to the jumper. 531 * after returning to the jumper.
527 */ 532 */
528 n = setjmp(initial_jmpbuf); 533 n = setjmp(initial_jmpbuf);
529 switch(n){ 534 switch(n) {
530 case INIT_JMP_NEW_THREAD: 535 case INIT_JMP_NEW_THREAD:
531 (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler; 536 (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;
532 (*switch_buf)[0].JB_SP = (unsigned long) stack + 537 (*switch_buf)[0].JB_SP = (unsigned long) stack +
@@ -538,10 +543,10 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
538 break; 543 break;
539 case INIT_JMP_HALT: 544 case INIT_JMP_HALT:
540 kmalloc_ok = 0; 545 kmalloc_ok = 0;
541 return(0); 546 return 0;
542 case INIT_JMP_REBOOT: 547 case INIT_JMP_REBOOT:
543 kmalloc_ok = 0; 548 kmalloc_ok = 0;
544 return(1); 549 return 1;
545 default: 550 default:
546 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); 551 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
547 } 552 }
@@ -557,7 +562,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
557 cb_back = &here; 562 cb_back = &here;
558 563
559 block_signals(); 564 block_signals();
560 if(UML_SETJMP(&here) == 0) 565 if (UML_SETJMP(&here) == 0)
561 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); 566 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
562 unblock_signals(); 567 unblock_signals();
563 568
@@ -583,10 +588,10 @@ void __switch_mm(struct mm_id *mm_idp)
583 int err; 588 int err;
584 589
585 /* FIXME: need cpu pid in __switch_mm */ 590 /* FIXME: need cpu pid in __switch_mm */
586 if(proc_mm){ 591 if (proc_mm) {
587 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, 592 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
588 mm_idp->u.mm_fd); 593 mm_idp->u.mm_fd);
589 if(err) 594 if (err)
590 panic("__switch_mm - PTRACE_SWITCH_MM failed, " 595 panic("__switch_mm - PTRACE_SWITCH_MM failed, "
591 "errno = %d\n", errno); 596 "errno = %d\n", errno);
592 } 597 }
diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c
index d43e470227de..e53face44200 100644
--- a/arch/um/os-Linux/skas/trap.c
+++ b/arch/um/os-Linux/skas/trap.c
@@ -1,19 +1,23 @@
1/* 1/*
2 * Copyright (C) 2002 - 2003 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 <signal.h> 6#if 0
7#include <errno.h>
8#include "kern_util.h" 7#include "kern_util.h"
9#include "as-layout.h"
10#include "task.h"
11#include "sigcontext.h"
12#include "skas.h" 8#include "skas.h"
13#include "ptrace_user.h" 9#include "ptrace_user.h"
14#include "sysdep/ptrace.h"
15#include "sysdep/ptrace_user.h" 10#include "sysdep/ptrace_user.h"
11#endif
12
13#include <errno.h>
14#include <signal.h>
15#include "sysdep/ptrace.h"
16#include "kern_constants.h"
17#include "as-layout.h"
16#include "os.h" 18#include "os.h"
19#include "sigcontext.h"
20#include "task.h"
17 21
18static struct uml_pt_regs ksig_regs[UM_NR_CPUS]; 22static struct uml_pt_regs ksig_regs[UM_NR_CPUS];
19 23
@@ -24,14 +28,16 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
24 void (*handler)(int, struct uml_pt_regs *); 28 void (*handler)(int, struct uml_pt_regs *);
25 int save_user, save_errno = errno; 29 int save_user, save_errno = errno;
26 30
27 /* This is done because to allow SIGSEGV to be delivered inside a SEGV 31 /*
32 * This is done because to allow SIGSEGV to be delivered inside a SEGV
28 * handler. This can happen in copy_user, and if SEGV is disabled, 33 * handler. This can happen in copy_user, and if SEGV is disabled,
29 * the process will die. 34 * the process will die.
30 * XXX Figure out why this is better than SA_NODEFER 35 * XXX Figure out why this is better than SA_NODEFER
31 */ 36 */
32 if(sig == SIGSEGV) { 37 if (sig == SIGSEGV) {
33 change_sig(SIGSEGV, 1); 38 change_sig(SIGSEGV, 1);
34 /* For segfaults, we want the data from the 39 /*
40 * For segfaults, we want the data from the
35 * sigcontext. In this case, we don't want to mangle 41 * sigcontext. In this case, we don't want to mangle
36 * the process registers, so use a static set of 42 * the process registers, so use a static set of
37 * registers. For other signals, the process 43 * registers. For other signals, the process
@@ -44,11 +50,9 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
44 50
45 save_user = r->is_user; 51 save_user = r->is_user;
46 r->is_user = 0; 52 r->is_user = 0;
47 if ( sig == SIGFPE || sig == SIGSEGV || 53 if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
48 sig == SIGBUS || sig == SIGILL || 54 (sig == SIGILL) || (sig == SIGTRAP))
49 sig == SIGTRAP ) {
50 GET_FAULTINFO_FROM_SC(r->faultinfo, sc); 55 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
51 }
52 56
53 change_sig(SIGUSR1, 1); 57 change_sig(SIGUSR1, 1);
54 58