diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-01 19:45:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-01 19:45:02 -0400 |
commit | 1871e845e564c4e17f561ec4e5e4bb6bb8578685 (patch) | |
tree | bcfb62936710321f48bee64153e05f313dc371d0 /arch | |
parent | a6dc77254b3c3eb0307b372b77b861d5cd2ead08 (diff) | |
parent | b070989aeb47ccdfe56d95e046bd317baa47f4fa (diff) |
Merge branch 'for-linus-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
Pull UML fixes from Richard Weinberger:
"This patch set contains mostly fixes and cleanups. The UML tty driver
uses now tty_port and is no longer broken like hell :-)"
* 'for-linus-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml:
um: Add arch/x86/um to MAINTAINERS
um: pass siginfo to guest process
um: fix ubd_file_size for read-only files
um: pull interrupt_end() into userspace()
um: split syscall_trace(), pass pt_regs to it
um: switch UPT_SET_RETURN_VALUE and regs_return_value to pt_regs
um: set BLK_CGROUP=y in defconfig
um: remove count_lock
um: fully use tty_port
um: Remove dead code
um: remove line_ioctl()
TTY: um/line, use tty from tty_port
TTY: um/line, add tty_port
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/defconfig | 2 | ||||
-rw-r--r-- | arch/um/drivers/chan_kern.c | 4 | ||||
-rw-r--r-- | arch/um/drivers/line.c | 218 | ||||
-rw-r--r-- | arch/um/drivers/line.h | 12 | ||||
-rw-r--r-- | arch/um/drivers/ssl.c | 42 | ||||
-rw-r--r-- | arch/um/drivers/stdio_console.c | 21 | ||||
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 2 | ||||
-rw-r--r-- | arch/um/include/asm/ptrace-generic.h | 2 | ||||
-rw-r--r-- | arch/um/include/shared/as-layout.h | 3 | ||||
-rw-r--r-- | arch/um/include/shared/irq_user.h | 3 | ||||
-rw-r--r-- | arch/um/include/shared/kern_util.h | 13 | ||||
-rw-r--r-- | arch/um/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/process.c | 13 | ||||
-rw-r--r-- | arch/um/kernel/ptrace.c | 71 | ||||
-rw-r--r-- | arch/um/kernel/skas/syscall.c | 6 | ||||
-rw-r--r-- | arch/um/kernel/time.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/trap.c | 39 | ||||
-rw-r--r-- | arch/um/os-Linux/internal.h | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/signal.c | 26 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 16 | ||||
-rw-r--r-- | arch/um/os-Linux/time.c | 2 | ||||
-rw-r--r-- | arch/x86/um/asm/ptrace.h | 6 |
22 files changed, 205 insertions, 302 deletions
diff --git a/arch/um/defconfig b/arch/um/defconfig index fec0d5d27460..08107a795062 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig | |||
@@ -163,7 +163,7 @@ CONFIG_CGROUP_SCHED=y | |||
163 | CONFIG_FAIR_GROUP_SCHED=y | 163 | CONFIG_FAIR_GROUP_SCHED=y |
164 | # CONFIG_CFS_BANDWIDTH is not set | 164 | # CONFIG_CFS_BANDWIDTH is not set |
165 | # CONFIG_RT_GROUP_SCHED is not set | 165 | # CONFIG_RT_GROUP_SCHED is not set |
166 | CONFIG_BLK_CGROUP=m | 166 | CONFIG_BLK_CGROUP=y |
167 | # CONFIG_DEBUG_BLK_CGROUP is not set | 167 | # CONFIG_DEBUG_BLK_CGROUP is not set |
168 | # CONFIG_CHECKPOINT_RESTORE is not set | 168 | # CONFIG_CHECKPOINT_RESTORE is not set |
169 | CONFIG_NAMESPACES=y | 169 | CONFIG_NAMESPACES=y |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 45e248c2f43c..87eebfe03c61 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -150,9 +150,11 @@ void chan_enable_winch(struct chan *chan, struct tty_struct *tty) | |||
150 | static void line_timer_cb(struct work_struct *work) | 150 | static void line_timer_cb(struct work_struct *work) |
151 | { | 151 | { |
152 | struct line *line = container_of(work, struct line, task.work); | 152 | struct line *line = container_of(work, struct line, task.work); |
153 | struct tty_struct *tty = tty_port_tty_get(&line->port); | ||
153 | 154 | ||
154 | if (!line->throttled) | 155 | if (!line->throttled) |
155 | chan_interrupt(line, line->tty, line->driver->read_irq); | 156 | chan_interrupt(line, tty, line->driver->read_irq); |
157 | tty_kref_put(tty); | ||
156 | } | 158 | } |
157 | 159 | ||
158 | int enable_chan(struct line *line) | 160 | int enable_chan(struct line *line) |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index ac9d25c8dc01..bbaf2c59830a 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -19,9 +19,11 @@ static irqreturn_t line_interrupt(int irq, void *data) | |||
19 | { | 19 | { |
20 | struct chan *chan = data; | 20 | struct chan *chan = data; |
21 | struct line *line = chan->line; | 21 | struct line *line = chan->line; |
22 | struct tty_struct *tty = tty_port_tty_get(&line->port); | ||
22 | 23 | ||
23 | if (line) | 24 | if (line) |
24 | chan_interrupt(line, line->tty, irq); | 25 | chan_interrupt(line, tty, irq); |
26 | tty_kref_put(tty); | ||
25 | return IRQ_HANDLED; | 27 | return IRQ_HANDLED; |
26 | } | 28 | } |
27 | 29 | ||
@@ -219,92 +221,6 @@ void line_set_termios(struct tty_struct *tty, struct ktermios * old) | |||
219 | /* nothing */ | 221 | /* nothing */ |
220 | } | 222 | } |
221 | 223 | ||
222 | static const struct { | ||
223 | int cmd; | ||
224 | char *level; | ||
225 | char *name; | ||
226 | } tty_ioctls[] = { | ||
227 | /* don't print these, they flood the log ... */ | ||
228 | { TCGETS, NULL, "TCGETS" }, | ||
229 | { TCSETS, NULL, "TCSETS" }, | ||
230 | { TCSETSW, NULL, "TCSETSW" }, | ||
231 | { TCFLSH, NULL, "TCFLSH" }, | ||
232 | { TCSBRK, NULL, "TCSBRK" }, | ||
233 | |||
234 | /* general tty stuff */ | ||
235 | { TCSETSF, KERN_DEBUG, "TCSETSF" }, | ||
236 | { TCGETA, KERN_DEBUG, "TCGETA" }, | ||
237 | { TIOCMGET, KERN_DEBUG, "TIOCMGET" }, | ||
238 | { TCSBRKP, KERN_DEBUG, "TCSBRKP" }, | ||
239 | { TIOCMSET, KERN_DEBUG, "TIOCMSET" }, | ||
240 | |||
241 | /* linux-specific ones */ | ||
242 | { TIOCLINUX, KERN_INFO, "TIOCLINUX" }, | ||
243 | { KDGKBMODE, KERN_INFO, "KDGKBMODE" }, | ||
244 | { KDGKBTYPE, KERN_INFO, "KDGKBTYPE" }, | ||
245 | { KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" }, | ||
246 | }; | ||
247 | |||
248 | int line_ioctl(struct tty_struct *tty, unsigned int cmd, | ||
249 | unsigned long arg) | ||
250 | { | ||
251 | int ret; | ||
252 | int i; | ||
253 | |||
254 | ret = 0; | ||
255 | switch(cmd) { | ||
256 | #ifdef TIOCGETP | ||
257 | case TIOCGETP: | ||
258 | case TIOCSETP: | ||
259 | case TIOCSETN: | ||
260 | #endif | ||
261 | #ifdef TIOCGETC | ||
262 | case TIOCGETC: | ||
263 | case TIOCSETC: | ||
264 | #endif | ||
265 | #ifdef TIOCGLTC | ||
266 | case TIOCGLTC: | ||
267 | case TIOCSLTC: | ||
268 | #endif | ||
269 | /* Note: these are out of date as we now have TCGETS2 etc but this | ||
270 | whole lot should probably go away */ | ||
271 | case TCGETS: | ||
272 | case TCSETSF: | ||
273 | case TCSETSW: | ||
274 | case TCSETS: | ||
275 | case TCGETA: | ||
276 | case TCSETAF: | ||
277 | case TCSETAW: | ||
278 | case TCSETA: | ||
279 | case TCXONC: | ||
280 | case TCFLSH: | ||
281 | case TIOCOUTQ: | ||
282 | case TIOCINQ: | ||
283 | case TIOCGLCKTRMIOS: | ||
284 | case TIOCSLCKTRMIOS: | ||
285 | case TIOCPKT: | ||
286 | case TIOCGSOFTCAR: | ||
287 | case TIOCSSOFTCAR: | ||
288 | return -ENOIOCTLCMD; | ||
289 | #if 0 | ||
290 | case TCwhatever: | ||
291 | /* do something */ | ||
292 | break; | ||
293 | #endif | ||
294 | default: | ||
295 | for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++) | ||
296 | if (cmd == tty_ioctls[i].cmd) | ||
297 | break; | ||
298 | if (i == ARRAY_SIZE(tty_ioctls)) { | ||
299 | printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n", | ||
300 | __func__, tty->name, cmd); | ||
301 | } | ||
302 | ret = -ENOIOCTLCMD; | ||
303 | break; | ||
304 | } | ||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | void line_throttle(struct tty_struct *tty) | 224 | void line_throttle(struct tty_struct *tty) |
309 | { | 225 | { |
310 | struct line *line = tty->driver_data; | 226 | struct line *line = tty->driver_data; |
@@ -333,7 +249,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) | |||
333 | { | 249 | { |
334 | struct chan *chan = data; | 250 | struct chan *chan = data; |
335 | struct line *line = chan->line; | 251 | struct line *line = chan->line; |
336 | struct tty_struct *tty = line->tty; | 252 | struct tty_struct *tty; |
337 | int err; | 253 | int err; |
338 | 254 | ||
339 | /* | 255 | /* |
@@ -352,10 +268,13 @@ static irqreturn_t line_write_interrupt(int irq, void *data) | |||
352 | } | 268 | } |
353 | spin_unlock(&line->lock); | 269 | spin_unlock(&line->lock); |
354 | 270 | ||
271 | tty = tty_port_tty_get(&line->port); | ||
355 | if (tty == NULL) | 272 | if (tty == NULL) |
356 | return IRQ_NONE; | 273 | return IRQ_NONE; |
357 | 274 | ||
358 | tty_wakeup(tty); | 275 | tty_wakeup(tty); |
276 | tty_kref_put(tty); | ||
277 | |||
359 | return IRQ_HANDLED; | 278 | return IRQ_HANDLED; |
360 | } | 279 | } |
361 | 280 | ||
@@ -377,43 +296,14 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) | |||
377 | return err; | 296 | return err; |
378 | } | 297 | } |
379 | 298 | ||
380 | /* | 299 | static int line_activate(struct tty_port *port, struct tty_struct *tty) |
381 | * Normally, a driver like this can rely mostly on the tty layer | ||
382 | * locking, particularly when it comes to the driver structure. | ||
383 | * However, in this case, mconsole requests can come in "from the | ||
384 | * side", and race with opens and closes. | ||
385 | * | ||
386 | * mconsole config requests will want to be sure the device isn't in | ||
387 | * use, and get_config, open, and close will want a stable | ||
388 | * configuration. The checking and modification of the configuration | ||
389 | * is done under a spinlock. Checking whether the device is in use is | ||
390 | * line->tty->count > 1, also under the spinlock. | ||
391 | * | ||
392 | * line->count serves to decide whether the device should be enabled or | ||
393 | * disabled on the host. If it's equal to 0, then we are doing the | ||
394 | * first open or last close. Otherwise, open and close just return. | ||
395 | */ | ||
396 | |||
397 | int line_open(struct line *lines, struct tty_struct *tty) | ||
398 | { | 300 | { |
399 | struct line *line = &lines[tty->index]; | 301 | int ret; |
400 | int err = -ENODEV; | 302 | struct line *line = tty->driver_data; |
401 | |||
402 | mutex_lock(&line->count_lock); | ||
403 | if (!line->valid) | ||
404 | goto out_unlock; | ||
405 | |||
406 | err = 0; | ||
407 | if (line->count++) | ||
408 | goto out_unlock; | ||
409 | |||
410 | BUG_ON(tty->driver_data); | ||
411 | tty->driver_data = line; | ||
412 | line->tty = tty; | ||
413 | 303 | ||
414 | err = enable_chan(line); | 304 | ret = enable_chan(line); |
415 | if (err) /* line_close() will be called by our caller */ | 305 | if (ret) |
416 | goto out_unlock; | 306 | return ret; |
417 | 307 | ||
418 | if (!line->sigio) { | 308 | if (!line->sigio) { |
419 | chan_enable_winch(line->chan_out, tty); | 309 | chan_enable_winch(line->chan_out, tty); |
@@ -421,44 +311,60 @@ int line_open(struct line *lines, struct tty_struct *tty) | |||
421 | } | 311 | } |
422 | 312 | ||
423 | chan_window_size(line, &tty->winsize.ws_row, | 313 | chan_window_size(line, &tty->winsize.ws_row, |
424 | &tty->winsize.ws_col); | 314 | &tty->winsize.ws_col); |
425 | out_unlock: | 315 | |
426 | mutex_unlock(&line->count_lock); | 316 | return 0; |
427 | return err; | ||
428 | } | 317 | } |
429 | 318 | ||
430 | static void unregister_winch(struct tty_struct *tty); | 319 | static const struct tty_port_operations line_port_ops = { |
320 | .activate = line_activate, | ||
321 | }; | ||
431 | 322 | ||
432 | void line_close(struct tty_struct *tty, struct file * filp) | 323 | int line_open(struct tty_struct *tty, struct file *filp) |
433 | { | 324 | { |
434 | struct line *line = tty->driver_data; | 325 | struct line *line = tty->driver_data; |
435 | 326 | ||
436 | /* | 327 | return tty_port_open(&line->port, tty, filp); |
437 | * If line_open fails (and tty->driver_data is never set), | 328 | } |
438 | * tty_open will call line_close. So just return in this case. | ||
439 | */ | ||
440 | if (line == NULL) | ||
441 | return; | ||
442 | 329 | ||
443 | /* We ignore the error anyway! */ | 330 | int line_install(struct tty_driver *driver, struct tty_struct *tty, |
444 | flush_buffer(line); | 331 | struct line *line) |
332 | { | ||
333 | int ret; | ||
445 | 334 | ||
446 | mutex_lock(&line->count_lock); | 335 | ret = tty_standard_install(driver, tty); |
447 | BUG_ON(!line->valid); | 336 | if (ret) |
337 | return ret; | ||
448 | 338 | ||
449 | if (--line->count) | 339 | tty->driver_data = line; |
450 | goto out_unlock; | ||
451 | 340 | ||
452 | line->tty = NULL; | 341 | return 0; |
453 | tty->driver_data = NULL; | 342 | } |
343 | |||
344 | static void unregister_winch(struct tty_struct *tty); | ||
345 | |||
346 | void line_cleanup(struct tty_struct *tty) | ||
347 | { | ||
348 | struct line *line = tty->driver_data; | ||
454 | 349 | ||
455 | if (line->sigio) { | 350 | if (line->sigio) { |
456 | unregister_winch(tty); | 351 | unregister_winch(tty); |
457 | line->sigio = 0; | 352 | line->sigio = 0; |
458 | } | 353 | } |
354 | } | ||
355 | |||
356 | void line_close(struct tty_struct *tty, struct file * filp) | ||
357 | { | ||
358 | struct line *line = tty->driver_data; | ||
459 | 359 | ||
460 | out_unlock: | 360 | tty_port_close(&line->port, tty, filp); |
461 | mutex_unlock(&line->count_lock); | 361 | } |
362 | |||
363 | void line_hangup(struct tty_struct *tty) | ||
364 | { | ||
365 | struct line *line = tty->driver_data; | ||
366 | |||
367 | tty_port_hangup(&line->port); | ||
462 | } | 368 | } |
463 | 369 | ||
464 | void close_lines(struct line *lines, int nlines) | 370 | void close_lines(struct line *lines, int nlines) |
@@ -476,9 +382,7 @@ int setup_one_line(struct line *lines, int n, char *init, | |||
476 | struct tty_driver *driver = line->driver->driver; | 382 | struct tty_driver *driver = line->driver->driver; |
477 | int err = -EINVAL; | 383 | int err = -EINVAL; |
478 | 384 | ||
479 | mutex_lock(&line->count_lock); | 385 | if (line->port.count) { |
480 | |||
481 | if (line->count) { | ||
482 | *error_out = "Device is already open"; | 386 | *error_out = "Device is already open"; |
483 | goto out; | 387 | goto out; |
484 | } | 388 | } |
@@ -519,7 +423,6 @@ int setup_one_line(struct line *lines, int n, char *init, | |||
519 | } | 423 | } |
520 | } | 424 | } |
521 | out: | 425 | out: |
522 | mutex_unlock(&line->count_lock); | ||
523 | return err; | 426 | return err; |
524 | } | 427 | } |
525 | 428 | ||
@@ -607,13 +510,17 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, | |||
607 | 510 | ||
608 | line = &lines[dev]; | 511 | line = &lines[dev]; |
609 | 512 | ||
610 | mutex_lock(&line->count_lock); | ||
611 | if (!line->valid) | 513 | if (!line->valid) |
612 | CONFIG_CHUNK(str, size, n, "none", 1); | 514 | CONFIG_CHUNK(str, size, n, "none", 1); |
613 | else if (line->tty == NULL) | 515 | else { |
614 | CONFIG_CHUNK(str, size, n, line->init_str, 1); | 516 | struct tty_struct *tty = tty_port_tty_get(&line->port); |
615 | else n = chan_config_string(line, str, size, error_out); | 517 | if (tty == NULL) { |
616 | mutex_unlock(&line->count_lock); | 518 | CONFIG_CHUNK(str, size, n, line->init_str, 1); |
519 | } else { | ||
520 | n = chan_config_string(line, str, size, error_out); | ||
521 | tty_kref_put(tty); | ||
522 | } | ||
523 | } | ||
617 | 524 | ||
618 | return n; | 525 | return n; |
619 | } | 526 | } |
@@ -663,8 +570,9 @@ int register_lines(struct line_driver *line_driver, | |||
663 | driver->init_termios = tty_std_termios; | 570 | driver->init_termios = tty_std_termios; |
664 | 571 | ||
665 | for (i = 0; i < nlines; i++) { | 572 | for (i = 0; i < nlines; i++) { |
573 | tty_port_init(&lines[i].port); | ||
574 | lines[i].port.ops = &line_port_ops; | ||
666 | spin_lock_init(&lines[i].lock); | 575 | spin_lock_init(&lines[i].lock); |
667 | mutex_init(&lines[i].count_lock); | ||
668 | lines[i].driver = line_driver; | 576 | lines[i].driver = line_driver; |
669 | INIT_LIST_HEAD(&lines[i].chan_list); | 577 | INIT_LIST_HEAD(&lines[i].chan_list); |
670 | } | 578 | } |
diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h index 0a1834719dba..bae95611e7ab 100644 --- a/arch/um/drivers/line.h +++ b/arch/um/drivers/line.h | |||
@@ -32,9 +32,7 @@ struct line_driver { | |||
32 | }; | 32 | }; |
33 | 33 | ||
34 | struct line { | 34 | struct line { |
35 | struct tty_struct *tty; | 35 | struct tty_port port; |
36 | struct mutex count_lock; | ||
37 | unsigned long count; | ||
38 | int valid; | 36 | int valid; |
39 | 37 | ||
40 | char *init_str; | 38 | char *init_str; |
@@ -59,7 +57,11 @@ struct line { | |||
59 | }; | 57 | }; |
60 | 58 | ||
61 | extern void line_close(struct tty_struct *tty, struct file * filp); | 59 | extern void line_close(struct tty_struct *tty, struct file * filp); |
62 | extern int line_open(struct line *lines, struct tty_struct *tty); | 60 | extern int line_open(struct tty_struct *tty, struct file *filp); |
61 | extern int line_install(struct tty_driver *driver, struct tty_struct *tty, | ||
62 | struct line *line); | ||
63 | extern void line_cleanup(struct tty_struct *tty); | ||
64 | extern void line_hangup(struct tty_struct *tty); | ||
63 | extern int line_setup(char **conf, unsigned nlines, char **def, | 65 | extern int line_setup(char **conf, unsigned nlines, char **def, |
64 | char *init, char *name); | 66 | char *init, char *name); |
65 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, | 67 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, |
@@ -70,8 +72,6 @@ extern int line_chars_in_buffer(struct tty_struct *tty); | |||
70 | extern void line_flush_buffer(struct tty_struct *tty); | 72 | extern void line_flush_buffer(struct tty_struct *tty); |
71 | extern void line_flush_chars(struct tty_struct *tty); | 73 | extern void line_flush_chars(struct tty_struct *tty); |
72 | extern int line_write_room(struct tty_struct *tty); | 74 | extern int line_write_room(struct tty_struct *tty); |
73 | extern int line_ioctl(struct tty_struct *tty, unsigned int cmd, | ||
74 | unsigned long arg); | ||
75 | extern void line_throttle(struct tty_struct *tty); | 75 | extern void line_throttle(struct tty_struct *tty); |
76 | extern void line_unthrottle(struct tty_struct *tty); | 76 | extern void line_unthrottle(struct tty_struct *tty); |
77 | 77 | ||
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index e09801a1327b..7e86f0070123 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c | |||
@@ -87,40 +87,13 @@ static int ssl_remove(int n, char **error_out) | |||
87 | error_out); | 87 | error_out); |
88 | } | 88 | } |
89 | 89 | ||
90 | static int ssl_open(struct tty_struct *tty, struct file *filp) | 90 | static int ssl_install(struct tty_driver *driver, struct tty_struct *tty) |
91 | { | ||
92 | int err = line_open(serial_lines, tty); | ||
93 | |||
94 | if (err) | ||
95 | printk(KERN_ERR "Failed to open serial line %d, err = %d\n", | ||
96 | tty->index, err); | ||
97 | |||
98 | return err; | ||
99 | } | ||
100 | |||
101 | #if 0 | ||
102 | static void ssl_flush_buffer(struct tty_struct *tty) | ||
103 | { | ||
104 | return; | ||
105 | } | ||
106 | |||
107 | static void ssl_stop(struct tty_struct *tty) | ||
108 | { | ||
109 | printk(KERN_ERR "Someone should implement ssl_stop\n"); | ||
110 | } | ||
111 | |||
112 | static void ssl_start(struct tty_struct *tty) | ||
113 | { | ||
114 | printk(KERN_ERR "Someone should implement ssl_start\n"); | ||
115 | } | ||
116 | |||
117 | void ssl_hangup(struct tty_struct *tty) | ||
118 | { | 91 | { |
92 | return line_install(driver, tty, &serial_lines[tty->index]); | ||
119 | } | 93 | } |
120 | #endif | ||
121 | 94 | ||
122 | static const struct tty_operations ssl_ops = { | 95 | static const struct tty_operations ssl_ops = { |
123 | .open = ssl_open, | 96 | .open = line_open, |
124 | .close = line_close, | 97 | .close = line_close, |
125 | .write = line_write, | 98 | .write = line_write, |
126 | .put_char = line_put_char, | 99 | .put_char = line_put_char, |
@@ -129,14 +102,11 @@ static const struct tty_operations ssl_ops = { | |||
129 | .flush_buffer = line_flush_buffer, | 102 | .flush_buffer = line_flush_buffer, |
130 | .flush_chars = line_flush_chars, | 103 | .flush_chars = line_flush_chars, |
131 | .set_termios = line_set_termios, | 104 | .set_termios = line_set_termios, |
132 | .ioctl = line_ioctl, | ||
133 | .throttle = line_throttle, | 105 | .throttle = line_throttle, |
134 | .unthrottle = line_unthrottle, | 106 | .unthrottle = line_unthrottle, |
135 | #if 0 | 107 | .install = ssl_install, |
136 | .stop = ssl_stop, | 108 | .cleanup = line_cleanup, |
137 | .start = ssl_start, | 109 | .hangup = line_hangup, |
138 | .hangup = ssl_hangup, | ||
139 | #endif | ||
140 | }; | 110 | }; |
141 | 111 | ||
142 | /* Changed by ssl_init and referenced by ssl_exit, which are both serialized | 112 | /* Changed by ssl_init and referenced by ssl_exit, which are both serialized |
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 7663541c372e..929b99a261f3 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c | |||
@@ -89,21 +89,17 @@ static int con_remove(int n, char **error_out) | |||
89 | return line_remove(vts, ARRAY_SIZE(vts), n, error_out); | 89 | return line_remove(vts, ARRAY_SIZE(vts), n, error_out); |
90 | } | 90 | } |
91 | 91 | ||
92 | static int con_open(struct tty_struct *tty, struct file *filp) | ||
93 | { | ||
94 | int err = line_open(vts, tty); | ||
95 | if (err) | ||
96 | printk(KERN_ERR "Failed to open console %d, err = %d\n", | ||
97 | tty->index, err); | ||
98 | |||
99 | return err; | ||
100 | } | ||
101 | |||
102 | /* Set in an initcall, checked in an exitcall */ | 92 | /* Set in an initcall, checked in an exitcall */ |
103 | static int con_init_done = 0; | 93 | static int con_init_done = 0; |
104 | 94 | ||
95 | static int con_install(struct tty_driver *driver, struct tty_struct *tty) | ||
96 | { | ||
97 | return line_install(driver, tty, &vts[tty->index]); | ||
98 | } | ||
99 | |||
105 | static const struct tty_operations console_ops = { | 100 | static const struct tty_operations console_ops = { |
106 | .open = con_open, | 101 | .open = line_open, |
102 | .install = con_install, | ||
107 | .close = line_close, | 103 | .close = line_close, |
108 | .write = line_write, | 104 | .write = line_write, |
109 | .put_char = line_put_char, | 105 | .put_char = line_put_char, |
@@ -112,9 +108,10 @@ static const struct tty_operations console_ops = { | |||
112 | .flush_buffer = line_flush_buffer, | 108 | .flush_buffer = line_flush_buffer, |
113 | .flush_chars = line_flush_chars, | 109 | .flush_chars = line_flush_chars, |
114 | .set_termios = line_set_termios, | 110 | .set_termios = line_set_termios, |
115 | .ioctl = line_ioctl, | ||
116 | .throttle = line_throttle, | 111 | .throttle = line_throttle, |
117 | .unthrottle = line_unthrottle, | 112 | .unthrottle = line_unthrottle, |
113 | .cleanup = line_cleanup, | ||
114 | .hangup = line_hangup, | ||
118 | }; | 115 | }; |
119 | 116 | ||
120 | static void uml_console_write(struct console *console, const char *string, | 117 | static void uml_console_write(struct console *console, const char *string, |
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 20505cafa299..0643e5bc9f41 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -514,7 +514,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) | |||
514 | goto out; | 514 | goto out; |
515 | } | 515 | } |
516 | 516 | ||
517 | fd = os_open_file(ubd_dev->file, global_openflags, 0); | 517 | fd = os_open_file(ubd_dev->file, of_read(OPENFLAGS()), 0); |
518 | if (fd < 0) | 518 | if (fd < 0) |
519 | return fd; | 519 | return fd; |
520 | 520 | ||
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index e786a6a3ec5e..442f1d025dc2 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h | |||
@@ -37,6 +37,8 @@ extern int putreg(struct task_struct *child, int regno, unsigned long value); | |||
37 | 37 | ||
38 | extern int arch_copy_tls(struct task_struct *new); | 38 | extern int arch_copy_tls(struct task_struct *new); |
39 | extern void clear_flushed_tls(struct task_struct *task); | 39 | extern void clear_flushed_tls(struct task_struct *task); |
40 | extern void syscall_trace_enter(struct pt_regs *regs); | ||
41 | extern void syscall_trace_leave(struct pt_regs *regs); | ||
40 | 42 | ||
41 | #endif | 43 | #endif |
42 | 44 | ||
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index 896e16602176..86daa5461815 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h | |||
@@ -60,7 +60,8 @@ extern unsigned long host_task_size; | |||
60 | 60 | ||
61 | extern int linux_main(int argc, char **argv); | 61 | extern int linux_main(int argc, char **argv); |
62 | 62 | ||
63 | extern void (*sig_info[])(int, struct uml_pt_regs *); | 63 | struct siginfo; |
64 | extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *); | ||
64 | 65 | ||
65 | #endif | 66 | #endif |
66 | 67 | ||
diff --git a/arch/um/include/shared/irq_user.h b/arch/um/include/shared/irq_user.h index c6c784df2673..2b6d703925b5 100644 --- a/arch/um/include/shared/irq_user.h +++ b/arch/um/include/shared/irq_user.h | |||
@@ -20,7 +20,8 @@ struct irq_fd { | |||
20 | 20 | ||
21 | enum { IRQ_READ, IRQ_WRITE }; | 21 | enum { IRQ_READ, IRQ_WRITE }; |
22 | 22 | ||
23 | extern void sigio_handler(int sig, struct uml_pt_regs *regs); | 23 | struct siginfo; |
24 | extern void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); | ||
24 | extern void free_irq_by_fd(int fd); | 25 | extern void free_irq_by_fd(int fd); |
25 | extern void reactivate_fd(int fd, int irqnum); | 26 | extern void reactivate_fd(int fd, int irqnum); |
26 | extern void deactivate_fd(int fd, int irqnum); | 27 | extern void deactivate_fd(int fd, int irqnum); |
diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index 00965d06d2ca..af6b6dc868ba 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #include "sysdep/ptrace.h" | 9 | #include "sysdep/ptrace.h" |
10 | #include "sysdep/faultinfo.h" | 10 | #include "sysdep/faultinfo.h" |
11 | 11 | ||
12 | struct siginfo; | ||
13 | |||
12 | extern int uml_exitcode; | 14 | extern int uml_exitcode; |
13 | 15 | ||
14 | extern int ncpus; | 16 | extern int ncpus; |
@@ -22,7 +24,7 @@ extern void free_stack(unsigned long stack, int order); | |||
22 | 24 | ||
23 | extern int do_signal(void); | 25 | extern int do_signal(void); |
24 | extern void interrupt_end(void); | 26 | extern void interrupt_end(void); |
25 | extern void relay_signal(int sig, struct uml_pt_regs *regs); | 27 | extern void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs); |
26 | 28 | ||
27 | extern unsigned long segv(struct faultinfo fi, unsigned long ip, | 29 | extern unsigned long segv(struct faultinfo fi, unsigned long ip, |
28 | int is_user, struct uml_pt_regs *regs); | 30 | int is_user, struct uml_pt_regs *regs); |
@@ -33,9 +35,8 @@ extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs); | |||
33 | extern int smp_sigio_handler(void); | 35 | extern int smp_sigio_handler(void); |
34 | extern void initial_thread_cb(void (*proc)(void *), void *arg); | 36 | extern void initial_thread_cb(void (*proc)(void *), void *arg); |
35 | extern int is_syscall(unsigned long addr); | 37 | extern int is_syscall(unsigned long addr); |
36 | extern void timer_handler(int sig, struct uml_pt_regs *regs); | ||
37 | 38 | ||
38 | extern void timer_handler(int sig, struct uml_pt_regs *regs); | 39 | extern void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); |
39 | 40 | ||
40 | extern int start_uml(void); | 41 | extern int start_uml(void); |
41 | extern void paging_init(void); | 42 | extern void paging_init(void); |
@@ -59,9 +60,9 @@ extern unsigned long from_irq_stack(int nested); | |||
59 | extern void syscall_trace(struct uml_pt_regs *regs, int entryexit); | 60 | extern void syscall_trace(struct uml_pt_regs *regs, int entryexit); |
60 | extern int singlestepping(void *t); | 61 | extern int singlestepping(void *t); |
61 | 62 | ||
62 | extern void segv_handler(int sig, struct uml_pt_regs *regs); | 63 | extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); |
63 | extern void bus_handler(int sig, struct uml_pt_regs *regs); | 64 | extern void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs); |
64 | extern void winch(int sig, struct uml_pt_regs *regs); | 65 | extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); |
65 | extern void fatal_sigsegv(void) __attribute__ ((noreturn)); | 66 | extern void fatal_sigsegv(void) __attribute__ ((noreturn)); |
66 | 67 | ||
67 | 68 | ||
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 00506c3d5d6e..9883026f0730 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -30,7 +30,7 @@ static struct irq_fd **last_irq_ptr = &active_fds; | |||
30 | 30 | ||
31 | extern void free_irqs(void); | 31 | extern void free_irqs(void); |
32 | 32 | ||
33 | void sigio_handler(int sig, struct uml_pt_regs *regs) | 33 | void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
34 | { | 34 | { |
35 | struct irq_fd *irq_fd; | 35 | struct irq_fd *irq_fd; |
36 | int n; | 36 | int n; |
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index ccb9a9d283f1..57fc7028714a 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -151,12 +151,10 @@ void new_thread_handler(void) | |||
151 | * 0 if it just exits | 151 | * 0 if it just exits |
152 | */ | 152 | */ |
153 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); | 153 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); |
154 | if (n == 1) { | 154 | if (n == 1) |
155 | /* Handle any immediate reschedules or signals */ | ||
156 | interrupt_end(); | ||
157 | userspace(¤t->thread.regs.regs); | 155 | userspace(¤t->thread.regs.regs); |
158 | } | 156 | else |
159 | else do_exit(0); | 157 | do_exit(0); |
160 | } | 158 | } |
161 | 159 | ||
162 | /* Called magically, see new_thread_handler above */ | 160 | /* Called magically, see new_thread_handler above */ |
@@ -175,9 +173,6 @@ void fork_handler(void) | |||
175 | 173 | ||
176 | current->thread.prev_sched = NULL; | 174 | current->thread.prev_sched = NULL; |
177 | 175 | ||
178 | /* Handle any immediate reschedules or signals */ | ||
179 | interrupt_end(); | ||
180 | |||
181 | userspace(¤t->thread.regs.regs); | 176 | userspace(¤t->thread.regs.regs); |
182 | } | 177 | } |
183 | 178 | ||
@@ -193,7 +188,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
193 | if (current->thread.forking) { | 188 | if (current->thread.forking) { |
194 | memcpy(&p->thread.regs.regs, ®s->regs, | 189 | memcpy(&p->thread.regs.regs, ®s->regs, |
195 | sizeof(p->thread.regs.regs)); | 190 | sizeof(p->thread.regs.regs)); |
196 | UPT_SET_SYSCALL_RETURN(&p->thread.regs.regs, 0); | 191 | PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0); |
197 | if (sp != 0) | 192 | if (sp != 0) |
198 | REGS_SP(p->thread.regs.regs.gp) = sp; | 193 | REGS_SP(p->thread.regs.regs.gp) = sp; |
199 | 194 | ||
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 06b190390505..694d551c8899 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -3,11 +3,12 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/audit.h" | 6 | #include <linux/audit.h> |
7 | #include "linux/ptrace.h" | 7 | #include <linux/ptrace.h> |
8 | #include "linux/sched.h" | 8 | #include <linux/sched.h> |
9 | #include "asm/uaccess.h" | 9 | #include <linux/tracehook.h> |
10 | #include "skas_ptrace.h" | 10 | #include <asm/uaccess.h> |
11 | #include <skas_ptrace.h> | ||
11 | 12 | ||
12 | 13 | ||
13 | 14 | ||
@@ -162,48 +163,36 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, | |||
162 | * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and | 163 | * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and |
163 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check | 164 | * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check |
164 | */ | 165 | */ |
165 | void syscall_trace(struct uml_pt_regs *regs, int entryexit) | 166 | void syscall_trace_enter(struct pt_regs *regs) |
166 | { | 167 | { |
167 | int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit; | 168 | audit_syscall_entry(HOST_AUDIT_ARCH, |
168 | int tracesysgood; | 169 | UPT_SYSCALL_NR(®s->regs), |
169 | 170 | UPT_SYSCALL_ARG1(®s->regs), | |
170 | if (!entryexit) | 171 | UPT_SYSCALL_ARG2(®s->regs), |
171 | audit_syscall_entry(HOST_AUDIT_ARCH, | 172 | UPT_SYSCALL_ARG3(®s->regs), |
172 | UPT_SYSCALL_NR(regs), | 173 | UPT_SYSCALL_ARG4(®s->regs)); |
173 | UPT_SYSCALL_ARG1(regs), | ||
174 | UPT_SYSCALL_ARG2(regs), | ||
175 | UPT_SYSCALL_ARG3(regs), | ||
176 | UPT_SYSCALL_ARG4(regs)); | ||
177 | else | ||
178 | audit_syscall_exit(regs); | ||
179 | |||
180 | /* Fake a debug trap */ | ||
181 | if (is_singlestep) | ||
182 | send_sigtrap(current, regs, 0); | ||
183 | 174 | ||
184 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 175 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
185 | return; | 176 | return; |
186 | 177 | ||
187 | if (!(current->ptrace & PT_PTRACED)) | 178 | tracehook_report_syscall_entry(regs); |
188 | return; | 179 | } |
189 | 180 | ||
190 | /* | 181 | void syscall_trace_leave(struct pt_regs *regs) |
191 | * the 0x80 provides a way for the tracing parent to distinguish | 182 | { |
192 | * between a syscall stop and SIGTRAP delivery | 183 | int ptraced = current->ptrace; |
193 | */ | ||
194 | tracesysgood = (current->ptrace & PT_TRACESYSGOOD); | ||
195 | ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); | ||
196 | 184 | ||
197 | if (entryexit) /* force do_signal() --> is_syscall() */ | 185 | audit_syscall_exit(regs); |
198 | set_thread_flag(TIF_SIGPENDING); | ||
199 | 186 | ||
200 | /* | 187 | /* Fake a debug trap */ |
201 | * this isn't the same as continuing with a signal, but it will do | 188 | if (ptraced & PT_DTRACE) |
202 | * for normal use. strace only continues with a signal if the | 189 | send_sigtrap(current, ®s->regs, 0); |
203 | * stopping signal is not SIGTRAP. -brl | 190 | |
204 | */ | 191 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
205 | if (current->exit_code) { | 192 | return; |
206 | send_sig(current->exit_code, current, 1); | 193 | |
207 | current->exit_code = 0; | 194 | tracehook_report_syscall_exit(regs, 0); |
208 | } | 195 | /* force do_signal() --> is_syscall() */ |
196 | if (ptraced & PT_PTRACED) | ||
197 | set_thread_flag(TIF_SIGPENDING); | ||
209 | } | 198 | } |
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index 05fbeb480e0b..86368a025a96 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c | |||
@@ -18,7 +18,7 @@ void handle_syscall(struct uml_pt_regs *r) | |||
18 | long result; | 18 | long result; |
19 | int syscall; | 19 | int syscall; |
20 | 20 | ||
21 | syscall_trace(r, 0); | 21 | syscall_trace_enter(regs); |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * This should go in the declaration of syscall, but when I do that, | 24 | * This should go in the declaration of syscall, but when I do that, |
@@ -34,7 +34,7 @@ void handle_syscall(struct uml_pt_regs *r) | |||
34 | result = -ENOSYS; | 34 | result = -ENOSYS; |
35 | else result = EXECUTE_SYSCALL(syscall, regs); | 35 | else result = EXECUTE_SYSCALL(syscall, regs); |
36 | 36 | ||
37 | UPT_SET_SYSCALL_RETURN(r, result); | 37 | PT_REGS_SET_SYSCALL_RETURN(regs, result); |
38 | 38 | ||
39 | syscall_trace(r, 1); | 39 | syscall_trace_leave(regs); |
40 | } | 40 | } |
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index d1a23fb3190d..5f76d4ba151c 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include "kern_util.h" | 13 | #include "kern_util.h" |
14 | #include "os.h" | 14 | #include "os.h" |
15 | 15 | ||
16 | void timer_handler(int sig, struct uml_pt_regs *regs) | 16 | void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
17 | { | 17 | { |
18 | unsigned long flags; | 18 | unsigned long flags; |
19 | 19 | ||
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 3be60765c0e2..0353b98ae35a 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c | |||
@@ -172,7 +172,7 @@ void fatal_sigsegv(void) | |||
172 | os_dump_core(); | 172 | os_dump_core(); |
173 | } | 173 | } |
174 | 174 | ||
175 | void segv_handler(int sig, struct uml_pt_regs *regs) | 175 | void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
176 | { | 176 | { |
177 | struct faultinfo * fi = UPT_FAULTINFO(regs); | 177 | struct faultinfo * fi = UPT_FAULTINFO(regs); |
178 | 178 | ||
@@ -258,8 +258,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, | |||
258 | return 0; | 258 | return 0; |
259 | } | 259 | } |
260 | 260 | ||
261 | void relay_signal(int sig, struct uml_pt_regs *regs) | 261 | void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs) |
262 | { | 262 | { |
263 | struct faultinfo *fi; | ||
264 | struct siginfo clean_si; | ||
265 | |||
263 | if (!UPT_IS_USER(regs)) { | 266 | if (!UPT_IS_USER(regs)) { |
264 | if (sig == SIGBUS) | 267 | if (sig == SIGBUS) |
265 | printk(KERN_ERR "Bus error - the host /dev/shm or /tmp " | 268 | printk(KERN_ERR "Bus error - the host /dev/shm or /tmp " |
@@ -269,18 +272,40 @@ void relay_signal(int sig, struct uml_pt_regs *regs) | |||
269 | 272 | ||
270 | arch_examine_signal(sig, regs); | 273 | arch_examine_signal(sig, regs); |
271 | 274 | ||
272 | current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); | 275 | memset(&clean_si, 0, sizeof(clean_si)); |
273 | force_sig(sig, current); | 276 | clean_si.si_signo = si->si_signo; |
277 | clean_si.si_errno = si->si_errno; | ||
278 | clean_si.si_code = si->si_code; | ||
279 | switch (sig) { | ||
280 | case SIGILL: | ||
281 | case SIGFPE: | ||
282 | case SIGSEGV: | ||
283 | case SIGBUS: | ||
284 | case SIGTRAP: | ||
285 | fi = UPT_FAULTINFO(regs); | ||
286 | clean_si.si_addr = (void __user *) FAULT_ADDRESS(*fi); | ||
287 | current->thread.arch.faultinfo = *fi; | ||
288 | #ifdef __ARCH_SI_TRAPNO | ||
289 | clean_si.si_trapno = si->si_trapno; | ||
290 | #endif | ||
291 | break; | ||
292 | default: | ||
293 | printk(KERN_ERR "Attempted to relay unknown signal %d (si_code = %d)\n", | ||
294 | sig, si->si_code); | ||
295 | } | ||
296 | |||
297 | force_sig_info(sig, &clean_si, current); | ||
274 | } | 298 | } |
275 | 299 | ||
276 | void bus_handler(int sig, struct uml_pt_regs *regs) | 300 | void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs) |
277 | { | 301 | { |
278 | if (current->thread.fault_catcher != NULL) | 302 | if (current->thread.fault_catcher != NULL) |
279 | UML_LONGJMP(current->thread.fault_catcher, 1); | 303 | UML_LONGJMP(current->thread.fault_catcher, 1); |
280 | else relay_signal(sig, regs); | 304 | else |
305 | relay_signal(sig, si, regs); | ||
281 | } | 306 | } |
282 | 307 | ||
283 | void winch(int sig, struct uml_pt_regs *regs) | 308 | void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) |
284 | { | 309 | { |
285 | do_IRQ(WINCH_IRQ, regs); | 310 | do_IRQ(WINCH_IRQ, regs); |
286 | } | 311 | } |
diff --git a/arch/um/os-Linux/internal.h b/arch/um/os-Linux/internal.h index 2c3c3ecd8c01..0dc2c9f135f6 100644 --- a/arch/um/os-Linux/internal.h +++ b/arch/um/os-Linux/internal.h | |||
@@ -1 +1 @@ | |||
void alarm_handler(int, mcontext_t *); | void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc); | ||
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 2d22f1fcd8e2..6366ce904b9b 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
@@ -13,8 +13,9 @@ | |||
13 | #include "kern_util.h" | 13 | #include "kern_util.h" |
14 | #include "os.h" | 14 | #include "os.h" |
15 | #include "sysdep/mcontext.h" | 15 | #include "sysdep/mcontext.h" |
16 | #include "internal.h" | ||
16 | 17 | ||
17 | void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { | 18 | void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = { |
18 | [SIGTRAP] = relay_signal, | 19 | [SIGTRAP] = relay_signal, |
19 | [SIGFPE] = relay_signal, | 20 | [SIGFPE] = relay_signal, |
20 | [SIGILL] = relay_signal, | 21 | [SIGILL] = relay_signal, |
@@ -24,7 +25,7 @@ void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { | |||
24 | [SIGIO] = sigio_handler, | 25 | [SIGIO] = sigio_handler, |
25 | [SIGVTALRM] = timer_handler }; | 26 | [SIGVTALRM] = timer_handler }; |
26 | 27 | ||
27 | static void sig_handler_common(int sig, mcontext_t *mc) | 28 | static void sig_handler_common(int sig, siginfo_t *si, mcontext_t *mc) |
28 | { | 29 | { |
29 | struct uml_pt_regs r; | 30 | struct uml_pt_regs r; |
30 | int save_errno = errno; | 31 | int save_errno = errno; |
@@ -40,7 +41,7 @@ static void sig_handler_common(int sig, mcontext_t *mc) | |||
40 | if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM)) | 41 | if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM)) |
41 | unblock_signals(); | 42 | unblock_signals(); |
42 | 43 | ||
43 | (*sig_info[sig])(sig, &r); | 44 | (*sig_info[sig])(sig, si, &r); |
44 | 45 | ||
45 | errno = save_errno; | 46 | errno = save_errno; |
46 | } | 47 | } |
@@ -60,7 +61,7 @@ static void sig_handler_common(int sig, mcontext_t *mc) | |||
60 | static int signals_enabled; | 61 | static int signals_enabled; |
61 | static unsigned int signals_pending; | 62 | static unsigned int signals_pending; |
62 | 63 | ||
63 | void sig_handler(int sig, mcontext_t *mc) | 64 | void sig_handler(int sig, siginfo_t *si, mcontext_t *mc) |
64 | { | 65 | { |
65 | int enabled; | 66 | int enabled; |
66 | 67 | ||
@@ -72,7 +73,7 @@ void sig_handler(int sig, mcontext_t *mc) | |||
72 | 73 | ||
73 | block_signals(); | 74 | block_signals(); |
74 | 75 | ||
75 | sig_handler_common(sig, mc); | 76 | sig_handler_common(sig, si, mc); |
76 | 77 | ||
77 | set_signals(enabled); | 78 | set_signals(enabled); |
78 | } | 79 | } |
@@ -85,10 +86,10 @@ static void real_alarm_handler(mcontext_t *mc) | |||
85 | get_regs_from_mc(®s, mc); | 86 | get_regs_from_mc(®s, mc); |
86 | regs.is_user = 0; | 87 | regs.is_user = 0; |
87 | unblock_signals(); | 88 | unblock_signals(); |
88 | timer_handler(SIGVTALRM, ®s); | 89 | timer_handler(SIGVTALRM, NULL, ®s); |
89 | } | 90 | } |
90 | 91 | ||
91 | void alarm_handler(int sig, mcontext_t *mc) | 92 | void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc) |
92 | { | 93 | { |
93 | int enabled; | 94 | int enabled; |
94 | 95 | ||
@@ -119,7 +120,7 @@ void set_sigstack(void *sig_stack, int size) | |||
119 | panic("enabling signal stack failed, errno = %d\n", errno); | 120 | panic("enabling signal stack failed, errno = %d\n", errno); |
120 | } | 121 | } |
121 | 122 | ||
122 | static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = { | 123 | static void (*handlers[_NSIG])(int sig, siginfo_t *si, mcontext_t *mc) = { |
123 | [SIGSEGV] = sig_handler, | 124 | [SIGSEGV] = sig_handler, |
124 | [SIGBUS] = sig_handler, | 125 | [SIGBUS] = sig_handler, |
125 | [SIGILL] = sig_handler, | 126 | [SIGILL] = sig_handler, |
@@ -132,7 +133,7 @@ static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = { | |||
132 | }; | 133 | }; |
133 | 134 | ||
134 | 135 | ||
135 | static void hard_handler(int sig, siginfo_t *info, void *p) | 136 | static void hard_handler(int sig, siginfo_t *si, void *p) |
136 | { | 137 | { |
137 | struct ucontext *uc = p; | 138 | struct ucontext *uc = p; |
138 | mcontext_t *mc = &uc->uc_mcontext; | 139 | mcontext_t *mc = &uc->uc_mcontext; |
@@ -161,7 +162,7 @@ static void hard_handler(int sig, siginfo_t *info, void *p) | |||
161 | while ((sig = ffs(pending)) != 0){ | 162 | while ((sig = ffs(pending)) != 0){ |
162 | sig--; | 163 | sig--; |
163 | pending &= ~(1 << sig); | 164 | pending &= ~(1 << sig); |
164 | (*handlers[sig])(sig, mc); | 165 | (*handlers[sig])(sig, si, mc); |
165 | } | 166 | } |
166 | 167 | ||
167 | /* | 168 | /* |
@@ -273,9 +274,12 @@ void unblock_signals(void) | |||
273 | * Deal with SIGIO first because the alarm handler might | 274 | * Deal with SIGIO first because the alarm handler might |
274 | * schedule, leaving the pending SIGIO stranded until we come | 275 | * schedule, leaving the pending SIGIO stranded until we come |
275 | * back here. | 276 | * back here. |
277 | * | ||
278 | * SIGIO's handler doesn't use siginfo or mcontext, | ||
279 | * so they can be NULL. | ||
276 | */ | 280 | */ |
277 | if (save_pending & SIGIO_MASK) | 281 | if (save_pending & SIGIO_MASK) |
278 | sig_handler_common(SIGIO, NULL); | 282 | sig_handler_common(SIGIO, NULL, NULL); |
279 | 283 | ||
280 | if (save_pending & SIGVTALRM_MASK) | 284 | if (save_pending & SIGVTALRM_MASK) |
281 | real_alarm_handler(NULL); | 285 | real_alarm_handler(NULL); |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index cd65727854eb..d93bb40499f7 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -346,6 +346,10 @@ void userspace(struct uml_pt_regs *regs) | |||
346 | int err, status, op, pid = userspace_pid[0]; | 346 | int err, status, op, pid = userspace_pid[0]; |
347 | /* To prevent races if using_sysemu changes under us.*/ | 347 | /* To prevent races if using_sysemu changes under us.*/ |
348 | int local_using_sysemu; | 348 | int local_using_sysemu; |
349 | siginfo_t si; | ||
350 | |||
351 | /* Handle any immediate reschedules or signals */ | ||
352 | interrupt_end(); | ||
349 | 353 | ||
350 | if (getitimer(ITIMER_VIRTUAL, &timer)) | 354 | if (getitimer(ITIMER_VIRTUAL, &timer)) |
351 | printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno); | 355 | printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno); |
@@ -404,13 +408,17 @@ void userspace(struct uml_pt_regs *regs) | |||
404 | 408 | ||
405 | if (WIFSTOPPED(status)) { | 409 | if (WIFSTOPPED(status)) { |
406 | int sig = WSTOPSIG(status); | 410 | int sig = WSTOPSIG(status); |
411 | |||
412 | ptrace(PTRACE_GETSIGINFO, pid, 0, &si); | ||
413 | |||
407 | switch (sig) { | 414 | switch (sig) { |
408 | case SIGSEGV: | 415 | case SIGSEGV: |
409 | if (PTRACE_FULL_FAULTINFO || | 416 | if (PTRACE_FULL_FAULTINFO || |
410 | !ptrace_faultinfo) { | 417 | !ptrace_faultinfo) { |
411 | get_skas_faultinfo(pid, | 418 | get_skas_faultinfo(pid, |
412 | ®s->faultinfo); | 419 | ®s->faultinfo); |
413 | (*sig_info[SIGSEGV])(SIGSEGV, regs); | 420 | (*sig_info[SIGSEGV])(SIGSEGV, &si, |
421 | regs); | ||
414 | } | 422 | } |
415 | else handle_segv(pid, regs); | 423 | else handle_segv(pid, regs); |
416 | break; | 424 | break; |
@@ -418,14 +426,14 @@ void userspace(struct uml_pt_regs *regs) | |||
418 | handle_trap(pid, regs, local_using_sysemu); | 426 | handle_trap(pid, regs, local_using_sysemu); |
419 | break; | 427 | break; |
420 | case SIGTRAP: | 428 | case SIGTRAP: |
421 | relay_signal(SIGTRAP, regs); | 429 | relay_signal(SIGTRAP, &si, regs); |
422 | break; | 430 | break; |
423 | case SIGVTALRM: | 431 | case SIGVTALRM: |
424 | now = os_nsecs(); | 432 | now = os_nsecs(); |
425 | if (now < nsecs) | 433 | if (now < nsecs) |
426 | break; | 434 | break; |
427 | block_signals(); | 435 | block_signals(); |
428 | (*sig_info[sig])(sig, regs); | 436 | (*sig_info[sig])(sig, &si, regs); |
429 | unblock_signals(); | 437 | unblock_signals(); |
430 | nsecs = timer.it_value.tv_sec * | 438 | nsecs = timer.it_value.tv_sec * |
431 | UM_NSEC_PER_SEC + | 439 | UM_NSEC_PER_SEC + |
@@ -439,7 +447,7 @@ void userspace(struct uml_pt_regs *regs) | |||
439 | case SIGFPE: | 447 | case SIGFPE: |
440 | case SIGWINCH: | 448 | case SIGWINCH: |
441 | block_signals(); | 449 | block_signals(); |
442 | (*sig_info[sig])(sig, regs); | 450 | (*sig_info[sig])(sig, &si, regs); |
443 | unblock_signals(); | 451 | unblock_signals(); |
444 | break; | 452 | break; |
445 | default: | 453 | default: |
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 910499d76a67..f60238559af3 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c | |||
@@ -87,7 +87,7 @@ static int after_sleep_interval(struct timespec *ts) | |||
87 | 87 | ||
88 | static void deliver_alarm(void) | 88 | static void deliver_alarm(void) |
89 | { | 89 | { |
90 | alarm_handler(SIGVTALRM, NULL); | 90 | alarm_handler(SIGVTALRM, NULL, NULL); |
91 | } | 91 | } |
92 | 92 | ||
93 | static unsigned long long sleep_time(unsigned long long nsecs) | 93 | static unsigned long long sleep_time(unsigned long long nsecs) |
diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h index 950dfb7b8417..e72cd0df5ba3 100644 --- a/arch/x86/um/asm/ptrace.h +++ b/arch/x86/um/asm/ptrace.h | |||
@@ -30,10 +30,10 @@ | |||
30 | #define profile_pc(regs) PT_REGS_IP(regs) | 30 | #define profile_pc(regs) PT_REGS_IP(regs) |
31 | 31 | ||
32 | #define UPT_RESTART_SYSCALL(r) (UPT_IP(r) -= 2) | 32 | #define UPT_RESTART_SYSCALL(r) (UPT_IP(r) -= 2) |
33 | #define UPT_SET_SYSCALL_RETURN(r, res) (UPT_AX(r) = (res)) | 33 | #define PT_REGS_SET_SYSCALL_RETURN(r, res) (PT_REGS_AX(r) = (res)) |
34 | 34 | ||
35 | static inline long regs_return_value(struct uml_pt_regs *regs) | 35 | static inline long regs_return_value(struct pt_regs *regs) |
36 | { | 36 | { |
37 | return UPT_AX(regs); | 37 | return PT_REGS_AX(regs); |
38 | } | 38 | } |
39 | #endif /* __UM_X86_PTRACE_H */ | 39 | #endif /* __UM_X86_PTRACE_H */ |