diff options
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r-- | arch/um/os-Linux/aio.c | 61 | ||||
-rw-r--r-- | arch/um/os-Linux/drivers/ethertap_user.c | 66 | ||||
-rw-r--r-- | arch/um/os-Linux/drivers/tuntap_user.c | 44 | ||||
-rw-r--r-- | arch/um/os-Linux/file.c | 47 | ||||
-rw-r--r-- | arch/um/os-Linux/helper.c | 31 | ||||
-rw-r--r-- | arch/um/os-Linux/irq.c | 1 | ||||
-rw-r--r-- | arch/um/os-Linux/main.c | 23 | ||||
-rw-r--r-- | arch/um/os-Linux/mem.c | 15 | ||||
-rw-r--r-- | arch/um/os-Linux/process.c | 45 | ||||
-rw-r--r-- | arch/um/os-Linux/sigio.c | 164 | ||||
-rw-r--r-- | arch/um/os-Linux/signal.c | 1 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/mem.c | 75 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 190 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/trap.c | 49 | ||||
-rw-r--r-- | arch/um/os-Linux/start_up.c | 173 | ||||
-rw-r--r-- | arch/um/os-Linux/sys-i386/tls.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/time.c | 1 | ||||
-rw-r--r-- | arch/um/os-Linux/trap.c | 1 | ||||
-rw-r--r-- | arch/um/os-Linux/tt.c | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/tty_log.c | 28 | ||||
-rw-r--r-- | arch/um/os-Linux/util.c | 26 |
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) | |||
146 | static int do_not_aio(struct aio_thread_req *req) | 146 | static 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 | ||
179 | out: | 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 | ||
27 | void etap_user_init(void *data, void *dev) | 27 | static 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 | ||
34 | struct addr_change { | 35 | struct 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 | ||
138 | static int etap_open(void *data) | 144 | static 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 | ||
183 | static void etap_close(int fd, void *data) | 190 | static void etap_close(int fd, void *data) |
@@ -195,7 +202,7 @@ static void etap_close(int fd, void *data) | |||
195 | 202 | ||
196 | static int etap_set_mtu(int mtu, void *data) | 203 | static int etap_set_mtu(int mtu, void *data) |
197 | { | 204 | { |
198 | return(mtu); | 205 | return mtu; |
199 | } | 206 | } |
200 | 207 | ||
201 | static void etap_add_addr(unsigned char *addr, unsigned char *netmask, | 208 | static 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 | ||
27 | void tuntap_user_init(void *data, void *dev) | 26 | static 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 | ||
34 | static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, | 34 | static 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 { | |||
58 | static void tuntap_pre_exec(void *arg) | 60 | static 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 | ||
129 | static int tuntap_open(void *data) | 132 | static 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 | ||
193 | static void tuntap_close(int fd, void *data) | 196 | static void tuntap_close(int fd, void *data) |
@@ -202,7 +205,7 @@ static void tuntap_close(int fd, void *data) | |||
202 | 205 | ||
203 | static int tuntap_set_mtu(int mtu, void *data) | 206 | static int tuntap_set_mtu(int mtu, void *data) |
204 | { | 207 | { |
205 | return(mtu); | 208 | return mtu; |
206 | } | 209 | } |
207 | 210 | ||
208 | const struct net_user_info tuntap_user_info = { | 211 | const 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 | ||
23 | static void copy_stat(struct uml_stat *dst, struct stat64 *src) | 22 | static 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 | ||
294 | static int fault_buffer(void *start, int len, | 293 | int 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 | |||
311 | static 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 | ||
332 | int 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 | |||
338 | int os_write_file(int fd, const void *buf, int len) | 302 | int 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 | ||
344 | int os_file_size(char *file, unsigned long long *size_out) | 311 | int 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 | ||
20 | struct helper_data { | 20 | struct 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 */ | ||
29 | int helper_pause = 0; | ||
30 | |||
31 | static void helper_hup(int sig) | ||
32 | { | ||
33 | } | ||
34 | |||
35 | static int helper_child(void *arg) | 28 | static 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 | */ | ||
31 | unsigned long stacksizelim; | ||
32 | |||
33 | /* Set in main */ | ||
34 | char *linux_prog; | 29 | char *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 | ||
58 | static __init void do_uml_initcalls(void) | 52 | static __init void do_uml_initcalls(void) |
@@ -126,7 +120,7 @@ extern int uml_exitcode; | |||
126 | 120 | ||
127 | extern void scan_elf_aux( char **envp); | 121 | extern void scan_elf_aux( char **envp); |
128 | 122 | ||
129 | int main(int argc, char **argv, char **envp) | 123 | int __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 | ||
254 | void *__wrap_calloc(int n, int size) | 248 | void *__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 | ||
263 | extern void __real_free(void *); | 258 | extern 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 | */ |
168 | int make_tempfile(const char *template, char **out_tempname, int do_unlink) | 167 | int __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 | */ |
209 | int create_tmp_file(unsigned long long len) | 209 | int __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 | ||
245 | int create_mem_file(unsigned long long len) | 244 | int __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 | ||
260 | void check_tmpexec(void) | 259 | void __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 | ||
62 | int os_process_parent(int pid) | 62 | int 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 | ||
93 | void os_stop_process(int pid) | 94 | void os_stop_process(int pid) |
@@ -145,7 +146,7 @@ void os_usr1_process(int pid) | |||
145 | 146 | ||
146 | int os_getpid(void) | 147 | int os_getpid(void) |
147 | { | 148 | { |
148 | return(syscall(__NR_getpid)); | 149 | return syscall(__NR_getpid); |
149 | } | 150 | } |
150 | 151 | ||
151 | int os_getpgrp(void) | 152 | int 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 | ||
172 | int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) | 173 | int 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 | ||
182 | int os_unmap_memory(void *addr, int len) | 183 | int 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 | ||
196 | int os_drop_memory(void *addr, int length) | 197 | int __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 | ||
206 | int can_drop_memory(void) | 207 | int __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 */ | ||
326 | static int pty_output_sigio = 0; | ||
327 | static int pty_close_sigio = 0; | ||
328 | |||
323 | void maybe_sigio_broken(int fd, int read) | 329 | void 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 */ | ||
368 | static volatile int got_sigio = 0; | ||
369 | |||
370 | static void __init handler(int sig) | ||
371 | { | ||
372 | got_sigio = 1; | ||
373 | } | ||
374 | |||
375 | struct openpty_arg { | ||
376 | int master; | ||
377 | int slave; | ||
378 | int err; | ||
379 | }; | ||
380 | |||
381 | static 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 | |||
390 | static 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 | |||
408 | static 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 | |||
454 | static 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 | |||
477 | static 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 | |||
489 | void __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 */ | ||
502 | void __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 | ||
28 | extern unsigned long batch_syscall_stub, __syscall_stub_start; | 29 | extern unsigned long batch_syscall_stub, __syscall_stub_start; |
29 | 30 | ||
30 | extern void wait_stub_done(int pid, int sig, char * fname); | 31 | extern void wait_stub_done(int pid); |
31 | 32 | ||
32 | static inline unsigned long *check_init_stack(struct mm_id * mm_idp, | 33 | static 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 | ||
43 | static unsigned long syscall_regs[MAX_REG_NR]; | ||
44 | |||
45 | static 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 | |||
42 | extern int proc_mm; | 56 | extern int proc_mm; |
43 | 57 | ||
44 | int single_count = 0; | 58 | int single_count = 0; |
@@ -47,12 +61,11 @@ int multi_op_count = 0; | |||
47 | 61 | ||
48 | static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) | 62 | static 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 | ||
179 | int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, | 192 | int 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 | ||
220 | int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done, | 231 | int 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 | ||
251 | int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, | 264 | int 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 | ||
38 | int is_skas_winch(int pid, int fd, void *data) | 39 | int 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 | ||
47 | void wait_stub_done(int pid, int sig, char * fname) | 48 | static 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 | |||
73 | void 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 | |||
94 | bad_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 | ||
88 | extern unsigned long current_stub_stack(void); | 102 | extern 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, ®s->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 | ||
356 | static unsigned long thread_regs[MAX_REG_NR]; | ||
357 | static unsigned long thread_fp_regs[HOST_FP_SIZE]; | ||
358 | |||
359 | static 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 | |||
328 | int copy_context_skas0(unsigned long new_stack, int pid) | 376 | int 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 | */ |
402 | void map_stub_pages(int fd, unsigned long code, | 441 | void 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 | ||
507 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) | 555 | void 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 | ||
18 | static union uml_pt_regs ksig_regs[UM_NR_CPUS]; | ||
19 | |||
18 | void sig_handler_common_skas(int sig, void *sc_ptr) | 20 | void 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 | |||
58 | extern int ptrace_faultinfo; | ||
59 | |||
60 | void 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, ®s->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 | ||
330 | extern void check_tmpexec(void); | 330 | extern void check_tmpexec(void); |
331 | 331 | ||
332 | void os_early_checks(void) | 332 | static 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 | |||
353 | void __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 */ | ||
534 | int pty_output_sigio = 0; | ||
535 | int pty_close_sigio = 0; | ||
536 | |||
537 | /* Used as a flag during SIGIO testing early in boot */ | ||
538 | static volatile int got_sigio = 0; | ||
539 | |||
540 | static void __init handler(int sig) | ||
541 | { | ||
542 | got_sigio = 1; | ||
543 | } | ||
544 | |||
545 | struct openpty_arg { | ||
546 | int master; | ||
547 | int slave; | ||
548 | int err; | ||
549 | }; | ||
550 | |||
551 | static 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 | |||
560 | static 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 | |||
578 | static 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 | |||
624 | static 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 | |||
646 | static 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 | |||
658 | void __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 | |||
670 | void 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 | ||
36 | int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, | 36 | int 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, ¤t_tty, data.len); | 57 | write(tty_log_fd, ¤t_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 | ||
73 | void close_tty_log(int fd, void *tty) | 73 | void 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 | ||
118 | int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) | 118 | int 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 | ||
139 | void log_exec(char **argv, void *tty) | 139 | void 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 *), | |||
179 | static int register_logger(void) | 179 | static 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 | ||
34 | void stack_protections(unsigned long address) | 34 | void 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 | ||
42 | void task_protections(unsigned long address) | 42 | void 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 | ||
99 | char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1]; | 99 | void setup_hostinfo(char *buf, int len) |
100 | |||
101 | void 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 | ||
110 | int setjmp_wrapper(void (*proc)(void *, void *), ...) | 108 | int 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 | |||
123 | void os_dump_core(void) | ||
124 | { | ||
125 | signal(SIGSEGV, SIG_DFL); | ||
126 | abort(); | ||
127 | } | ||