aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r--arch/um/os-Linux/aio.c112
-rw-r--r--arch/um/os-Linux/file.c4
-rw-r--r--arch/um/os-Linux/main.c80
-rw-r--r--arch/um/os-Linux/process.c100
-rw-r--r--arch/um/os-Linux/registers.c9
-rw-r--r--arch/um/os-Linux/signal.c96
-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
-rw-r--r--arch/um/os-Linux/start_up.c153
-rw-r--r--arch/um/os-Linux/trap.c6
-rw-r--r--arch/um/os-Linux/umid.c136
12 files changed, 540 insertions, 511 deletions
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 11c2b01a92b..68454daf958 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -1,19 +1,19 @@
1/* 1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2004 - 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>
7#include <unistd.h> 6#include <unistd.h>
7#include <sched.h>
8#include <signal.h> 8#include <signal.h>
9#include <errno.h> 9#include <errno.h>
10#include <sched.h> 10#include <sys/time.h>
11#include <sys/syscall.h> 11#include <asm/unistd.h>
12#include "os.h"
13#include "aio.h" 12#include "aio.h"
14#include "init.h" 13#include "init.h"
15#include "user.h"
16#include "kern_constants.h" 14#include "kern_constants.h"
15#include "os.h"
16#include "user.h"
17 17
18struct aio_thread_req { 18struct aio_thread_req {
19 enum aio_type type; 19 enum aio_type type;
@@ -27,7 +27,8 @@ struct aio_thread_req {
27#if defined(HAVE_AIO_ABI) 27#if defined(HAVE_AIO_ABI)
28#include <linux/aio_abi.h> 28#include <linux/aio_abi.h>
29 29
30/* If we have the headers, we are going to build with AIO enabled. 30/*
31 * If we have the headers, we are going to build with AIO enabled.
31 * If we don't have aio in libc, we define the necessary stubs here. 32 * If we don't have aio in libc, we define the necessary stubs here.
32 */ 33 */
33 34
@@ -51,7 +52,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
51 52
52#endif 53#endif
53 54
54/* The AIO_MMAP cases force the mmapped page into memory here 55/*
56 * The AIO_MMAP cases force the mmapped page into memory here
55 * rather than in whatever place first touches the data. I used 57 * rather than in whatever place first touches the data. I used
56 * to do this by touching the page, but that's delicate because 58 * to do this by touching the page, but that's delicate because
57 * gcc is prone to optimizing that away. So, what's done here 59 * gcc is prone to optimizing that away. So, what's done here
@@ -105,12 +107,12 @@ static int aio_thread(void *arg)
105 107
106 signal(SIGWINCH, SIG_IGN); 108 signal(SIGWINCH, SIG_IGN);
107 109
108 while(1){ 110 while (1) {
109 n = io_getevents(ctx, 1, 1, &event, NULL); 111 n = io_getevents(ctx, 1, 1, &event, NULL);
110 if(n < 0){ 112 if (n < 0) {
111 if(errno == EINTR) 113 if (errno == EINTR)
112 continue; 114 continue;
113 printk("aio_thread - io_getevents failed, " 115 printk(UM_KERN_ERR "aio_thread - io_getevents failed, "
114 "errno = %d\n", errno); 116 "errno = %d\n", errno);
115 } 117 }
116 else { 118 else {
@@ -119,9 +121,9 @@ static int aio_thread(void *arg)
119 .err = event.res }); 121 .err = event.res });
120 reply_fd = ((struct aio_context *) reply.data)->reply_fd; 122 reply_fd = ((struct aio_context *) reply.data)->reply_fd;
121 err = write(reply_fd, &reply, sizeof(reply)); 123 err = write(reply_fd, &reply, sizeof(reply));
122 if(err != sizeof(reply)) 124 if (err != sizeof(reply))
123 printk("aio_thread - write failed, fd = %d, " 125 printk(UM_KERN_ERR "aio_thread - write failed, "
124 "err = %d\n", reply_fd, errno); 126 "fd = %d, err = %d\n", reply_fd, errno);
125 } 127 }
126 } 128 }
127 return 0; 129 return 0;
@@ -136,10 +138,10 @@ static int do_not_aio(struct aio_thread_req *req)
136 int n; 138 int n;
137 139
138 actual = lseek64(req->io_fd, req->offset, SEEK_SET); 140 actual = lseek64(req->io_fd, req->offset, SEEK_SET);
139 if(actual != req->offset) 141 if (actual != req->offset)
140 return -errno; 142 return -errno;
141 143
142 switch(req->type){ 144 switch(req->type) {
143 case AIO_READ: 145 case AIO_READ:
144 n = read(req->io_fd, req->buf, req->len); 146 n = read(req->io_fd, req->buf, req->len);
145 break; 147 break;
@@ -150,11 +152,12 @@ static int do_not_aio(struct aio_thread_req *req)
150 n = read(req->io_fd, &c, sizeof(c)); 152 n = read(req->io_fd, &c, sizeof(c));
151 break; 153 break;
152 default: 154 default:
153 printk("do_not_aio - bad request type : %d\n", req->type); 155 printk(UM_KERN_ERR "do_not_aio - bad request type : %d\n",
156 req->type);
154 return -EINVAL; 157 return -EINVAL;
155 } 158 }
156 159
157 if(n < 0) 160 if (n < 0)
158 return -errno; 161 return -errno;
159 return 0; 162 return 0;
160} 163}
@@ -172,16 +175,18 @@ static int not_aio_thread(void *arg)
172 int err; 175 int err;
173 176
174 signal(SIGWINCH, SIG_IGN); 177 signal(SIGWINCH, SIG_IGN);
175 while(1){ 178 while (1) {
176 err = read(aio_req_fd_r, &req, sizeof(req)); 179 err = read(aio_req_fd_r, &req, sizeof(req));
177 if(err != sizeof(req)){ 180 if (err != sizeof(req)) {
178 if(err < 0) 181 if (err < 0)
179 printk("not_aio_thread - read failed, " 182 printk(UM_KERN_ERR "not_aio_thread - "
180 "fd = %d, err = %d\n", aio_req_fd_r, 183 "read failed, fd = %d, err = %d\n",
184 aio_req_fd_r,
181 errno); 185 errno);
182 else { 186 else {
183 printk("not_aio_thread - short read, fd = %d, " 187 printk(UM_KERN_ERR "not_aio_thread - short "
184 "length = %d\n", aio_req_fd_r, err); 188 "read, fd = %d, length = %d\n",
189 aio_req_fd_r, err);
185 } 190 }
186 continue; 191 continue;
187 } 192 }
@@ -189,9 +194,9 @@ static int not_aio_thread(void *arg)
189 reply = ((struct aio_thread_reply) { .data = req.aio, 194 reply = ((struct aio_thread_reply) { .data = req.aio,
190 .err = err }); 195 .err = err });
191 err = write(req.aio->reply_fd, &reply, sizeof(reply)); 196 err = write(req.aio->reply_fd, &reply, sizeof(reply));
192 if(err != sizeof(reply)) 197 if (err != sizeof(reply))
193 printk("not_aio_thread - write failed, fd = %d, " 198 printk(UM_KERN_ERR "not_aio_thread - write failed, "
194 "err = %d\n", req.aio->reply_fd, errno); 199 "fd = %d, err = %d\n", req.aio->reply_fd, errno);
195 } 200 }
196 201
197 return 0; 202 return 0;
@@ -202,19 +207,19 @@ static int init_aio_24(void)
202 int fds[2], err; 207 int fds[2], err;
203 208
204 err = os_pipe(fds, 1, 1); 209 err = os_pipe(fds, 1, 1);
205 if(err) 210 if (err)
206 goto out; 211 goto out;
207 212
208 aio_req_fd_w = fds[0]; 213 aio_req_fd_w = fds[0];
209 aio_req_fd_r = fds[1]; 214 aio_req_fd_r = fds[1];
210 215
211 err = os_set_fd_block(aio_req_fd_w, 0); 216 err = os_set_fd_block(aio_req_fd_w, 0);
212 if(err) 217 if (err)
213 goto out_close_pipe; 218 goto out_close_pipe;
214 219
215 err = run_helper_thread(not_aio_thread, NULL, 220 err = run_helper_thread(not_aio_thread, NULL,
216 CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); 221 CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack);
217 if(err < 0) 222 if (err < 0)
218 goto out_close_pipe; 223 goto out_close_pipe;
219 224
220 aio_pid = err; 225 aio_pid = err;
@@ -227,10 +232,11 @@ out_close_pipe:
227 aio_req_fd_r = -1; 232 aio_req_fd_r = -1;
228out: 233out:
229#ifndef HAVE_AIO_ABI 234#ifndef HAVE_AIO_ABI
230 printk("/usr/include/linux/aio_abi.h not present during build\n"); 235 printk(UM_KERN_INFO "/usr/include/linux/aio_abi.h not present during "
236 "build\n");
231#endif 237#endif
232 printk("2.6 host AIO support not used - falling back to I/O " 238 printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to "
233 "thread\n"); 239 "I/O thread\n");
234 return 0; 240 return 0;
235} 241}
236 242
@@ -240,21 +246,21 @@ static int init_aio_26(void)
240{ 246{
241 int err; 247 int err;
242 248
243 if(io_setup(256, &ctx)){ 249 if (io_setup(256, &ctx)) {
244 err = -errno; 250 err = -errno;
245 printk("aio_thread failed to initialize context, err = %d\n", 251 printk(UM_KERN_ERR "aio_thread failed to initialize context, "
246 errno); 252 "err = %d\n", errno);
247 return err; 253 return err;
248 } 254 }
249 255
250 err = run_helper_thread(aio_thread, NULL, 256 err = run_helper_thread(aio_thread, NULL,
251 CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); 257 CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack);
252 if(err < 0) 258 if (err < 0)
253 return err; 259 return err;
254 260
255 aio_pid = err; 261 aio_pid = err;
256 262
257 printk("Using 2.6 host AIO\n"); 263 printk(UM_KERN_INFO "Using 2.6 host AIO\n");
258 return 0; 264 return 0;
259} 265}
260 266
@@ -265,13 +271,13 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
265 int err; 271 int err;
266 272
267 err = do_aio(ctx, type, io_fd, buf, len, offset, aio); 273 err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
268 if(err){ 274 if (err) {
269 reply = ((struct aio_thread_reply) { .data = aio, 275 reply = ((struct aio_thread_reply) { .data = aio,
270 .err = err }); 276 .err = err });
271 err = write(aio->reply_fd, &reply, sizeof(reply)); 277 err = write(aio->reply_fd, &reply, sizeof(reply));
272 if(err != sizeof(reply)){ 278 if (err != sizeof(reply)) {
273 err = -errno; 279 err = -errno;
274 printk("submit_aio_26 - write failed, " 280 printk(UM_KERN_ERR "submit_aio_26 - write failed, "
275 "fd = %d, err = %d\n", aio->reply_fd, -err); 281 "fd = %d, err = %d\n", aio->reply_fd, -err);
276 } 282 }
277 else err = 0; 283 else err = 0;
@@ -319,23 +325,24 @@ static int init_aio(void)
319{ 325{
320 int err; 326 int err;
321 327
322 if(!aio_24){ 328 if (!aio_24) {
323 err = init_aio_26(); 329 err = init_aio_26();
324 if(err && (errno == ENOSYS)){ 330 if (err && (errno == ENOSYS)) {
325 printk("2.6 AIO not supported on the host - " 331 printk(UM_KERN_INFO "2.6 AIO not supported on the "
326 "reverting to 2.4 AIO\n"); 332 "host - reverting to 2.4 AIO\n");
327 aio_24 = 1; 333 aio_24 = 1;
328 } 334 }
329 else return err; 335 else return err;
330 } 336 }
331 337
332 if(aio_24) 338 if (aio_24)
333 return init_aio_24(); 339 return init_aio_24();
334 340
335 return 0; 341 return 0;
336} 342}
337 343
338/* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio 344/*
345 * The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
339 * needs to be called when the kernel is running because it calls run_helper, 346 * needs to be called when the kernel is running because it calls run_helper,
340 * which needs get_free_page. exit_aio is a __uml_exitcall because the generic 347 * which needs get_free_page. exit_aio is a __uml_exitcall because the generic
341 * kernel does not run __exitcalls on shutdown, and can't because many of them 348 * kernel does not run __exitcalls on shutdown, and can't because many of them
@@ -366,7 +373,7 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
366 int err; 373 int err;
367 374
368 err = write(aio_req_fd_w, &req, sizeof(req)); 375 err = write(aio_req_fd_w, &req, sizeof(req));
369 if(err == sizeof(req)) 376 if (err == sizeof(req))
370 err = 0; 377 err = 0;
371 else err = -errno; 378 else err = -errno;
372 379
@@ -378,9 +385,8 @@ int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
378 struct aio_context *aio) 385 struct aio_context *aio)
379{ 386{
380 aio->reply_fd = reply_fd; 387 aio->reply_fd = reply_fd;
381 if(aio_24) 388 if (aio_24)
382 return submit_aio_24(type, io_fd, buf, len, offset, aio); 389 return submit_aio_24(type, io_fd, buf, len, offset, aio);
383 else { 390 else
384 return submit_aio_26(type, io_fd, buf, len, offset, aio); 391 return submit_aio_26(type, io_fd, buf, len, offset, aio);
385 }
386} 392}
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index f52006ee70e..d463a820563 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -267,9 +267,9 @@ void os_close_file(int fd)
267 close(fd); 267 close(fd);
268} 268}
269 269
270int os_seek_file(int fd, __u64 offset) 270int os_seek_file(int fd, unsigned long long offset)
271{ 271{
272 __u64 actual; 272 unsigned long long actual;
273 273
274 actual = lseek64(fd, offset, SEEK_SET); 274 actual = lseek64(fd, offset, SEEK_SET);
275 if(actual != offset) 275 if(actual != offset)
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index aeeecc63473..1518f7a45a2 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -1,27 +1,21 @@
1/* 1/*
2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <unistd.h>
7#include <stdio.h> 6#include <stdio.h>
8#include <stdlib.h> 7#include <stdlib.h>
9#include <string.h> 8#include <unistd.h>
10#include <signal.h>
11#include <errno.h> 9#include <errno.h>
10#include <signal.h>
11#include <string.h>
12#include <sys/resource.h> 12#include <sys/resource.h>
13#include <sys/mman.h>
14#include <sys/user.h>
15#include "kern_util.h"
16#include "as-layout.h" 13#include "as-layout.h"
17#include "mem_user.h"
18#include "irq_user.h"
19#include "user.h"
20#include "init.h" 14#include "init.h"
21#include "uml-config.h" 15#include "kern_constants.h"
16#include "kern_util.h"
22#include "os.h" 17#include "os.h"
23#include "um_malloc.h" 18#include "um_malloc.h"
24#include "kern_constants.h"
25 19
26#define PGD_BOUND (4 * 1024 * 1024) 20#define PGD_BOUND (4 * 1024 * 1024)
27#define STACKSIZE (8 * 1024 * 1024) 21#define STACKSIZE (8 * 1024 * 1024)
@@ -31,13 +25,13 @@ static void set_stklim(void)
31{ 25{
32 struct rlimit lim; 26 struct rlimit lim;
33 27
34 if(getrlimit(RLIMIT_STACK, &lim) < 0){ 28 if (getrlimit(RLIMIT_STACK, &lim) < 0) {
35 perror("getrlimit"); 29 perror("getrlimit");
36 exit(1); 30 exit(1);
37 } 31 }
38 if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){ 32 if ((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)) {
39 lim.rlim_cur = STACKSIZE; 33 lim.rlim_cur = STACKSIZE;
40 if(setrlimit(RLIMIT_STACK, &lim) < 0){ 34 if (setrlimit(RLIMIT_STACK, &lim) < 0) {
41 perror("setrlimit"); 35 perror("setrlimit");
42 exit(1); 36 exit(1);
43 } 37 }
@@ -49,7 +43,7 @@ static __init void do_uml_initcalls(void)
49 initcall_t *call; 43 initcall_t *call;
50 44
51 call = &__uml_initcall_start; 45 call = &__uml_initcall_start;
52 while (call < &__uml_initcall_end){ 46 while (call < &__uml_initcall_end) {
53 (*call)(); 47 (*call)();
54 call++; 48 call++;
55 } 49 }
@@ -68,7 +62,8 @@ static void install_fatal_handler(int sig)
68 /* All signals are enabled in this handler ... */ 62 /* All signals are enabled in this handler ... */
69 sigemptyset(&action.sa_mask); 63 sigemptyset(&action.sa_mask);
70 64
71 /* ... including the signal being handled, plus we want the 65 /*
66 * ... including the signal being handled, plus we want the
72 * handler reset to the default behavior, so that if an exit 67 * handler reset to the default behavior, so that if an exit
73 * handler is hanging for some reason, the UML will just die 68 * handler is hanging for some reason, the UML will just die
74 * after this signal is sent a second time. 69 * after this signal is sent a second time.
@@ -76,7 +71,7 @@ static void install_fatal_handler(int sig)
76 action.sa_flags = SA_RESETHAND | SA_NODEFER; 71 action.sa_flags = SA_RESETHAND | SA_NODEFER;
77 action.sa_restorer = NULL; 72 action.sa_restorer = NULL;
78 action.sa_handler = last_ditch_exit; 73 action.sa_handler = last_ditch_exit;
79 if(sigaction(sig, &action, NULL) < 0){ 74 if (sigaction(sig, &action, NULL) < 0) {
80 printf("failed to install handler for signal %d - errno = %d\n", 75 printf("failed to install handler for signal %d - errno = %d\n",
81 errno); 76 errno);
82 exit(1); 77 exit(1);
@@ -92,7 +87,8 @@ static void setup_env_path(void)
92 int path_len = 0; 87 int path_len = 0;
93 88
94 old_path = getenv("PATH"); 89 old_path = getenv("PATH");
95 /* if no PATH variable is set or it has an empty value 90 /*
91 * if no PATH variable is set or it has an empty value
96 * just use the default + /usr/lib/uml 92 * just use the default + /usr/lib/uml
97 */ 93 */
98 if (!old_path || (path_len = strlen(old_path)) == 0) { 94 if (!old_path || (path_len = strlen(old_path)) == 0) {
@@ -125,38 +121,41 @@ int __init main(int argc, char **argv, char **envp)
125 setup_env_path(); 121 setup_env_path();
126 122
127 new_argv = malloc((argc + 1) * sizeof(char *)); 123 new_argv = malloc((argc + 1) * sizeof(char *));
128 if(new_argv == NULL){ 124 if (new_argv == NULL) {
129 perror("Mallocing argv"); 125 perror("Mallocing argv");
130 exit(1); 126 exit(1);
131 } 127 }
132 for(i=0;i<argc;i++){ 128 for (i = 0; i < argc; i++) {
133 new_argv[i] = strdup(argv[i]); 129 new_argv[i] = strdup(argv[i]);
134 if(new_argv[i] == NULL){ 130 if (new_argv[i] == NULL) {
135 perror("Mallocing an arg"); 131 perror("Mallocing an arg");
136 exit(1); 132 exit(1);
137 } 133 }
138 } 134 }
139 new_argv[argc] = NULL; 135 new_argv[argc] = NULL;
140 136
141 /* Allow these signals to bring down a UML if all other 137 /*
138 * Allow these signals to bring down a UML if all other
142 * methods of control fail. 139 * methods of control fail.
143 */ 140 */
144 install_fatal_handler(SIGINT); 141 install_fatal_handler(SIGINT);
145 install_fatal_handler(SIGTERM); 142 install_fatal_handler(SIGTERM);
146 install_fatal_handler(SIGHUP); 143 install_fatal_handler(SIGHUP);
147 144
148 scan_elf_aux( envp); 145 scan_elf_aux(envp);
149 146
150 do_uml_initcalls(); 147 do_uml_initcalls();
151 ret = linux_main(argc, argv); 148 ret = linux_main(argc, argv);
152 149
153 /* Disable SIGPROF - I have no idea why libc doesn't do this or turn 150 /*
151 * Disable SIGPROF - I have no idea why libc doesn't do this or turn
154 * off the profiling time, but UML dies with a SIGPROF just before 152 * off the profiling time, but UML dies with a SIGPROF just before
155 * exiting when profiling is active. 153 * exiting when profiling is active.
156 */ 154 */
157 change_sig(SIGPROF, 0); 155 change_sig(SIGPROF, 0);
158 156
159 /* This signal stuff used to be in the reboot case. However, 157 /*
158 * This signal stuff used to be in the reboot case. However,
160 * sometimes a SIGVTALRM can come in when we're halting (reproducably 159 * sometimes a SIGVTALRM can come in when we're halting (reproducably
161 * when writing out gcov information, presumably because that takes 160 * when writing out gcov information, presumably because that takes
162 * some time) and cause a segfault. 161 * some time) and cause a segfault.
@@ -167,17 +166,18 @@ int __init main(int argc, char **argv, char **envp)
167 166
168 /* disable SIGIO for the fds and set SIGIO to be ignored */ 167 /* disable SIGIO for the fds and set SIGIO to be ignored */
169 err = deactivate_all_fds(); 168 err = deactivate_all_fds();
170 if(err) 169 if (err)
171 printf("deactivate_all_fds failed, errno = %d\n", -err); 170 printf("deactivate_all_fds failed, errno = %d\n", -err);
172 171
173 /* Let any pending signals fire now. This ensures 172 /*
173 * Let any pending signals fire now. This ensures
174 * that they won't be delivered after the exec, when 174 * that they won't be delivered after the exec, when
175 * they are definitely not expected. 175 * they are definitely not expected.
176 */ 176 */
177 unblock_signals(); 177 unblock_signals();
178 178
179 /* Reboot */ 179 /* Reboot */
180 if(ret){ 180 if (ret) {
181 printf("\n"); 181 printf("\n");
182 execvp(new_argv[0], new_argv); 182 execvp(new_argv[0], new_argv);
183 perror("Failed to exec kernel"); 183 perror("Failed to exec kernel");
@@ -193,17 +193,18 @@ void *__wrap_malloc(int size)
193{ 193{
194 void *ret; 194 void *ret;
195 195
196 if(!kmalloc_ok) 196 if (!kmalloc_ok)
197 return __real_malloc(size); 197 return __real_malloc(size);
198 else if(size <= UM_KERN_PAGE_SIZE) 198 else if (size <= UM_KERN_PAGE_SIZE)
199 /* finding contiguous pages can be hard*/ 199 /* finding contiguous pages can be hard*/
200 ret = kmalloc(size, UM_GFP_KERNEL); 200 ret = kmalloc(size, UM_GFP_KERNEL);
201 else ret = vmalloc(size); 201 else ret = vmalloc(size);
202 202
203 /* glibc people insist that if malloc fails, errno should be 203 /*
204 * glibc people insist that if malloc fails, errno should be
204 * set by malloc as well. So we do. 205 * set by malloc as well. So we do.
205 */ 206 */
206 if(ret == NULL) 207 if (ret == NULL)
207 errno = ENOMEM; 208 errno = ENOMEM;
208 209
209 return ret; 210 return ret;
@@ -213,7 +214,7 @@ void *__wrap_calloc(int n, int size)
213{ 214{
214 void *ptr = __wrap_malloc(n * size); 215 void *ptr = __wrap_malloc(n * size);
215 216
216 if(ptr == NULL) 217 if (ptr == NULL)
217 return NULL; 218 return NULL;
218 memset(ptr, 0, n * size); 219 memset(ptr, 0, n * size);
219 return ptr; 220 return ptr;
@@ -227,7 +228,8 @@ void __wrap_free(void *ptr)
227{ 228{
228 unsigned long addr = (unsigned long) ptr; 229 unsigned long addr = (unsigned long) ptr;
229 230
230 /* We need to know how the allocation happened, so it can be correctly 231 /*
232 * We need to know how the allocation happened, so it can be correctly
231 * freed. This is done by seeing what region of memory the pointer is 233 * freed. This is done by seeing what region of memory the pointer is
232 * in - 234 * in -
233 * physical memory - kmalloc/kfree 235 * physical memory - kmalloc/kfree
@@ -245,12 +247,12 @@ void __wrap_free(void *ptr)
245 * there is a possibility for memory leaks. 247 * there is a possibility for memory leaks.
246 */ 248 */
247 249
248 if((addr >= uml_physmem) && (addr < high_physmem)){ 250 if ((addr >= uml_physmem) && (addr < high_physmem)) {
249 if(kmalloc_ok) 251 if (kmalloc_ok)
250 kfree(ptr); 252 kfree(ptr);
251 } 253 }
252 else if((addr >= start_vm) && (addr < end_vm)){ 254 else if ((addr >= start_vm) && (addr < end_vm)) {
253 if(kmalloc_ok) 255 if (kmalloc_ok)
254 vfree(ptr); 256 vfree(ptr);
255 } 257 }
256 else __real_free(ptr); 258 else __real_free(ptr);
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index a955e9bcd04..b2e0d8c4258 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -1,27 +1,23 @@
1/* 1/*
2 * Copyright (C) 2002 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 <unistd.h>
7#include <stdio.h> 6#include <stdio.h>
7#include <unistd.h>
8#include <errno.h> 8#include <errno.h>
9#include <signal.h> 9#include <signal.h>
10#include <sys/mman.h> 10#include <sys/mman.h>
11#include <sys/ptrace.h>
11#include <sys/wait.h> 12#include <sys/wait.h>
12#include <sys/mman.h> 13#include <asm/unistd.h>
13#include <sys/syscall.h> 14#include "init.h"
14#include "ptrace_user.h" 15#include "kern_constants.h"
16#include "longjmp.h"
15#include "os.h" 17#include "os.h"
16#include "user.h"
17#include "process.h" 18#include "process.h"
18#include "irq_user.h"
19#include "kern_util.h"
20#include "longjmp.h"
21#include "skas_ptrace.h" 19#include "skas_ptrace.h"
22#include "kern_constants.h" 20#include "user.h"
23#include "uml-config.h"
24#include "init.h"
25 21
26#define ARBITRARY_ADDR -1 22#define ARBITRARY_ADDR -1
27#define FAILURE_PID -1 23#define FAILURE_PID -1
@@ -37,24 +33,25 @@ unsigned long os_process_pc(int pid)
37 33
38 sprintf(proc_stat, "/proc/%d/stat", pid); 34 sprintf(proc_stat, "/proc/%d/stat", pid);
39 fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0); 35 fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
40 if(fd < 0){ 36 if (fd < 0) {
41 printk("os_process_pc - couldn't open '%s', err = %d\n", 37 printk(UM_KERN_ERR "os_process_pc - couldn't open '%s', "
42 proc_stat, -fd); 38 "err = %d\n", proc_stat, -fd);
43 return ARBITRARY_ADDR; 39 return ARBITRARY_ADDR;
44 } 40 }
45 CATCH_EINTR(err = read(fd, buf, sizeof(buf))); 41 CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
46 if(err < 0){ 42 if (err < 0) {
47 printk("os_process_pc - couldn't read '%s', err = %d\n", 43 printk(UM_KERN_ERR "os_process_pc - couldn't read '%s', "
48 proc_stat, errno); 44 "err = %d\n", proc_stat, errno);
49 os_close_file(fd); 45 os_close_file(fd);
50 return ARBITRARY_ADDR; 46 return ARBITRARY_ADDR;
51 } 47 }
52 os_close_file(fd); 48 os_close_file(fd);
53 pc = ARBITRARY_ADDR; 49 pc = ARBITRARY_ADDR;
54 if(sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d " 50 if (sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d "
55 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " 51 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
56 "%*d %*d %*d %*d %*d %lu", &pc) != 1){ 52 "%*d %*d %*d %*d %*d %lu", &pc) != 1) {
57 printk("os_process_pc - couldn't find pc in '%s'\n", buf); 53 printk(UM_KERN_ERR "os_process_pc - couldn't find pc in '%s'\n",
54 buf);
58 } 55 }
59 return pc; 56 return pc;
60} 57}
@@ -65,28 +62,29 @@ int os_process_parent(int pid)
65 char data[256]; 62 char data[256];
66 int parent, n, fd; 63 int parent, n, fd;
67 64
68 if(pid == -1) 65 if (pid == -1)
69 return -1; 66 return -1;
70 67
71 snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); 68 snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
72 fd = os_open_file(stat, of_read(OPENFLAGS()), 0); 69 fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
73 if(fd < 0){ 70 if (fd < 0) {
74 printk("Couldn't open '%s', err = %d\n", stat, -fd); 71 printk(UM_KERN_ERR "Couldn't open '%s', err = %d\n", stat, -fd);
75 return FAILURE_PID; 72 return FAILURE_PID;
76 } 73 }
77 74
78 CATCH_EINTR(n = read(fd, data, sizeof(data))); 75 CATCH_EINTR(n = read(fd, data, sizeof(data)));
79 os_close_file(fd); 76 os_close_file(fd);
80 77
81 if(n < 0){ 78 if (n < 0) {
82 printk("Couldn't read '%s', err = %d\n", stat, errno); 79 printk(UM_KERN_ERR "Couldn't read '%s', err = %d\n", stat,
80 errno);
83 return FAILURE_PID; 81 return FAILURE_PID;
84 } 82 }
85 83
86 parent = FAILURE_PID; 84 parent = FAILURE_PID;
87 n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent); 85 n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent);
88 if(n != 1) 86 if (n != 1)
89 printk("Failed to scan '%s'\n", data); 87 printk(UM_KERN_ERR "Failed to scan '%s'\n", data);
90 88
91 return parent; 89 return parent;
92} 90}
@@ -99,9 +97,8 @@ void os_stop_process(int pid)
99void os_kill_process(int pid, int reap_child) 97void os_kill_process(int pid, int reap_child)
100{ 98{
101 kill(pid, SIGKILL); 99 kill(pid, SIGKILL);
102 if(reap_child) 100 if (reap_child)
103 CATCH_EINTR(waitpid(pid, NULL, 0)); 101 CATCH_EINTR(waitpid(pid, NULL, 0));
104
105} 102}
106 103
107/* This is here uniquely to have access to the userspace errno, i.e. the one 104/* This is here uniquely to have access to the userspace errno, i.e. the one
@@ -129,7 +126,7 @@ void os_kill_ptraced_process(int pid, int reap_child)
129 kill(pid, SIGKILL); 126 kill(pid, SIGKILL);
130 ptrace(PTRACE_KILL, pid); 127 ptrace(PTRACE_KILL, pid);
131 ptrace(PTRACE_CONT, pid); 128 ptrace(PTRACE_CONT, pid);
132 if(reap_child) 129 if (reap_child)
133 CATCH_EINTR(waitpid(pid, NULL, 0)); 130 CATCH_EINTR(waitpid(pid, NULL, 0));
134} 131}
135 132
@@ -153,34 +150,35 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
153 void *loc; 150 void *loc;
154 int prot; 151 int prot;
155 152
156 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 153 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
157 (x ? PROT_EXEC : 0); 154 (x ? PROT_EXEC : 0);
158 155
159 loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 156 loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
160 fd, off); 157 fd, off);
161 if(loc == MAP_FAILED) 158 if (loc == MAP_FAILED)
162 return -errno; 159 return -errno;
163 return 0; 160 return 0;
164} 161}
165 162
166int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) 163int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
167{ 164{
168 int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 165 int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
169 (x ? PROT_EXEC : 0)); 166 (x ? PROT_EXEC : 0));
170 167
171 if(mprotect(addr, len, prot) < 0) 168 if (mprotect(addr, len, prot) < 0)
172 return -errno; 169 return -errno;
173 return 0; 170
171 return 0;
174} 172}
175 173
176int os_unmap_memory(void *addr, int len) 174int os_unmap_memory(void *addr, int len)
177{ 175{
178 int err; 176 int err;
179 177
180 err = munmap(addr, len); 178 err = munmap(addr, len);
181 if(err < 0) 179 if (err < 0)
182 return -errno; 180 return -errno;
183 return 0; 181 return 0;
184} 182}
185 183
186#ifndef MADV_REMOVE 184#ifndef MADV_REMOVE
@@ -192,7 +190,7 @@ int os_drop_memory(void *addr, int length)
192 int err; 190 int err;
193 191
194 err = madvise(addr, length, MADV_REMOVE); 192 err = madvise(addr, length, MADV_REMOVE);
195 if(err < 0) 193 if (err < 0)
196 err = -errno; 194 err = -errno;
197 return err; 195 return err;
198} 196}
@@ -202,22 +200,24 @@ int __init can_drop_memory(void)
202 void *addr; 200 void *addr;
203 int fd, ok = 0; 201 int fd, ok = 0;
204 202
205 printk("Checking host MADV_REMOVE support..."); 203 printk(UM_KERN_INFO "Checking host MADV_REMOVE support...");
206 fd = create_mem_file(UM_KERN_PAGE_SIZE); 204 fd = create_mem_file(UM_KERN_PAGE_SIZE);
207 if(fd < 0){ 205 if (fd < 0) {
208 printk("Creating test memory file failed, err = %d\n", -fd); 206 printk(UM_KERN_ERR "Creating test memory file failed, "
207 "err = %d\n", -fd);
209 goto out; 208 goto out;
210 } 209 }
211 210
212 addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, 211 addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
213 MAP_SHARED, fd, 0); 212 MAP_SHARED, fd, 0);
214 if(addr == MAP_FAILED){ 213 if (addr == MAP_FAILED) {
215 printk("Mapping test memory file failed, err = %d\n", -errno); 214 printk(UM_KERN_ERR "Mapping test memory file failed, "
215 "err = %d\n", -errno);
216 goto out_close; 216 goto out_close;
217 } 217 }
218 218
219 if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){ 219 if (madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0) {
220 printk("MADV_REMOVE failed, err = %d\n", -errno); 220 printk(UM_KERN_ERR "MADV_REMOVE failed, err = %d\n", -errno);
221 goto out_unmap; 221 goto out_unmap;
222 } 222 }
223 223
@@ -256,7 +256,7 @@ int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
256 256
257 *jmp_ptr = &buf; 257 *jmp_ptr = &buf;
258 n = UML_SETJMP(&buf); 258 n = UML_SETJMP(&buf);
259 if(n != 0) 259 if (n != 0)
260 return n; 260 return n;
261 (*fn)(arg); 261 (*fn)(arg);
262 return 0; 262 return 0;
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c
index ce0b791160e..14732f98e0a 100644
--- a/arch/um/os-Linux/registers.c
+++ b/arch/um/os-Linux/registers.c
@@ -1,13 +1,14 @@
1/* 1/*
2 * Copyright (C) 2004 PathScale, Inc 2 * Copyright (C) 2004 PathScale, Inc
3 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 4 * Licensed under the GPL
4 */ 5 */
5 6
6#include <errno.h> 7#include <errno.h>
7#include <string.h> 8#include <string.h>
8#include <sys/ptrace.h> 9#include <sys/ptrace.h>
9#include "user.h"
10#include "sysdep/ptrace.h" 10#include "sysdep/ptrace.h"
11#include "user.h"
11 12
12/* This is set once at boot time and not changed thereafter */ 13/* This is set once at boot time and not changed thereafter */
13 14
@@ -23,7 +24,7 @@ void save_registers(int pid, struct uml_pt_regs *regs)
23 int err; 24 int err;
24 25
25 err = ptrace(PTRACE_GETREGS, pid, 0, regs->regs); 26 err = ptrace(PTRACE_GETREGS, pid, 0, regs->regs);
26 if(err < 0) 27 if (err < 0)
27 panic("save_registers - saving registers failed, errno = %d\n", 28 panic("save_registers - saving registers failed, errno = %d\n",
28 errno); 29 errno);
29} 30}
@@ -33,7 +34,7 @@ void restore_registers(int pid, struct uml_pt_regs *regs)
33 int err; 34 int err;
34 35
35 err = ptrace(PTRACE_SETREGS, pid, 0, regs->regs); 36 err = ptrace(PTRACE_SETREGS, pid, 0, regs->regs);
36 if(err < 0) 37 if (err < 0)
37 panic("restore_registers - saving registers failed, " 38 panic("restore_registers - saving registers failed, "
38 "errno = %d\n", errno); 39 "errno = %d\n", errno);
39} 40}
@@ -43,7 +44,7 @@ void init_registers(int pid)
43 int err; 44 int err;
44 45
45 err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); 46 err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
46 if(err) 47 if (err)
47 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", 48 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
48 errno); 49 errno);
49} 50}
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 583424b9797..49c113b576b 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -1,24 +1,21 @@
1/* 1/*
2 * Copyright (C) 2004 PathScale, Inc 2 * Copyright (C) 2004 PathScale, Inc
3 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 4 * Licensed under the GPL
4 */ 5 */
5 6
6#include <signal.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <stdlib.h> 7#include <stdlib.h>
10#include <errno.h>
11#include <stdarg.h> 8#include <stdarg.h>
12#include <string.h> 9#include <errno.h>
13#include <sys/mman.h> 10#include <signal.h>
14#include "user.h" 11#include <strings.h>
15#include "signal_kern.h"
16#include "sysdep/sigcontext.h"
17#include "sysdep/barrier.h"
18#include "sigcontext.h"
19#include "os.h" 12#include "os.h"
13#include "sysdep/barrier.h"
14#include "sysdep/sigcontext.h"
15#include "user.h"
20 16
21/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled 17/*
18 * These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
22 * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to 19 * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to
23 * be able to profile all of UML, not just the non-critical sections. If 20 * be able to profile all of UML, not just the non-critical sections. If
24 * profiling is not thread-safe, then that is not my problem. We can disable 21 * profiling is not thread-safe, then that is not my problem. We can disable
@@ -33,7 +30,8 @@
33#define SIGALRM_BIT 2 30#define SIGALRM_BIT 2
34#define SIGALRM_MASK (1 << SIGALRM_BIT) 31#define SIGALRM_MASK (1 << SIGALRM_BIT)
35 32
36/* These are used by both the signal handlers and 33/*
34 * These are used by both the signal handlers and
37 * block/unblock_signals. I don't want modifications cached in a 35 * block/unblock_signals. I don't want modifications cached in a
38 * register - they must go straight to memory. 36 * register - they must go straight to memory.
39 */ 37 */
@@ -45,7 +43,7 @@ void sig_handler(int sig, struct sigcontext *sc)
45 int enabled; 43 int enabled;
46 44
47 enabled = signals_enabled; 45 enabled = signals_enabled;
48 if(!enabled && (sig == SIGIO)){ 46 if (!enabled && (sig == SIGIO)) {
49 pending |= SIGIO_MASK; 47 pending |= SIGIO_MASK;
50 return; 48 return;
51 } 49 }
@@ -61,16 +59,16 @@ static void real_alarm_handler(int sig, struct sigcontext *sc)
61{ 59{
62 struct uml_pt_regs regs; 60 struct uml_pt_regs regs;
63 61
64 if(sig == SIGALRM) 62 if (sig == SIGALRM)
65 switch_timers(0); 63 switch_timers(0);
66 64
67 if(sc != NULL) 65 if (sc != NULL)
68 copy_sc(&regs, sc); 66 copy_sc(&regs, sc);
69 regs.is_user = 0; 67 regs.is_user = 0;
70 unblock_signals(); 68 unblock_signals();
71 timer_handler(sig, &regs); 69 timer_handler(sig, &regs);
72 70
73 if(sig == SIGALRM) 71 if (sig == SIGALRM)
74 switch_timers(1); 72 switch_timers(1);
75} 73}
76 74
@@ -79,8 +77,8 @@ void alarm_handler(int sig, struct sigcontext *sc)
79 int enabled; 77 int enabled;
80 78
81 enabled = signals_enabled; 79 enabled = signals_enabled;
82 if(!signals_enabled){ 80 if (!signals_enabled) {
83 if(sig == SIGVTALRM) 81 if (sig == SIGVTALRM)
84 pending |= SIGVTALRM_MASK; 82 pending |= SIGVTALRM_MASK;
85 else pending |= SIGALRM_MASK; 83 else pending |= SIGALRM_MASK;
86 84
@@ -99,7 +97,7 @@ void set_sigstack(void *sig_stack, int size)
99 .ss_sp = (__ptr_t) sig_stack, 97 .ss_sp = (__ptr_t) sig_stack,
100 .ss_size = size - sizeof(void *) }); 98 .ss_size = size - sizeof(void *) });
101 99
102 if(sigaltstack(&stack, NULL) != 0) 100 if (sigaltstack(&stack, NULL) != 0)
103 panic("enabling signal stack failed, errno = %d\n", errno); 101 panic("enabling signal stack failed, errno = %d\n", errno);
104} 102}
105 103
@@ -109,7 +107,7 @@ void remove_sigstack(void)
109 .ss_sp = NULL, 107 .ss_sp = NULL,
110 .ss_size = 0 }); 108 .ss_size = 0 });
111 109
112 if(sigaltstack(&stack, NULL) != 0) 110 if (sigaltstack(&stack, NULL) != 0)
113 panic("disabling signal stack failed, errno = %d\n", errno); 111 panic("disabling signal stack failed, errno = %d\n", errno);
114} 112}
115 113
@@ -133,26 +131,27 @@ void handle_signal(int sig, struct sigcontext *sc)
133 * with this interrupt. 131 * with this interrupt.
134 */ 132 */
135 bail = to_irq_stack(&pending); 133 bail = to_irq_stack(&pending);
136 if(bail) 134 if (bail)
137 return; 135 return;
138 136
139 nested = pending & 1; 137 nested = pending & 1;
140 pending &= ~1; 138 pending &= ~1;
141 139
142 while((sig = ffs(pending)) != 0){ 140 while ((sig = ffs(pending)) != 0){
143 sig--; 141 sig--;
144 pending &= ~(1 << sig); 142 pending &= ~(1 << sig);
145 (*handlers[sig])(sig, sc); 143 (*handlers[sig])(sig, sc);
146 } 144 }
147 145
148 /* Again, pending comes back with a mask of signals 146 /*
147 * Again, pending comes back with a mask of signals
149 * that arrived while tearing down the stack. If this 148 * that arrived while tearing down the stack. If this
150 * is non-zero, we just go back, set up the stack 149 * is non-zero, we just go back, set up the stack
151 * again, and handle the new interrupts. 150 * again, and handle the new interrupts.
152 */ 151 */
153 if(!nested) 152 if (!nested)
154 pending = from_irq_stack(nested); 153 pending = from_irq_stack(nested);
155 } while(pending); 154 } while (pending);
156} 155}
157 156
158extern void hard_handler(int sig); 157extern void hard_handler(int sig);
@@ -170,18 +169,18 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
170 sigemptyset(&action.sa_mask); 169 sigemptyset(&action.sa_mask);
171 170
172 va_start(ap, flags); 171 va_start(ap, flags);
173 while((mask = va_arg(ap, int)) != -1) 172 while ((mask = va_arg(ap, int)) != -1)
174 sigaddset(&action.sa_mask, mask); 173 sigaddset(&action.sa_mask, mask);
175 va_end(ap); 174 va_end(ap);
176 175
177 action.sa_flags = flags; 176 action.sa_flags = flags;
178 action.sa_restorer = NULL; 177 action.sa_restorer = NULL;
179 if(sigaction(sig, &action, NULL) < 0) 178 if (sigaction(sig, &action, NULL) < 0)
180 panic("sigaction failed - errno = %d\n", errno); 179 panic("sigaction failed - errno = %d\n", errno);
181 180
182 sigemptyset(&sig_mask); 181 sigemptyset(&sig_mask);
183 sigaddset(&sig_mask, sig); 182 sigaddset(&sig_mask, sig);
184 if(sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0) 183 if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
185 panic("sigprocmask failed - errno = %d\n", errno); 184 panic("sigprocmask failed - errno = %d\n", errno);
186} 185}
187 186
@@ -192,13 +191,14 @@ int change_sig(int signal, int on)
192 sigemptyset(&sigset); 191 sigemptyset(&sigset);
193 sigaddset(&sigset, signal); 192 sigaddset(&sigset, signal);
194 sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old); 193 sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
195 return(!sigismember(&old, signal)); 194 return !sigismember(&old, signal);
196} 195}
197 196
198void block_signals(void) 197void block_signals(void)
199{ 198{
200 signals_enabled = 0; 199 signals_enabled = 0;
201 /* This must return with signals disabled, so this barrier 200 /*
201 * This must return with signals disabled, so this barrier
202 * ensures that writes are flushed out before the return. 202 * ensures that writes are flushed out before the return.
203 * This might matter if gcc figures out how to inline this and 203 * This might matter if gcc figures out how to inline this and
204 * decides to shuffle this code into the caller. 204 * decides to shuffle this code into the caller.
@@ -210,27 +210,31 @@ void unblock_signals(void)
210{ 210{
211 int save_pending; 211 int save_pending;
212 212
213 if(signals_enabled == 1) 213 if (signals_enabled == 1)
214 return; 214 return;
215 215
216 /* We loop because the IRQ handler returns with interrupts off. So, 216 /*
217 * We loop because the IRQ handler returns with interrupts off. So,
217 * interrupts may have arrived and we need to re-enable them and 218 * interrupts may have arrived and we need to re-enable them and
218 * recheck pending. 219 * recheck pending.
219 */ 220 */
220 while(1){ 221 while(1) {
221 /* Save and reset save_pending after enabling signals. This 222 /*
223 * Save and reset save_pending after enabling signals. This
222 * way, pending won't be changed while we're reading it. 224 * way, pending won't be changed while we're reading it.
223 */ 225 */
224 signals_enabled = 1; 226 signals_enabled = 1;
225 227
226 /* Setting signals_enabled and reading pending must 228 /*
229 * Setting signals_enabled and reading pending must
227 * happen in this order. 230 * happen in this order.
228 */ 231 */
229 mb(); 232 mb();
230 233
231 save_pending = pending; 234 save_pending = pending;
232 if(save_pending == 0){ 235 if (save_pending == 0) {
233 /* This must return with signals enabled, so 236 /*
237 * This must return with signals enabled, so
234 * this barrier ensures that writes are 238 * this barrier ensures that writes are
235 * flushed out before the return. This might 239 * flushed out before the return. This might
236 * matter if gcc figures out how to inline 240 * matter if gcc figures out how to inline
@@ -243,24 +247,26 @@ void unblock_signals(void)
243 247
244 pending = 0; 248 pending = 0;
245 249
246 /* We have pending interrupts, so disable signals, as the 250 /*
251 * We have pending interrupts, so disable signals, as the
247 * handlers expect them off when they are called. They will 252 * handlers expect them off when they are called. They will
248 * be enabled again above. 253 * be enabled again above.
249 */ 254 */
250 255
251 signals_enabled = 0; 256 signals_enabled = 0;
252 257
253 /* Deal with SIGIO first because the alarm handler might 258 /*
259 * Deal with SIGIO first because the alarm handler might
254 * schedule, leaving the pending SIGIO stranded until we come 260 * schedule, leaving the pending SIGIO stranded until we come
255 * back here. 261 * back here.
256 */ 262 */
257 if(save_pending & SIGIO_MASK) 263 if (save_pending & SIGIO_MASK)
258 sig_handler_common_skas(SIGIO, NULL); 264 sig_handler_common_skas(SIGIO, NULL);
259 265
260 if(save_pending & SIGALRM_MASK) 266 if (save_pending & SIGALRM_MASK)
261 real_alarm_handler(SIGALRM, NULL); 267 real_alarm_handler(SIGALRM, NULL);
262 268
263 if(save_pending & SIGVTALRM_MASK) 269 if (save_pending & SIGVTALRM_MASK)
264 real_alarm_handler(SIGVTALRM, NULL); 270 real_alarm_handler(SIGVTALRM, NULL);
265 } 271 }
266} 272}
@@ -273,11 +279,11 @@ int get_signals(void)
273int set_signals(int enable) 279int set_signals(int enable)
274{ 280{
275 int ret; 281 int ret;
276 if(signals_enabled == enable) 282 if (signals_enabled == enable)
277 return enable; 283 return enable;
278 284
279 ret = signals_enabled; 285 ret = signals_enabled;
280 if(enable) 286 if (enable)
281 unblock_signals(); 287 unblock_signals();
282 else block_signals(); 288 else block_signals();
283 289
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index ae7685710c4..d58d11179bb 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 eb027673f35..e12d18cc77d 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 d43e470227d..e53face4420 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
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index abfc094c3c4..f2271586892 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -1,41 +1,29 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <pty.h>
7#include <stdio.h> 6#include <stdio.h>
8#include <stddef.h>
9#include <stdarg.h>
10#include <stdlib.h> 7#include <stdlib.h>
11#include <string.h> 8#include <stdarg.h>
12#include <unistd.h> 9#include <unistd.h>
13#include <signal.h>
14#include <sched.h>
15#include <fcntl.h>
16#include <errno.h> 10#include <errno.h>
17#include <sys/time.h> 11#include <fcntl.h>
18#include <sys/wait.h> 12#include <sched.h>
13#include <signal.h>
14#include <string.h>
19#include <sys/mman.h> 15#include <sys/mman.h>
20#include <sys/resource.h> 16#include <sys/ptrace.h>
17#include <sys/stat.h>
18#include <sys/wait.h>
21#include <asm/unistd.h> 19#include <asm/unistd.h>
22#include <sys/types.h>
23#include "kern_util.h"
24#include "user.h"
25#include "signal_kern.h"
26#include "sysdep/ptrace.h"
27#include "sysdep/sigcontext.h"
28#include "irq_user.h"
29#include "ptrace_user.h"
30#include "mem_user.h"
31#include "init.h" 20#include "init.h"
32#include "os.h"
33#include "uml-config.h"
34#include "tempfile.h"
35#include "kern_constants.h" 21#include "kern_constants.h"
36#include "skas.h" 22#include "os.h"
37#include "skas_ptrace.h" 23#include "mem_user.h"
24#include "ptrace_user.h"
38#include "registers.h" 25#include "registers.h"
26#include "skas_ptrace.h"
39 27
40static int ptrace_child(void *arg) 28static int ptrace_child(void *arg)
41{ 29{
@@ -44,26 +32,33 @@ static int ptrace_child(void *arg)
44 int sc_result; 32 int sc_result;
45 33
46 change_sig(SIGWINCH, 0); 34 change_sig(SIGWINCH, 0);
47 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ 35 if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
48 perror("ptrace"); 36 perror("ptrace");
49 os_kill_process(pid, 0); 37 os_kill_process(pid, 0);
50 } 38 }
51 kill(pid, SIGSTOP); 39 kill(pid, SIGSTOP);
52 40
53 /*This syscall will be intercepted by the parent. Don't call more than 41 /*
54 * once, please.*/ 42 * This syscall will be intercepted by the parent. Don't call more than
43 * once, please.
44 */
55 sc_result = os_getpid(); 45 sc_result = os_getpid();
56 46
57 if (sc_result == pid) 47 if (sc_result == pid)
58 ret = 1; /*Nothing modified by the parent, we are running 48 /* Nothing modified by the parent, we are running normally. */
59 normally.*/ 49 ret = 1;
60 else if (sc_result == ppid) 50 else if (sc_result == ppid)
61 ret = 0; /*Expected in check_ptrace and check_sysemu when they 51 /*
62 succeed in modifying the stack frame*/ 52 * Expected in check_ptrace and check_sysemu when they succeed
53 * in modifying the stack frame
54 */
55 ret = 0;
63 else 56 else
64 ret = 2; /*Serious trouble! This could be caused by a bug in 57 /* Serious trouble! This could be caused by a bug in host 2.6
65 host 2.6 SKAS3/2.6 patch before release -V6, together 58 * SKAS3/2.6 patch before release -V6, together with a bug in
66 with a bug in the UML code itself.*/ 59 * the UML code itself.
60 */
61 ret = 2;
67 _exit(ret); 62 _exit(ret);
68} 63}
69 64
@@ -104,16 +99,18 @@ static int start_ptraced_child(void **stack_out)
104 stack = mmap(NULL, UM_KERN_PAGE_SIZE, 99 stack = mmap(NULL, UM_KERN_PAGE_SIZE,
105 PROT_READ | PROT_WRITE | PROT_EXEC, 100 PROT_READ | PROT_WRITE | PROT_EXEC,
106 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 101 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
107 if(stack == MAP_FAILED) 102 if (stack == MAP_FAILED)
108 fatal_perror("check_ptrace : mmap failed"); 103 fatal_perror("check_ptrace : mmap failed");
104
109 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); 105 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
110 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); 106 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
111 if(pid < 0) 107 if (pid < 0)
112 fatal_perror("start_ptraced_child : clone failed"); 108 fatal_perror("start_ptraced_child : clone failed");
109
113 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 110 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
114 if(n < 0) 111 if (n < 0)
115 fatal_perror("check_ptrace : clone failed"); 112 fatal_perror("check_ptrace : clone failed");
116 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) 113 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
117 fatal("check_ptrace : expected SIGSTOP, got status = %d", 114 fatal("check_ptrace : expected SIGSTOP, got status = %d",
118 status); 115 status);
119 116
@@ -132,10 +129,10 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
132{ 129{
133 int status, n, ret = 0; 130 int status, n, ret = 0;
134 131
135 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) 132 if (ptrace(PTRACE_CONT, pid, 0, 0) < 0)
136 fatal_perror("stop_ptraced_child : ptrace failed"); 133 fatal_perror("stop_ptraced_child : ptrace failed");
137 CATCH_EINTR(n = waitpid(pid, &status, 0)); 134 CATCH_EINTR(n = waitpid(pid, &status, 0));
138 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { 135 if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
139 int exit_with = WEXITSTATUS(status); 136 int exit_with = WEXITSTATUS(status);
140 if (exit_with == 2) 137 if (exit_with == 2)
141 non_fatal("check_ptrace : child exited with status 2. " 138 non_fatal("check_ptrace : child exited with status 2. "
@@ -148,7 +145,7 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
148 ret = -1; 145 ret = -1;
149 } 146 }
150 147
151 if(munmap(stack, UM_KERN_PAGE_SIZE) < 0) 148 if (munmap(stack, UM_KERN_PAGE_SIZE) < 0)
152 fatal_perror("check_ptrace : munmap failed"); 149 fatal_perror("check_ptrace : munmap failed");
153 return ret; 150 return ret;
154} 151}
@@ -209,26 +206,26 @@ static void __init check_sysemu(void)
209 sysemu_supported = 0; 206 sysemu_supported = 0;
210 pid = start_ptraced_child(&stack); 207 pid = start_ptraced_child(&stack);
211 208
212 if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) 209 if (ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
213 goto fail; 210 goto fail;
214 211
215 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 212 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
216 if (n < 0) 213 if (n < 0)
217 fatal_perror("check_sysemu : wait failed"); 214 fatal_perror("check_sysemu : wait failed");
218 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) 215 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
219 fatal("check_sysemu : expected SIGTRAP, got status = %d", 216 fatal("check_sysemu : expected SIGTRAP, got status = %d",
220 status); 217 status);
221 218
222 if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) 219 if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
223 fatal_perror("check_sysemu : PTRACE_GETREGS failed"); 220 fatal_perror("check_sysemu : PTRACE_GETREGS failed");
224 if(PT_SYSCALL_NR(regs) != __NR_getpid){ 221 if (PT_SYSCALL_NR(regs) != __NR_getpid) {
225 non_fatal("check_sysemu got system call number %d, " 222 non_fatal("check_sysemu got system call number %d, "
226 "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid); 223 "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid);
227 goto fail; 224 goto fail;
228 } 225 }
229 226
230 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); 227 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid());
231 if(n < 0){ 228 if (n < 0) {
232 non_fatal("check_sysemu : failed to modify system call " 229 non_fatal("check_sysemu : failed to modify system call "
233 "return"); 230 "return");
234 goto fail; 231 goto fail;
@@ -244,30 +241,31 @@ static void __init check_sysemu(void)
244 non_fatal("Checking advanced syscall emulation patch for ptrace..."); 241 non_fatal("Checking advanced syscall emulation patch for ptrace...");
245 pid = start_ptraced_child(&stack); 242 pid = start_ptraced_child(&stack);
246 243
247 if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, 244 if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
248 (void *) PTRACE_O_TRACESYSGOOD) < 0)) 245 (void *) PTRACE_O_TRACESYSGOOD) < 0))
249 fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed"); 246 fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
250 247
251 while(1){ 248 while (1) {
252 count++; 249 count++;
253 if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) 250 if (ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
254 goto fail; 251 goto fail;
255 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 252 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
256 if(n < 0) 253 if (n < 0)
257 fatal_perror("check_ptrace : wait failed"); 254 fatal_perror("check_ptrace : wait failed");
258 255
259 if(WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))){ 256 if (WIFSTOPPED(status) &&
257 (WSTOPSIG(status) == (SIGTRAP|0x80))) {
260 if (!count) 258 if (!count)
261 fatal("check_ptrace : SYSEMU_SINGLESTEP " 259 fatal("check_ptrace : SYSEMU_SINGLESTEP "
262 "doesn't singlestep"); 260 "doesn't singlestep");
263 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, 261 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
264 os_getpid()); 262 os_getpid());
265 if(n < 0) 263 if (n < 0)
266 fatal_perror("check_sysemu : failed to modify " 264 fatal_perror("check_sysemu : failed to modify "
267 "system call return"); 265 "system call return");
268 break; 266 break;
269 } 267 }
270 else if(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) 268 else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
271 count++; 269 count++;
272 else 270 else
273 fatal("check_ptrace : expected SIGTRAP or " 271 fatal("check_ptrace : expected SIGTRAP or "
@@ -279,7 +277,7 @@ static void __init check_sysemu(void)
279 sysemu_supported = 2; 277 sysemu_supported = 2;
280 non_fatal("OK\n"); 278 non_fatal("OK\n");
281 279
282 if ( !force_sysemu_disabled ) 280 if (!force_sysemu_disabled)
283 set_using_sysemu(sysemu_supported); 281 set_using_sysemu(sysemu_supported);
284 return; 282 return;
285 283
@@ -297,29 +295,29 @@ static void __init check_ptrace(void)
297 non_fatal("Checking that ptrace can change system call numbers..."); 295 non_fatal("Checking that ptrace can change system call numbers...");
298 pid = start_ptraced_child(&stack); 296 pid = start_ptraced_child(&stack);
299 297
300 if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, 298 if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
301 (void *) PTRACE_O_TRACESYSGOOD) < 0)) 299 (void *) PTRACE_O_TRACESYSGOOD) < 0))
302 fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed"); 300 fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
303 301
304 while(1){ 302 while (1) {
305 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) 303 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
306 fatal_perror("check_ptrace : ptrace failed"); 304 fatal_perror("check_ptrace : ptrace failed");
307 305
308 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 306 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
309 if(n < 0) 307 if (n < 0)
310 fatal_perror("check_ptrace : wait failed"); 308 fatal_perror("check_ptrace : wait failed");
311 309
312 if(!WIFSTOPPED(status) || 310 if (!WIFSTOPPED(status) ||
313 (WSTOPSIG(status) != (SIGTRAP | 0x80))) 311 (WSTOPSIG(status) != (SIGTRAP | 0x80)))
314 fatal("check_ptrace : expected (SIGTRAP|0x80), " 312 fatal("check_ptrace : expected (SIGTRAP|0x80), "
315 "got status = %d", status); 313 "got status = %d", status);
316 314
317 syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, 315 syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET,
318 0); 316 0);
319 if(syscall == __NR_getpid){ 317 if (syscall == __NR_getpid) {
320 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, 318 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
321 __NR_getppid); 319 __NR_getppid);
322 if(n < 0) 320 if (n < 0)
323 fatal_perror("check_ptrace : failed to modify " 321 fatal_perror("check_ptrace : failed to modify "
324 "system call"); 322 "system call");
325 break; 323 break;
@@ -337,18 +335,18 @@ static void __init check_coredump_limit(void)
337 struct rlimit lim; 335 struct rlimit lim;
338 int err = getrlimit(RLIMIT_CORE, &lim); 336 int err = getrlimit(RLIMIT_CORE, &lim);
339 337
340 if(err){ 338 if (err) {
341 perror("Getting core dump limit"); 339 perror("Getting core dump limit");
342 return; 340 return;
343 } 341 }
344 342
345 printf("Core dump limits :\n\tsoft - "); 343 printf("Core dump limits :\n\tsoft - ");
346 if(lim.rlim_cur == RLIM_INFINITY) 344 if (lim.rlim_cur == RLIM_INFINITY)
347 printf("NONE\n"); 345 printf("NONE\n");
348 else printf("%lu\n", lim.rlim_cur); 346 else printf("%lu\n", lim.rlim_cur);
349 347
350 printf("\thard - "); 348 printf("\thard - ");
351 if(lim.rlim_max == RLIM_INFINITY) 349 if (lim.rlim_max == RLIM_INFINITY)
352 printf("NONE\n"); 350 printf("NONE\n");
353 else printf("%lu\n", lim.rlim_max); 351 else printf("%lu\n", lim.rlim_max);
354} 352}
@@ -414,7 +412,7 @@ static inline void check_skas3_ptrace_faultinfo(void)
414 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); 412 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
415 if (n < 0) { 413 if (n < 0) {
416 ptrace_faultinfo = 0; 414 ptrace_faultinfo = 0;
417 if(errno == EIO) 415 if (errno == EIO)
418 non_fatal("not found\n"); 416 non_fatal("not found\n");
419 else 417 else
420 perror("not found"); 418 perror("not found");
@@ -446,7 +444,7 @@ static inline void check_skas3_ptrace_ldt(void)
446 444
447 n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op); 445 n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
448 if (n < 0) { 446 if (n < 0) {
449 if(errno == EIO) 447 if (errno == EIO)
450 non_fatal("not found\n"); 448 non_fatal("not found\n");
451 else { 449 else {
452 perror("not found"); 450 perror("not found");
@@ -454,7 +452,7 @@ static inline void check_skas3_ptrace_ldt(void)
454 ptrace_ldt = 0; 452 ptrace_ldt = 0;
455 } 453 }
456 else { 454 else {
457 if(ptrace_ldt) 455 if (ptrace_ldt)
458 non_fatal("found\n"); 456 non_fatal("found\n");
459 else 457 else
460 non_fatal("found, but use is disabled\n"); 458 non_fatal("found, but use is disabled\n");
@@ -477,12 +475,9 @@ static inline void check_skas3_proc_mm(void)
477 proc_mm = 0; 475 proc_mm = 0;
478 perror("not found"); 476 perror("not found");
479 } 477 }
480 else { 478 else if (!proc_mm)
481 if (!proc_mm) 479 non_fatal("found but disabled on command line\n");
482 non_fatal("found but disabled on command line\n"); 480 else non_fatal("found\n");
483 else
484 non_fatal("found\n");
485 }
486} 481}
487 482
488int can_do_skas(void) 483int can_do_skas(void)
@@ -493,7 +488,7 @@ int can_do_skas(void)
493 check_skas3_ptrace_faultinfo(); 488 check_skas3_ptrace_faultinfo();
494 check_skas3_ptrace_ldt(); 489 check_skas3_ptrace_ldt();
495 490
496 if(!proc_mm || !ptrace_faultinfo || !ptrace_ldt) 491 if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
497 skas_needs_stub = 1; 492 skas_needs_stub = 1;
498 493
499 return 1; 494 return 1;
@@ -508,25 +503,25 @@ int __init parse_iomem(char *str, int *add)
508 503
509 driver = str; 504 driver = str;
510 file = strchr(str,','); 505 file = strchr(str,',');
511 if(file == NULL){ 506 if (file == NULL) {
512 printf("parse_iomem : failed to parse iomem\n"); 507 printf("parse_iomem : failed to parse iomem\n");
513 goto out; 508 goto out;
514 } 509 }
515 *file = '\0'; 510 *file = '\0';
516 file++; 511 file++;
517 fd = open(file, O_RDWR, 0); 512 fd = open(file, O_RDWR, 0);
518 if(fd < 0){ 513 if (fd < 0) {
519 os_print_error(fd, "parse_iomem - Couldn't open io file"); 514 os_print_error(fd, "parse_iomem - Couldn't open io file");
520 goto out; 515 goto out;
521 } 516 }
522 517
523 if(fstat64(fd, &buf) < 0){ 518 if (fstat64(fd, &buf) < 0) {
524 perror("parse_iomem - cannot stat_fd file"); 519 perror("parse_iomem - cannot stat_fd file");
525 goto out_close; 520 goto out_close;
526 } 521 }
527 522
528 new = malloc(sizeof(*new)); 523 new = malloc(sizeof(*new));
529 if(new == NULL){ 524 if (new == NULL) {
530 perror("Couldn't allocate iomem_region struct"); 525 perror("Couldn't allocate iomem_region struct");
531 goto out_close; 526 goto out_close;
532 } 527 }
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index e87fb5362f4..be8e029f58b 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -1,13 +1,11 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 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>
7#include <signal.h> 6#include <signal.h>
8#include "kern_util.h"
9#include "os.h" 7#include "os.h"
10#include "longjmp.h" 8#include "sysdep/ptrace.h"
11 9
12/* Initialized from linux_main() */ 10/* Initialized from linux_main() */
13void (*sig_info[NSIG])(int, struct uml_pt_regs *); 11void (*sig_info[NSIG])(int, struct uml_pt_regs *);
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index e36541e5ec0..106fa864155 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -1,14 +1,19 @@
1/*
2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
1#include <stdio.h> 6#include <stdio.h>
2#include <unistd.h>
3#include <stdlib.h> 7#include <stdlib.h>
4#include <string.h> 8#include <dirent.h>
5#include <errno.h> 9#include <errno.h>
10#include <fcntl.h>
6#include <signal.h> 11#include <signal.h>
7#include <dirent.h> 12#include <string.h>
8#include <sys/fcntl.h> 13#include <unistd.h>
9#include <sys/stat.h> 14#include <sys/stat.h>
10#include <sys/param.h>
11#include "init.h" 15#include "init.h"
16#include "kern_constants.h"
12#include "os.h" 17#include "os.h"
13#include "user.h" 18#include "user.h"
14 19
@@ -27,13 +32,13 @@ static int __init make_uml_dir(void)
27 char dir[512] = { '\0' }; 32 char dir[512] = { '\0' };
28 int len, err; 33 int len, err;
29 34
30 if(*uml_dir == '~'){ 35 if (*uml_dir == '~') {
31 char *home = getenv("HOME"); 36 char *home = getenv("HOME");
32 37
33 err = -ENOENT; 38 err = -ENOENT;
34 if(home == NULL){ 39 if (home == NULL) {
35 printk("make_uml_dir : no value in environment for " 40 printk(UM_KERN_ERR "make_uml_dir : no value in "
36 "$HOME\n"); 41 "environment for $HOME\n");
37 goto err; 42 goto err;
38 } 43 }
39 strlcpy(dir, home, sizeof(dir)); 44 strlcpy(dir, home, sizeof(dir));
@@ -52,7 +57,7 @@ static int __init make_uml_dir(void)
52 } 57 }
53 strcpy(uml_dir, dir); 58 strcpy(uml_dir, dir);
54 59
55 if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){ 60 if ((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)) {
56 printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno)); 61 printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno));
57 err = -errno; 62 err = -errno;
58 goto err_free; 63 goto err_free;
@@ -69,8 +74,8 @@ err:
69/* 74/*
70 * Unlinks the files contained in @dir and then removes @dir. 75 * Unlinks the files contained in @dir and then removes @dir.
71 * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We 76 * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We
72 * ignore ENOENT errors for anything (they happen, strangely enough - possibly due 77 * ignore ENOENT errors for anything (they happen, strangely enough - possibly
73 * to races between multiple dying UML threads). 78 * due to races between multiple dying UML threads).
74 */ 79 */
75static int remove_files_and_dir(char *dir) 80static int remove_files_and_dir(char *dir)
76{ 81{
@@ -115,7 +120,8 @@ out:
115 return ret; 120 return ret;
116} 121}
117 122
118/* This says that there isn't already a user of the specified directory even if 123/*
124 * This says that there isn't already a user of the specified directory even if
119 * there are errors during the checking. This is because if these errors 125 * there are errors during the checking. This is because if these errors
120 * happen, the directory is unusable by the pre-existing UML, so we might as 126 * happen, the directory is unusable by the pre-existing UML, so we might as
121 * well take it over. This could happen either by 127 * well take it over. This could happen either by
@@ -133,44 +139,45 @@ static inline int is_umdir_used(char *dir)
133 int dead, fd, p, n, err; 139 int dead, fd, p, n, err;
134 140
135 n = snprintf(file, sizeof(file), "%s/pid", dir); 141 n = snprintf(file, sizeof(file), "%s/pid", dir);
136 if(n >= sizeof(file)){ 142 if (n >= sizeof(file)) {
137 printk("is_umdir_used - pid filename too long\n"); 143 printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n");
138 err = -E2BIG; 144 err = -E2BIG;
139 goto out; 145 goto out;
140 } 146 }
141 147
142 dead = 0; 148 dead = 0;
143 fd = open(file, O_RDONLY); 149 fd = open(file, O_RDONLY);
144 if(fd < 0) { 150 if (fd < 0) {
145 fd = -errno; 151 fd = -errno;
146 if(fd != -ENOENT){ 152 if (fd != -ENOENT) {
147 printk("is_umdir_used : couldn't open pid file '%s', " 153 printk(UM_KERN_ERR "is_umdir_used : couldn't open pid "
148 "err = %d\n", file, -fd); 154 "file '%s', err = %d\n", file, -fd);
149 } 155 }
150 goto out; 156 goto out;
151 } 157 }
152 158
153 err = 0; 159 err = 0;
154 n = read(fd, pid, sizeof(pid)); 160 n = read(fd, pid, sizeof(pid));
155 if(n < 0){ 161 if (n < 0) {
156 printk("is_umdir_used : couldn't read pid file '%s', " 162 printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
157 "err = %d\n", file, errno); 163 "'%s', err = %d\n", file, errno);
158 goto out_close; 164 goto out_close;
159 } else if(n == 0){ 165 } else if (n == 0) {
160 printk("is_umdir_used : couldn't read pid file '%s', " 166 printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
161 "0-byte read\n", file); 167 "'%s', 0-byte read\n", file);
162 goto out_close; 168 goto out_close;
163 } 169 }
164 170
165 p = strtoul(pid, &end, 0); 171 p = strtoul(pid, &end, 0);
166 if(end == pid){ 172 if (end == pid) {
167 printk("is_umdir_used : couldn't parse pid file '%s', " 173 printk(UM_KERN_ERR "is_umdir_used : couldn't parse pid file "
168 "errno = %d\n", file, errno); 174 "'%s', errno = %d\n", file, errno);
169 goto out_close; 175 goto out_close;
170 } 176 }
171 177
172 if((kill(p, 0) == 0) || (errno != ESRCH)){ 178 if ((kill(p, 0) == 0) || (errno != ESRCH)) {
173 printk("umid \"%s\" is already in use by pid %d\n", umid, p); 179 printk(UM_KERN_ERR "umid \"%s\" is already in use by pid %d\n",
180 umid, p);
174 return 1; 181 return 1;
175 } 182 }
176 183
@@ -194,8 +201,8 @@ static int umdir_take_if_dead(char *dir)
194 201
195 ret = remove_files_and_dir(dir); 202 ret = remove_files_and_dir(dir);
196 if (ret) { 203 if (ret) {
197 printk("is_umdir_used - remove_files_and_dir failed with " 204 printk(UM_KERN_ERR "is_umdir_used - remove_files_and_dir "
198 "err = %d\n", ret); 205 "failed with err = %d\n", ret);
199 } 206 }
200 return ret; 207 return ret;
201} 208}
@@ -206,27 +213,28 @@ static void __init create_pid_file(void)
206 char pid[sizeof("nnnnn\0")]; 213 char pid[sizeof("nnnnn\0")];
207 int fd, n; 214 int fd, n;
208 215
209 if(umid_file_name("pid", file, sizeof(file))) 216 if (umid_file_name("pid", file, sizeof(file)))
210 return; 217 return;
211 218
212 fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644); 219 fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644);
213 if(fd < 0){ 220 if (fd < 0) {
214 printk("Open of machine pid file \"%s\" failed: %s\n", 221 printk(UM_KERN_ERR "Open of machine pid file \"%s\" failed: "
215 file, strerror(errno)); 222 "%s\n", file, strerror(errno));
216 return; 223 return;
217 } 224 }
218 225
219 snprintf(pid, sizeof(pid), "%d\n", getpid()); 226 snprintf(pid, sizeof(pid), "%d\n", getpid());
220 n = write(fd, pid, strlen(pid)); 227 n = write(fd, pid, strlen(pid));
221 if(n != strlen(pid)) 228 if (n != strlen(pid))
222 printk("Write of pid file failed - err = %d\n", errno); 229 printk(UM_KERN_ERR "Write of pid file failed - err = %d\n",
230 errno);
223 231
224 close(fd); 232 close(fd);
225} 233}
226 234
227int __init set_umid(char *name) 235int __init set_umid(char *name)
228{ 236{
229 if(strlen(name) > UMID_LEN - 1) 237 if (strlen(name) > UMID_LEN - 1)
230 return -E2BIG; 238 return -E2BIG;
231 239
232 strlcpy(umid, name, sizeof(umid)); 240 strlcpy(umid, name, sizeof(umid));
@@ -242,18 +250,18 @@ int __init make_umid(void)
242 int fd, err; 250 int fd, err;
243 char tmp[256]; 251 char tmp[256];
244 252
245 if(umid_setup) 253 if (umid_setup)
246 return 0; 254 return 0;
247 255
248 make_uml_dir(); 256 make_uml_dir();
249 257
250 if(*umid == '\0'){ 258 if (*umid == '\0') {
251 strlcpy(tmp, uml_dir, sizeof(tmp)); 259 strlcpy(tmp, uml_dir, sizeof(tmp));
252 strlcat(tmp, "XXXXXX", sizeof(tmp)); 260 strlcat(tmp, "XXXXXX", sizeof(tmp));
253 fd = mkstemp(tmp); 261 fd = mkstemp(tmp);
254 if(fd < 0){ 262 if (fd < 0) {
255 printk("make_umid - mkstemp(%s) failed: %s\n", 263 printk(UM_KERN_ERR "make_umid - mkstemp(%s) failed: "
256 tmp, strerror(errno)); 264 "%s\n", tmp, strerror(errno));
257 err = -errno; 265 err = -errno;
258 goto err; 266 goto err;
259 } 267 }
@@ -262,11 +270,12 @@ int __init make_umid(void)
262 270
263 set_umid(&tmp[strlen(uml_dir)]); 271 set_umid(&tmp[strlen(uml_dir)]);
264 272
265 /* There's a nice tiny little race between this unlink and 273 /*
274 * There's a nice tiny little race between this unlink and
266 * the mkdir below. It'd be nice if there were a mkstemp 275 * the mkdir below. It'd be nice if there were a mkstemp
267 * for directories. 276 * for directories.
268 */ 277 */
269 if(unlink(tmp)){ 278 if (unlink(tmp)) {
270 err = -errno; 279 err = -errno;
271 goto err; 280 goto err;
272 } 281 }
@@ -274,9 +283,9 @@ int __init make_umid(void)
274 283
275 snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid); 284 snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid);
276 err = mkdir(tmp, 0777); 285 err = mkdir(tmp, 0777);
277 if(err < 0){ 286 if (err < 0) {
278 err = -errno; 287 err = -errno;
279 if(err != -EEXIST) 288 if (err != -EEXIST)
280 goto err; 289 goto err;
281 290
282 if (umdir_take_if_dead(tmp) < 0) 291 if (umdir_take_if_dead(tmp) < 0)
@@ -284,9 +293,10 @@ int __init make_umid(void)
284 293
285 err = mkdir(tmp, 0777); 294 err = mkdir(tmp, 0777);
286 } 295 }
287 if(err){ 296 if (err) {
288 err = -errno; 297 err = -errno;
289 printk("Failed to create '%s' - err = %d\n", umid, -errno); 298 printk(UM_KERN_ERR "Failed to create '%s' - err = %d\n", umid,
299 errno);
290 goto err; 300 goto err;
291 } 301 }
292 302
@@ -301,14 +311,15 @@ int __init make_umid(void)
301 311
302static int __init make_umid_init(void) 312static int __init make_umid_init(void)
303{ 313{
304 if(!make_umid()) 314 if (!make_umid())
305 return 0; 315 return 0;
306 316
307 /* If initializing with the given umid failed, then try again with 317 /*
318 * If initializing with the given umid failed, then try again with
308 * a random one. 319 * a random one.
309 */ 320 */
310 printk("Failed to initialize umid \"%s\", trying with a random umid\n", 321 printk(UM_KERN_ERR "Failed to initialize umid \"%s\", trying with a "
311 umid); 322 "random umid\n", umid);
312 *umid = '\0'; 323 *umid = '\0';
313 make_umid(); 324 make_umid();
314 325
@@ -322,12 +333,12 @@ int __init umid_file_name(char *name, char *buf, int len)
322 int n, err; 333 int n, err;
323 334
324 err = make_umid(); 335 err = make_umid();
325 if(err) 336 if (err)
326 return err; 337 return err;
327 338
328 n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name); 339 n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name);
329 if(n >= len){ 340 if (n >= len) {
330 printk("umid_file_name : buffer too short\n"); 341 printk(UM_KERN_ERR "umid_file_name : buffer too short\n");
331 return -E2BIG; 342 return -E2BIG;
332 } 343 }
333 344
@@ -341,21 +352,22 @@ char *get_umid(void)
341 352
342static int __init set_uml_dir(char *name, int *add) 353static int __init set_uml_dir(char *name, int *add)
343{ 354{
344 if(*name == '\0'){ 355 if (*name == '\0') {
345 printf("uml_dir can't be an empty string\n"); 356 printf("uml_dir can't be an empty string\n");
346 return 0; 357 return 0;
347 } 358 }
348 359
349 if(name[strlen(name) - 1] == '/'){ 360 if (name[strlen(name) - 1] == '/') {
350 uml_dir = name; 361 uml_dir = name;
351 return 0; 362 return 0;
352 } 363 }
353 364
354 uml_dir = malloc(strlen(name) + 2); 365 uml_dir = malloc(strlen(name) + 2);
355 if(uml_dir == NULL){ 366 if (uml_dir == NULL) {
356 printf("Failed to malloc uml_dir - error = %d\n", errno); 367 printf("Failed to malloc uml_dir - error = %d\n", errno);
357 368
358 /* Return 0 here because do_initcalls doesn't look at 369 /*
370 * Return 0 here because do_initcalls doesn't look at
359 * the return value. 371 * the return value.
360 */ 372 */
361 return 0; 373 return 0;
@@ -376,7 +388,7 @@ static void remove_umid_dir(void)
376 388
377 sprintf(dir, "%s%s", uml_dir, umid); 389 sprintf(dir, "%s%s", uml_dir, umid);
378 err = remove_files_and_dir(dir); 390 err = remove_files_and_dir(dir);
379 if(err) 391 if (err)
380 printf("remove_umid_dir - remove_files_and_dir failed with " 392 printf("remove_umid_dir - remove_files_and_dir failed with "
381 "err = %d\n", err); 393 "err = %d\n", err);
382} 394}