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/Makefile4
-rw-r--r--arch/um/os-Linux/aio.c1
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c2
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c5
-rw-r--r--arch/um/os-Linux/file.c287
-rw-r--r--arch/um/os-Linux/helper.c74
-rw-r--r--arch/um/os-Linux/irq.c39
-rw-r--r--arch/um/os-Linux/main.c14
-rw-r--r--arch/um/os-Linux/mem.c13
-rw-r--r--arch/um/os-Linux/process.c5
-rw-r--r--arch/um/os-Linux/registers.c34
-rw-r--r--arch/um/os-Linux/sigio.c244
-rw-r--r--arch/um/os-Linux/signal.c102
-rw-r--r--arch/um/os-Linux/skas/Makefile6
-rw-r--r--arch/um/os-Linux/skas/process.c281
-rw-r--r--arch/um/os-Linux/skas/trap.c69
-rw-r--r--arch/um/os-Linux/start_up.c17
-rw-r--r--arch/um/os-Linux/trap.c23
-rw-r--r--arch/um/os-Linux/tty.c57
-rw-r--r--arch/um/os-Linux/tty_log.c1
-rw-r--r--arch/um/os-Linux/util.c15
21 files changed, 648 insertions, 645 deletions
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 8e129af8170d..8a48d6a30064 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -4,7 +4,7 @@
4# 4#
5 5
6obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ 6obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
7 registers.o sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o \ 7 registers.o sigio.o signal.o start_up.o time.o tty.o uaccess.o \
8 umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/ 8 umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/
9 9
10obj-$(CONFIG_TTY_LOG) += tty_log.o 10obj-$(CONFIG_TTY_LOG) += tty_log.o
@@ -12,7 +12,7 @@ user-objs-$(CONFIG_TTY_LOG) += tty_log.o
12 12
13USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ 13USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \
14 main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ 14 main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \
15 trap.o tty.o tls.o uaccess.o umid.o util.o 15 tty.o tls.o uaccess.o umid.o util.o
16 16
17CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) 17CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
18 18
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 93dc0c80ebaf..b8d8c9ca8d4a 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -12,6 +12,7 @@
12#include "aio.h" 12#include "aio.h"
13#include "init.h" 13#include "init.h"
14#include "kern_constants.h" 14#include "kern_constants.h"
15#include "kern_util.h"
15#include "os.h" 16#include "os.h"
16#include "user.h" 17#include "user.h"
17 18
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 07ca0cb472ac..6fb0b174f538 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -131,7 +131,7 @@ static int etap_tramp(char *dev, char *gate, int control_me,
131 } 131 }
132 if (c != 1) { 132 if (c != 1) {
133 printk(UM_KERN_ERR "etap_tramp : uml_net failed\n"); 133 printk(UM_KERN_ERR "etap_tramp : uml_net failed\n");
134 err = helper_wait(pid, 0, "uml_net"); 134 err = helper_wait(pid);
135 } 135 }
136 return err; 136 return err;
137} 137}
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index 1037a3b6386e..2448be03fd7a 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -14,6 +14,7 @@
14#include <sys/wait.h> 14#include <sys/wait.h>
15#include <sys/uio.h> 15#include <sys/uio.h>
16#include "kern_constants.h" 16#include "kern_constants.h"
17#include "kern_util.h"
17#include "os.h" 18#include "os.h"
18#include "tuntap.h" 19#include "tuntap.h"
19#include "user.h" 20#include "user.h"
@@ -107,7 +108,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
107 "errno = %d\n", errno); 108 "errno = %d\n", errno);
108 return err; 109 return err;
109 } 110 }
110 helper_wait(pid, 0, "tuntap_open_tramp"); 111 helper_wait(pid);
111 112
112 cmsg = CMSG_FIRSTHDR(&msg); 113 cmsg = CMSG_FIRSTHDR(&msg);
113 if (cmsg == NULL) { 114 if (cmsg == NULL) {
@@ -148,7 +149,7 @@ static int tuntap_open(void *data)
148 memset(&ifr, 0, sizeof(ifr)); 149 memset(&ifr, 0, sizeof(ifr));
149 ifr.ifr_flags = IFF_TAP | IFF_NO_PI; 150 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
150 strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name)); 151 strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
151 if (ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0) { 152 if (ioctl(pri->fd, TUNSETIFF, &ifr) < 0) {
152 err = -errno; 153 err = -errno;
153 printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n", 154 printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n",
154 errno); 155 errno);
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index f83462758627..b5afcfd0f861 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -1,5 +1,5 @@
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
@@ -8,18 +8,16 @@
8#include <errno.h> 8#include <errno.h>
9#include <fcntl.h> 9#include <fcntl.h>
10#include <signal.h> 10#include <signal.h>
11#include <sys/types.h>
12#include <sys/stat.h>
13#include <sys/socket.h>
14#include <sys/un.h>
15#include <sys/ioctl.h> 11#include <sys/ioctl.h>
16#include <sys/mount.h> 12#include <sys/mount.h>
17#include <sys/uio.h> 13#include <sys/socket.h>
14#include <sys/stat.h>
15#include <sys/un.h>
16#include "kern_constants.h"
18#include "os.h" 17#include "os.h"
19#include "user.h" 18#include "user.h"
20#include "kern_util.h"
21 19
22static void copy_stat(struct uml_stat *dst, struct stat64 *src) 20static void copy_stat(struct uml_stat *dst, const struct stat64 *src)
23{ 21{
24 *dst = ((struct uml_stat) { 22 *dst = ((struct uml_stat) {
25 .ust_dev = src->st_dev, /* device */ 23 .ust_dev = src->st_dev, /* device */
@@ -43,10 +41,10 @@ int os_stat_fd(const int fd, struct uml_stat *ubuf)
43 int err; 41 int err;
44 42
45 CATCH_EINTR(err = fstat64(fd, &sbuf)); 43 CATCH_EINTR(err = fstat64(fd, &sbuf));
46 if(err < 0) 44 if (err < 0)
47 return -errno; 45 return -errno;
48 46
49 if(ubuf != NULL) 47 if (ubuf != NULL)
50 copy_stat(ubuf, &sbuf); 48 copy_stat(ubuf, &sbuf);
51 return err; 49 return err;
52} 50}
@@ -56,27 +54,26 @@ int os_stat_file(const char *file_name, struct uml_stat *ubuf)
56 struct stat64 sbuf; 54 struct stat64 sbuf;
57 int err; 55 int err;
58 56
59 do { 57 CATCH_EINTR(err = stat64(file_name, &sbuf));
60 err = stat64(file_name, &sbuf); 58 if (err < 0)
61 } while((err < 0) && (errno == EINTR)) ;
62
63 if(err < 0)
64 return -errno; 59 return -errno;
65 60
66 if(ubuf != NULL) 61 if (ubuf != NULL)
67 copy_stat(ubuf, &sbuf); 62 copy_stat(ubuf, &sbuf);
68 return err; 63 return err;
69} 64}
70 65
71int os_access(const char* file, int mode) 66int os_access(const char *file, int mode)
72{ 67{
73 int amode, err; 68 int amode, err;
74 69
75 amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) | 70 amode = (mode & OS_ACC_R_OK ? R_OK : 0) |
76 (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ; 71 (mode & OS_ACC_W_OK ? W_OK : 0) |
72 (mode & OS_ACC_X_OK ? X_OK : 0) |
73 (mode & OS_ACC_F_OK ? F_OK : 0);
77 74
78 err = access(file, amode); 75 err = access(file, amode);
79 if(err < 0) 76 if (err < 0)
80 return -errno; 77 return -errno;
81 78
82 return 0; 79 return 0;
@@ -88,7 +85,7 @@ int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
88 int err; 85 int err;
89 86
90 err = ioctl(fd, cmd, arg); 87 err = ioctl(fd, cmd, arg);
91 if(err < 0) 88 if (err < 0)
92 return -errno; 89 return -errno;
93 90
94 return err; 91 return err;
@@ -97,7 +94,7 @@ int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
97/* FIXME: ensure namebuf in os_get_if_name is big enough */ 94/* FIXME: ensure namebuf in os_get_if_name is big enough */
98int os_get_ifname(int fd, char* namebuf) 95int os_get_ifname(int fd, char* namebuf)
99{ 96{
100 if(ioctl(fd, SIOCGIFNAME, namebuf) < 0) 97 if (ioctl(fd, SIOCGIFNAME, namebuf) < 0)
101 return -errno; 98 return -errno;
102 99
103 return 0; 100 return 0;
@@ -108,37 +105,22 @@ int os_set_slip(int fd)
108 int disc, sencap; 105 int disc, sencap;
109 106
110 disc = N_SLIP; 107 disc = N_SLIP;
111 if(ioctl(fd, TIOCSETD, &disc) < 0) 108 if (ioctl(fd, TIOCSETD, &disc) < 0)
112 return -errno; 109 return -errno;
113 110
114 sencap = 0; 111 sencap = 0;
115 if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0) 112 if (ioctl(fd, SIOCSIFENCAP, &sencap) < 0)
116 return -errno; 113 return -errno;
117 114
118 return 0; 115 return 0;
119} 116}
120 117
121int os_set_owner(int fd, int pid)
122{
123 if(fcntl(fd, F_SETOWN, pid) < 0){
124 int save_errno = errno;
125
126 if(fcntl(fd, F_GETOWN, 0) != pid)
127 return -save_errno;
128 }
129
130 return 0;
131}
132
133int os_mode_fd(int fd, int mode) 118int os_mode_fd(int fd, int mode)
134{ 119{
135 int err; 120 int err;
136 121
137 do { 122 CATCH_EINTR(err = fchmod(fd, mode));
138 err = fchmod(fd, mode); 123 if (err < 0)
139 } while((err < 0) && (errno==EINTR)) ;
140
141 if(err < 0)
142 return -errno; 124 return -errno;
143 125
144 return 0; 126 return 0;
@@ -150,64 +132,73 @@ int os_file_type(char *file)
150 int err; 132 int err;
151 133
152 err = os_stat_file(file, &buf); 134 err = os_stat_file(file, &buf);
153 if(err < 0) 135 if (err < 0)
154 return err; 136 return err;
155 137
156 if(S_ISDIR(buf.ust_mode)) 138 if (S_ISDIR(buf.ust_mode))
157 return OS_TYPE_DIR; 139 return OS_TYPE_DIR;
158 else if(S_ISLNK(buf.ust_mode)) 140 else if (S_ISLNK(buf.ust_mode))
159 return OS_TYPE_SYMLINK; 141 return OS_TYPE_SYMLINK;
160 else if(S_ISCHR(buf.ust_mode)) 142 else if (S_ISCHR(buf.ust_mode))
161 return OS_TYPE_CHARDEV; 143 return OS_TYPE_CHARDEV;
162 else if(S_ISBLK(buf.ust_mode)) 144 else if (S_ISBLK(buf.ust_mode))
163 return OS_TYPE_BLOCKDEV; 145 return OS_TYPE_BLOCKDEV;
164 else if(S_ISFIFO(buf.ust_mode)) 146 else if (S_ISFIFO(buf.ust_mode))
165 return OS_TYPE_FIFO; 147 return OS_TYPE_FIFO;
166 else if(S_ISSOCK(buf.ust_mode)) 148 else if (S_ISSOCK(buf.ust_mode))
167 return OS_TYPE_SOCK; 149 return OS_TYPE_SOCK;
168 else return OS_TYPE_FILE; 150 else return OS_TYPE_FILE;
169} 151}
170 152
171int os_file_mode(char *file, struct openflags *mode_out) 153int os_file_mode(const char *file, struct openflags *mode_out)
172{ 154{
173 int err; 155 int err;
174 156
175 *mode_out = OPENFLAGS(); 157 *mode_out = OPENFLAGS();
176 158
177 err = access(file, W_OK); 159 err = access(file, W_OK);
178 if(err && (errno != EACCES)) 160 if (err && (errno != EACCES))
179 return -errno; 161 return -errno;
180 else if(!err) 162 else if (!err)
181 *mode_out = of_write(*mode_out); 163 *mode_out = of_write(*mode_out);
182 164
183 err = access(file, R_OK); 165 err = access(file, R_OK);
184 if(err && (errno != EACCES)) 166 if (err && (errno != EACCES))
185 return -errno; 167 return -errno;
186 else if(!err) 168 else if (!err)
187 *mode_out = of_read(*mode_out); 169 *mode_out = of_read(*mode_out);
188 170
189 return err; 171 return err;
190} 172}
191 173
192int os_open_file(char *file, struct openflags flags, int mode) 174int os_open_file(const char *file, struct openflags flags, int mode)
193{ 175{
194 int fd, err, f = 0; 176 int fd, err, f = 0;
195 177
196 if(flags.r && flags.w) f = O_RDWR; 178 if (flags.r && flags.w)
197 else if(flags.r) f = O_RDONLY; 179 f = O_RDWR;
198 else if(flags.w) f = O_WRONLY; 180 else if (flags.r)
181 f = O_RDONLY;
182 else if (flags.w)
183 f = O_WRONLY;
199 else f = 0; 184 else f = 0;
200 185
201 if(flags.s) f |= O_SYNC; 186 if (flags.s)
202 if(flags.c) f |= O_CREAT; 187 f |= O_SYNC;
203 if(flags.t) f |= O_TRUNC; 188 if (flags.c)
204 if(flags.e) f |= O_EXCL; 189 f |= O_CREAT;
190 if (flags.t)
191 f |= O_TRUNC;
192 if (flags.e)
193 f |= O_EXCL;
194 if (flags.a)
195 f |= O_APPEND;
205 196
206 fd = open64(file, f, mode); 197 fd = open64(file, f, mode);
207 if(fd < 0) 198 if (fd < 0)
208 return -errno; 199 return -errno;
209 200
210 if(flags.cl && fcntl(fd, F_SETFD, 1)){ 201 if (flags.cl && fcntl(fd, F_SETFD, 1)) {
211 err = -errno; 202 err = -errno;
212 close(fd); 203 close(fd);
213 return err; 204 return err;
@@ -216,7 +207,7 @@ int os_open_file(char *file, struct openflags flags, int mode)
216 return fd; 207 return fd;
217} 208}
218 209
219int os_connect_socket(char *name) 210int os_connect_socket(const char *name)
220{ 211{
221 struct sockaddr_un sock; 212 struct sockaddr_un sock;
222 int fd, err; 213 int fd, err;
@@ -225,13 +216,13 @@ int os_connect_socket(char *name)
225 snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name); 216 snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
226 217
227 fd = socket(AF_UNIX, SOCK_STREAM, 0); 218 fd = socket(AF_UNIX, SOCK_STREAM, 0);
228 if(fd < 0) { 219 if (fd < 0) {
229 err = -errno; 220 err = -errno;
230 goto out; 221 goto out;
231 } 222 }
232 223
233 err = connect(fd, (struct sockaddr *) &sock, sizeof(sock)); 224 err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
234 if(err) { 225 if (err) {
235 err = -errno; 226 err = -errno;
236 goto out_close; 227 goto out_close;
237 } 228 }
@@ -254,7 +245,7 @@ int os_seek_file(int fd, unsigned long long offset)
254 unsigned long long actual; 245 unsigned long long actual;
255 246
256 actual = lseek64(fd, offset, SEEK_SET); 247 actual = lseek64(fd, offset, SEEK_SET);
257 if(actual != offset) 248 if (actual != offset)
258 return -errno; 249 return -errno;
259 return 0; 250 return 0;
260} 251}
@@ -263,7 +254,7 @@ int os_read_file(int fd, void *buf, int len)
263{ 254{
264 int n = read(fd, buf, len); 255 int n = read(fd, buf, len);
265 256
266 if(n < 0) 257 if (n < 0)
267 return -errno; 258 return -errno;
268 return n; 259 return n;
269} 260}
@@ -272,37 +263,38 @@ int os_write_file(int fd, const void *buf, int len)
272{ 263{
273 int n = write(fd, (void *) buf, len); 264 int n = write(fd, (void *) buf, len);
274 265
275 if(n < 0) 266 if (n < 0)
276 return -errno; 267 return -errno;
277 return n; 268 return n;
278} 269}
279 270
280int os_file_size(char *file, unsigned long long *size_out) 271int os_file_size(const char *file, unsigned long long *size_out)
281{ 272{
282 struct uml_stat buf; 273 struct uml_stat buf;
283 int err; 274 int err;
284 275
285 err = os_stat_file(file, &buf); 276 err = os_stat_file(file, &buf);
286 if(err < 0){ 277 if (err < 0) {
287 printk("Couldn't stat \"%s\" : err = %d\n", file, -err); 278 printk(UM_KERN_ERR "Couldn't stat \"%s\" : err = %d\n", file,
279 -err);
288 return err; 280 return err;
289 } 281 }
290 282
291 if(S_ISBLK(buf.ust_mode)){ 283 if (S_ISBLK(buf.ust_mode)) {
292 int fd; 284 int fd;
293 long blocks; 285 long blocks;
294 286
295 fd = open(file, O_RDONLY, 0); 287 fd = open(file, O_RDONLY, 0);
296 if(fd < 0) { 288 if (fd < 0) {
297 err = -errno; 289 err = -errno;
298 printk("Couldn't open \"%s\", errno = %d\n", file, 290 printk(UM_KERN_ERR "Couldn't open \"%s\", "
299 errno); 291 "errno = %d\n", file, errno);
300 return err; 292 return err;
301 } 293 }
302 if(ioctl(fd, BLKGETSIZE, &blocks) < 0){ 294 if (ioctl(fd, BLKGETSIZE, &blocks) < 0) {
303 err = -errno; 295 err = -errno;
304 printk("Couldn't get the block size of \"%s\", " 296 printk(UM_KERN_ERR "Couldn't get the block size of "
305 "errno = %d\n", file, errno); 297 "\"%s\", errno = %d\n", file, errno);
306 close(fd); 298 close(fd);
307 return err; 299 return err;
308 } 300 }
@@ -314,14 +306,15 @@ int os_file_size(char *file, unsigned long long *size_out)
314 return 0; 306 return 0;
315} 307}
316 308
317int os_file_modtime(char *file, unsigned long *modtime) 309int os_file_modtime(const char *file, unsigned long *modtime)
318{ 310{
319 struct uml_stat buf; 311 struct uml_stat buf;
320 int err; 312 int err;
321 313
322 err = os_stat_file(file, &buf); 314 err = os_stat_file(file, &buf);
323 if(err < 0){ 315 if (err < 0) {
324 printk("Couldn't stat \"%s\" : err = %d\n", file, -err); 316 printk(UM_KERN_ERR "Couldn't stat \"%s\" : err = %d\n", file,
317 -err);
325 return err; 318 return err;
326 } 319 }
327 320
@@ -329,26 +322,13 @@ int os_file_modtime(char *file, unsigned long *modtime)
329 return 0; 322 return 0;
330} 323}
331 324
332int os_get_exec_close(int fd, int *close_on_exec)
333{
334 int ret;
335
336 CATCH_EINTR(ret = fcntl(fd, F_GETFD));
337
338 if(ret < 0)
339 return -errno;
340
341 *close_on_exec = (ret & FD_CLOEXEC) ? 1 : 0;
342 return ret;
343}
344
345int os_set_exec_close(int fd) 325int os_set_exec_close(int fd)
346{ 326{
347 int err; 327 int err;
348 328
349 CATCH_EINTR(err = fcntl(fd, F_SETFD, FD_CLOEXEC)); 329 CATCH_EINTR(err = fcntl(fd, F_SETFD, FD_CLOEXEC));
350 330
351 if(err < 0) 331 if (err < 0)
352 return -errno; 332 return -errno;
353 return err; 333 return err;
354} 334}
@@ -358,53 +338,51 @@ int os_pipe(int *fds, int stream, int close_on_exec)
358 int err, type = stream ? SOCK_STREAM : SOCK_DGRAM; 338 int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
359 339
360 err = socketpair(AF_UNIX, type, 0, fds); 340 err = socketpair(AF_UNIX, type, 0, fds);
361 if(err < 0) 341 if (err < 0)
362 return -errno; 342 return -errno;
363 343
364 if(!close_on_exec) 344 if (!close_on_exec)
365 return 0; 345 return 0;
366 346
367 err = os_set_exec_close(fds[0]); 347 err = os_set_exec_close(fds[0]);
368 if(err < 0) 348 if (err < 0)
369 goto error; 349 goto error;
370 350
371 err = os_set_exec_close(fds[1]); 351 err = os_set_exec_close(fds[1]);
372 if(err < 0) 352 if (err < 0)
373 goto error; 353 goto error;
374 354
375 return 0; 355 return 0;
376 356
377 error: 357 error:
378 printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err); 358 printk(UM_KERN_ERR "os_pipe : Setting FD_CLOEXEC failed, err = %d\n",
359 -err);
379 close(fds[1]); 360 close(fds[1]);
380 close(fds[0]); 361 close(fds[0]);
381 return err; 362 return err;
382} 363}
383 364
384int os_set_fd_async(int fd, int owner) 365int os_set_fd_async(int fd)
385{ 366{
386 int err; 367 int err, flags;
368
369 flags = fcntl(fd, F_GETFL);
370 if (flags < 0)
371 return -errno;
387 372
388 /* XXX This should do F_GETFL first */ 373 flags |= O_ASYNC | O_NONBLOCK;
389 if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){ 374 if (fcntl(fd, F_SETFL, flags) < 0) {
390 err = -errno; 375 err = -errno;
391 printk("os_set_fd_async : failed to set O_ASYNC and " 376 printk(UM_KERN_ERR "os_set_fd_async : failed to set O_ASYNC "
392 "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno); 377 "and O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
393 return err; 378 return err;
394 } 379 }
395#ifdef notdef
396 if(fcntl(fd, F_SETFD, 1) < 0){
397 printk("os_set_fd_async : Setting FD_CLOEXEC failed, "
398 "errno = %d\n", errno);
399 }
400#endif
401 380
402 if((fcntl(fd, F_SETSIG, SIGIO) < 0) || 381 if ((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
403 (fcntl(fd, F_SETOWN, owner) < 0)){ 382 (fcntl(fd, F_SETOWN, os_getpid()) < 0)) {
404 err = -errno; 383 err = -errno;
405 printk("os_set_fd_async : Failed to fcntl F_SETOWN " 384 printk(UM_KERN_ERR "os_set_fd_async : Failed to fcntl F_SETOWN "
406 "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, 385 "(or F_SETSIG) fd %d, errno = %d\n", fd, errno);
407 owner, errno);
408 return err; 386 return err;
409 } 387 }
410 388
@@ -413,10 +391,14 @@ int os_set_fd_async(int fd, int owner)
413 391
414int os_clear_fd_async(int fd) 392int os_clear_fd_async(int fd)
415{ 393{
416 int flags = fcntl(fd, F_GETFL); 394 int flags;
395
396 flags = fcntl(fd, F_GETFL);
397 if (flags < 0)
398 return -errno;
417 399
418 flags &= ~(O_ASYNC | O_NONBLOCK); 400 flags &= ~(O_ASYNC | O_NONBLOCK);
419 if(fcntl(fd, F_SETFL, flags) < 0) 401 if (fcntl(fd, F_SETFL, flags) < 0)
420 return -errno; 402 return -errno;
421 return 0; 403 return 0;
422} 404}
@@ -426,11 +408,15 @@ int os_set_fd_block(int fd, int blocking)
426 int flags; 408 int flags;
427 409
428 flags = fcntl(fd, F_GETFL); 410 flags = fcntl(fd, F_GETFL);
411 if (flags < 0)
412 return -errno;
429 413
430 if(blocking) flags &= ~O_NONBLOCK; 414 if (blocking)
431 else flags |= O_NONBLOCK; 415 flags &= ~O_NONBLOCK;
416 else
417 flags |= O_NONBLOCK;
432 418
433 if(fcntl(fd, F_SETFL, flags) < 0) 419 if (fcntl(fd, F_SETFL, flags) < 0)
434 return -errno; 420 return -errno;
435 421
436 return 0; 422 return 0;
@@ -441,7 +427,7 @@ int os_accept_connection(int fd)
441 int new; 427 int new;
442 428
443 new = accept(fd, NULL, 0); 429 new = accept(fd, NULL, 0);
444 if(new < 0) 430 if (new < 0)
445 return -errno; 431 return -errno;
446 return new; 432 return new;
447} 433}
@@ -462,15 +448,17 @@ int os_shutdown_socket(int fd, int r, int w)
462{ 448{
463 int what, err; 449 int what, err;
464 450
465 if(r && w) what = SHUT_RDWR; 451 if (r && w)
466 else if(r) what = SHUT_RD; 452 what = SHUT_RDWR;
467 else if(w) what = SHUT_WR; 453 else if (r)
468 else { 454 what = SHUT_RD;
469 printk("os_shutdown_socket : neither r or w was set\n"); 455 else if (w)
456 what = SHUT_WR;
457 else
470 return -EINVAL; 458 return -EINVAL;
471 } 459
472 err = shutdown(fd, what); 460 err = shutdown(fd, what);
473 if(err < 0) 461 if (err < 0)
474 return -errno; 462 return -errno;
475 return 0; 463 return 0;
476} 464}
@@ -494,19 +482,20 @@ int os_rcv_fd(int fd, int *helper_pid_out)
494 msg.msg_flags = 0; 482 msg.msg_flags = 0;
495 483
496 n = recvmsg(fd, &msg, 0); 484 n = recvmsg(fd, &msg, 0);
497 if(n < 0) 485 if (n < 0)
498 return -errno; 486 return -errno;
499 else if(n != iov.iov_len) 487 else if (n != iov.iov_len)
500 *helper_pid_out = -1; 488 *helper_pid_out = -1;
501 489
502 cmsg = CMSG_FIRSTHDR(&msg); 490 cmsg = CMSG_FIRSTHDR(&msg);
503 if(cmsg == NULL){ 491 if (cmsg == NULL) {
504 printk("rcv_fd didn't receive anything, error = %d\n", errno); 492 printk(UM_KERN_ERR "rcv_fd didn't receive anything, "
493 "error = %d\n", errno);
505 return -1; 494 return -1;
506 } 495 }
507 if((cmsg->cmsg_level != SOL_SOCKET) || 496 if ((cmsg->cmsg_level != SOL_SOCKET) ||
508 (cmsg->cmsg_type != SCM_RIGHTS)){ 497 (cmsg->cmsg_type != SCM_RIGHTS)) {
509 printk("rcv_fd didn't receive a descriptor\n"); 498 printk(UM_KERN_ERR "rcv_fd didn't receive a descriptor\n");
510 return -1; 499 return -1;
511 } 500 }
512 501
@@ -514,29 +503,28 @@ int os_rcv_fd(int fd, int *helper_pid_out)
514 return new; 503 return new;
515} 504}
516 505
517int os_create_unix_socket(char *file, int len, int close_on_exec) 506int os_create_unix_socket(const char *file, int len, int close_on_exec)
518{ 507{
519 struct sockaddr_un addr; 508 struct sockaddr_un addr;
520 int sock, err; 509 int sock, err;
521 510
522 sock = socket(PF_UNIX, SOCK_DGRAM, 0); 511 sock = socket(PF_UNIX, SOCK_DGRAM, 0);
523 if(sock < 0) 512 if (sock < 0)
524 return -errno; 513 return -errno;
525 514
526 if(close_on_exec) { 515 if (close_on_exec) {
527 err = os_set_exec_close(sock); 516 err = os_set_exec_close(sock);
528 if(err < 0) 517 if (err < 0)
529 printk("create_unix_socket : close_on_exec failed, " 518 printk(UM_KERN_ERR "create_unix_socket : "
530 "err = %d", -err); 519 "close_on_exec failed, err = %d", -err);
531 } 520 }
532 521
533 addr.sun_family = AF_UNIX; 522 addr.sun_family = AF_UNIX;
534 523
535 /* XXX Be more careful about overflow */
536 snprintf(addr.sun_path, len, "%s", file); 524 snprintf(addr.sun_path, len, "%s", file);
537 525
538 err = bind(sock, (struct sockaddr *) &addr, sizeof(addr)); 526 err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
539 if(err < 0) 527 if (err < 0)
540 return -errno; 528 return -errno;
541 529
542 return sock; 530 return sock;
@@ -557,17 +545,18 @@ int os_lock_file(int fd, int excl)
557 int err, save; 545 int err, save;
558 546
559 err = fcntl(fd, F_SETLK, &lock); 547 err = fcntl(fd, F_SETLK, &lock);
560 if(!err) 548 if (!err)
561 goto out; 549 goto out;
562 550
563 save = -errno; 551 save = -errno;
564 err = fcntl(fd, F_GETLK, &lock); 552 err = fcntl(fd, F_GETLK, &lock);
565 if(err){ 553 if (err) {
566 err = -errno; 554 err = -errno;
567 goto out; 555 goto out;
568 } 556 }
569 557
570 printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid); 558 printk(UM_KERN_ERR "F_SETLK failed, file already locked by pid %d\n",
559 lock.l_pid);
571 err = save; 560 err = save;
572 out: 561 out:
573 return err; 562 return err;
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index fba3f0fefeef..f4bd349d4412 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -1,22 +1,19 @@
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 <stdio.h>
7#include <stdlib.h> 6#include <stdlib.h>
8#include <unistd.h> 7#include <unistd.h>
9#include <errno.h> 8#include <errno.h>
10#include <sched.h> 9#include <sched.h>
11#include <limits.h>
12#include <sys/signal.h>
13#include <sys/wait.h>
14#include <sys/socket.h> 10#include <sys/socket.h>
15#include "user.h" 11#include <sys/wait.h>
12#include "kern_constants.h"
16#include "kern_util.h" 13#include "kern_util.h"
17#include "os.h" 14#include "os.h"
18#include "um_malloc.h" 15#include "um_malloc.h"
19#include "kern_constants.h" 16#include "user.h"
20 17
21struct helper_data { 18struct helper_data {
22 void (*pre_exec)(void*); 19 void (*pre_exec)(void*);
@@ -30,21 +27,19 @@ static int helper_child(void *arg)
30{ 27{
31 struct helper_data *data = arg; 28 struct helper_data *data = arg;
32 char **argv = data->argv; 29 char **argv = data->argv;
33 int errval; 30 int err;
34 31
35 if (data->pre_exec != NULL) 32 if (data->pre_exec != NULL)
36 (*data->pre_exec)(data->pre_data); 33 (*data->pre_exec)(data->pre_data);
37 errval = execvp_noalloc(data->buf, argv[0], argv); 34 err = execvp_noalloc(data->buf, argv[0], argv);
38 printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], 35
39 -errval); 36 /* If the exec succeeds, we don't get here */
40 write(data->fd, &errval, sizeof(errval)); 37 write(data->fd, &err, sizeof(err));
41 kill(os_getpid(), SIGKILL); 38
42 return 0; 39 return 0;
43} 40}
44 41
45/* Returns either the pid of the child process we run or -E* on failure. 42/* Returns either the pid of the child process we run or -E* on failure. */
46 * XXX The alloc_stack here breaks if this is called in the tracing thread, so
47 * we need to receive a preallocated stack (a local buffer is ok). */
48int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) 43int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
49{ 44{
50 struct helper_data data; 45 struct helper_data data;
@@ -58,14 +53,15 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
58 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 53 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
59 if (ret < 0) { 54 if (ret < 0) {
60 ret = -errno; 55 ret = -errno;
61 printk("run_helper : pipe failed, errno = %d\n", errno); 56 printk(UM_KERN_ERR "run_helper : pipe failed, errno = %d\n",
57 errno);
62 goto out_free; 58 goto out_free;
63 } 59 }
64 60
65 ret = os_set_exec_close(fds[1]); 61 ret = os_set_exec_close(fds[1]);
66 if (ret < 0) { 62 if (ret < 0) {
67 printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n", 63 printk(UM_KERN_ERR "run_helper : setting FD_CLOEXEC failed, "
68 -ret); 64 "ret = %d\n", -ret);
69 goto out_close; 65 goto out_close;
70 } 66 }
71 67
@@ -79,7 +75,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
79 pid = clone(helper_child, (void *) sp, CLONE_VM, &data); 75 pid = clone(helper_child, (void *) sp, CLONE_VM, &data);
80 if (pid < 0) { 76 if (pid < 0) {
81 ret = -errno; 77 ret = -errno;
82 printk("run_helper : clone failed, errno = %d\n", errno); 78 printk(UM_KERN_ERR "run_helper : clone failed, errno = %d\n",
79 errno);
83 goto out_free2; 80 goto out_free2;
84 } 81 }
85 82
@@ -96,10 +93,9 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
96 } else { 93 } else {
97 if (n < 0) { 94 if (n < 0) {
98 n = -errno; 95 n = -errno;
99 printk("run_helper : read on pipe failed, ret = %d\n", 96 printk(UM_KERN_ERR "run_helper : read on pipe failed, "
100 -n); 97 "ret = %d\n", -n);
101 ret = n; 98 ret = n;
102 kill(pid, SIGKILL);
103 } 99 }
104 CATCH_EINTR(waitpid(pid, NULL, __WCLONE)); 100 CATCH_EINTR(waitpid(pid, NULL, __WCLONE));
105 } 101 }
@@ -129,50 +125,40 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
129 pid = clone(proc, (void *) sp, flags, arg); 125 pid = clone(proc, (void *) sp, flags, arg);
130 if (pid < 0) { 126 if (pid < 0) {
131 err = -errno; 127 err = -errno;
132 printk("run_helper_thread : clone failed, errno = %d\n", 128 printk(UM_KERN_ERR "run_helper_thread : clone failed, "
133 errno); 129 "errno = %d\n", errno);
134 return err; 130 return err;
135 } 131 }
136 if (stack_out == NULL) { 132 if (stack_out == NULL) {
137 CATCH_EINTR(pid = waitpid(pid, &status, __WCLONE)); 133 CATCH_EINTR(pid = waitpid(pid, &status, __WCLONE));
138 if (pid < 0) { 134 if (pid < 0) {
139 err = -errno; 135 err = -errno;
140 printk("run_helper_thread - wait failed, errno = %d\n", 136 printk(UM_KERN_ERR "run_helper_thread - wait failed, "
141 errno); 137 "errno = %d\n", errno);
142 pid = err; 138 pid = err;
143 } 139 }
144 if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) 140 if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
145 printk("run_helper_thread - thread returned status " 141 printk(UM_KERN_ERR "run_helper_thread - thread "
146 "0x%x\n", status); 142 "returned status 0x%x\n", status);
147 free_stack(stack, 0); 143 free_stack(stack, 0);
148 } else 144 } else
149 *stack_out = stack; 145 *stack_out = stack;
150 return pid; 146 return pid;
151} 147}
152 148
153int helper_wait(int pid, int nohang, char *pname) 149int helper_wait(int pid)
154{ 150{
155 int ret, status; 151 int ret, status;
156 int wflags = __WCLONE; 152 int wflags = __WCLONE;
157 153
158 if (nohang)
159 wflags |= WNOHANG;
160
161 if (!pname)
162 pname = "helper_wait";
163
164 CATCH_EINTR(ret = waitpid(pid, &status, wflags)); 154 CATCH_EINTR(ret = waitpid(pid, &status, wflags));
165 if (ret < 0) { 155 if (ret < 0) {
166 printk(UM_KERN_ERR "%s : waitpid process %d failed, " 156 printk(UM_KERN_ERR "helper_wait : waitpid process %d failed, "
167 "errno = %d\n", pname, pid, errno); 157 "errno = %d\n", pid, errno);
168 return -errno; 158 return -errno;
169 } else if (nohang && ret == 0) {
170 printk(UM_KERN_ERR "%s : process %d has not exited\n",
171 pname, pid);
172 return -ECHILD;
173 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 159 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
174 printk(UM_KERN_ERR "%s : process %d didn't exit with " 160 printk(UM_KERN_ERR "helper_wait : process %d exited with "
175 "status 0\n", pname, pid); 161 "status 0x%x\n", pid, status);
176 return -ECHILD; 162 return -ECHILD;
177 } else 163 } else
178 return 0; 164 return 0;
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index 6aa6f95d6524..0348b975e81c 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -1,23 +1,19 @@
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> 6#include <stdlib.h>
7#include <unistd.h>
8#include <errno.h> 7#include <errno.h>
8#include <poll.h>
9#include <signal.h> 9#include <signal.h>
10#include <string.h> 10#include <string.h>
11#include <sys/poll.h>
12#include <sys/types.h>
13#include <sys/time.h>
14#include "kern_util.h"
15#include "user.h"
16#include "process.h"
17#include "sigio.h"
18#include "irq_user.h" 11#include "irq_user.h"
12#include "kern_constants.h"
19#include "os.h" 13#include "os.h"
14#include "process.h"
20#include "um_malloc.h" 15#include "um_malloc.h"
16#include "user.h"
21 17
22/* 18/*
23 * Locked by irq_lock in arch/um/kernel/irq.c. Changed by os_create_pollfd 19 * Locked by irq_lock in arch/um/kernel/irq.c. Changed by os_create_pollfd
@@ -36,7 +32,7 @@ int os_waiting_for_events(struct irq_fd *active_fds)
36 if (n < 0) { 32 if (n < 0) {
37 err = -errno; 33 err = -errno;
38 if (errno != EINTR) 34 if (errno != EINTR)
39 printk("sigio_handler: os_waiting_for_events:" 35 printk(UM_KERN_ERR "os_waiting_for_events:"
40 " poll returned %d, errno = %d\n", n, errno); 36 " poll returned %d, errno = %d\n", n, errno);
41 return err; 37 return err;
42 } 38 }
@@ -95,24 +91,26 @@ void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg,
95 struct irq_fd *old_fd = *prev; 91 struct irq_fd *old_fd = *prev;
96 if ((pollfds[i].fd != -1) && 92 if ((pollfds[i].fd != -1) &&
97 (pollfds[i].fd != (*prev)->fd)) { 93 (pollfds[i].fd != (*prev)->fd)) {
98 printk("os_free_irq_by_cb - mismatch between " 94 printk(UM_KERN_ERR "os_free_irq_by_cb - "
99 "active_fds and pollfds, fd %d vs %d\n", 95 "mismatch between active_fds and "
96 "pollfds, fd %d vs %d\n",
100 (*prev)->fd, pollfds[i].fd); 97 (*prev)->fd, pollfds[i].fd);
101 goto out; 98 goto out;
102 } 99 }
103 100
104 pollfds_num--; 101 pollfds_num--;
105 102
106 /* This moves the *whole* array after pollfds[i] 103 /*
104 * This moves the *whole* array after pollfds[i]
107 * (though it doesn't spot as such)! 105 * (though it doesn't spot as such)!
108 */ 106 */
109 memmove(&pollfds[i], &pollfds[i + 1], 107 memmove(&pollfds[i], &pollfds[i + 1],
110 (pollfds_num - i) * sizeof(pollfds[0])); 108 (pollfds_num - i) * sizeof(pollfds[0]));
111 if(*last_irq_ptr2 == &old_fd->next) 109 if (*last_irq_ptr2 == &old_fd->next)
112 *last_irq_ptr2 = prev; 110 *last_irq_ptr2 = prev;
113 111
114 *prev = (*prev)->next; 112 *prev = (*prev)->next;
115 if(old_fd->type == IRQ_WRITE) 113 if (old_fd->type == IRQ_WRITE)
116 ignore_sigio_fd(old_fd->fd); 114 ignore_sigio_fd(old_fd->fd);
117 kfree(old_fd); 115 kfree(old_fd);
118 continue; 116 continue;
@@ -138,14 +136,3 @@ void os_set_ioignore(void)
138{ 136{
139 signal(SIGIO, SIG_IGN); 137 signal(SIGIO, SIG_IGN);
140} 138}
141
142void init_irq_signals(int on_sigstack)
143{
144 int flags;
145
146 flags = on_sigstack ? SA_ONSTACK : 0;
147
148 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
149 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
150 signal(SIGWINCH, SIG_IGN);
151}
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 82c3778627b8..abb9b0ffd960 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -73,7 +73,7 @@ static void install_fatal_handler(int sig)
73 action.sa_handler = last_ditch_exit; 73 action.sa_handler = last_ditch_exit;
74 if (sigaction(sig, &action, NULL) < 0) { 74 if (sigaction(sig, &action, NULL) < 0) {
75 printf("failed to install handler for signal %d - errno = %d\n", 75 printf("failed to install handler for signal %d - errno = %d\n",
76 errno); 76 sig, errno);
77 exit(1); 77 exit(1);
78 } 78 }
79} 79}
@@ -92,7 +92,8 @@ static void setup_env_path(void)
92 * just use the default + /usr/lib/uml 92 * just use the default + /usr/lib/uml
93 */ 93 */
94 if (!old_path || (path_len = strlen(old_path)) == 0) { 94 if (!old_path || (path_len = strlen(old_path)) == 0) {
95 putenv("PATH=:/bin:/usr/bin/" UML_LIB_PATH); 95 if (putenv("PATH=:/bin:/usr/bin/" UML_LIB_PATH))
96 perror("couldn't putenv");
96 return; 97 return;
97 } 98 }
98 99
@@ -100,15 +101,16 @@ static void setup_env_path(void)
100 path_len += strlen("PATH=" UML_LIB_PATH) + 1; 101 path_len += strlen("PATH=" UML_LIB_PATH) + 1;
101 new_path = malloc(path_len); 102 new_path = malloc(path_len);
102 if (!new_path) { 103 if (!new_path) {
103 perror("coudn't malloc to set a new PATH"); 104 perror("couldn't malloc to set a new PATH");
104 return; 105 return;
105 } 106 }
106 snprintf(new_path, path_len, "PATH=%s" UML_LIB_PATH, old_path); 107 snprintf(new_path, path_len, "PATH=%s" UML_LIB_PATH, old_path);
107 putenv(new_path); 108 if (putenv(new_path)) {
109 perror("couldn't putenv to set a new PATH");
110 free(new_path);
111 }
108} 112}
109 113
110extern int uml_exitcode;
111
112extern void scan_elf_aux( char **envp); 114extern void scan_elf_aux( char **envp);
113 115
114int __init main(int argc, char **argv, char **envp) 116int __init main(int argc, char **argv, char **envp)
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 436f8d20b20f..eedc2d88ef8a 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -9,7 +9,6 @@
9#include <sys/types.h> 9#include <sys/types.h>
10#include <sys/mman.h> 10#include <sys/mman.h>
11#include <sys/statfs.h> 11#include <sys/statfs.h>
12#include "kern_util.h"
13#include "user.h" 12#include "user.h"
14#include "mem_user.h" 13#include "mem_user.h"
15#include "init.h" 14#include "init.h"
@@ -30,7 +29,7 @@ static char *tempdir = NULL;
30 29
31static void __init find_tempdir(void) 30static void __init find_tempdir(void)
32{ 31{
33 char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL }; 32 const char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
34 int i; 33 int i;
35 char *dir = NULL; 34 char *dir = NULL;
36 35
@@ -59,9 +58,10 @@ static void __init find_tempdir(void)
59 * read the file as needed. If there's an error, -errno is returned; 58 * read the file as needed. If there's an error, -errno is returned;
60 * if the end of the file is reached, 0 is returned. 59 * if the end of the file is reached, 0 is returned.
61 */ 60 */
62static int next(int fd, char *buf, int size, char c) 61static int next(int fd, char *buf, size_t size, char c)
63{ 62{
64 int n, len; 63 ssize_t n;
64 size_t len;
65 char *ptr; 65 char *ptr;
66 66
67 while((ptr = strchr(buf, c)) == NULL){ 67 while((ptr = strchr(buf, c)) == NULL){
@@ -172,13 +172,15 @@ int __init make_tempfile(const char *template, char **out_tempname,
172 172
173 which_tmpdir(); 173 which_tmpdir();
174 tempname = malloc(MAXPATHLEN); 174 tempname = malloc(MAXPATHLEN);
175 if (!tempname)
176 goto out;
175 177
176 find_tempdir(); 178 find_tempdir();
177 if (template[0] != '/') 179 if (template[0] != '/')
178 strcpy(tempname, tempdir); 180 strcpy(tempname, tempdir);
179 else 181 else
180 tempname[0] = '\0'; 182 tempname[0] = '\0';
181 strcat(tempname, template); 183 strncat(tempname, template, MAXPATHLEN-1-strlen(tempname));
182 fd = mkstemp(tempname); 184 fd = mkstemp(tempname);
183 if(fd < 0){ 185 if(fd < 0){
184 fprintf(stderr, "open - cannot create %s: %s\n", tempname, 186 fprintf(stderr, "open - cannot create %s: %s\n", tempname,
@@ -268,6 +270,7 @@ void __init check_tmpexec(void)
268 if(addr == MAP_FAILED){ 270 if(addr == MAP_FAILED){
269 err = errno; 271 err = errno;
270 perror("failed"); 272 perror("failed");
273 close(fd);
271 if(err == EPERM) 274 if(err == EPERM)
272 printf("%s must be not mounted noexec\n",tempdir); 275 printf("%s must be not mounted noexec\n",tempdir);
273 exit(1); 276 exit(1);
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index bda5c3150d6c..abf6beae3df1 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -249,7 +249,10 @@ void init_new_thread_signals(void)
249 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); 249 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
250 signal(SIGHUP, SIG_IGN); 250 signal(SIGHUP, SIG_IGN);
251 251
252 init_irq_signals(1); 252 set_handler(SIGIO, (__sighandler_t) sig_handler,
253 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM,
254 SIGVTALRM, -1);
255 signal(SIGWINCH, SIG_IGN);
253} 256}
254 257
255int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr) 258int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr)
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c
index a32ba6ab1211..830fe6a1518a 100644
--- a/arch/um/os-Linux/registers.c
+++ b/arch/um/os-Linux/registers.c
@@ -8,47 +8,41 @@
8#include <string.h> 8#include <string.h>
9#include <sys/ptrace.h> 9#include <sys/ptrace.h>
10#include "sysdep/ptrace.h" 10#include "sysdep/ptrace.h"
11#include "user.h"
12 11
13/* This is set once at boot time and not changed thereafter */ 12int save_registers(int pid, struct uml_pt_regs *regs)
14
15static unsigned long exec_regs[MAX_REG_NR];
16
17void init_thread_registers(struct uml_pt_regs *to)
18{
19 memcpy(to->gp, exec_regs, sizeof(to->gp));
20}
21
22void save_registers(int pid, struct uml_pt_regs *regs)
23{ 13{
24 int err; 14 int err;
25 15
26 err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp); 16 err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp);
27 if (err < 0) 17 if (err < 0)
28 panic("save_registers - saving registers failed, errno = %d\n", 18 return -errno;
29 errno); 19 return 0;
30} 20}
31 21
32void restore_registers(int pid, struct uml_pt_regs *regs) 22int restore_registers(int pid, struct uml_pt_regs *regs)
33{ 23{
34 int err; 24 int err;
35 25
36 err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp); 26 err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp);
37 if (err < 0) 27 if (err < 0)
38 panic("restore_registers - saving registers failed, " 28 return -errno;
39 "errno = %d\n", errno); 29 return 0;
40} 30}
41 31
42void init_registers(int pid) 32/* This is set once at boot time and not changed thereafter */
33
34static unsigned long exec_regs[MAX_REG_NR];
35
36int init_registers(int pid)
43{ 37{
44 int err; 38 int err;
45 39
46 err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); 40 err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
47 if (err) 41 if (err < 0)
48 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", 42 return -errno;
49 errno);
50 43
51 arch_init_registers(pid); 44 arch_init_registers(pid);
45 return 0;
52} 46}
53 47
54void get_safe_registers(unsigned long *regs) 48void get_safe_registers(unsigned long *regs)
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index dc03e9cccb63..abf47a7c4abd 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -1,34 +1,33 @@
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 <unistd.h> 6#include <unistd.h>
7#include <stdlib.h> 7#include <errno.h>
8#include <termios.h> 8#include <fcntl.h>
9#include <poll.h>
9#include <pty.h> 10#include <pty.h>
11#include <sched.h>
10#include <signal.h> 12#include <signal.h>
11#include <fcntl.h>
12#include <errno.h>
13#include <string.h> 13#include <string.h>
14#include <sched.h> 14#include "kern_constants.h"
15#include <sys/socket.h>
16#include <sys/poll.h>
17#include "init.h"
18#include "user.h"
19#include "kern_util.h" 15#include "kern_util.h"
20#include "sigio.h" 16#include "init.h"
21#include "os.h" 17#include "os.h"
18#include "sigio.h"
22#include "um_malloc.h" 19#include "um_malloc.h"
23#include "init.h" 20#include "user.h"
24 21
25/* Protected by sigio_lock(), also used by sigio_cleanup, which is an 22/*
23 * Protected by sigio_lock(), also used by sigio_cleanup, which is an
26 * exitcall. 24 * exitcall.
27 */ 25 */
28static int write_sigio_pid = -1; 26static int write_sigio_pid = -1;
29static unsigned long write_sigio_stack; 27static unsigned long write_sigio_stack;
30 28
31/* These arrays are initialized before the sigio thread is started, and 29/*
30 * These arrays are initialized before the sigio thread is started, and
32 * the descriptors closed after it is killed. So, it can't see them change. 31 * the descriptors closed after it is killed. So, it can't see them change.
33 * On the UML side, they are changed under the sigio_lock. 32 * On the UML side, they are changed under the sigio_lock.
34 */ 33 */
@@ -43,7 +42,8 @@ struct pollfds {
43 int used; 42 int used;
44}; 43};
45 44
46/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread 45/*
46 * Protected by sigio_lock(). Used by the sigio thread, but the UML thread
47 * synchronizes with it. 47 * synchronizes with it.
48 */ 48 */
49static struct pollfds current_poll; 49static struct pollfds current_poll;
@@ -57,23 +57,26 @@ static int write_sigio_thread(void *unused)
57 int i, n, respond_fd; 57 int i, n, respond_fd;
58 char c; 58 char c;
59 59
60 signal(SIGWINCH, SIG_IGN); 60 signal(SIGWINCH, SIG_IGN);
61 fds = &current_poll; 61 fds = &current_poll;
62 while(1){ 62 while (1) {
63 n = poll(fds->poll, fds->used, -1); 63 n = poll(fds->poll, fds->used, -1);
64 if(n < 0){ 64 if (n < 0) {
65 if(errno == EINTR) continue; 65 if (errno == EINTR)
66 printk("write_sigio_thread : poll returned %d, " 66 continue;
67 "errno = %d\n", n, errno); 67 printk(UM_KERN_ERR "write_sigio_thread : poll returned "
68 "%d, errno = %d\n", n, errno);
68 } 69 }
69 for(i = 0; i < fds->used; i++){ 70 for (i = 0; i < fds->used; i++) {
70 p = &fds->poll[i]; 71 p = &fds->poll[i];
71 if(p->revents == 0) continue; 72 if (p->revents == 0)
72 if(p->fd == sigio_private[1]){ 73 continue;
74 if (p->fd == sigio_private[1]) {
73 CATCH_EINTR(n = read(sigio_private[1], &c, 75 CATCH_EINTR(n = read(sigio_private[1], &c,
74 sizeof(c))); 76 sizeof(c)));
75 if(n != sizeof(c)) 77 if (n != sizeof(c))
76 printk("write_sigio_thread : " 78 printk(UM_KERN_ERR
79 "write_sigio_thread : "
77 "read on socket failed, " 80 "read on socket failed, "
78 "err = %d\n", errno); 81 "err = %d\n", errno);
79 tmp = current_poll; 82 tmp = current_poll;
@@ -89,9 +92,10 @@ static int write_sigio_thread(void *unused)
89 } 92 }
90 93
91 CATCH_EINTR(n = write(respond_fd, &c, sizeof(c))); 94 CATCH_EINTR(n = write(respond_fd, &c, sizeof(c)));
92 if(n != sizeof(c)) 95 if (n != sizeof(c))
93 printk("write_sigio_thread : write on socket " 96 printk(UM_KERN_ERR "write_sigio_thread : "
94 "failed, err = %d\n", errno); 97 "write on socket failed, err = %d\n",
98 errno);
95 } 99 }
96 } 100 }
97 101
@@ -102,12 +106,13 @@ static int need_poll(struct pollfds *polls, int n)
102{ 106{
103 struct pollfd *new; 107 struct pollfd *new;
104 108
105 if(n <= polls->size) 109 if (n <= polls->size)
106 return 0; 110 return 0;
107 111
108 new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC); 112 new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
109 if(new == NULL){ 113 if (new == NULL) {
110 printk("need_poll : failed to allocate new pollfds\n"); 114 printk(UM_KERN_ERR "need_poll : failed to allocate new "
115 "pollfds\n");
111 return -ENOMEM; 116 return -ENOMEM;
112 } 117 }
113 118
@@ -119,7 +124,8 @@ static int need_poll(struct pollfds *polls, int n)
119 return 0; 124 return 0;
120} 125}
121 126
122/* Must be called with sigio_lock held, because it's needed by the marked 127/*
128 * Must be called with sigio_lock held, because it's needed by the marked
123 * critical section. 129 * critical section.
124 */ 130 */
125static void update_thread(void) 131static void update_thread(void)
@@ -129,15 +135,17 @@ static void update_thread(void)
129 char c; 135 char c;
130 136
131 flags = set_signals(0); 137 flags = set_signals(0);
132 n = write(sigio_private[0], &c, sizeof(c)); 138 CATCH_EINTR(n = write(sigio_private[0], &c, sizeof(c)));
133 if(n != sizeof(c)){ 139 if (n != sizeof(c)) {
134 printk("update_thread : write failed, err = %d\n", errno); 140 printk(UM_KERN_ERR "update_thread : write failed, err = %d\n",
141 errno);
135 goto fail; 142 goto fail;
136 } 143 }
137 144
138 CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c))); 145 CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c)));
139 if(n != sizeof(c)){ 146 if (n != sizeof(c)) {
140 printk("update_thread : read failed, err = %d\n", errno); 147 printk(UM_KERN_ERR "update_thread : read failed, err = %d\n",
148 errno);
141 goto fail; 149 goto fail;
142 } 150 }
143 151
@@ -164,23 +172,23 @@ int add_sigio_fd(int fd)
164 int err = 0, i, n; 172 int err = 0, i, n;
165 173
166 sigio_lock(); 174 sigio_lock();
167 for(i = 0; i < all_sigio_fds.used; i++){ 175 for (i = 0; i < all_sigio_fds.used; i++) {
168 if(all_sigio_fds.poll[i].fd == fd) 176 if (all_sigio_fds.poll[i].fd == fd)
169 break; 177 break;
170 } 178 }
171 if(i == all_sigio_fds.used) 179 if (i == all_sigio_fds.used)
172 goto out; 180 goto out;
173 181
174 p = &all_sigio_fds.poll[i]; 182 p = &all_sigio_fds.poll[i];
175 183
176 for(i = 0; i < current_poll.used; i++){ 184 for (i = 0; i < current_poll.used; i++) {
177 if(current_poll.poll[i].fd == fd) 185 if (current_poll.poll[i].fd == fd)
178 goto out; 186 goto out;
179 } 187 }
180 188
181 n = current_poll.used; 189 n = current_poll.used;
182 err = need_poll(&next_poll, n + 1); 190 err = need_poll(&next_poll, n + 1);
183 if(err) 191 if (err)
184 goto out; 192 goto out;
185 193
186 memcpy(next_poll.poll, current_poll.poll, 194 memcpy(next_poll.poll, current_poll.poll,
@@ -198,27 +206,29 @@ int ignore_sigio_fd(int fd)
198 struct pollfd *p; 206 struct pollfd *p;
199 int err = 0, i, n = 0; 207 int err = 0, i, n = 0;
200 208
201 /* This is called from exitcalls elsewhere in UML - if 209 /*
210 * This is called from exitcalls elsewhere in UML - if
202 * sigio_cleanup has already run, then update_thread will hang 211 * sigio_cleanup has already run, then update_thread will hang
203 * or fail because the thread is no longer running. 212 * or fail because the thread is no longer running.
204 */ 213 */
205 if(write_sigio_pid == -1) 214 if (write_sigio_pid == -1)
206 return -EIO; 215 return -EIO;
207 216
208 sigio_lock(); 217 sigio_lock();
209 for(i = 0; i < current_poll.used; i++){ 218 for (i = 0; i < current_poll.used; i++) {
210 if(current_poll.poll[i].fd == fd) break; 219 if (current_poll.poll[i].fd == fd)
220 break;
211 } 221 }
212 if(i == current_poll.used) 222 if (i == current_poll.used)
213 goto out; 223 goto out;
214 224
215 err = need_poll(&next_poll, current_poll.used - 1); 225 err = need_poll(&next_poll, current_poll.used - 1);
216 if(err) 226 if (err)
217 goto out; 227 goto out;
218 228
219 for(i = 0; i < current_poll.used; i++){ 229 for (i = 0; i < current_poll.used; i++) {
220 p = &current_poll.poll[i]; 230 p = &current_poll.poll[i];
221 if(p->fd != fd) 231 if (p->fd != fd)
222 next_poll.poll[n++] = *p; 232 next_poll.poll[n++] = *p;
223 } 233 }
224 next_poll.used = current_poll.used - 1; 234 next_poll.used = current_poll.used - 1;
@@ -235,7 +245,8 @@ static struct pollfd *setup_initial_poll(int fd)
235 245
236 p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL); 246 p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
237 if (p == NULL) { 247 if (p == NULL) {
238 printk("setup_initial_poll : failed to allocate poll\n"); 248 printk(UM_KERN_ERR "setup_initial_poll : failed to allocate "
249 "poll\n");
239 return NULL; 250 return NULL;
240 } 251 }
241 *p = ((struct pollfd) { .fd = fd, 252 *p = ((struct pollfd) { .fd = fd,
@@ -261,27 +272,29 @@ static void write_sigio_workaround(void)
261 return; 272 return;
262 273
263 err = os_pipe(l_write_sigio_fds, 1, 1); 274 err = os_pipe(l_write_sigio_fds, 1, 1);
264 if(err < 0){ 275 if (err < 0) {
265 printk("write_sigio_workaround - os_pipe 1 failed, " 276 printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 1 failed, "
266 "err = %d\n", -err); 277 "err = %d\n", -err);
267 return; 278 return;
268 } 279 }
269 err = os_pipe(l_sigio_private, 1, 1); 280 err = os_pipe(l_sigio_private, 1, 1);
270 if(err < 0){ 281 if (err < 0) {
271 printk("write_sigio_workaround - os_pipe 2 failed, " 282 printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 2 failed, "
272 "err = %d\n", -err); 283 "err = %d\n", -err);
273 goto out_close1; 284 goto out_close1;
274 } 285 }
275 286
276 p = setup_initial_poll(l_sigio_private[1]); 287 p = setup_initial_poll(l_sigio_private[1]);
277 if(!p) 288 if (!p)
278 goto out_close2; 289 goto out_close2;
279 290
280 sigio_lock(); 291 sigio_lock();
281 292
282 /* Did we race? Don't try to optimize this, please, it's not so likely 293 /*
283 * to happen, and no more than once at the boot. */ 294 * Did we race? Don't try to optimize this, please, it's not so likely
284 if(write_sigio_pid != -1) 295 * to happen, and no more than once at the boot.
296 */
297 if (write_sigio_pid != -1)
285 goto out_free; 298 goto out_free;
286 299
287 current_poll = ((struct pollfds) { .poll = p, 300 current_poll = ((struct pollfds) { .poll = p,
@@ -333,19 +346,19 @@ void maybe_sigio_broken(int fd, int read)
333{ 346{
334 int err; 347 int err;
335 348
336 if(!isatty(fd)) 349 if (!isatty(fd))
337 return; 350 return;
338 351
339 if((read || pty_output_sigio) && (!read || pty_close_sigio)) 352 if ((read || pty_output_sigio) && (!read || pty_close_sigio))
340 return; 353 return;
341 354
342 write_sigio_workaround(); 355 write_sigio_workaround();
343 356
344 sigio_lock(); 357 sigio_lock();
345 err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1); 358 err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
346 if(err){ 359 if (err) {
347 printk("maybe_sigio_broken - failed to add pollfd for " 360 printk(UM_KERN_ERR "maybe_sigio_broken - failed to add pollfd "
348 "descriptor %d\n", fd); 361 "for descriptor %d\n", fd);
349 goto out; 362 goto out;
350 } 363 }
351 364
@@ -388,7 +401,7 @@ static void openpty_cb(void *arg)
388 struct openpty_arg *info = arg; 401 struct openpty_arg *info = arg;
389 402
390 info->err = 0; 403 info->err = 0;
391 if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) 404 if (openpty(&info->master, &info->slave, NULL, NULL, NULL))
392 info->err = -errno; 405 info->err = -errno;
393} 406}
394 407
@@ -397,17 +410,17 @@ static int async_pty(int master, int slave)
397 int flags; 410 int flags;
398 411
399 flags = fcntl(master, F_GETFL); 412 flags = fcntl(master, F_GETFL);
400 if(flags < 0) 413 if (flags < 0)
401 return -errno; 414 return -errno;
402 415
403 if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || 416 if ((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
404 (fcntl(master, F_SETOWN, os_getpid()) < 0)) 417 (fcntl(master, F_SETOWN, os_getpid()) < 0))
405 return -errno; 418 return -errno;
406 419
407 if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) 420 if ((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
408 return -errno; 421 return -errno;
409 422
410 return(0); 423 return 0;
411} 424}
412 425
413static void __init check_one_sigio(void (*proc)(int, int)) 426static void __init check_one_sigio(void (*proc)(int, int))
@@ -417,34 +430,49 @@ static void __init check_one_sigio(void (*proc)(int, int))
417 int master, slave, err; 430 int master, slave, err;
418 431
419 initial_thread_cb(openpty_cb, &pty); 432 initial_thread_cb(openpty_cb, &pty);
420 if(pty.err){ 433 if (pty.err) {
421 printk("openpty failed, errno = %d\n", -pty.err); 434 printk(UM_KERN_ERR "check_one_sigio failed, errno = %d\n",
435 -pty.err);
422 return; 436 return;
423 } 437 }
424 438
425 master = pty.master; 439 master = pty.master;
426 slave = pty.slave; 440 slave = pty.slave;
427 441
428 if((master == -1) || (slave == -1)){ 442 if ((master == -1) || (slave == -1)) {
429 printk("openpty failed to allocate a pty\n"); 443 printk(UM_KERN_ERR "check_one_sigio failed to allocate a "
444 "pty\n");
430 return; 445 return;
431 } 446 }
432 447
433 /* Not now, but complain so we now where we failed. */ 448 /* Not now, but complain so we now where we failed. */
434 err = raw(master); 449 err = raw(master);
435 if (err < 0) 450 if (err < 0) {
436 panic("check_sigio : __raw failed, errno = %d\n", -err); 451 printk(UM_KERN_ERR "check_one_sigio : raw failed, errno = %d\n",
452 -err);
453 return;
454 }
437 455
438 err = async_pty(master, slave); 456 err = async_pty(master, slave);
439 if(err < 0) 457 if (err < 0) {
440 panic("tty_fds : sigio_async failed, err = %d\n", -err); 458 printk(UM_KERN_ERR "check_one_sigio : sigio_async failed, "
459 "err = %d\n", -err);
460 return;
461 }
462
463 if (sigaction(SIGIO, NULL, &old) < 0) {
464 printk(UM_KERN_ERR "check_one_sigio : sigaction 1 failed, "
465 "errno = %d\n", errno);
466 return;
467 }
441 468
442 if(sigaction(SIGIO, NULL, &old) < 0)
443 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
444 new = old; 469 new = old;
445 new.sa_handler = handler; 470 new.sa_handler = handler;
446 if(sigaction(SIGIO, &new, NULL) < 0) 471 if (sigaction(SIGIO, &new, NULL) < 0) {
447 panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); 472 printk(UM_KERN_ERR "check_one_sigio : sigaction 2 failed, "
473 "errno = %d\n", errno);
474 return;
475 }
448 476
449 got_sigio = 0; 477 got_sigio = 0;
450 (*proc)(master, slave); 478 (*proc)(master, slave);
@@ -452,8 +480,9 @@ static void __init check_one_sigio(void (*proc)(int, int))
452 close(master); 480 close(master);
453 close(slave); 481 close(slave);
454 482
455 if(sigaction(SIGIO, &old, NULL) < 0) 483 if (sigaction(SIGIO, &old, NULL) < 0)
456 panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); 484 printk(UM_KERN_ERR "check_one_sigio : sigaction 3 failed, "
485 "errno = %d\n", errno);
457} 486}
458 487
459static void tty_output(int master, int slave) 488static void tty_output(int master, int slave)
@@ -461,42 +490,45 @@ static void tty_output(int master, int slave)
461 int n; 490 int n;
462 char buf[512]; 491 char buf[512];
463 492
464 printk("Checking that host ptys support output SIGIO..."); 493 printk(UM_KERN_INFO "Checking that host ptys support output SIGIO...");
465 494
466 memset(buf, 0, sizeof(buf)); 495 memset(buf, 0, sizeof(buf));
467 496
468 while(write(master, buf, sizeof(buf)) > 0) ; 497 while (write(master, buf, sizeof(buf)) > 0) ;
469 if(errno != EAGAIN) 498 if (errno != EAGAIN)
470 panic("tty_output : write failed, errno = %d\n", errno); 499 printk(UM_KERN_ERR "tty_output : write failed, errno = %d\n",
471 while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; 500 errno);
501 while (((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio)
502 ;
472 503
473 if(got_sigio){ 504 if (got_sigio) {
474 printk("Yes\n"); 505 printk(UM_KERN_CONT "Yes\n");
475 pty_output_sigio = 1; 506 pty_output_sigio = 1;
476 } 507 } else if (n == -EAGAIN)
477 else if(n == -EAGAIN) 508 printk(UM_KERN_CONT "No, enabling workaround\n");
478 printk("No, enabling workaround\n"); 509 else
479 else panic("tty_output : read failed, err = %d\n", n); 510 printk(UM_KERN_CONT "tty_output : read failed, err = %d\n", n);
480} 511}
481 512
482static void tty_close(int master, int slave) 513static void tty_close(int master, int slave)
483{ 514{
484 printk("Checking that host ptys support SIGIO on close..."); 515 printk(UM_KERN_INFO "Checking that host ptys support SIGIO on "
516 "close...");
485 517
486 close(slave); 518 close(slave);
487 if(got_sigio){ 519 if (got_sigio) {
488 printk("Yes\n"); 520 printk(UM_KERN_CONT "Yes\n");
489 pty_close_sigio = 1; 521 pty_close_sigio = 1;
490 } 522 } else
491 else printk("No, enabling workaround\n"); 523 printk(UM_KERN_CONT "No, enabling workaround\n");
492} 524}
493 525
494void __init check_sigio(void) 526void __init check_sigio(void)
495{ 527{
496 if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && 528 if ((access("/dev/ptmx", R_OK) < 0) &&
497 (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ 529 (access("/dev/ptyp0", R_OK) < 0)) {
498 printk("No pseudo-terminals available - skipping pty SIGIO " 530 printk(UM_KERN_WARNING "No pseudo-terminals available - "
499 "check\n"); 531 "skipping pty SIGIO check\n");
500 return; 532 return;
501 } 533 }
502 check_one_sigio(tty_output); 534 check_one_sigio(tty_output);
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index e9800b0b5689..0fb0cc8d4757 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -9,11 +9,47 @@
9#include <errno.h> 9#include <errno.h>
10#include <signal.h> 10#include <signal.h>
11#include <strings.h> 11#include <strings.h>
12#include "as-layout.h"
13#include "kern_util.h"
12#include "os.h" 14#include "os.h"
13#include "sysdep/barrier.h" 15#include "sysdep/barrier.h"
14#include "sysdep/sigcontext.h" 16#include "sysdep/sigcontext.h"
15#include "user.h" 17#include "user.h"
16 18
19/* Copied from linux/compiler-gcc.h since we can't include it directly */
20#define barrier() __asm__ __volatile__("": : :"memory")
21
22void (*sig_info[NSIG])(int, struct uml_pt_regs *) = {
23 [SIGTRAP] = relay_signal,
24 [SIGFPE] = relay_signal,
25 [SIGILL] = relay_signal,
26 [SIGWINCH] = winch,
27 [SIGBUS] = bus_handler,
28 [SIGSEGV] = segv_handler,
29 [SIGIO] = sigio_handler,
30 [SIGVTALRM] = timer_handler };
31
32static void sig_handler_common(int sig, struct sigcontext *sc)
33{
34 struct uml_pt_regs r;
35 int save_errno = errno;
36
37 r.is_user = 0;
38 if (sig == SIGSEGV) {
39 /* For segfaults, we want the data from the sigcontext. */
40 copy_sc(&r, sc);
41 GET_FAULTINFO_FROM_SC(r.faultinfo, sc);
42 }
43
44 /* enable signals if sig isn't IRQ signal */
45 if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM))
46 unblock_signals();
47
48 (*sig_info[sig])(sig, &r);
49
50 errno = save_errno;
51}
52
17/* 53/*
18 * These are the asynchronous signals. SIGPROF is excluded because we want to 54 * These are the asynchronous signals. SIGPROF is excluded because we want to
19 * be able to profile all of UML, not just the non-critical sections. If 55 * be able to profile all of UML, not just the non-critical sections. If
@@ -26,13 +62,8 @@
26#define SIGVTALRM_BIT 1 62#define SIGVTALRM_BIT 1
27#define SIGVTALRM_MASK (1 << SIGVTALRM_BIT) 63#define SIGVTALRM_MASK (1 << SIGVTALRM_BIT)
28 64
29/* 65static int signals_enabled;
30 * These are used by both the signal handlers and 66static unsigned int signals_pending;
31 * block/unblock_signals. I don't want modifications cached in a
32 * register - they must go straight to memory.
33 */
34static volatile int signals_enabled = 1;
35static volatile int pending = 0;
36 67
37void sig_handler(int sig, struct sigcontext *sc) 68void sig_handler(int sig, struct sigcontext *sc)
38{ 69{
@@ -40,13 +71,13 @@ void sig_handler(int sig, struct sigcontext *sc)
40 71
41 enabled = signals_enabled; 72 enabled = signals_enabled;
42 if (!enabled && (sig == SIGIO)) { 73 if (!enabled && (sig == SIGIO)) {
43 pending |= SIGIO_MASK; 74 signals_pending |= SIGIO_MASK;
44 return; 75 return;
45 } 76 }
46 77
47 block_signals(); 78 block_signals();
48 79
49 sig_handler_common_skas(sig, sc); 80 sig_handler_common(sig, sc);
50 81
51 set_signals(enabled); 82 set_signals(enabled);
52} 83}
@@ -68,7 +99,7 @@ void alarm_handler(int sig, struct sigcontext *sc)
68 99
69 enabled = signals_enabled; 100 enabled = signals_enabled;
70 if (!signals_enabled) { 101 if (!signals_enabled) {
71 pending |= SIGVTALRM_MASK; 102 signals_pending |= SIGVTALRM_MASK;
72 return; 103 return;
73 } 104 }
74 105
@@ -94,16 +125,6 @@ void set_sigstack(void *sig_stack, int size)
94 panic("enabling signal stack failed, errno = %d\n", errno); 125 panic("enabling signal stack failed, errno = %d\n", errno);
95} 126}
96 127
97void remove_sigstack(void)
98{
99 stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE,
100 .ss_sp = NULL,
101 .ss_size = 0 });
102
103 if (sigaltstack(&stack, NULL) != 0)
104 panic("disabling signal stack failed, errno = %d\n", errno);
105}
106
107void (*handlers[_NSIG])(int sig, struct sigcontext *sc); 128void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
108 129
109void handle_signal(int sig, struct sigcontext *sc) 130void handle_signal(int sig, struct sigcontext *sc)
@@ -166,6 +187,9 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
166 sigaddset(&action.sa_mask, mask); 187 sigaddset(&action.sa_mask, mask);
167 va_end(ap); 188 va_end(ap);
168 189
190 if (sig == SIGSEGV)
191 flags |= SA_NODEFER;
192
169 action.sa_flags = flags; 193 action.sa_flags = flags;
170 action.sa_restorer = NULL; 194 action.sa_restorer = NULL;
171 if (sigaction(sig, &action, NULL) < 0) 195 if (sigaction(sig, &action, NULL) < 0)
@@ -179,12 +203,14 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
179 203
180int change_sig(int signal, int on) 204int change_sig(int signal, int on)
181{ 205{
182 sigset_t sigset, old; 206 sigset_t sigset;
183 207
184 sigemptyset(&sigset); 208 sigemptyset(&sigset);
185 sigaddset(&sigset, signal); 209 sigaddset(&sigset, signal);
186 sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old); 210 if (sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, NULL) < 0)
187 return !sigismember(&old, signal); 211 return -errno;
212
213 return 0;
188} 214}
189 215
190void block_signals(void) 216void block_signals(void)
@@ -196,7 +222,7 @@ void block_signals(void)
196 * This might matter if gcc figures out how to inline this and 222 * This might matter if gcc figures out how to inline this and
197 * decides to shuffle this code into the caller. 223 * decides to shuffle this code into the caller.
198 */ 224 */
199 mb(); 225 barrier();
200} 226}
201 227
202void unblock_signals(void) 228void unblock_signals(void)
@@ -209,36 +235,26 @@ void unblock_signals(void)
209 /* 235 /*
210 * We loop because the IRQ handler returns with interrupts off. So, 236 * We loop because the IRQ handler returns with interrupts off. So,
211 * interrupts may have arrived and we need to re-enable them and 237 * interrupts may have arrived and we need to re-enable them and
212 * recheck pending. 238 * recheck signals_pending.
213 */ 239 */
214 while(1) { 240 while(1) {
215 /* 241 /*
216 * Save and reset save_pending after enabling signals. This 242 * Save and reset save_pending after enabling signals. This
217 * way, pending won't be changed while we're reading it. 243 * way, signals_pending won't be changed while we're reading it.
218 */ 244 */
219 signals_enabled = 1; 245 signals_enabled = 1;
220 246
221 /* 247 /*
222 * Setting signals_enabled and reading pending must 248 * Setting signals_enabled and reading signals_pending must
223 * happen in this order. 249 * happen in this order.
224 */ 250 */
225 mb(); 251 barrier();
226 252
227 save_pending = pending; 253 save_pending = signals_pending;
228 if (save_pending == 0) { 254 if (save_pending == 0)
229 /*
230 * This must return with signals enabled, so
231 * this barrier ensures that writes are
232 * flushed out before the return. This might
233 * matter if gcc figures out how to inline
234 * this (unlikely, given its size) and decides
235 * to shuffle this code into the caller.
236 */
237 mb();
238 return; 255 return;
239 }
240 256
241 pending = 0; 257 signals_pending = 0;
242 258
243 /* 259 /*
244 * We have pending interrupts, so disable signals, as the 260 * We have pending interrupts, so disable signals, as the
@@ -254,7 +270,7 @@ void unblock_signals(void)
254 * back here. 270 * back here.
255 */ 271 */
256 if (save_pending & SIGIO_MASK) 272 if (save_pending & SIGIO_MASK)
257 sig_handler_common_skas(SIGIO, NULL); 273 sig_handler_common(SIGIO, NULL);
258 274
259 if (save_pending & SIGVTALRM_MASK) 275 if (save_pending & SIGVTALRM_MASK)
260 real_alarm_handler(NULL); 276 real_alarm_handler(NULL);
diff --git a/arch/um/os-Linux/skas/Makefile b/arch/um/os-Linux/skas/Makefile
index 5fd8d4dad66a..d2ea3409e072 100644
--- a/arch/um/os-Linux/skas/Makefile
+++ b/arch/um/os-Linux/skas/Makefile
@@ -1,10 +1,10 @@
1# 1#
2# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) 2# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y := mem.o process.o trap.o 6obj-y := mem.o process.o
7 7
8USER_OBJS := mem.o process.o trap.o 8USER_OBJS := $(obj-y)
9 9
10include arch/um/scripts/Makefile.rules 10include arch/um/scripts/Makefile.rules
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index e8b7a97e83d3..d36c89c24a45 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -15,6 +15,7 @@
15#include "as-layout.h" 15#include "as-layout.h"
16#include "chan_user.h" 16#include "chan_user.h"
17#include "kern_constants.h" 17#include "kern_constants.h"
18#include "kern_util.h"
18#include "mem.h" 19#include "mem.h"
19#include "os.h" 20#include "os.h"
20#include "process.h" 21#include "process.h"
@@ -37,27 +38,27 @@ int is_skas_winch(int pid, int fd, void *data)
37 38
38static int ptrace_dump_regs(int pid) 39static int ptrace_dump_regs(int pid)
39{ 40{
40 unsigned long regs[MAX_REG_NR]; 41 unsigned long regs[MAX_REG_NR];
41 int i; 42 int i;
42 43
43 if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) 44 if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
44 return -errno; 45 return -errno;
45 46
46 printk(UM_KERN_ERR "Stub registers -\n"); 47 printk(UM_KERN_ERR "Stub registers -\n");
47 for (i = 0; i < ARRAY_SIZE(regs); i++) 48 for (i = 0; i < ARRAY_SIZE(regs); i++)
48 printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]); 49 printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]);
49 50
50 return 0; 51 return 0;
51} 52}
52 53
53/* 54/*
54 * Signals that are OK to receive in the stub - we'll just continue it. 55 * Signals that are OK to receive in the stub - we'll just continue it.
55 * SIGWINCH will happen when UML is inside a detached screen. 56 * SIGWINCH will happen when UML is inside a detached screen.
56 */ 57 */
57#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH)) 58#define STUB_SIG_MASK (1 << SIGVTALRM)
58 59
59/* Signals that the stub will finish with - anything else is an error */ 60/* Signals that the stub will finish with - anything else is an error */
60#define STUB_DONE_MASK ((1 << SIGUSR1) | (1 << SIGTRAP)) 61#define STUB_DONE_MASK (1 << SIGTRAP)
61 62
62void wait_stub_done(int pid) 63void wait_stub_done(int pid)
63{ 64{
@@ -72,9 +73,11 @@ void wait_stub_done(int pid)
72 break; 73 break;
73 74
74 err = ptrace(PTRACE_CONT, pid, 0, 0); 75 err = ptrace(PTRACE_CONT, pid, 0, 0);
75 if (err) 76 if (err) {
76 panic("wait_stub_done : continue failed, errno = %d\n", 77 printk(UM_KERN_ERR "wait_stub_done : continue failed, "
77 errno); 78 "errno = %d\n", errno);
79 fatal_sigsegv();
80 }
78 } 81 }
79 82
80 if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) 83 if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
@@ -85,8 +88,10 @@ bad_wait:
85 if (err) 88 if (err)
86 printk(UM_KERN_ERR "Failed to get registers from stub, " 89 printk(UM_KERN_ERR "Failed to get registers from stub, "
87 "errno = %d\n", -err); 90 "errno = %d\n", -err);
88 panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, " 91 printk(UM_KERN_ERR "wait_stub_done : failed to wait for SIGTRAP, "
89 "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status); 92 "pid = %d, n = %d, errno = %d, status = 0x%x\n", pid, n, errno,
93 status);
94 fatal_sigsegv();
90} 95}
91 96
92extern unsigned long current_stub_stack(void); 97extern unsigned long current_stub_stack(void);
@@ -97,9 +102,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
97 102
98 if (ptrace_faultinfo) { 103 if (ptrace_faultinfo) {
99 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); 104 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
100 if (err) 105 if (err) {
101 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " 106 printk(UM_KERN_ERR "get_skas_faultinfo - "
102 "errno = %d\n", errno); 107 "PTRACE_FAULTINFO failed, errno = %d\n", errno);
108 fatal_sigsegv();
109 }
103 110
104 /* Special handling for i386, which has different structs */ 111 /* Special handling for i386, which has different structs */
105 if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo)) 112 if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
@@ -109,9 +116,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
109 } 116 }
110 else { 117 else {
111 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); 118 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
112 if (err) 119 if (err) {
113 panic("Failed to continue stub, pid = %d, errno = %d\n", 120 printk(UM_KERN_ERR "Failed to continue stub, pid = %d, "
114 pid, errno); 121 "errno = %d\n", pid, errno);
122 fatal_sigsegv();
123 }
115 wait_stub_done(pid); 124 wait_stub_done(pid);
116 125
117 /* 126 /*
@@ -137,6 +146,9 @@ static void handle_trap(int pid, struct uml_pt_regs *regs,
137{ 146{
138 int err, status; 147 int err, status;
139 148
149 if ((UPT_IP(regs) >= STUB_START) && (UPT_IP(regs) < STUB_END))
150 fatal_sigsegv();
151
140 /* Mark this as a syscall */ 152 /* Mark this as a syscall */
141 UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp); 153 UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp);
142 154
@@ -144,25 +156,31 @@ static void handle_trap(int pid, struct uml_pt_regs *regs,
144 { 156 {
145 err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, 157 err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
146 __NR_getpid); 158 __NR_getpid);
147 if (err < 0) 159 if (err < 0) {
148 panic("handle_trap - nullifying syscall failed, " 160 printk(UM_KERN_ERR "handle_trap - nullifying syscall "
149 "errno = %d\n", errno); 161 "failed, errno = %d\n", errno);
162 fatal_sigsegv();
163 }
150 164
151 err = ptrace(PTRACE_SYSCALL, pid, 0, 0); 165 err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
152 if (err < 0) 166 if (err < 0) {
153 panic("handle_trap - continuing to end of syscall " 167 printk(UM_KERN_ERR "handle_trap - continuing to end of "
154 "failed, errno = %d\n", errno); 168 "syscall failed, errno = %d\n", errno);
169 fatal_sigsegv();
170 }
155 171
156 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL)); 172 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL));
157 if ((err < 0) || !WIFSTOPPED(status) || 173 if ((err < 0) || !WIFSTOPPED(status) ||
158 (WSTOPSIG(status) != SIGTRAP + 0x80)) { 174 (WSTOPSIG(status) != SIGTRAP + 0x80)) {
159 err = ptrace_dump_regs(pid); 175 err = ptrace_dump_regs(pid);
160 if (err) 176 if (err)
161 printk(UM_KERN_ERR "Failed to get registers " 177 printk(UM_KERN_ERR "Failed to get registers "
162 "from process, errno = %d\n", -err); 178 "from process, errno = %d\n", -err);
163 panic("handle_trap - failed to wait at end of syscall, " 179 printk(UM_KERN_ERR "handle_trap - failed to wait at "
164 "errno = %d, status = %d\n", errno, status); 180 "end of syscall, errno = %d, status = %d\n",
165 } 181 errno, status);
182 fatal_sigsegv();
183 }
166 } 184 }
167 185
168 handle_syscall(regs); 186 handle_syscall(regs);
@@ -178,10 +196,13 @@ static int userspace_tramp(void *stack)
178 ptrace(PTRACE_TRACEME, 0, 0, 0); 196 ptrace(PTRACE_TRACEME, 0, 0, 0);
179 197
180 signal(SIGTERM, SIG_DFL); 198 signal(SIGTERM, SIG_DFL);
199 signal(SIGWINCH, SIG_IGN);
181 err = set_interval(); 200 err = set_interval();
182 if (err) 201 if (err) {
183 panic("userspace_tramp - setting timer failed, errno = %d\n", 202 printk(UM_KERN_ERR "userspace_tramp - setting timer failed, "
184 err); 203 "errno = %d\n", err);
204 exit(1);
205 }
185 206
186 if (!proc_mm) { 207 if (!proc_mm) {
187 /* 208 /*
@@ -221,16 +242,14 @@ static int userspace_tramp(void *stack)
221 242
222 set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE); 243 set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
223 sigemptyset(&sa.sa_mask); 244 sigemptyset(&sa.sa_mask);
224 sigaddset(&sa.sa_mask, SIGIO); 245 sa.sa_flags = SA_ONSTACK | SA_NODEFER;
225 sigaddset(&sa.sa_mask, SIGWINCH);
226 sigaddset(&sa.sa_mask, SIGVTALRM);
227 sigaddset(&sa.sa_mask, SIGUSR1);
228 sa.sa_flags = SA_ONSTACK;
229 sa.sa_handler = (void *) v; 246 sa.sa_handler = (void *) v;
230 sa.sa_restorer = NULL; 247 sa.sa_restorer = NULL;
231 if (sigaction(SIGSEGV, &sa, NULL) < 0) 248 if (sigaction(SIGSEGV, &sa, NULL) < 0) {
232 panic("userspace_tramp - setting SIGSEGV handler " 249 printk(UM_KERN_ERR "userspace_tramp - setting SIGSEGV "
233 "failed - errno = %d\n", errno); 250 "handler failed - errno = %d\n", errno);
251 exit(1);
252 }
234 } 253 }
235 254
236 kill(os_getpid(), SIGSTOP); 255 kill(os_getpid(), SIGSTOP);
@@ -246,13 +265,18 @@ int start_userspace(unsigned long stub_stack)
246{ 265{
247 void *stack; 266 void *stack;
248 unsigned long sp; 267 unsigned long sp;
249 int pid, status, n, flags; 268 int pid, status, n, flags, err;
250 269
251 stack = mmap(NULL, UM_KERN_PAGE_SIZE, 270 stack = mmap(NULL, UM_KERN_PAGE_SIZE,
252 PROT_READ | PROT_WRITE | PROT_EXEC, 271 PROT_READ | PROT_WRITE | PROT_EXEC,
253 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 272 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
254 if (stack == MAP_FAILED) 273 if (stack == MAP_FAILED) {
255 panic("start_userspace : mmap failed, errno = %d", errno); 274 err = -errno;
275 printk(UM_KERN_ERR "start_userspace : mmap failed, "
276 "errno = %d\n", errno);
277 return err;
278 }
279
256 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); 280 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
257 281
258 flags = CLONE_FILES; 282 flags = CLONE_FILES;
@@ -262,29 +286,50 @@ int start_userspace(unsigned long stub_stack)
262 flags |= SIGCHLD; 286 flags |= SIGCHLD;
263 287
264 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); 288 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
265 if (pid < 0) 289 if (pid < 0) {
266 panic("start_userspace : clone failed, errno = %d", errno); 290 err = -errno;
291 printk(UM_KERN_ERR "start_userspace : clone failed, "
292 "errno = %d\n", errno);
293 return err;
294 }
267 295
268 do { 296 do {
269 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL)); 297 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL));
270 if (n < 0) 298 if (n < 0) {
271 panic("start_userspace : wait failed, errno = %d", 299 err = -errno;
272 errno); 300 printk(UM_KERN_ERR "start_userspace : wait failed, "
301 "errno = %d\n", errno);
302 goto out_kill;
303 }
273 } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM)); 304 } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
274 305
275 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) 306 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) {
276 panic("start_userspace : expected SIGSTOP, got status = %d", 307 err = -EINVAL;
277 status); 308 printk(UM_KERN_ERR "start_userspace : expected SIGSTOP, got "
309 "status = %d\n", status);
310 goto out_kill;
311 }
278 312
279 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, 313 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
280 (void *) PTRACE_O_TRACESYSGOOD) < 0) 314 (void *) PTRACE_O_TRACESYSGOOD) < 0) {
281 panic("start_userspace : PTRACE_OLDSETOPTIONS failed, " 315 err = -errno;
282 "errno = %d\n", errno); 316 printk(UM_KERN_ERR "start_userspace : PTRACE_OLDSETOPTIONS "
317 "failed, errno = %d\n", errno);
318 goto out_kill;
319 }
283 320
284 if (munmap(stack, UM_KERN_PAGE_SIZE) < 0) 321 if (munmap(stack, UM_KERN_PAGE_SIZE) < 0) {
285 panic("start_userspace : munmap failed, errno = %d\n", errno); 322 err = -errno;
323 printk(UM_KERN_ERR "start_userspace : munmap failed, "
324 "errno = %d\n", errno);
325 goto out_kill;
326 }
286 327
287 return pid; 328 return pid;
329
330 out_kill:
331 os_kill_ptraced_process(pid, 1);
332 return err;
288} 333}
289 334
290void userspace(struct uml_pt_regs *regs) 335void userspace(struct uml_pt_regs *regs)
@@ -302,7 +347,16 @@ void userspace(struct uml_pt_regs *regs)
302 nsecs += os_nsecs(); 347 nsecs += os_nsecs();
303 348
304 while (1) { 349 while (1) {
305 restore_registers(pid, regs); 350 /*
351 * This can legitimately fail if the process loads a
352 * bogus value into a segment register. It will
353 * segfault and PTRACE_GETREGS will read that value
354 * out of the process. However, PTRACE_SETREGS will
355 * fail. In this case, there is nothing to do but
356 * just kill the process.
357 */
358 if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp))
359 fatal_sigsegv();
306 360
307 /* Now we set local_using_sysemu to be used for one loop */ 361 /* Now we set local_using_sysemu to be used for one loop */
308 local_using_sysemu = get_using_sysemu(); 362 local_using_sysemu = get_using_sysemu();
@@ -310,19 +364,26 @@ void userspace(struct uml_pt_regs *regs)
310 op = SELECT_PTRACE_OPERATION(local_using_sysemu, 364 op = SELECT_PTRACE_OPERATION(local_using_sysemu,
311 singlestepping(NULL)); 365 singlestepping(NULL));
312 366
313 err = ptrace(op, pid, 0, 0); 367 if (ptrace(op, pid, 0, 0)) {
314 if (err) 368 printk(UM_KERN_ERR "userspace - ptrace continue "
315 panic("userspace - could not resume userspace process, " 369 "failed, op = %d, errno = %d\n", op, errno);
316 "pid=%d, ptrace operation = %d, errno = %d\n", 370 fatal_sigsegv();
317 pid, op, errno); 371 }
318 372
319 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL)); 373 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL));
320 if (err < 0) 374 if (err < 0) {
321 panic("userspace - waitpid failed, errno = %d\n", 375 printk(UM_KERN_ERR "userspace - wait failed, "
322 errno); 376 "errno = %d\n", errno);
377 fatal_sigsegv();
378 }
323 379
324 regs->is_user = 1; 380 regs->is_user = 1;
325 save_registers(pid, regs); 381 if (ptrace(PTRACE_GETREGS, pid, 0, regs->gp)) {
382 printk(UM_KERN_ERR "userspace - PTRACE_GETREGS failed, "
383 "errno = %d\n", errno);
384 fatal_sigsegv();
385 }
386
326 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ 387 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
327 388
328 if (WIFSTOPPED(status)) { 389 if (WIFSTOPPED(status)) {
@@ -345,7 +406,7 @@ void userspace(struct uml_pt_regs *regs)
345 break; 406 break;
346 case SIGVTALRM: 407 case SIGVTALRM:
347 now = os_nsecs(); 408 now = os_nsecs();
348 if(now < nsecs) 409 if (now < nsecs)
349 break; 410 break;
350 block_signals(); 411 block_signals();
351 (*sig_info[sig])(sig, regs); 412 (*sig_info[sig])(sig, regs);
@@ -368,6 +429,7 @@ void userspace(struct uml_pt_regs *regs)
368 default: 429 default:
369 printk(UM_KERN_ERR "userspace - child stopped " 430 printk(UM_KERN_ERR "userspace - child stopped "
370 "with signal %d\n", sig); 431 "with signal %d\n", sig);
432 fatal_sigsegv();
371 } 433 }
372 pid = userspace_pid[0]; 434 pid = userspace_pid[0];
373 interrupt_end(); 435 interrupt_end();
@@ -419,9 +481,12 @@ int copy_context_skas0(unsigned long new_stack, int pid)
419 .it_interval = tv }) }); 481 .it_interval = tv }) });
420 482
421 err = ptrace_setregs(pid, thread_regs); 483 err = ptrace_setregs(pid, thread_regs);
422 if (err < 0) 484 if (err < 0) {
423 panic("copy_context_skas0 : PTRACE_SETREGS failed, " 485 err = -errno;
424 "pid = %d, errno = %d\n", pid, -err); 486 printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_SETREGS "
487 "failed, pid = %d, errno = %d\n", pid, -err);
488 return err;
489 }
425 490
426 /* set a well known return code for detection of child write failure */ 491 /* set a well known return code for detection of child write failure */
427 child_data->err = 12345678; 492 child_data->err = 12345678;
@@ -431,31 +496,47 @@ int copy_context_skas0(unsigned long new_stack, int pid)
431 * parent's stack, and check, if bad result. 496 * parent's stack, and check, if bad result.
432 */ 497 */
433 err = ptrace(PTRACE_CONT, pid, 0, 0); 498 err = ptrace(PTRACE_CONT, pid, 0, 0);
434 if (err) 499 if (err) {
435 panic("Failed to continue new process, pid = %d, " 500 err = -errno;
436 "errno = %d\n", pid, errno); 501 printk(UM_KERN_ERR "Failed to continue new process, pid = %d, "
502 "errno = %d\n", pid, errno);
503 return err;
504 }
505
437 wait_stub_done(pid); 506 wait_stub_done(pid);
438 507
439 pid = data->err; 508 pid = data->err;
440 if (pid < 0) 509 if (pid < 0) {
441 panic("copy_context_skas0 - stub-parent reports error %d\n", 510 printk(UM_KERN_ERR "copy_context_skas0 - stub-parent reports "
442 -pid); 511 "error %d\n", -pid);
512 return pid;
513 }
443 514
444 /* 515 /*
445 * Wait, until child has finished too: read child's result from 516 * Wait, until child has finished too: read child's result from
446 * child's stack and check it. 517 * child's stack and check it.
447 */ 518 */
448 wait_stub_done(pid); 519 wait_stub_done(pid);
449 if (child_data->err != STUB_DATA) 520 if (child_data->err != STUB_DATA) {
450 panic("copy_context_skas0 - stub-child reports error %ld\n", 521 printk(UM_KERN_ERR "copy_context_skas0 - stub-child reports "
451 child_data->err); 522 "error %ld\n", child_data->err);
523 err = child_data->err;
524 goto out_kill;
525 }
452 526
453 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, 527 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
454 (void *)PTRACE_O_TRACESYSGOOD) < 0) 528 (void *)PTRACE_O_TRACESYSGOOD) < 0) {
455 panic("copy_context_skas0 : PTRACE_OLDSETOPTIONS failed, " 529 err = -errno;
456 "errno = %d\n", errno); 530 printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_OLDSETOPTIONS "
531 "failed, errno = %d\n", errno);
532 goto out_kill;
533 }
457 534
458 return pid; 535 return pid;
536
537 out_kill:
538 os_kill_ptraced_process(pid, 1);
539 return err;
459} 540}
460 541
461/* 542/*
@@ -463,8 +544,8 @@ int copy_context_skas0(unsigned long new_stack, int pid)
463 * available. Opening /proc/mm creates a new mm_context, which lacks 544 * available. Opening /proc/mm creates a new mm_context, which lacks
464 * the stub-pages. Thus, we map them using /proc/mm-fd 545 * the stub-pages. Thus, we map them using /proc/mm-fd
465 */ 546 */
466void map_stub_pages(int fd, unsigned long code, 547int map_stub_pages(int fd, unsigned long code, unsigned long data,
467 unsigned long data, unsigned long stack) 548 unsigned long stack)
468{ 549{
469 struct proc_mm_op mmop; 550 struct proc_mm_op mmop;
470 int n; 551 int n;
@@ -488,8 +569,9 @@ void map_stub_pages(int fd, unsigned long code,
488 printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, " 569 printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, "
489 "offset = %llx\n", code, code_fd, 570 "offset = %llx\n", code, code_fd,
490 (unsigned long long) code_offset); 571 (unsigned long long) code_offset);
491 panic("map_stub_pages : /proc/mm map for code failed, " 572 printk(UM_KERN_ERR "map_stub_pages : /proc/mm map for code "
492 "err = %d\n", n); 573 "failed, err = %d\n", n);
574 return -n;
493 } 575 }
494 576
495 if (stack) { 577 if (stack) {
@@ -507,10 +589,15 @@ void map_stub_pages(int fd, unsigned long code,
507 .offset = map_offset 589 .offset = map_offset
508 } } }); 590 } } });
509 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); 591 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
510 if (n != sizeof(mmop)) 592 if (n != sizeof(mmop)) {
511 panic("map_stub_pages : /proc/mm map for data failed, " 593 n = errno;
512 "err = %d\n", errno); 594 printk(UM_KERN_ERR "map_stub_pages : /proc/mm map for "
595 "data failed, err = %d\n", n);
596 return -n;
597 }
513 } 598 }
599
600 return 0;
514} 601}
515 602
516void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)) 603void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
@@ -571,7 +658,9 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
571 kmalloc_ok = 0; 658 kmalloc_ok = 0;
572 return 1; 659 return 1;
573 default: 660 default:
574 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); 661 printk(UM_KERN_ERR "Bad sigsetjmp return in "
662 "start_idle_thread - %d\n", n);
663 fatal_sigsegv();
575 } 664 }
576 longjmp(*switch_buf, 1); 665 longjmp(*switch_buf, 1);
577} 666}
@@ -614,9 +703,11 @@ void __switch_mm(struct mm_id *mm_idp)
614 if (proc_mm) { 703 if (proc_mm) {
615 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, 704 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
616 mm_idp->u.mm_fd); 705 mm_idp->u.mm_fd);
617 if (err) 706 if (err) {
618 panic("__switch_mm - PTRACE_SWITCH_MM failed, " 707 printk(UM_KERN_ERR "__switch_mm - PTRACE_SWITCH_MM "
619 "errno = %d\n", errno); 708 "failed, errno = %d\n", errno);
709 fatal_sigsegv();
710 }
620 } 711 }
621 else userspace_pid[0] = mm_idp->u.pid; 712 else userspace_pid[0] = mm_idp->u.pid;
622} 713}
diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c
deleted file mode 100644
index 3b1b9244f468..000000000000
--- a/arch/um/os-Linux/skas/trap.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
6#if 0
7#include "kern_util.h"
8#include "skas.h"
9#include "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"
18#include "os.h"
19#include "sigcontext.h"
20#include "task.h"
21
22static struct uml_pt_regs ksig_regs[UM_NR_CPUS];
23
24void sig_handler_common_skas(int sig, void *sc_ptr)
25{
26 struct sigcontext *sc = sc_ptr;
27 struct uml_pt_regs *r;
28 void (*handler)(int, struct uml_pt_regs *);
29 int save_user, save_errno = errno;
30
31 /*
32 * This is done because to allow SIGSEGV to be delivered inside a SEGV
33 * handler. This can happen in copy_user, and if SEGV is disabled,
34 * the process will die.
35 * XXX Figure out why this is better than SA_NODEFER
36 */
37 if (sig == SIGSEGV) {
38 change_sig(SIGSEGV, 1);
39 /*
40 * For segfaults, we want the data from the
41 * sigcontext. In this case, we don't want to mangle
42 * the process registers, so use a static set of
43 * registers. For other signals, the process
44 * registers are OK.
45 */
46 r = &ksig_regs[cpu()];
47 copy_sc(r, sc_ptr);
48 }
49 else r = TASK_REGS(get_current());
50
51 save_user = r->is_user;
52 r->is_user = 0;
53 if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
54 (sig == SIGILL) || (sig == SIGTRAP))
55 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
56
57 change_sig(SIGUSR1, 1);
58
59 handler = sig_info[sig];
60
61 /* unblock SIGVTALRM, SIGIO if sig isn't IRQ signal */
62 if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM))
63 unblock_signals();
64
65 handler(sig, r);
66
67 errno = save_errno;
68 r->is_user = save_user;
69}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 7b81f6c08a5e..b616e15638fb 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -60,10 +60,11 @@ static int ptrace_child(void)
60 * the UML code itself. 60 * the UML code itself.
61 */ 61 */
62 ret = 2; 62 ret = 2;
63 _exit(ret); 63
64 exit(ret);
64} 65}
65 66
66static void fatal_perror(char *str) 67static void fatal_perror(const char *str)
67{ 68{
68 perror(str); 69 perror(str);
69 exit(1); 70 exit(1);
@@ -341,6 +342,8 @@ static void __init check_coredump_limit(void)
341 342
342void __init os_early_checks(void) 343void __init os_early_checks(void)
343{ 344{
345 int pid;
346
344 /* Print out the core dump limits early */ 347 /* Print out the core dump limits early */
345 check_coredump_limit(); 348 check_coredump_limit();
346 349
@@ -350,6 +353,11 @@ void __init os_early_checks(void)
350 * kernel is running. 353 * kernel is running.
351 */ 354 */
352 check_tmpexec(); 355 check_tmpexec();
356
357 pid = start_ptraced_child();
358 if (init_registers(pid))
359 fatal("Failed to initialize default registers");
360 stop_ptraced_child(pid, 1, 1);
353} 361}
354 362
355static int __init noprocmm_cmd_param(char *str, int* add) 363static int __init noprocmm_cmd_param(char *str, int* add)
@@ -411,7 +419,6 @@ static inline void check_skas3_ptrace_faultinfo(void)
411 non_fatal("found\n"); 419 non_fatal("found\n");
412 } 420 }
413 421
414 init_registers(pid);
415 stop_ptraced_child(pid, 1, 1); 422 stop_ptraced_child(pid, 1, 1);
416} 423}
417 424
@@ -466,7 +473,7 @@ static inline void check_skas3_proc_mm(void)
466 else non_fatal("found\n"); 473 else non_fatal("found\n");
467} 474}
468 475
469int can_do_skas(void) 476void can_do_skas(void)
470{ 477{
471 non_fatal("Checking for the skas3 patch in the host:\n"); 478 non_fatal("Checking for the skas3 patch in the host:\n");
472 479
@@ -476,8 +483,6 @@ int can_do_skas(void)
476 483
477 if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt) 484 if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
478 skas_needs_stub = 1; 485 skas_needs_stub = 1;
479
480 return 1;
481} 486}
482 487
483int __init parse_iomem(char *str, int *add) 488int __init parse_iomem(char *str, int *add)
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
deleted file mode 100644
index 2a1c9843e32e..000000000000
--- a/arch/um/os-Linux/trap.c
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
6#include <signal.h>
7#include "os.h"
8#include "sysdep/ptrace.h"
9
10/* Initialized from linux_main() */
11void (*sig_info[NSIG])(int, struct uml_pt_regs *);
12
13void os_fill_handlinfo(struct kern_handlers h)
14{
15 sig_info[SIGTRAP] = h.relay_signal;
16 sig_info[SIGFPE] = h.relay_signal;
17 sig_info[SIGILL] = h.relay_signal;
18 sig_info[SIGWINCH] = h.winch;
19 sig_info[SIGBUS] = h.bus_handler;
20 sig_info[SIGSEGV] = h.page_fault;
21 sig_info[SIGIO] = h.sigio_handler;
22 sig_info[SIGVTALRM] = h.timer_handler;
23}
diff --git a/arch/um/os-Linux/tty.c b/arch/um/os-Linux/tty.c
index 4cfdd18ea1ef..b09ff66a77ee 100644
--- a/arch/um/os-Linux/tty.c
+++ b/arch/um/os-Linux/tty.c
@@ -1,13 +1,16 @@
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 <stdlib.h> 6#include <stdlib.h>
7#include <unistd.h>
7#include <errno.h> 8#include <errno.h>
9#include <fcntl.h>
10#include "kern_constants.h"
11#include "kern_util.h"
8#include "os.h" 12#include "os.h"
9#include "user.h" 13#include "user.h"
10#include "kern_util.h"
11 14
12struct grantpt_info { 15struct grantpt_info {
13 int fd; 16 int fd;
@@ -26,36 +29,34 @@ static void grantpt_cb(void *arg)
26int get_pty(void) 29int get_pty(void)
27{ 30{
28 struct grantpt_info info; 31 struct grantpt_info info;
29 int fd; 32 int fd, err;
30 33
31 fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0); 34 fd = open("/dev/ptmx", O_RDWR);
32 if(fd < 0){ 35 if (fd < 0) {
33 printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd); 36 err = -errno;
34 return(fd); 37 printk(UM_KERN_ERR "get_pty : Couldn't open /dev/ptmx - "
38 "err = %d\n", errno);
39 return err;
35 } 40 }
36 41
37 info.fd = fd; 42 info.fd = fd;
38 initial_thread_cb(grantpt_cb, &info); 43 initial_thread_cb(grantpt_cb, &info);
39 44
40 if(info.res < 0){ 45 if (info.res < 0) {
41 printk("get_pty : Couldn't grant pty - errno = %d\n", 46 err = -info.err;
42 -info.err); 47 printk(UM_KERN_ERR "get_pty : Couldn't grant pty - "
43 return(-1); 48 "errno = %d\n", -info.err);
49 goto out;
44 } 50 }
45 if(unlockpt(fd) < 0){ 51
46 printk("get_pty : Couldn't unlock pty - errno = %d\n", errno); 52 if (unlockpt(fd) < 0) {
47 return(-1); 53 err = -errno;
54 printk(UM_KERN_ERR "get_pty : Couldn't unlock pty - "
55 "errno = %d\n", errno);
56 goto out;
48 } 57 }
49 return(fd); 58 return fd;
59out:
60 close(fd);
61 return err;
50} 62}
51
52/*
53 * Overrides for Emacs so that we follow Linus's tabbing style.
54 * Emacs will notice this stuff at the end of the file and automatically
55 * adjust the settings for this buffer only. This must remain at the end
56 * of the file.
57 * ---------------------------------------------------------------------------
58 * Local variables:
59 * c-file-style: "linux"
60 * End:
61 */
diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c
index d11a55baa6bd..cc648e6fd3a2 100644
--- a/arch/um/os-Linux/tty_log.c
+++ b/arch/um/os-Linux/tty_log.c
@@ -12,7 +12,6 @@
12#include <sys/time.h> 12#include <sys/time.h>
13#include "init.h" 13#include "init.h"
14#include "user.h" 14#include "user.h"
15#include "kern_util.h"
16#include "os.h" 15#include "os.h"
17 16
18#define TTY_LOG_DIR "./" 17#define TTY_LOG_DIR "./"
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 3e058ce9ffb6..a6f31d476993 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -88,21 +88,6 @@ void setup_hostinfo(char *buf, int len)
88 host.release, host.version, host.machine); 88 host.release, host.version, host.machine);
89} 89}
90 90
91int setjmp_wrapper(void (*proc)(void *, void *), ...)
92{
93 va_list args;
94 jmp_buf buf;
95 int n;
96
97 n = UML_SETJMP(&buf);
98 if(n == 0){
99 va_start(args, proc);
100 (*proc)(&buf, &args);
101 }
102 va_end(args);
103 return n;
104}
105
106void os_dump_core(void) 91void os_dump_core(void)
107{ 92{
108 int pid; 93 int pid;