aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r--arch/um/os-Linux/aio.c61
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c66
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c44
-rw-r--r--arch/um/os-Linux/file.c47
-rw-r--r--arch/um/os-Linux/helper.c31
-rw-r--r--arch/um/os-Linux/irq.c1
-rw-r--r--arch/um/os-Linux/main.c23
-rw-r--r--arch/um/os-Linux/mem.c15
-rw-r--r--arch/um/os-Linux/process.c45
-rw-r--r--arch/um/os-Linux/sigio.c164
-rw-r--r--arch/um/os-Linux/signal.c1
-rw-r--r--arch/um/os-Linux/skas/mem.c75
-rw-r--r--arch/um/os-Linux/skas/process.c190
-rw-r--r--arch/um/os-Linux/skas/trap.c49
-rw-r--r--arch/um/os-Linux/start_up.c173
-rw-r--r--arch/um/os-Linux/sys-i386/tls.c2
-rw-r--r--arch/um/os-Linux/time.c1
-rw-r--r--arch/um/os-Linux/trap.c1
-rw-r--r--arch/um/os-Linux/tt.c4
-rw-r--r--arch/um/os-Linux/tty_log.c28
-rw-r--r--arch/um/os-Linux/util.c26
21 files changed, 536 insertions, 511 deletions
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 6ff12743a0bd..9bf944f6a1db 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -132,10 +132,10 @@ static int aio_thread(void *arg)
132 { .data = (void *) (long) event.data, 132 { .data = (void *) (long) event.data,
133 .err = event.res }); 133 .err = event.res });
134 reply_fd = ((struct aio_context *) reply.data)->reply_fd; 134 reply_fd = ((struct aio_context *) reply.data)->reply_fd;
135 err = os_write_file(reply_fd, &reply, sizeof(reply)); 135 err = write(reply_fd, &reply, sizeof(reply));
136 if(err != sizeof(reply)) 136 if(err != sizeof(reply))
137 printk("aio_thread - write failed, fd = %d, " 137 printk("aio_thread - write failed, fd = %d, "
138 "err = %d\n", reply_fd, -err); 138 "err = %d\n", reply_fd, errno);
139 } 139 }
140 } 140 }
141 return 0; 141 return 0;
@@ -146,38 +146,31 @@ static int aio_thread(void *arg)
146static int do_not_aio(struct aio_thread_req *req) 146static int do_not_aio(struct aio_thread_req *req)
147{ 147{
148 char c; 148 char c;
149 int err; 149 unsigned long long actual;
150 int n;
151
152 actual = lseek64(req->io_fd, req->offset, SEEK_SET);
153 if(actual != req->offset)
154 return -errno;
150 155
151 switch(req->type){ 156 switch(req->type){
152 case AIO_READ: 157 case AIO_READ:
153 err = os_seek_file(req->io_fd, req->offset); 158 n = read(req->io_fd, req->buf, req->len);
154 if(err)
155 goto out;
156
157 err = os_read_file(req->io_fd, req->buf, req->len);
158 break; 159 break;
159 case AIO_WRITE: 160 case AIO_WRITE:
160 err = os_seek_file(req->io_fd, req->offset); 161 n = write(req->io_fd, req->buf, req->len);
161 if(err)
162 goto out;
163
164 err = os_write_file(req->io_fd, req->buf, req->len);
165 break; 162 break;
166 case AIO_MMAP: 163 case AIO_MMAP:
167 err = os_seek_file(req->io_fd, req->offset); 164 n = read(req->io_fd, &c, sizeof(c));
168 if(err)
169 goto out;
170
171 err = os_read_file(req->io_fd, &c, sizeof(c));
172 break; 165 break;
173 default: 166 default:
174 printk("do_not_aio - bad request type : %d\n", req->type); 167 printk("do_not_aio - bad request type : %d\n", req->type);
175 err = -EINVAL; 168 return -EINVAL;
176 break;
177 } 169 }
178 170
179out: 171 if(n < 0)
180 return err; 172 return -errno;
173 return 0;
181} 174}
182 175
183/* These are initialized in initcalls and not changed */ 176/* These are initialized in initcalls and not changed */
@@ -193,12 +186,12 @@ static int not_aio_thread(void *arg)
193 186
194 signal(SIGWINCH, SIG_IGN); 187 signal(SIGWINCH, SIG_IGN);
195 while(1){ 188 while(1){
196 err = os_read_file(aio_req_fd_r, &req, sizeof(req)); 189 err = read(aio_req_fd_r, &req, sizeof(req));
197 if(err != sizeof(req)){ 190 if(err != sizeof(req)){
198 if(err < 0) 191 if(err < 0)
199 printk("not_aio_thread - read failed, " 192 printk("not_aio_thread - read failed, "
200 "fd = %d, err = %d\n", aio_req_fd_r, 193 "fd = %d, err = %d\n", aio_req_fd_r,
201 -err); 194 errno);
202 else { 195 else {
203 printk("not_aio_thread - short read, fd = %d, " 196 printk("not_aio_thread - short read, fd = %d, "
204 "length = %d\n", aio_req_fd_r, err); 197 "length = %d\n", aio_req_fd_r, err);
@@ -207,11 +200,11 @@ static int not_aio_thread(void *arg)
207 } 200 }
208 err = do_not_aio(&req); 201 err = do_not_aio(&req);
209 reply = ((struct aio_thread_reply) { .data = req.aio, 202 reply = ((struct aio_thread_reply) { .data = req.aio,
210 .err = err }); 203 .err = err });
211 err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply)); 204 err = write(req.aio->reply_fd, &reply, sizeof(reply));
212 if(err != sizeof(reply)) 205 if(err != sizeof(reply))
213 printk("not_aio_thread - write failed, fd = %d, " 206 printk("not_aio_thread - write failed, fd = %d, "
214 "err = %d\n", req.aio->reply_fd, -err); 207 "err = %d\n", req.aio->reply_fd, errno);
215 } 208 }
216 209
217 return 0; 210 return 0;
@@ -228,6 +221,11 @@ static int init_aio_24(void)
228 221
229 aio_req_fd_w = fds[0]; 222 aio_req_fd_w = fds[0];
230 aio_req_fd_r = fds[1]; 223 aio_req_fd_r = fds[1];
224
225 err = os_set_fd_block(aio_req_fd_w, 0);
226 if(err)
227 goto out_close_pipe;
228
231 err = run_helper_thread(not_aio_thread, NULL, 229 err = run_helper_thread(not_aio_thread, NULL,
232 CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); 230 CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
233 if(err < 0) 231 if(err < 0)
@@ -285,10 +283,12 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
285 if(err){ 283 if(err){
286 reply = ((struct aio_thread_reply) { .data = aio, 284 reply = ((struct aio_thread_reply) { .data = aio,
287 .err = err }); 285 .err = err });
288 err = os_write_file(aio->reply_fd, &reply, sizeof(reply)); 286 err = write(aio->reply_fd, &reply, sizeof(reply));
289 if(err != sizeof(reply)) 287 if(err != sizeof(reply)){
288 err = -errno;
290 printk("submit_aio_26 - write failed, " 289 printk("submit_aio_26 - write failed, "
291 "fd = %d, err = %d\n", aio->reply_fd, -err); 290 "fd = %d, err = %d\n", aio->reply_fd, -err);
291 }
292 else err = 0; 292 else err = 0;
293 } 293 }
294 294
@@ -383,9 +383,10 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
383 }; 383 };
384 int err; 384 int err;
385 385
386 err = os_write_file(aio_req_fd_w, &req, sizeof(req)); 386 err = write(aio_req_fd_w, &req, sizeof(req));
387 if(err == sizeof(req)) 387 if(err == sizeof(req))
388 err = 0; 388 err = 0;
389 else err = -errno;
389 390
390 return err; 391 return err;
391} 392}
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 863981ba1468..acba30161287 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
3 * James Leu (jleu@mindspring.net). 3 * James Leu (jleu@mindspring.net).
4 * Copyright (C) 2001 by various other people who didn't put their name here. 4 * Copyright (C) 2001 by various other people who didn't put their name here.
5 * Licensed under the GPL. 5 * Licensed under the GPL.
@@ -16,19 +16,20 @@
16#include <net/if.h> 16#include <net/if.h>
17#include "user.h" 17#include "user.h"
18#include "kern_util.h" 18#include "kern_util.h"
19#include "user_util.h"
20#include "net_user.h" 19#include "net_user.h"
21#include "etap.h" 20#include "etap.h"
22#include "os.h" 21#include "os.h"
23#include "um_malloc.h" 22#include "um_malloc.h"
23#include "kern_constants.h"
24 24
25#define MAX_PACKET ETH_MAX_PACKET 25#define MAX_PACKET ETH_MAX_PACKET
26 26
27void etap_user_init(void *data, void *dev) 27static int etap_user_init(void *data, void *dev)
28{ 28{
29 struct ethertap_data *pri = data; 29 struct ethertap_data *pri = data;
30 30
31 pri->dev = dev; 31 pri->dev = dev;
32 return 0;
32} 33}
33 34
34struct addr_change { 35struct addr_change {
@@ -47,13 +48,16 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
47 change.what = op; 48 change.what = op;
48 memcpy(change.addr, addr, sizeof(change.addr)); 49 memcpy(change.addr, addr, sizeof(change.addr));
49 memcpy(change.netmask, netmask, sizeof(change.netmask)); 50 memcpy(change.netmask, netmask, sizeof(change.netmask));
50 n = os_write_file(fd, &change, sizeof(change)); 51 CATCH_EINTR(n = write(fd, &change, sizeof(change)));
51 if(n != sizeof(change)) 52 if(n != sizeof(change)){
52 printk("etap_change - request failed, err = %d\n", -n); 53 printk("etap_change - request failed, err = %d\n", errno);
53 output = um_kmalloc(page_size()); 54 return;
55 }
56
57 output = um_kmalloc(UM_KERN_PAGE_SIZE);
54 if(output == NULL) 58 if(output == NULL)
55 printk("etap_change : Failed to allocate output buffer\n"); 59 printk("etap_change : Failed to allocate output buffer\n");
56 read_output(fd, output, page_size()); 60 read_output(fd, output, UM_KERN_PAGE_SIZE);
57 if(output != NULL){ 61 if(output != NULL){
58 printk("%s", output); 62 printk("%s", output);
59 kfree(output); 63 kfree(output);
@@ -115,13 +119,15 @@ static int etap_tramp(char *dev, char *gate, int control_me,
115 pe_data.data_me = data_me; 119 pe_data.data_me = data_me;
116 pid = run_helper(etap_pre_exec, &pe_data, args, NULL); 120 pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
117 121
118 if(pid < 0) err = pid; 122 if(pid < 0)
123 err = pid;
119 os_close_file(data_remote); 124 os_close_file(data_remote);
120 os_close_file(control_remote); 125 os_close_file(control_remote);
121 n = os_read_file(control_me, &c, sizeof(c)); 126 CATCH_EINTR(n = read(control_me, &c, sizeof(c)));
122 if(n != sizeof(c)){ 127 if(n != sizeof(c)){
123 printk("etap_tramp : read of status failed, err = %d\n", -n); 128 err = -errno;
124 return(-EINVAL); 129 printk("etap_tramp : read of status failed, err = %d\n", -err);
130 return err;
125 } 131 }
126 if(c != 1){ 132 if(c != 1){
127 printk("etap_tramp : uml_net failed\n"); 133 printk("etap_tramp : uml_net failed\n");
@@ -132,7 +138,7 @@ static int etap_tramp(char *dev, char *gate, int control_me,
132 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) 138 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
133 printk("uml_net didn't exit with status 1\n"); 139 printk("uml_net didn't exit with status 1\n");
134 } 140 }
135 return(err); 141 return err;
136} 142}
137 143
138static int etap_open(void *data) 144static int etap_open(void *data)
@@ -142,23 +148,24 @@ static int etap_open(void *data)
142 int data_fds[2], control_fds[2], err, output_len; 148 int data_fds[2], control_fds[2], err, output_len;
143 149
144 err = tap_open_common(pri->dev, pri->gate_addr); 150 err = tap_open_common(pri->dev, pri->gate_addr);
145 if(err) return(err); 151 if(err)
152 return err;
146 153
147 err = os_pipe(data_fds, 0, 0); 154 err = os_pipe(data_fds, 0, 0);
148 if(err < 0){ 155 if(err < 0){
149 printk("data os_pipe failed - err = %d\n", -err); 156 printk("data os_pipe failed - err = %d\n", -err);
150 return(err); 157 return err;
151 } 158 }
152 159
153 err = os_pipe(control_fds, 1, 0); 160 err = os_pipe(control_fds, 1, 0);
154 if(err < 0){ 161 if(err < 0){
155 printk("control os_pipe failed - err = %d\n", -err); 162 printk("control os_pipe failed - err = %d\n", -err);
156 return(err); 163 return err;
157 } 164 }
158 165
159 err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], 166 err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
160 control_fds[1], data_fds[0], data_fds[1]); 167 control_fds[1], data_fds[0], data_fds[1]);
161 output_len = page_size(); 168 output_len = UM_KERN_PAGE_SIZE;
162 output = um_kmalloc(output_len); 169 output = um_kmalloc(output_len);
163 read_output(control_fds[0], output, output_len); 170 read_output(control_fds[0], output, output_len);
164 171
@@ -171,13 +178,13 @@ static int etap_open(void *data)
171 178
172 if(err < 0){ 179 if(err < 0){
173 printk("etap_tramp failed - err = %d\n", -err); 180 printk("etap_tramp failed - err = %d\n", -err);
174 return(err); 181 return err;
175 } 182 }
176 183
177 pri->data_fd = data_fds[0]; 184 pri->data_fd = data_fds[0];
178 pri->control_fd = control_fds[0]; 185 pri->control_fd = control_fds[0];
179 iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); 186 iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
180 return(data_fds[0]); 187 return data_fds[0];
181} 188}
182 189
183static void etap_close(int fd, void *data) 190static void etap_close(int fd, void *data)
@@ -195,7 +202,7 @@ static void etap_close(int fd, void *data)
195 202
196static int etap_set_mtu(int mtu, void *data) 203static int etap_set_mtu(int mtu, void *data)
197{ 204{
198 return(mtu); 205 return mtu;
199} 206}
200 207
201static void etap_add_addr(unsigned char *addr, unsigned char *netmask, 208static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
@@ -204,7 +211,8 @@ static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
204 struct ethertap_data *pri = data; 211 struct ethertap_data *pri = data;
205 212
206 tap_check_ips(pri->gate_addr, addr); 213 tap_check_ips(pri->gate_addr, addr);
207 if(pri->control_fd == -1) return; 214 if(pri->control_fd == -1)
215 return;
208 etap_open_addr(addr, netmask, &pri->control_fd); 216 etap_open_addr(addr, netmask, &pri->control_fd);
209} 217}
210 218
@@ -213,7 +221,8 @@ static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
213{ 221{
214 struct ethertap_data *pri = data; 222 struct ethertap_data *pri = data;
215 223
216 if(pri->control_fd == -1) return; 224 if(pri->control_fd == -1)
225 return;
217 etap_close_addr(addr, netmask, &pri->control_fd); 226 etap_close_addr(addr, netmask, &pri->control_fd);
218} 227}
219 228
@@ -227,14 +236,3 @@ const struct net_user_info ethertap_user_info = {
227 .delete_address = etap_del_addr, 236 .delete_address = etap_del_addr,
228 .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP 237 .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP
229}; 238};
230
231/*
232 * Overrides for Emacs so that we follow Linus's tabbing style.
233 * Emacs will notice this stuff at the end of the file and automatically
234 * adjust the settings for this buffer only. This must remain at the end
235 * of the file.
236 * ---------------------------------------------------------------------------
237 * Local variables:
238 * c-file-style: "linux"
239 * End:
240 */
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index e846b23f7558..11a9779dc9f1 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -18,17 +18,17 @@
18#include "net_user.h" 18#include "net_user.h"
19#include "tuntap.h" 19#include "tuntap.h"
20#include "kern_util.h" 20#include "kern_util.h"
21#include "user_util.h"
22#include "user.h" 21#include "user.h"
23#include "os.h" 22#include "os.h"
24 23
25#define MAX_PACKET ETH_MAX_PACKET 24#define MAX_PACKET ETH_MAX_PACKET
26 25
27void tuntap_user_init(void *data, void *dev) 26static int tuntap_user_init(void *data, void *dev)
28{ 27{
29 struct tuntap_data *pri = data; 28 struct tuntap_data *pri = data;
30 29
31 pri->dev = dev; 30 pri->dev = dev;
31 return 0;
32} 32}
33 33
34static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, 34static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
@@ -37,7 +37,8 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
37 struct tuntap_data *pri = data; 37 struct tuntap_data *pri = data;
38 38
39 tap_check_ips(pri->gate_addr, addr); 39 tap_check_ips(pri->gate_addr, addr);
40 if((pri->fd == -1) || pri->fixed_config) return; 40 if((pri->fd == -1) || pri->fixed_config)
41 return;
41 open_addr(addr, netmask, pri->dev_name); 42 open_addr(addr, netmask, pri->dev_name);
42} 43}
43 44
@@ -46,7 +47,8 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
46{ 47{
47 struct tuntap_data *pri = data; 48 struct tuntap_data *pri = data;
48 49
49 if((pri->fd == -1) || pri->fixed_config) return; 50 if((pri->fd == -1) || pri->fixed_config)
51 return;
50 close_addr(addr, netmask, pri->dev_name); 52 close_addr(addr, netmask, pri->dev_name);
51} 53}
52 54
@@ -58,7 +60,7 @@ struct tuntap_pre_exec_data {
58static void tuntap_pre_exec(void *arg) 60static void tuntap_pre_exec(void *arg)
59{ 61{
60 struct tuntap_pre_exec_data *data = arg; 62 struct tuntap_pre_exec_data *data = arg;
61 63
62 dup2(data->stdout, 1); 64 dup2(data->stdout, 1);
63 os_close_file(data->close_me); 65 os_close_file(data->close_me);
64} 66}
@@ -83,7 +85,8 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
83 85
84 pid = run_helper(tuntap_pre_exec, &data, argv, NULL); 86 pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
85 87
86 if(pid < 0) return(-pid); 88 if(pid < 0)
89 return -pid;
87 90
88 os_close_file(remote); 91 os_close_file(remote);
89 92
@@ -114,16 +117,16 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
114 cmsg = CMSG_FIRSTHDR(&msg); 117 cmsg = CMSG_FIRSTHDR(&msg);
115 if(cmsg == NULL){ 118 if(cmsg == NULL){
116 printk("tuntap_open_tramp : didn't receive a message\n"); 119 printk("tuntap_open_tramp : didn't receive a message\n");
117 return(-EINVAL); 120 return -EINVAL;
118 } 121 }
119 if((cmsg->cmsg_level != SOL_SOCKET) || 122 if((cmsg->cmsg_level != SOL_SOCKET) ||
120 (cmsg->cmsg_type != SCM_RIGHTS)){ 123 (cmsg->cmsg_type != SCM_RIGHTS)){
121 printk("tuntap_open_tramp : didn't receive a descriptor\n"); 124 printk("tuntap_open_tramp : didn't receive a descriptor\n");
122 return(-EINVAL); 125 return -EINVAL;
123 } 126 }
124 *fd_out = ((int *) CMSG_DATA(cmsg))[0]; 127 *fd_out = ((int *) CMSG_DATA(cmsg))[0];
125 os_set_exec_close(*fd_out, 1); 128 os_set_exec_close(*fd_out, 1);
126 return(0); 129 return 0;
127} 130}
128 131
129static int tuntap_open(void *data) 132static int tuntap_open(void *data)
@@ -135,7 +138,7 @@ static int tuntap_open(void *data)
135 138
136 err = tap_open_common(pri->dev, pri->gate_addr); 139 err = tap_open_common(pri->dev, pri->gate_addr);
137 if(err < 0) 140 if(err < 0)
138 return(err); 141 return err;
139 142
140 if(pri->fixed_config){ 143 if(pri->fixed_config){
141 pri->fd = os_open_file("/dev/net/tun", 144 pri->fd = os_open_file("/dev/net/tun",
@@ -143,7 +146,7 @@ static int tuntap_open(void *data)
143 if(pri->fd < 0){ 146 if(pri->fd < 0){
144 printk("Failed to open /dev/net/tun, err = %d\n", 147 printk("Failed to open /dev/net/tun, err = %d\n",
145 -pri->fd); 148 -pri->fd);
146 return(pri->fd); 149 return pri->fd;
147 } 150 }
148 memset(&ifr, 0, sizeof(ifr)); 151 memset(&ifr, 0, sizeof(ifr));
149 ifr.ifr_flags = IFF_TAP | IFF_NO_PI; 152 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
@@ -160,7 +163,7 @@ static int tuntap_open(void *data)
160 if(err < 0){ 163 if(err < 0){
161 printk("tuntap_open : os_pipe failed - err = %d\n", 164 printk("tuntap_open : os_pipe failed - err = %d\n",
162 -err); 165 -err);
163 return(err); 166 return err;
164 } 167 }
165 168
166 buffer = get_output_buffer(&len); 169 buffer = get_output_buffer(&len);
@@ -175,7 +178,7 @@ static int tuntap_open(void *data)
175 printk("%s", output); 178 printk("%s", output);
176 free_output_buffer(buffer); 179 free_output_buffer(buffer);
177 printk("tuntap_open_tramp failed - err = %d\n", -err); 180 printk("tuntap_open_tramp failed - err = %d\n", -err);
178 return(err); 181 return err;
179 } 182 }
180 183
181 pri->dev_name = uml_strdup(buffer); 184 pri->dev_name = uml_strdup(buffer);
@@ -187,7 +190,7 @@ static int tuntap_open(void *data)
187 iter_addresses(pri->dev, open_addr, pri->dev_name); 190 iter_addresses(pri->dev, open_addr, pri->dev_name);
188 } 191 }
189 192
190 return(pri->fd); 193 return pri->fd;
191} 194}
192 195
193static void tuntap_close(int fd, void *data) 196static void tuntap_close(int fd, void *data)
@@ -202,7 +205,7 @@ static void tuntap_close(int fd, void *data)
202 205
203static int tuntap_set_mtu(int mtu, void *data) 206static int tuntap_set_mtu(int mtu, void *data)
204{ 207{
205 return(mtu); 208 return mtu;
206} 209}
207 210
208const struct net_user_info tuntap_user_info = { 211const struct net_user_info tuntap_user_info = {
@@ -215,14 +218,3 @@ const struct net_user_info tuntap_user_info = {
215 .delete_address = tuntap_del_addr, 218 .delete_address = tuntap_del_addr,
216 .max_packet = MAX_PACKET 219 .max_packet = MAX_PACKET
217}; 220};
218
219/*
220 * Overrides for Emacs so that we follow Linus's tabbing style.
221 * Emacs will notice this stuff at the end of the file and automatically
222 * adjust the settings for this buffer only. This must remain at the end
223 * of the file.
224 * ---------------------------------------------------------------------------
225 * Local variables:
226 * c-file-style: "linux"
227 * End:
228 */
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 371b4335f46d..6f92f732d253 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -18,7 +18,6 @@
18#include "os.h" 18#include "os.h"
19#include "user.h" 19#include "user.h"
20#include "kern_util.h" 20#include "kern_util.h"
21#include "user_util.h"
22 21
23static void copy_stat(struct uml_stat *dst, struct stat64 *src) 22static void copy_stat(struct uml_stat *dst, struct stat64 *src)
24{ 23{
@@ -291,54 +290,22 @@ int os_seek_file(int fd, __u64 offset)
291 return 0; 290 return 0;
292} 291}
293 292
294static int fault_buffer(void *start, int len, 293int os_read_file(int fd, void *buf, int len)
295 int (*copy_proc)(void *addr, void *buf, int len))
296{
297 int page = getpagesize(), i;
298 char c;
299
300 for(i = 0; i < len; i += page){
301 if((*copy_proc)(start + i, &c, sizeof(c)))
302 return -EFAULT;
303 }
304 if((len % page) != 0){
305 if((*copy_proc)(start + len - 1, &c, sizeof(c)))
306 return -EFAULT;
307 }
308 return 0;
309}
310
311static int file_io(int fd, void *buf, int len,
312 int (*io_proc)(int fd, void *buf, int len),
313 int (*copy_user_proc)(void *addr, void *buf, int len))
314{ 294{
315 int n, err; 295 int n = read(fd, buf, len);
316
317 do {
318 n = (*io_proc)(fd, buf, len);
319 if((n < 0) && (errno == EFAULT)){
320 err = fault_buffer(buf, len, copy_user_proc);
321 if(err)
322 return err;
323 n = (*io_proc)(fd, buf, len);
324 }
325 } while((n < 0) && (errno == EINTR));
326 296
327 if(n < 0) 297 if(n < 0)
328 return -errno; 298 return -errno;
329 return n; 299 return n;
330} 300}
331 301
332int os_read_file(int fd, void *buf, int len)
333{
334 return file_io(fd, buf, len, (int (*)(int, void *, int)) read,
335 copy_from_user_proc);
336}
337
338int os_write_file(int fd, const void *buf, int len) 302int os_write_file(int fd, const void *buf, int len)
339{ 303{
340 return file_io(fd, (void *) buf, len, 304 int n = write(fd, (void *) buf, len);
341 (int (*)(int, void *, int)) write, copy_to_user_proc); 305
306 if(n < 0)
307 return -errno;
308 return n;
342} 309}
343 310
344int os_file_size(char *file, unsigned long long *size_out) 311int os_file_size(char *file, unsigned long long *size_out)
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index c7ad6306e22f..97bed16bf4c7 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -13,9 +13,9 @@
13#include <sys/wait.h> 13#include <sys/wait.h>
14#include "user.h" 14#include "user.h"
15#include "kern_util.h" 15#include "kern_util.h"
16#include "user_util.h"
17#include "os.h" 16#include "os.h"
18#include "um_malloc.h" 17#include "um_malloc.h"
18#include "kern_constants.h"
19 19
20struct helper_data { 20struct helper_data {
21 void (*pre_exec)(void*); 21 void (*pre_exec)(void*);
@@ -25,28 +25,18 @@ struct helper_data {
25 char *buf; 25 char *buf;
26}; 26};
27 27
28/* Debugging aid, changed only from gdb */
29int helper_pause = 0;
30
31static void helper_hup(int sig)
32{
33}
34
35static int helper_child(void *arg) 28static int helper_child(void *arg)
36{ 29{
37 struct helper_data *data = arg; 30 struct helper_data *data = arg;
38 char **argv = data->argv; 31 char **argv = data->argv;
39 int errval; 32 int errval;
40 33
41 if (helper_pause){
42 signal(SIGHUP, helper_hup);
43 pause();
44 }
45 if (data->pre_exec != NULL) 34 if (data->pre_exec != NULL)
46 (*data->pre_exec)(data->pre_data); 35 (*data->pre_exec)(data->pre_data);
47 errval = execvp_noalloc(data->buf, argv[0], argv); 36 errval = execvp_noalloc(data->buf, argv[0], argv);
48 printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval); 37 printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0],
49 os_write_file(data->fd, &errval, sizeof(errval)); 38 -errval);
39 write(data->fd, &errval, sizeof(errval));
50 kill(os_getpid(), SIGKILL); 40 kill(os_getpid(), SIGKILL);
51 return 0; 41 return 0;
52} 42}
@@ -81,7 +71,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
81 goto out_close; 71 goto out_close;
82 } 72 }
83 73
84 sp = stack + page_size() - sizeof(void *); 74 sp = stack + UM_KERN_PAGE_SIZE - sizeof(void *);
85 data.pre_exec = pre_exec; 75 data.pre_exec = pre_exec;
86 data.pre_data = pre_data; 76 data.pre_data = pre_data;
87 data.argv = argv; 77 data.argv = argv;
@@ -98,13 +88,16 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
98 close(fds[1]); 88 close(fds[1]);
99 fds[1] = -1; 89 fds[1] = -1;
100 90
101 /* Read the errno value from the child, if the exec failed, or get 0 if 91 /*
102 * the exec succeeded because the pipe fd was set as close-on-exec. */ 92 * Read the errno value from the child, if the exec failed, or get 0 if
103 n = os_read_file(fds[0], &ret, sizeof(ret)); 93 * the exec succeeded because the pipe fd was set as close-on-exec.
94 */
95 n = read(fds[0], &ret, sizeof(ret));
104 if (n == 0) { 96 if (n == 0) {
105 ret = pid; 97 ret = pid;
106 } else { 98 } else {
107 if (n < 0) { 99 if (n < 0) {
100 n = -errno;
108 printk("run_helper : read on pipe failed, ret = %d\n", 101 printk("run_helper : read on pipe failed, ret = %d\n",
109 -n); 102 -n);
110 ret = n; 103 ret = n;
@@ -135,7 +128,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
135 if (stack == 0) 128 if (stack == 0)
136 return -ENOMEM; 129 return -ENOMEM;
137 130
138 sp = stack + (page_size() << stack_order) - sizeof(void *); 131 sp = stack + (UM_KERN_PAGE_SIZE << stack_order) - sizeof(void *);
139 pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); 132 pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
140 if (pid < 0) { 133 if (pid < 0) {
141 err = -errno; 134 err = -errno;
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index d1b61d474e0a..a633fa8e0a94 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -11,7 +11,6 @@
11#include <sys/poll.h> 11#include <sys/poll.h>
12#include <sys/types.h> 12#include <sys/types.h>
13#include <sys/time.h> 13#include <sys/time.h>
14#include "user_util.h"
15#include "kern_util.h" 14#include "kern_util.h"
16#include "user.h" 15#include "user.h"
17#include "process.h" 16#include "process.h"
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 685feaab65d2..ea9a23696f36 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -13,8 +13,8 @@
13#include <sys/mman.h> 13#include <sys/mman.h>
14#include <sys/user.h> 14#include <sys/user.h>
15#include <asm/page.h> 15#include <asm/page.h>
16#include "user_util.h"
17#include "kern_util.h" 16#include "kern_util.h"
17#include "as-layout.h"
18#include "mem_user.h" 18#include "mem_user.h"
19#include "irq_user.h" 19#include "irq_user.h"
20#include "user.h" 20#include "user.h"
@@ -25,12 +25,7 @@
25#include "os.h" 25#include "os.h"
26#include "um_malloc.h" 26#include "um_malloc.h"
27 27
28/* Set in set_stklim, which is called from main and __wrap_malloc. 28/* Set in main, unchanged thereafter */
29 * __wrap_malloc only calls it if main hasn't started.
30 */
31unsigned long stacksizelim;
32
33/* Set in main */
34char *linux_prog; 29char *linux_prog;
35 30
36#define PGD_BOUND (4 * 1024 * 1024) 31#define PGD_BOUND (4 * 1024 * 1024)
@@ -52,7 +47,6 @@ static void set_stklim(void)
52 exit(1); 47 exit(1);
53 } 48 }
54 } 49 }
55 stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
56} 50}
57 51
58static __init void do_uml_initcalls(void) 52static __init void do_uml_initcalls(void)
@@ -126,7 +120,7 @@ extern int uml_exitcode;
126 120
127extern void scan_elf_aux( char **envp); 121extern void scan_elf_aux( char **envp);
128 122
129int main(int argc, char **argv, char **envp) 123int __init main(int argc, char **argv, char **envp)
130{ 124{
131 char **new_argv; 125 char **new_argv;
132 int ret, i, err; 126 int ret, i, err;
@@ -224,7 +218,7 @@ int main(int argc, char **argv, char **envp)
224 ret = 1; 218 ret = 1;
225 } 219 }
226 printf("\n"); 220 printf("\n");
227 return(uml_exitcode); 221 return uml_exitcode;
228} 222}
229 223
230#define CAN_KMALLOC() \ 224#define CAN_KMALLOC() \
@@ -237,7 +231,7 @@ void *__wrap_malloc(int size)
237 void *ret; 231 void *ret;
238 232
239 if(!CAN_KMALLOC()) 233 if(!CAN_KMALLOC())
240 return(__real_malloc(size)); 234 return __real_malloc(size);
241 else if(size <= PAGE_SIZE) /* finding contiguos pages can be hard*/ 235 else if(size <= PAGE_SIZE) /* finding contiguos pages can be hard*/
242 ret = um_kmalloc(size); 236 ret = um_kmalloc(size);
243 else ret = um_vmalloc(size); 237 else ret = um_vmalloc(size);
@@ -248,16 +242,17 @@ void *__wrap_malloc(int size)
248 if(ret == NULL) 242 if(ret == NULL)
249 errno = ENOMEM; 243 errno = ENOMEM;
250 244
251 return(ret); 245 return ret;
252} 246}
253 247
254void *__wrap_calloc(int n, int size) 248void *__wrap_calloc(int n, int size)
255{ 249{
256 void *ptr = __wrap_malloc(n * size); 250 void *ptr = __wrap_malloc(n * size);
257 251
258 if(ptr == NULL) return(NULL); 252 if(ptr == NULL)
253 return NULL;
259 memset(ptr, 0, n * size); 254 memset(ptr, 0, n * size);
260 return(ptr); 255 return ptr;
261} 256}
262 257
263extern void __real_free(void *); 258extern void __real_free(void *);
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index f1ea169db85e..c6378c6d10d2 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -11,7 +11,6 @@
11#include <sys/statfs.h> 11#include <sys/statfs.h>
12#include "kern_util.h" 12#include "kern_util.h"
13#include "user.h" 13#include "user.h"
14#include "user_util.h"
15#include "mem_user.h" 14#include "mem_user.h"
16#include "init.h" 15#include "init.h"
17#include "os.h" 16#include "os.h"
@@ -165,7 +164,8 @@ found:
165 * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). 164 * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger).
166 * So it isn't 'static' yet. 165 * So it isn't 'static' yet.
167 */ 166 */
168int make_tempfile(const char *template, char **out_tempname, int do_unlink) 167int __init make_tempfile(const char *template, char **out_tempname,
168 int do_unlink)
169{ 169{
170 char *tempname; 170 char *tempname;
171 int fd; 171 int fd;
@@ -206,7 +206,7 @@ out:
206 * This proc is used in start_up.c 206 * This proc is used in start_up.c
207 * So it isn't 'static'. 207 * So it isn't 'static'.
208 */ 208 */
209int create_tmp_file(unsigned long long len) 209int __init create_tmp_file(unsigned long long len)
210{ 210{
211 int fd, err; 211 int fd, err;
212 char zero; 212 char zero;
@@ -232,17 +232,16 @@ int create_tmp_file(unsigned long long len)
232 232
233 zero = 0; 233 zero = 0;
234 234
235 err = os_write_file(fd, &zero, 1); 235 err = write(fd, &zero, 1);
236 if(err != 1){ 236 if(err != 1){
237 errno = -err; 237 perror("write");
238 perror("os_write_file");
239 exit(1); 238 exit(1);
240 } 239 }
241 240
242 return fd; 241 return fd;
243} 242}
244 243
245int create_mem_file(unsigned long long len) 244int __init create_mem_file(unsigned long long len)
246{ 245{
247 int err, fd; 246 int err, fd;
248 247
@@ -257,7 +256,7 @@ int create_mem_file(unsigned long long len)
257} 256}
258 257
259 258
260void check_tmpexec(void) 259void __init check_tmpexec(void)
261{ 260{
262 void *addr; 261 void *addr;
263 int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); 262 int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 76bdd6712417..92a7b59120d6 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -14,7 +14,6 @@
14#include "ptrace_user.h" 14#include "ptrace_user.h"
15#include "os.h" 15#include "os.h"
16#include "user.h" 16#include "user.h"
17#include "user_util.h"
18#include "process.h" 17#include "process.h"
19#include "irq_user.h" 18#include "irq_user.h"
20#include "kern_util.h" 19#include "kern_util.h"
@@ -22,6 +21,7 @@
22#include "skas_ptrace.h" 21#include "skas_ptrace.h"
23#include "kern_constants.h" 22#include "kern_constants.h"
24#include "uml-config.h" 23#include "uml-config.h"
24#include "init.h"
25 25
26#define ARBITRARY_ADDR -1 26#define ARBITRARY_ADDR -1
27#define FAILURE_PID -1 27#define FAILURE_PID -1
@@ -40,14 +40,14 @@ unsigned long os_process_pc(int pid)
40 if(fd < 0){ 40 if(fd < 0){
41 printk("os_process_pc - couldn't open '%s', err = %d\n", 41 printk("os_process_pc - couldn't open '%s', err = %d\n",
42 proc_stat, -fd); 42 proc_stat, -fd);
43 return(ARBITRARY_ADDR); 43 return ARBITRARY_ADDR;
44 } 44 }
45 err = os_read_file(fd, buf, sizeof(buf)); 45 CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
46 if(err < 0){ 46 if(err < 0){
47 printk("os_process_pc - couldn't read '%s', err = %d\n", 47 printk("os_process_pc - couldn't read '%s', err = %d\n",
48 proc_stat, -err); 48 proc_stat, errno);
49 os_close_file(fd); 49 os_close_file(fd);
50 return(ARBITRARY_ADDR); 50 return ARBITRARY_ADDR;
51 } 51 }
52 os_close_file(fd); 52 os_close_file(fd);
53 pc = ARBITRARY_ADDR; 53 pc = ARBITRARY_ADDR;
@@ -56,7 +56,7 @@ unsigned long os_process_pc(int pid)
56 "%*d %*d %*d %*d %*d %lu", &pc) != 1){ 56 "%*d %*d %*d %*d %*d %lu", &pc) != 1){
57 printk("os_process_pc - couldn't find pc in '%s'\n", buf); 57 printk("os_process_pc - couldn't find pc in '%s'\n", buf);
58 } 58 }
59 return(pc); 59 return pc;
60} 60}
61 61
62int os_process_parent(int pid) 62int os_process_parent(int pid)
@@ -65,21 +65,22 @@ int os_process_parent(int pid)
65 char data[256]; 65 char data[256];
66 int parent, n, fd; 66 int parent, n, fd;
67 67
68 if(pid == -1) return(-1); 68 if(pid == -1)
69 return -1;
69 70
70 snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); 71 snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
71 fd = os_open_file(stat, of_read(OPENFLAGS()), 0); 72 fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
72 if(fd < 0){ 73 if(fd < 0){
73 printk("Couldn't open '%s', err = %d\n", stat, -fd); 74 printk("Couldn't open '%s', err = %d\n", stat, -fd);
74 return(FAILURE_PID); 75 return FAILURE_PID;
75 } 76 }
76 77
77 n = os_read_file(fd, data, sizeof(data)); 78 CATCH_EINTR(n = read(fd, data, sizeof(data)));
78 os_close_file(fd); 79 os_close_file(fd);
79 80
80 if(n < 0){ 81 if(n < 0){
81 printk("Couldn't read '%s', err = %d\n", stat, -n); 82 printk("Couldn't read '%s', err = %d\n", stat, errno);
82 return(FAILURE_PID); 83 return FAILURE_PID;
83 } 84 }
84 85
85 parent = FAILURE_PID; 86 parent = FAILURE_PID;
@@ -87,7 +88,7 @@ int os_process_parent(int pid)
87 if(n != 1) 88 if(n != 1)
88 printk("Failed to scan '%s'\n", data); 89 printk("Failed to scan '%s'\n", data);
89 90
90 return(parent); 91 return parent;
91} 92}
92 93
93void os_stop_process(int pid) 94void os_stop_process(int pid)
@@ -145,7 +146,7 @@ void os_usr1_process(int pid)
145 146
146int os_getpid(void) 147int os_getpid(void)
147{ 148{
148 return(syscall(__NR_getpid)); 149 return syscall(__NR_getpid);
149} 150}
150 151
151int os_getpgrp(void) 152int os_getpgrp(void)
@@ -165,8 +166,8 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
165 loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 166 loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
166 fd, off); 167 fd, off);
167 if(loc == MAP_FAILED) 168 if(loc == MAP_FAILED)
168 return(-errno); 169 return -errno;
169 return(0); 170 return 0;
170} 171}
171 172
172int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) 173int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
@@ -175,8 +176,8 @@ int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
175 (x ? PROT_EXEC : 0)); 176 (x ? PROT_EXEC : 0));
176 177
177 if(mprotect(addr, len, prot) < 0) 178 if(mprotect(addr, len, prot) < 0)
178 return(-errno); 179 return -errno;
179 return(0); 180 return 0;
180} 181}
181 182
182int os_unmap_memory(void *addr, int len) 183int os_unmap_memory(void *addr, int len)
@@ -185,15 +186,15 @@ int os_unmap_memory(void *addr, int len)
185 186
186 err = munmap(addr, len); 187 err = munmap(addr, len);
187 if(err < 0) 188 if(err < 0)
188 return(-errno); 189 return -errno;
189 return(0); 190 return 0;
190} 191}
191 192
192#ifndef MADV_REMOVE 193#ifndef MADV_REMOVE
193#define MADV_REMOVE KERNEL_MADV_REMOVE 194#define MADV_REMOVE KERNEL_MADV_REMOVE
194#endif 195#endif
195 196
196int os_drop_memory(void *addr, int length) 197int __init os_drop_memory(void *addr, int length)
197{ 198{
198 int err; 199 int err;
199 200
@@ -203,7 +204,7 @@ int os_drop_memory(void *addr, int length)
203 return err; 204 return err;
204} 205}
205 206
206int can_drop_memory(void) 207int __init can_drop_memory(void)
207{ 208{
208 void *addr; 209 void *addr;
209 int fd, ok = 0; 210 int fd, ok = 0;
@@ -244,7 +245,7 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
244 245
245 if(sig_stack != NULL){ 246 if(sig_stack != NULL){
246 pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER); 247 pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER);
247 set_sigstack(sig_stack, pages * page_size()); 248 set_sigstack(sig_stack, pages * UM_KERN_PAGE_SIZE);
248 flags = SA_ONSTACK; 249 flags = SA_ONSTACK;
249 } 250 }
250 if(usr1_handler){ 251 if(usr1_handler){
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 3fc43b33db66..8d4e0c6b8c92 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -8,6 +8,7 @@
8#include <termios.h> 8#include <termios.h>
9#include <pty.h> 9#include <pty.h>
10#include <signal.h> 10#include <signal.h>
11#include <fcntl.h>
11#include <errno.h> 12#include <errno.h>
12#include <string.h> 13#include <string.h>
13#include <sched.h> 14#include <sched.h>
@@ -16,10 +17,10 @@
16#include "init.h" 17#include "init.h"
17#include "user.h" 18#include "user.h"
18#include "kern_util.h" 19#include "kern_util.h"
19#include "user_util.h"
20#include "sigio.h" 20#include "sigio.h"
21#include "os.h" 21#include "os.h"
22#include "um_malloc.h" 22#include "um_malloc.h"
23#include "init.h"
23 24
24/* Protected by sigio_lock(), also used by sigio_cleanup, which is an 25/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
25 * exitcall. 26 * exitcall.
@@ -68,11 +69,12 @@ static int write_sigio_thread(void *unused)
68 p = &fds->poll[i]; 69 p = &fds->poll[i];
69 if(p->revents == 0) continue; 70 if(p->revents == 0) continue;
70 if(p->fd == sigio_private[1]){ 71 if(p->fd == sigio_private[1]){
71 n = os_read_file(sigio_private[1], &c, sizeof(c)); 72 CATCH_EINTR(n = read(sigio_private[1], &c,
73 sizeof(c)));
72 if(n != sizeof(c)) 74 if(n != sizeof(c))
73 printk("write_sigio_thread : " 75 printk("write_sigio_thread : "
74 "read on socket failed, " 76 "read on socket failed, "
75 "err = %d\n", -n); 77 "err = %d\n", errno);
76 tmp = current_poll; 78 tmp = current_poll;
77 current_poll = next_poll; 79 current_poll = next_poll;
78 next_poll = tmp; 80 next_poll = tmp;
@@ -85,10 +87,10 @@ static int write_sigio_thread(void *unused)
85 (fds->used - i) * sizeof(*fds->poll)); 87 (fds->used - i) * sizeof(*fds->poll));
86 } 88 }
87 89
88 n = os_write_file(respond_fd, &c, sizeof(c)); 90 CATCH_EINTR(n = write(respond_fd, &c, sizeof(c)));
89 if(n != sizeof(c)) 91 if(n != sizeof(c))
90 printk("write_sigio_thread : write on socket " 92 printk("write_sigio_thread : write on socket "
91 "failed, err = %d\n", -n); 93 "failed, err = %d\n", errno);
92 } 94 }
93 } 95 }
94 96
@@ -126,15 +128,15 @@ static void update_thread(void)
126 char c; 128 char c;
127 129
128 flags = set_signals(0); 130 flags = set_signals(0);
129 n = os_write_file(sigio_private[0], &c, sizeof(c)); 131 n = write(sigio_private[0], &c, sizeof(c));
130 if(n != sizeof(c)){ 132 if(n != sizeof(c)){
131 printk("update_thread : write failed, err = %d\n", -n); 133 printk("update_thread : write failed, err = %d\n", errno);
132 goto fail; 134 goto fail;
133 } 135 }
134 136
135 n = os_read_file(sigio_private[0], &c, sizeof(c)); 137 CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c)));
136 if(n != sizeof(c)){ 138 if(n != sizeof(c)){
137 printk("update_thread : read failed, err = %d\n", -n); 139 printk("update_thread : read failed, err = %d\n", errno);
138 goto fail; 140 goto fail;
139 } 141 }
140 142
@@ -320,6 +322,10 @@ out_close1:
320 close(l_write_sigio_fds[1]); 322 close(l_write_sigio_fds[1]);
321} 323}
322 324
325/* Changed during early boot */
326static int pty_output_sigio = 0;
327static int pty_close_sigio = 0;
328
323void maybe_sigio_broken(int fd, int read) 329void maybe_sigio_broken(int fd, int read)
324{ 330{
325 int err; 331 int err;
@@ -357,3 +363,143 @@ static void sigio_cleanup(void)
357} 363}
358 364
359__uml_exitcall(sigio_cleanup); 365__uml_exitcall(sigio_cleanup);
366
367/* Used as a flag during SIGIO testing early in boot */
368static volatile int got_sigio = 0;
369
370static void __init handler(int sig)
371{
372 got_sigio = 1;
373}
374
375struct openpty_arg {
376 int master;
377 int slave;
378 int err;
379};
380
381static void openpty_cb(void *arg)
382{
383 struct openpty_arg *info = arg;
384
385 info->err = 0;
386 if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
387 info->err = -errno;
388}
389
390static int async_pty(int master, int slave)
391{
392 int flags;
393
394 flags = fcntl(master, F_GETFL);
395 if(flags < 0)
396 return -errno;
397
398 if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
399 (fcntl(master, F_SETOWN, os_getpid()) < 0))
400 return -errno;
401
402 if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
403 return -errno;
404
405 return(0);
406}
407
408static void __init check_one_sigio(void (*proc)(int, int))
409{
410 struct sigaction old, new;
411 struct openpty_arg pty = { .master = -1, .slave = -1 };
412 int master, slave, err;
413
414 initial_thread_cb(openpty_cb, &pty);
415 if(pty.err){
416 printk("openpty failed, errno = %d\n", -pty.err);
417 return;
418 }
419
420 master = pty.master;
421 slave = pty.slave;
422
423 if((master == -1) || (slave == -1)){
424 printk("openpty failed to allocate a pty\n");
425 return;
426 }
427
428 /* Not now, but complain so we now where we failed. */
429 err = raw(master);
430 if (err < 0)
431 panic("check_sigio : __raw failed, errno = %d\n", -err);
432
433 err = async_pty(master, slave);
434 if(err < 0)
435 panic("tty_fds : sigio_async failed, err = %d\n", -err);
436
437 if(sigaction(SIGIO, NULL, &old) < 0)
438 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
439 new = old;
440 new.sa_handler = handler;
441 if(sigaction(SIGIO, &new, NULL) < 0)
442 panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
443
444 got_sigio = 0;
445 (*proc)(master, slave);
446
447 close(master);
448 close(slave);
449
450 if(sigaction(SIGIO, &old, NULL) < 0)
451 panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
452}
453
454static void tty_output(int master, int slave)
455{
456 int n;
457 char buf[512];
458
459 printk("Checking that host ptys support output SIGIO...");
460
461 memset(buf, 0, sizeof(buf));
462
463 while(write(master, buf, sizeof(buf)) > 0) ;
464 if(errno != EAGAIN)
465 panic("tty_output : write failed, errno = %d\n", errno);
466 while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
467
468 if(got_sigio){
469 printk("Yes\n");
470 pty_output_sigio = 1;
471 }
472 else if(n == -EAGAIN)
473 printk("No, enabling workaround\n");
474 else panic("tty_output : read failed, err = %d\n", n);
475}
476
477static void tty_close(int master, int slave)
478{
479 printk("Checking that host ptys support SIGIO on close...");
480
481 close(slave);
482 if(got_sigio){
483 printk("Yes\n");
484 pty_close_sigio = 1;
485 }
486 else printk("No, enabling workaround\n");
487}
488
489void __init check_sigio(void)
490{
491 if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
492 (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
493 printk("No pseudo-terminals available - skipping pty SIGIO "
494 "check\n");
495 return;
496 }
497 check_one_sigio(tty_output);
498 check_one_sigio(tty_close);
499}
500
501/* Here because it only does the SIGIO testing for now */
502void __init os_check_bugs(void)
503{
504 check_sigio();
505}
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 266768629fee..48d493415301 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -11,7 +11,6 @@
11#include <stdarg.h> 11#include <stdarg.h>
12#include <string.h> 12#include <string.h>
13#include <sys/mman.h> 13#include <sys/mman.h>
14#include "user_util.h"
15#include "user.h" 14#include "user.h"
16#include "signal_kern.h" 15#include "signal_kern.h"
17#include "sysdep/sigcontext.h" 16#include "sysdep/sigcontext.h"
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 9383e8751ae7..8e490fff3d47 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -6,6 +6,7 @@
6#include <signal.h> 6#include <signal.h>
7#include <errno.h> 7#include <errno.h>
8#include <string.h> 8#include <string.h>
9#include <unistd.h>
9#include <sys/mman.h> 10#include <sys/mman.h>
10#include <sys/wait.h> 11#include <sys/wait.h>
11#include <asm/page.h> 12#include <asm/page.h>
@@ -17,17 +18,17 @@
17#include "os.h" 18#include "os.h"
18#include "proc_mm.h" 19#include "proc_mm.h"
19#include "ptrace_user.h" 20#include "ptrace_user.h"
20#include "user_util.h"
21#include "kern_util.h" 21#include "kern_util.h"
22#include "task.h" 22#include "task.h"
23#include "registers.h" 23#include "registers.h"
24#include "uml-config.h" 24#include "uml-config.h"
25#include "sysdep/ptrace.h" 25#include "sysdep/ptrace.h"
26#include "sysdep/stub.h" 26#include "sysdep/stub.h"
27#include "init.h"
27 28
28extern unsigned long batch_syscall_stub, __syscall_stub_start; 29extern unsigned long batch_syscall_stub, __syscall_stub_start;
29 30
30extern void wait_stub_done(int pid, int sig, char * fname); 31extern void wait_stub_done(int pid);
31 32
32static inline unsigned long *check_init_stack(struct mm_id * mm_idp, 33static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
33 unsigned long *stack) 34 unsigned long *stack)
@@ -39,6 +40,19 @@ static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
39 return stack; 40 return stack;
40} 41}
41 42
43static unsigned long syscall_regs[MAX_REG_NR];
44
45static int __init init_syscall_regs(void)
46{
47 get_safe_registers(syscall_regs, NULL);
48 syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
49 ((unsigned long) &batch_syscall_stub -
50 (unsigned long) &__syscall_stub_start);
51 return 0;
52}
53
54__initcall(init_syscall_regs);
55
42extern int proc_mm; 56extern int proc_mm;
43 57
44int single_count = 0; 58int single_count = 0;
@@ -47,12 +61,11 @@ int multi_op_count = 0;
47 61
48static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) 62static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
49{ 63{
50 unsigned long regs[MAX_REG_NR];
51 int n, i; 64 int n, i;
52 long ret, offset; 65 long ret, offset;
53 unsigned long * data; 66 unsigned long * data;
54 unsigned long * syscall; 67 unsigned long * syscall;
55 int pid = mm_idp->u.pid; 68 int err, pid = mm_idp->u.pid;
56 69
57 if(proc_mm) 70 if(proc_mm)
58#warning Need to look up userspace_pid by cpu 71#warning Need to look up userspace_pid by cpu
@@ -60,21 +73,21 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
60 73
61 multi_count++; 74 multi_count++;
62 75
63 get_safe_registers(regs, NULL); 76 n = ptrace_setregs(pid, syscall_regs);
64 regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
65 ((unsigned long) &batch_syscall_stub -
66 (unsigned long) &__syscall_stub_start);
67
68 n = ptrace_setregs(pid, regs);
69 if(n < 0){ 77 if(n < 0){
70 printk("Registers - \n"); 78 printk("Registers - \n");
71 for(i = 0; i < MAX_REG_NR; i++) 79 for(i = 0; i < MAX_REG_NR; i++)
72 printk("\t%d\t0x%lx\n", i, regs[i]); 80 printk("\t%d\t0x%lx\n", i, syscall_regs[i]);
73 panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", 81 panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
74 -n); 82 -n);
75 } 83 }
76 84
77 wait_stub_done(pid, 0, "do_syscall_stub"); 85 err = ptrace(PTRACE_CONT, pid, 0, 0);
86 if(err)
87 panic("Failed to continue stub, pid = %d, errno = %d\n", pid,
88 errno);
89
90 wait_stub_done(pid);
78 91
79 /* When the stub stops, we find the following values on the 92 /* When the stub stops, we find the following values on the
80 * beginning of the stack: 93 * beginning of the stack:
@@ -176,14 +189,10 @@ long syscall_stub_data(struct mm_id * mm_idp,
176 return 0; 189 return 0;
177} 190}
178 191
179int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, 192int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
180 int r, int w, int x, int phys_fd, unsigned long long offset, 193 int phys_fd, unsigned long long offset, int done, void **data)
181 int done, void **data)
182{ 194{
183 int prot, ret; 195 int ret;
184
185 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
186 (x ? PROT_EXEC : 0);
187 196
188 if(proc_mm){ 197 if(proc_mm){
189 struct proc_mm_op map; 198 struct proc_mm_op map;
@@ -200,9 +209,11 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
200 .fd = phys_fd, 209 .fd = phys_fd,
201 .offset= offset 210 .offset= offset
202 } } } ); 211 } } } );
203 ret = os_write_file(fd, &map, sizeof(map)); 212 CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
204 if(ret != sizeof(map)) 213 if(ret != sizeof(map)){
214 ret = -errno;
205 printk("map : /proc/mm map failed, err = %d\n", -ret); 215 printk("map : /proc/mm map failed, err = %d\n", -ret);
216 }
206 else ret = 0; 217 else ret = 0;
207 } 218 }
208 else { 219 else {
@@ -217,8 +228,8 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
217 return ret; 228 return ret;
218} 229}
219 230
220int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done, 231int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
221 void **data) 232 int done, void **data)
222{ 233{
223 int ret; 234 int ret;
224 235
@@ -232,9 +243,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
232 { .addr = 243 { .addr =
233 (unsigned long) addr, 244 (unsigned long) addr,
234 .len = len } } } ); 245 .len = len } } } );
235 ret = os_write_file(fd, &unmap, sizeof(unmap)); 246 CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
236 if(ret != sizeof(unmap)) 247 if(ret != sizeof(unmap)){
248 ret = -errno;
237 printk("unmap - proc_mm write returned %d\n", ret); 249 printk("unmap - proc_mm write returned %d\n", ret);
250 }
238 else ret = 0; 251 else ret = 0;
239 } 252 }
240 else { 253 else {
@@ -249,13 +262,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
249} 262}
250 263
251int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, 264int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
252 int r, int w, int x, int done, void **data) 265 unsigned int prot, int done, void **data)
253{ 266{
254 struct proc_mm_op protect; 267 struct proc_mm_op protect;
255 int prot, ret; 268 int ret;
256 269
257 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
258 (x ? PROT_EXEC : 0);
259 if(proc_mm){ 270 if(proc_mm){
260 int fd = mm_idp->u.mm_fd; 271 int fd = mm_idp->u.mm_fd;
261 272
@@ -267,9 +278,11 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
267 .len = len, 278 .len = len,
268 .prot = prot } } } ); 279 .prot = prot } } } );
269 280
270 ret = os_write_file(fd, &protect, sizeof(protect)); 281 CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
271 if(ret != sizeof(protect)) 282 if(ret != sizeof(protect)){
283 ret = -errno;
272 printk("protect failed, err = %d", -ret); 284 printk("protect failed, err = %d", -ret);
285 }
273 else ret = 0; 286 else ret = 0;
274 } 287 }
275 else { 288 else {
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 0564422c155f..5c088a55396c 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -18,7 +18,6 @@
18#include <asm/types.h> 18#include <asm/types.h>
19#include "user.h" 19#include "user.h"
20#include "sysdep/ptrace.h" 20#include "sysdep/ptrace.h"
21#include "user_util.h"
22#include "kern_util.h" 21#include "kern_util.h"
23#include "skas.h" 22#include "skas.h"
24#include "stub-data.h" 23#include "stub-data.h"
@@ -34,6 +33,8 @@
34#include "uml-config.h" 33#include "uml-config.h"
35#include "process.h" 34#include "process.h"
36#include "longjmp.h" 35#include "longjmp.h"
36#include "kern_constants.h"
37#include "as-layout.h"
37 38
38int is_skas_winch(int pid, int fd, void *data) 39int is_skas_winch(int pid, int fd, void *data)
39{ 40{
@@ -44,45 +45,58 @@ int is_skas_winch(int pid, int fd, void *data)
44 return(1); 45 return(1);
45} 46}
46 47
47void wait_stub_done(int pid, int sig, char * fname) 48static int ptrace_dump_regs(int pid)
48{ 49{
49 int n, status, err; 50 unsigned long regs[MAX_REG_NR];
51 int i;
52
53 if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
54 return -errno;
55 else {
56 printk("Stub registers -\n");
57 for(i = 0; i < ARRAY_SIZE(regs); i++)
58 printk("\t%d - %lx\n", i, regs[i]);
59 }
60
61 return 0;
62}
50 63
51 do { 64/*
52 if ( sig != -1 ) { 65 * Signals that are OK to receive in the stub - we'll just continue it.
53 err = ptrace(PTRACE_CONT, pid, 0, sig); 66 * SIGWINCH will happen when UML is inside a detached screen.
54 if(err) 67 */
55 panic("%s : continue failed, errno = %d\n", 68#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH))
56 fname, errno); 69
57 } 70/* Signals that the stub will finish with - anything else is an error */
58 sig = 0; 71#define STUB_DONE_MASK ((1 << SIGUSR1) | (1 << SIGTRAP))
72
73void wait_stub_done(int pid)
74{
75 int n, status, err;
59 76
77 while(1){
60 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 78 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
61 } while((n >= 0) && WIFSTOPPED(status) && 79 if((n < 0) || !WIFSTOPPED(status))
62 ((WSTOPSIG(status) == SIGVTALRM) || 80 goto bad_wait;
63 /* running UML inside a detached screen can cause 81
64 * SIGWINCHes 82 if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0)
65 */ 83 break;
66 (WSTOPSIG(status) == SIGWINCH))); 84
67 85 err = ptrace(PTRACE_CONT, pid, 0, 0);
68 if((n < 0) || !WIFSTOPPED(status) || 86 if(err)
69 (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ 87 panic("wait_stub_done : continue failed, errno = %d\n",
70 unsigned long regs[MAX_REG_NR]; 88 errno);
71
72 if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
73 printk("Failed to get registers from stub, "
74 "errno = %d\n", errno);
75 else {
76 int i;
77
78 printk("Stub registers -\n");
79 for(i = 0; i < ARRAY_SIZE(regs); i++)
80 printk("\t%d - %lx\n", i, regs[i]);
81 }
82 panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
83 "pid = %d, n = %d, errno = %d, status = 0x%x\n",
84 fname, pid, n, errno, status);
85 } 89 }
90
91 if(((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
92 return;
93
94bad_wait:
95 err = ptrace_dump_regs(pid);
96 if(err)
97 printk("Failed to get registers from stub, errno = %d\n", -err);
98 panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, "
99 "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status);
86} 100}
87 101
88extern unsigned long current_stub_stack(void); 102extern unsigned long current_stub_stack(void);
@@ -104,7 +118,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
104 sizeof(struct ptrace_faultinfo)); 118 sizeof(struct ptrace_faultinfo));
105 } 119 }
106 else { 120 else {
107 wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo"); 121 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
122 if(err)
123 panic("Failed to continue stub, pid = %d, errno = %d\n",
124 pid, errno);
125 wait_stub_done(pid);
108 126
109 /* faultinfo is prepared by the stub-segv-handler at start of 127 /* faultinfo is prepared by the stub-segv-handler at start of
110 * the stub stack page. We just have to copy it. 128 * the stub stack page. We just have to copy it.
@@ -142,9 +160,14 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu
142 160
143 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); 161 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
144 if((err < 0) || !WIFSTOPPED(status) || 162 if((err < 0) || !WIFSTOPPED(status) ||
145 (WSTOPSIG(status) != SIGTRAP + 0x80)) 163 (WSTOPSIG(status) != SIGTRAP + 0x80)){
164 err = ptrace_dump_regs(pid);
165 if(err)
166 printk("Failed to get registers from process, "
167 "errno = %d\n", -err);
146 panic("handle_trap - failed to wait at end of syscall, " 168 panic("handle_trap - failed to wait at end of syscall, "
147 "errno = %d, status = %d\n", errno, status); 169 "errno = %d, status = %d\n", errno, status);
170 }
148 } 171 }
149 172
150 handle_syscall(regs); 173 handle_syscall(regs);
@@ -172,7 +195,7 @@ static int userspace_tramp(void *stack)
172 int fd; 195 int fd;
173 __u64 offset; 196 __u64 offset;
174 fd = phys_mapping(to_phys(&__syscall_stub_start), &offset); 197 fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
175 addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(), 198 addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE,
176 PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); 199 PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
177 if(addr == MAP_FAILED){ 200 if(addr == MAP_FAILED){
178 printk("mapping mmap stub failed, errno = %d\n", 201 printk("mapping mmap stub failed, errno = %d\n",
@@ -182,8 +205,8 @@ static int userspace_tramp(void *stack)
182 205
183 if(stack != NULL){ 206 if(stack != NULL){
184 fd = phys_mapping(to_phys(stack), &offset); 207 fd = phys_mapping(to_phys(stack), &offset);
185 addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(), 208 addr = mmap((void *) UML_CONFIG_STUB_DATA,
186 PROT_READ | PROT_WRITE, 209 UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
187 MAP_FIXED | MAP_SHARED, fd, offset); 210 MAP_FIXED | MAP_SHARED, fd, offset);
188 if(addr == MAP_FAILED){ 211 if(addr == MAP_FAILED){
189 printk("mapping segfault stack failed, " 212 printk("mapping segfault stack failed, "
@@ -199,7 +222,7 @@ static int userspace_tramp(void *stack)
199 (unsigned long) stub_segv_handler - 222 (unsigned long) stub_segv_handler -
200 (unsigned long) &__syscall_stub_start; 223 (unsigned long) &__syscall_stub_start;
201 224
202 set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size()); 225 set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE);
203 sigemptyset(&sa.sa_mask); 226 sigemptyset(&sa.sa_mask);
204 sigaddset(&sa.sa_mask, SIGIO); 227 sigaddset(&sa.sa_mask, SIGIO);
205 sigaddset(&sa.sa_mask, SIGWINCH); 228 sigaddset(&sa.sa_mask, SIGWINCH);
@@ -291,10 +314,13 @@ void userspace(union uml_pt_regs *regs)
291 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ 314 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
292 315
293 if(WIFSTOPPED(status)){ 316 if(WIFSTOPPED(status)){
294 switch(WSTOPSIG(status)){ 317 int sig = WSTOPSIG(status);
318 switch(sig){
295 case SIGSEGV: 319 case SIGSEGV:
296 if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo) 320 if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){
297 user_signal(SIGSEGV, regs, pid); 321 get_skas_faultinfo(pid, &regs->skas.faultinfo);
322 (*sig_info[SIGSEGV])(SIGSEGV, regs);
323 }
298 else handle_segv(pid, regs); 324 else handle_segv(pid, regs);
299 break; 325 break;
300 case SIGTRAP + 0x80: 326 case SIGTRAP + 0x80:
@@ -309,11 +335,13 @@ void userspace(union uml_pt_regs *regs)
309 case SIGBUS: 335 case SIGBUS:
310 case SIGFPE: 336 case SIGFPE:
311 case SIGWINCH: 337 case SIGWINCH:
312 user_signal(WSTOPSIG(status), regs, pid); 338 block_signals();
339 (*sig_info[sig])(sig, regs);
340 unblock_signals();
313 break; 341 break;
314 default: 342 default:
315 printk("userspace - child stopped with signal " 343 printk("userspace - child stopped with signal "
316 "%d\n", WSTOPSIG(status)); 344 "%d\n", sig);
317 } 345 }
318 pid = userspace_pid[0]; 346 pid = userspace_pid[0];
319 interrupt_end(); 347 interrupt_end();
@@ -325,11 +353,29 @@ void userspace(union uml_pt_regs *regs)
325 } 353 }
326} 354}
327 355
356static unsigned long thread_regs[MAX_REG_NR];
357static unsigned long thread_fp_regs[HOST_FP_SIZE];
358
359static int __init init_thread_regs(void)
360{
361 get_safe_registers(thread_regs, thread_fp_regs);
362 /* Set parent's instruction pointer to start of clone-stub */
363 thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
364 (unsigned long) stub_clone_handler -
365 (unsigned long) &__syscall_stub_start;
366 thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
367 sizeof(void *);
368#ifdef __SIGNAL_FRAMESIZE
369 thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
370#endif
371 return 0;
372}
373
374__initcall(init_thread_regs);
375
328int copy_context_skas0(unsigned long new_stack, int pid) 376int copy_context_skas0(unsigned long new_stack, int pid)
329{ 377{
330 int err; 378 int err;
331 unsigned long regs[MAX_REG_NR];
332 unsigned long fp_regs[HOST_FP_SIZE];
333 unsigned long current_stack = current_stub_stack(); 379 unsigned long current_stack = current_stub_stack();
334 struct stub_data *data = (struct stub_data *) current_stack; 380 struct stub_data *data = (struct stub_data *) current_stack;
335 struct stub_data *child_data = (struct stub_data *) new_stack; 381 struct stub_data *child_data = (struct stub_data *) new_stack;
@@ -344,23 +390,12 @@ int copy_context_skas0(unsigned long new_stack, int pid)
344 .timer = ((struct itimerval) 390 .timer = ((struct itimerval)
345 { { 0, 1000000 / hz() }, 391 { { 0, 1000000 / hz() },
346 { 0, 1000000 / hz() }})}); 392 { 0, 1000000 / hz() }})});
347 get_safe_registers(regs, fp_regs); 393 err = ptrace_setregs(pid, thread_regs);
348
349 /* Set parent's instruction pointer to start of clone-stub */
350 regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
351 (unsigned long) stub_clone_handler -
352 (unsigned long) &__syscall_stub_start;
353 regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
354 sizeof(void *);
355#ifdef __SIGNAL_FRAMESIZE
356 regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
357#endif
358 err = ptrace_setregs(pid, regs);
359 if(err < 0) 394 if(err < 0)
360 panic("copy_context_skas0 : PTRACE_SETREGS failed, " 395 panic("copy_context_skas0 : PTRACE_SETREGS failed, "
361 "pid = %d, errno = %d\n", pid, -err); 396 "pid = %d, errno = %d\n", pid, -err);
362 397
363 err = ptrace_setfpregs(pid, fp_regs); 398 err = ptrace_setfpregs(pid, thread_fp_regs);
364 if(err < 0) 399 if(err < 0)
365 panic("copy_context_skas0 : PTRACE_SETFPREGS failed, " 400 panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
366 "pid = %d, errno = %d\n", pid, -err); 401 "pid = %d, errno = %d\n", pid, -err);
@@ -371,7 +406,11 @@ int copy_context_skas0(unsigned long new_stack, int pid)
371 /* Wait, until parent has finished its work: read child's pid from 406 /* Wait, until parent has finished its work: read child's pid from
372 * parent's stack, and check, if bad result. 407 * parent's stack, and check, if bad result.
373 */ 408 */
374 wait_stub_done(pid, 0, "copy_context_skas0"); 409 err = ptrace(PTRACE_CONT, pid, 0, 0);
410 if(err)
411 panic("Failed to continue new process, pid = %d, "
412 "errno = %d\n", pid, errno);
413 wait_stub_done(pid);
375 414
376 pid = data->err; 415 pid = data->err;
377 if(pid < 0) 416 if(pid < 0)
@@ -381,7 +420,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
381 /* Wait, until child has finished too: read child's result from 420 /* Wait, until child has finished too: read child's result from
382 * child's stack and check it. 421 * child's stack and check it.
383 */ 422 */
384 wait_stub_done(pid, -1, "copy_context_skas0"); 423 wait_stub_done(pid);
385 if (child_data->err != UML_CONFIG_STUB_DATA) 424 if (child_data->err != UML_CONFIG_STUB_DATA)
386 panic("copy_context_skas0 - stub-child reports error %ld\n", 425 panic("copy_context_skas0 - stub-child reports error %ld\n",
387 child_data->err); 426 child_data->err);
@@ -396,7 +435,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
396 435
397/* 436/*
398 * This is used only, if stub pages are needed, while proc_mm is 437 * This is used only, if stub pages are needed, while proc_mm is
399 * availabl. Opening /proc/mm creates a new mm_context, which lacks 438 * available. Opening /proc/mm creates a new mm_context, which lacks
400 * the stub-pages. Thus, we map them using /proc/mm-fd 439 * the stub-pages. Thus, we map them using /proc/mm-fd
401 */ 440 */
402void map_stub_pages(int fd, unsigned long code, 441void map_stub_pages(int fd, unsigned long code,
@@ -418,12 +457,13 @@ void map_stub_pages(int fd, unsigned long code,
418 .fd = code_fd, 457 .fd = code_fd,
419 .offset = code_offset 458 .offset = code_offset
420 } } }); 459 } } });
421 n = os_write_file(fd, &mmop, sizeof(mmop)); 460 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
422 if(n != sizeof(mmop)){ 461 if(n != sizeof(mmop)){
462 n = errno;
423 printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n", 463 printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n",
424 code, code_fd, (unsigned long long) code_offset); 464 code, code_fd, (unsigned long long) code_offset);
425 panic("map_stub_pages : /proc/mm map for code failed, " 465 panic("map_stub_pages : /proc/mm map for code failed, "
426 "err = %d\n", -n); 466 "err = %d\n", n);
427 } 467 }
428 468
429 if ( stack ) { 469 if ( stack ) {
@@ -440,10 +480,10 @@ void map_stub_pages(int fd, unsigned long code,
440 .fd = map_fd, 480 .fd = map_fd,
441 .offset = map_offset 481 .offset = map_offset
442 } } }); 482 } } });
443 n = os_write_file(fd, &mmop, sizeof(mmop)); 483 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
444 if(n != sizeof(mmop)) 484 if(n != sizeof(mmop))
445 panic("map_stub_pages : /proc/mm map for data failed, " 485 panic("map_stub_pages : /proc/mm map for data failed, "
446 "err = %d\n", -n); 486 "err = %d\n", errno);
447 } 487 }
448} 488}
449 489
@@ -480,7 +520,15 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
480 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, 520 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
481 SIGVTALRM, -1); 521 SIGVTALRM, -1);
482 522
483 n = UML_SETJMP(&initial_jmpbuf); 523 /*
524 * Can't use UML_SETJMP or UML_LONGJMP here because they save
525 * and restore signals, with the possible side-effect of
526 * trying to handle any signals which came when they were
527 * blocked, which can't be done on this stack.
528 * Signals must be blocked when jumping back here and restored
529 * after returning to the jumper.
530 */
531 n = setjmp(initial_jmpbuf);
484 switch(n){ 532 switch(n){
485 case INIT_JMP_NEW_THREAD: 533 case INIT_JMP_NEW_THREAD:
486 (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler; 534 (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;
@@ -490,7 +538,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
490 break; 538 break;
491 case INIT_JMP_CALLBACK: 539 case INIT_JMP_CALLBACK:
492 (*cb_proc)(cb_arg); 540 (*cb_proc)(cb_arg);
493 UML_LONGJMP(cb_back, 1); 541 longjmp(*cb_back, 1);
494 break; 542 break;
495 case INIT_JMP_HALT: 543 case INIT_JMP_HALT:
496 kmalloc_ok = 0; 544 kmalloc_ok = 0;
@@ -501,7 +549,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
501 default: 549 default:
502 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); 550 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
503 } 551 }
504 UML_LONGJMP(switch_buf, 1); 552 longjmp(*switch_buf, 1);
505} 553}
506 554
507void initial_thread_cb_skas(void (*proc)(void *), void *arg) 555void initial_thread_cb_skas(void (*proc)(void *), void *arg)
diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c
index 9ad5fbec4593..3b600c2e63b8 100644
--- a/arch/um/os-Linux/skas/trap.c
+++ b/arch/um/os-Linux/skas/trap.c
@@ -5,8 +5,8 @@
5 5
6#include <signal.h> 6#include <signal.h>
7#include <errno.h> 7#include <errno.h>
8#include "user_util.h"
9#include "kern_util.h" 8#include "kern_util.h"
9#include "as-layout.h"
10#include "task.h" 10#include "task.h"
11#include "sigcontext.h" 11#include "sigcontext.h"
12#include "skas.h" 12#include "skas.h"
@@ -15,29 +15,39 @@
15#include "sysdep/ptrace_user.h" 15#include "sysdep/ptrace_user.h"
16#include "os.h" 16#include "os.h"
17 17
18static union uml_pt_regs ksig_regs[UM_NR_CPUS];
19
18void sig_handler_common_skas(int sig, void *sc_ptr) 20void sig_handler_common_skas(int sig, void *sc_ptr)
19{ 21{
20 struct sigcontext *sc = sc_ptr; 22 struct sigcontext *sc = sc_ptr;
21 struct skas_regs *r; 23 union uml_pt_regs *r;
22 void (*handler)(int, union uml_pt_regs *); 24 void (*handler)(int, union uml_pt_regs *);
23 int save_errno = errno; 25 int save_user, save_errno = errno;
24 int save_user;
25 26
26 /* This is done because to allow SIGSEGV to be delivered inside a SEGV 27 /* This is done because to allow SIGSEGV to be delivered inside a SEGV
27 * handler. This can happen in copy_user, and if SEGV is disabled, 28 * handler. This can happen in copy_user, and if SEGV is disabled,
28 * the process will die. 29 * the process will die.
29 * XXX Figure out why this is better than SA_NODEFER 30 * XXX Figure out why this is better than SA_NODEFER
30 */ 31 */
31 if(sig == SIGSEGV) 32 if(sig == SIGSEGV) {
32 change_sig(SIGSEGV, 1); 33 change_sig(SIGSEGV, 1);
34 /* For segfaults, we want the data from the
35 * sigcontext. In this case, we don't want to mangle
36 * the process registers, so use a static set of
37 * registers. For other signals, the process
38 * registers are OK.
39 */
40 r = &ksig_regs[cpu()];
41 copy_sc(r, sc_ptr);
42 }
43 else r = TASK_REGS(get_current());
33 44
34 r = &TASK_REGS(get_current())->skas; 45 save_user = r->skas.is_user;
35 save_user = r->is_user; 46 r->skas.is_user = 0;
36 r->is_user = 0;
37 if ( sig == SIGFPE || sig == SIGSEGV || 47 if ( sig == SIGFPE || sig == SIGSEGV ||
38 sig == SIGBUS || sig == SIGILL || 48 sig == SIGBUS || sig == SIGILL ||
39 sig == SIGTRAP ) { 49 sig == SIGTRAP ) {
40 GET_FAULTINFO_FROM_SC(r->faultinfo, sc); 50 GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc);
41 } 51 }
42 52
43 change_sig(SIGUSR1, 1); 53 change_sig(SIGUSR1, 1);
@@ -49,25 +59,8 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
49 sig != SIGVTALRM && sig != SIGALRM) 59 sig != SIGVTALRM && sig != SIGALRM)
50 unblock_signals(); 60 unblock_signals();
51 61
52 handler(sig, (union uml_pt_regs *) r); 62 handler(sig, r);
53 63
54 errno = save_errno; 64 errno = save_errno;
55 r->is_user = save_user; 65 r->skas.is_user = save_user;
56}
57
58extern int ptrace_faultinfo;
59
60void user_signal(int sig, union uml_pt_regs *regs, int pid)
61{
62 void (*handler)(int, union uml_pt_regs *);
63 int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
64 (sig == SIGILL) || (sig == SIGTRAP));
65
66 if (segv)
67 get_skas_faultinfo(pid, &regs->skas.faultinfo);
68
69 handler = sig_info[sig];
70 handler(sig, (union uml_pt_regs *) regs);
71
72 unblock_signals();
73} 66}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 5178eba9afa5..79471f85eb89 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -17,10 +17,10 @@
17#include <sys/time.h> 17#include <sys/time.h>
18#include <sys/wait.h> 18#include <sys/wait.h>
19#include <sys/mman.h> 19#include <sys/mman.h>
20#include <sys/resource.h>
20#include <asm/unistd.h> 21#include <asm/unistd.h>
21#include <asm/page.h> 22#include <asm/page.h>
22#include <sys/types.h> 23#include <sys/types.h>
23#include "user_util.h"
24#include "kern_util.h" 24#include "kern_util.h"
25#include "user.h" 25#include "user.h"
26#include "signal_kern.h" 26#include "signal_kern.h"
@@ -329,8 +329,32 @@ static void __init check_ptrace(void)
329 329
330extern void check_tmpexec(void); 330extern void check_tmpexec(void);
331 331
332void os_early_checks(void) 332static void __init check_coredump_limit(void)
333{ 333{
334 struct rlimit lim;
335 int err = getrlimit(RLIMIT_CORE, &lim);
336
337 if(err){
338 perror("Getting core dump limit");
339 return;
340 }
341
342 printf("Core dump limits :\n\tsoft - ");
343 if(lim.rlim_cur == RLIM_INFINITY)
344 printf("NONE\n");
345 else printf("%lu\n", lim.rlim_cur);
346
347 printf("\thard - ");
348 if(lim.rlim_max == RLIM_INFINITY)
349 printf("NONE\n");
350 else printf("%lu\n", lim.rlim_max);
351}
352
353void __init os_early_checks(void)
354{
355 /* Print out the core dump limits early */
356 check_coredump_limit();
357
334 check_ptrace(); 358 check_ptrace();
335 359
336 /* Need to check this early because mmapping happens before the 360 /* Need to check this early because mmapping happens before the
@@ -528,148 +552,3 @@ int __init parse_iomem(char *str, int *add)
528 out: 552 out:
529 return 1; 553 return 1;
530} 554}
531
532
533/* Changed during early boot */
534int pty_output_sigio = 0;
535int pty_close_sigio = 0;
536
537/* Used as a flag during SIGIO testing early in boot */
538static volatile int got_sigio = 0;
539
540static void __init handler(int sig)
541{
542 got_sigio = 1;
543}
544
545struct openpty_arg {
546 int master;
547 int slave;
548 int err;
549};
550
551static void openpty_cb(void *arg)
552{
553 struct openpty_arg *info = arg;
554
555 info->err = 0;
556 if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
557 info->err = -errno;
558}
559
560static int async_pty(int master, int slave)
561{
562 int flags;
563
564 flags = fcntl(master, F_GETFL);
565 if(flags < 0)
566 return -errno;
567
568 if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
569 (fcntl(master, F_SETOWN, os_getpid()) < 0))
570 return -errno;
571
572 if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
573 return -errno;
574
575 return(0);
576}
577
578static void __init check_one_sigio(void (*proc)(int, int))
579{
580 struct sigaction old, new;
581 struct openpty_arg pty = { .master = -1, .slave = -1 };
582 int master, slave, err;
583
584 initial_thread_cb(openpty_cb, &pty);
585 if(pty.err){
586 printk("openpty failed, errno = %d\n", -pty.err);
587 return;
588 }
589
590 master = pty.master;
591 slave = pty.slave;
592
593 if((master == -1) || (slave == -1)){
594 printk("openpty failed to allocate a pty\n");
595 return;
596 }
597
598 /* Not now, but complain so we now where we failed. */
599 err = raw(master);
600 if (err < 0)
601 panic("check_sigio : __raw failed, errno = %d\n", -err);
602
603 err = async_pty(master, slave);
604 if(err < 0)
605 panic("tty_fds : sigio_async failed, err = %d\n", -err);
606
607 if(sigaction(SIGIO, NULL, &old) < 0)
608 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
609 new = old;
610 new.sa_handler = handler;
611 if(sigaction(SIGIO, &new, NULL) < 0)
612 panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
613
614 got_sigio = 0;
615 (*proc)(master, slave);
616
617 close(master);
618 close(slave);
619
620 if(sigaction(SIGIO, &old, NULL) < 0)
621 panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
622}
623
624static void tty_output(int master, int slave)
625{
626 int n;
627 char buf[512];
628
629 printk("Checking that host ptys support output SIGIO...");
630
631 memset(buf, 0, sizeof(buf));
632
633 while(os_write_file(master, buf, sizeof(buf)) > 0) ;
634 if(errno != EAGAIN)
635 panic("check_sigio : write failed, errno = %d\n", errno);
636 while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
637
638 if(got_sigio){
639 printk("Yes\n");
640 pty_output_sigio = 1;
641 }
642 else if(n == -EAGAIN) printk("No, enabling workaround\n");
643 else panic("check_sigio : read failed, err = %d\n", n);
644}
645
646static void tty_close(int master, int slave)
647{
648 printk("Checking that host ptys support SIGIO on close...");
649
650 close(slave);
651 if(got_sigio){
652 printk("Yes\n");
653 pty_close_sigio = 1;
654 }
655 else printk("No, enabling workaround\n");
656}
657
658void __init check_sigio(void)
659{
660 if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
661 (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
662 printk("No pseudo-terminals available - skipping pty SIGIO "
663 "check\n");
664 return;
665 }
666 check_one_sigio(tty_output);
667 check_one_sigio(tty_close);
668}
669
670void os_check_bugs(void)
671{
672 check_ptrace();
673 check_sigio();
674}
675
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
index 256532034c62..32ed41ec1a3d 100644
--- a/arch/um/os-Linux/sys-i386/tls.c
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -5,7 +5,7 @@
5#include <unistd.h> 5#include <unistd.h>
6 6
7#include "sysdep/tls.h" 7#include "sysdep/tls.h"
8#include "user_util.h" 8#include "user.h"
9 9
10/* Checks whether host supports TLS, and sets *tls_min according to the value 10/* Checks whether host supports TLS, and sets *tls_min according to the value
11 * valid on the host. 11 * valid on the host.
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 2115b8beb541..5de169b168f6 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -10,7 +10,6 @@
10#include <sys/time.h> 10#include <sys/time.h>
11#include <signal.h> 11#include <signal.h>
12#include <errno.h> 12#include <errno.h>
13#include "user_util.h"
14#include "kern_util.h" 13#include "kern_util.h"
15#include "user.h" 14#include "user.h"
16#include "process.h" 15#include "process.h"
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index d221214d2ed5..295da657931a 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -6,7 +6,6 @@
6#include <stdlib.h> 6#include <stdlib.h>
7#include <signal.h> 7#include <signal.h>
8#include "kern_util.h" 8#include "kern_util.h"
9#include "user_util.h"
10#include "os.h" 9#include "os.h"
11#include "mode.h" 10#include "mode.h"
12#include "longjmp.h" 11#include "longjmp.h"
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index 3dc3a02d6263..bcf9359c4e9f 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -18,7 +18,6 @@
18#include <asm/ptrace.h> 18#include <asm/ptrace.h>
19#include <asm/unistd.h> 19#include <asm/unistd.h>
20#include <asm/page.h> 20#include <asm/page.h>
21#include "user_util.h"
22#include "kern_util.h" 21#include "kern_util.h"
23#include "user.h" 22#include "user.h"
24#include "signal_kern.h" 23#include "signal_kern.h"
@@ -32,6 +31,7 @@
32#include "choose-mode.h" 31#include "choose-mode.h"
33#include "mode.h" 32#include "mode.h"
34#include "tempfile.h" 33#include "tempfile.h"
34#include "kern_constants.h"
35 35
36int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, 36int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
37 int must_succeed) 37 int must_succeed)
@@ -143,7 +143,7 @@ int outer_tramp(void *arg)
143 int sig = sigkill; 143 int sig = sigkill;
144 144
145 t = arg; 145 t = arg;
146 t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2, 146 t->pid = clone(t->tramp, (void *) t->temp_stack + UM_KERN_PAGE_SIZE/2,
147 t->flags, t->tramp_data); 147 t->flags, t->tramp_data);
148 if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL); 148 if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
149 kill(os_getpid(), sig); 149 kill(os_getpid(), sig);
diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c
index c6ba56c1560f..d11a55baa6bd 100644
--- a/arch/um/os-Linux/tty_log.c
+++ b/arch/um/os-Linux/tty_log.c
@@ -53,9 +53,9 @@ int open_tty_log(void *tty, void *current_tty)
53 .direction = 0, 53 .direction = 0,
54 .sec = tv.tv_sec, 54 .sec = tv.tv_sec,
55 .usec = tv.tv_usec } ); 55 .usec = tv.tv_usec } );
56 os_write_file(tty_log_fd, &data, sizeof(data)); 56 write(tty_log_fd, &data, sizeof(data));
57 os_write_file(tty_log_fd, &current_tty, data.len); 57 write(tty_log_fd, &current_tty, data.len);
58 return(tty_log_fd); 58 return tty_log_fd;
59 } 59 }
60 60
61 sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 61 sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
@@ -67,7 +67,7 @@ int open_tty_log(void *tty, void *current_tty)
67 printk("open_tty_log : couldn't open '%s', errno = %d\n", 67 printk("open_tty_log : couldn't open '%s', errno = %d\n",
68 buf, -fd); 68 buf, -fd);
69 } 69 }
70 return(fd); 70 return fd;
71} 71}
72 72
73void close_tty_log(int fd, void *tty) 73void close_tty_log(int fd, void *tty)
@@ -83,7 +83,7 @@ void close_tty_log(int fd, void *tty)
83 .direction = 0, 83 .direction = 0,
84 .sec = tv.tv_sec, 84 .sec = tv.tv_sec,
85 .usec = tv.tv_usec } ); 85 .usec = tv.tv_usec } );
86 os_write_file(tty_log_fd, &data, sizeof(data)); 86 write(tty_log_fd, &data, sizeof(data));
87 return; 87 return;
88 } 88 }
89 os_close_file(fd); 89 os_close_file(fd);
@@ -98,21 +98,21 @@ static int log_chunk(int fd, const char *buf, int len)
98 try = (len > sizeof(chunk)) ? sizeof(chunk) : len; 98 try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
99 missed = copy_from_user_proc(chunk, (char *) buf, try); 99 missed = copy_from_user_proc(chunk, (char *) buf, try);
100 try -= missed; 100 try -= missed;
101 n = os_write_file(fd, chunk, try); 101 n = write(fd, chunk, try);
102 if(n != try) { 102 if(n != try) {
103 if(n < 0) 103 if(n < 0)
104 return(n); 104 return -errno;
105 return(-EIO); 105 return -EIO;
106 } 106 }
107 if(missed != 0) 107 if(missed != 0)
108 return(-EFAULT); 108 return -EFAULT;
109 109
110 len -= try; 110 len -= try;
111 total += try; 111 total += try;
112 buf += try; 112 buf += try;
113 } 113 }
114 114
115 return(total); 115 return total;
116} 116}
117 117
118int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) 118int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
@@ -130,10 +130,10 @@ int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
130 .direction = direction, 130 .direction = direction,
131 .sec = tv.tv_sec, 131 .sec = tv.tv_sec,
132 .usec = tv.tv_usec } ); 132 .usec = tv.tv_usec } );
133 os_write_file(tty_log_fd, &data, sizeof(data)); 133 write(tty_log_fd, &data, sizeof(data));
134 } 134 }
135 135
136 return(log_chunk(fd, buf, len)); 136 return log_chunk(fd, buf, len);
137} 137}
138 138
139void log_exec(char **argv, void *tty) 139void log_exec(char **argv, void *tty)
@@ -161,7 +161,7 @@ void log_exec(char **argv, void *tty)
161 .direction = 0, 161 .direction = 0,
162 .sec = tv.tv_sec, 162 .sec = tv.tv_sec,
163 .usec = tv.tv_usec } ); 163 .usec = tv.tv_usec } );
164 os_write_file(tty_log_fd, &data, sizeof(data)); 164 write(tty_log_fd, &data, sizeof(data));
165 165
166 for(ptr = argv; ; ptr++){ 166 for(ptr = argv; ; ptr++){
167 if(copy_from_user_proc(&arg, ptr, sizeof(arg))) 167 if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
@@ -179,7 +179,7 @@ extern void register_tty_logger(int (*opener)(void *, void *),
179static int register_logger(void) 179static int register_logger(void)
180{ 180{
181 register_tty_logger(open_tty_log, write_tty_log, close_tty_log); 181 register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
182 return(0); 182 return 0;
183} 183}
184 184
185__uml_initcall(register_logger); 185__uml_initcall(register_logger);
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 56b8a50e8bc2..c307a89ed259 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -21,7 +21,6 @@
21#include <sched.h> 21#include <sched.h>
22#include <termios.h> 22#include <termios.h>
23#include <string.h> 23#include <string.h>
24#include "user_util.h"
25#include "kern_util.h" 24#include "kern_util.h"
26#include "user.h" 25#include "user.h"
27#include "mem_user.h" 26#include "mem_user.h"
@@ -30,28 +29,29 @@
30#include "uml-config.h" 29#include "uml-config.h"
31#include "os.h" 30#include "os.h"
32#include "longjmp.h" 31#include "longjmp.h"
32#include "kern_constants.h"
33 33
34void stack_protections(unsigned long address) 34void stack_protections(unsigned long address)
35{ 35{
36 int prot = PROT_READ | PROT_WRITE | PROT_EXEC; 36 int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
37 37
38 if(mprotect((void *) address, page_size(), prot) < 0) 38 if(mprotect((void *) address, UM_KERN_PAGE_SIZE, prot) < 0)
39 panic("protecting stack failed, errno = %d", errno); 39 panic("protecting stack failed, errno = %d", errno);
40} 40}
41 41
42void task_protections(unsigned long address) 42void task_protections(unsigned long address)
43{ 43{
44 unsigned long guard = address + page_size(); 44 unsigned long guard = address + UM_KERN_PAGE_SIZE;
45 unsigned long stack = guard + page_size(); 45 unsigned long stack = guard + UM_KERN_PAGE_SIZE;
46 int prot = 0, pages; 46 int prot = 0, pages;
47 47
48#ifdef notdef 48#ifdef notdef
49 if(mprotect((void *) stack, page_size(), prot) < 0) 49 if(mprotect((void *) stack, UM_KERN_PAGE_SIZE, prot) < 0)
50 panic("protecting guard page failed, errno = %d", errno); 50 panic("protecting guard page failed, errno = %d", errno);
51#endif 51#endif
52 pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2; 52 pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
53 prot = PROT_READ | PROT_WRITE | PROT_EXEC; 53 prot = PROT_READ | PROT_WRITE | PROT_EXEC;
54 if(mprotect((void *) stack, pages * page_size(), prot) < 0) 54 if(mprotect((void *) stack, pages * UM_KERN_PAGE_SIZE, prot) < 0)
55 panic("protecting stack failed, errno = %d", errno); 55 panic("protecting stack failed, errno = %d", errno);
56} 56}
57 57
@@ -96,15 +96,13 @@ void setup_machinename(char *machine_out)
96 strcpy(machine_out, host.machine); 96 strcpy(machine_out, host.machine);
97} 97}
98 98
99char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1]; 99void setup_hostinfo(char *buf, int len)
100
101void setup_hostinfo(void)
102{ 100{
103 struct utsname host; 101 struct utsname host;
104 102
105 uname(&host); 103 uname(&host);
106 sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename, 104 snprintf(buf, len, "%s %s %s %s %s", host.sysname, host.nodename,
107 host.release, host.version, host.machine); 105 host.release, host.version, host.machine);
108} 106}
109 107
110int setjmp_wrapper(void (*proc)(void *, void *), ...) 108int setjmp_wrapper(void (*proc)(void *, void *), ...)
@@ -121,3 +119,9 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...)
121 va_end(args); 119 va_end(args);
122 return n; 120 return n;
123} 121}
122
123void os_dump_core(void)
124{
125 signal(SIGSEGV, SIG_DFL);
126 abort();
127}