aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 19:45:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 19:45:02 -0400
commit1871e845e564c4e17f561ec4e5e4bb6bb8578685 (patch)
treebcfb62936710321f48bee64153e05f313dc371d0 /arch
parenta6dc77254b3c3eb0307b372b77b861d5cd2ead08 (diff)
parentb070989aeb47ccdfe56d95e046bd317baa47f4fa (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/defconfig2
-rw-r--r--arch/um/drivers/chan_kern.c4
-rw-r--r--arch/um/drivers/line.c218
-rw-r--r--arch/um/drivers/line.h12
-rw-r--r--arch/um/drivers/ssl.c42
-rw-r--r--arch/um/drivers/stdio_console.c21
-rw-r--r--arch/um/drivers/ubd_kern.c2
-rw-r--r--arch/um/include/asm/ptrace-generic.h2
-rw-r--r--arch/um/include/shared/as-layout.h3
-rw-r--r--arch/um/include/shared/irq_user.h3
-rw-r--r--arch/um/include/shared/kern_util.h13
-rw-r--r--arch/um/kernel/irq.c2
-rw-r--r--arch/um/kernel/process.c13
-rw-r--r--arch/um/kernel/ptrace.c71
-rw-r--r--arch/um/kernel/skas/syscall.c6
-rw-r--r--arch/um/kernel/time.c2
-rw-r--r--arch/um/kernel/trap.c39
-rw-r--r--arch/um/os-Linux/internal.h2
-rw-r--r--arch/um/os-Linux/signal.c26
-rw-r--r--arch/um/os-Linux/skas/process.c16
-rw-r--r--arch/um/os-Linux/time.c2
-rw-r--r--arch/x86/um/asm/ptrace.h6
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
163CONFIG_FAIR_GROUP_SCHED=y 163CONFIG_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
166CONFIG_BLK_CGROUP=m 166CONFIG_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
169CONFIG_NAMESPACES=y 169CONFIG_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)
150static void line_timer_cb(struct work_struct *work) 150static 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
158int enable_chan(struct line *line) 160int 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
222static 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
248int 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
308void line_throttle(struct tty_struct *tty) 224void 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/* 299static 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
397int 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);
425out_unlock: 315
426 mutex_unlock(&line->count_lock); 316 return 0;
427 return err;
428} 317}
429 318
430static void unregister_winch(struct tty_struct *tty); 319static const struct tty_port_operations line_port_ops = {
320 .activate = line_activate,
321};
431 322
432void line_close(struct tty_struct *tty, struct file * filp) 323int 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! */ 330int 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
344static void unregister_winch(struct tty_struct *tty);
345
346void 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
356void line_close(struct tty_struct *tty, struct file * filp)
357{
358 struct line *line = tty->driver_data;
459 359
460out_unlock: 360 tty_port_close(&line->port, tty, filp);
461 mutex_unlock(&line->count_lock); 361}
362
363void 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
464void close_lines(struct line *lines, int nlines) 370void 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 }
521out: 425out:
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
34struct line { 34struct 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
61extern void line_close(struct tty_struct *tty, struct file * filp); 59extern void line_close(struct tty_struct *tty, struct file * filp);
62extern int line_open(struct line *lines, struct tty_struct *tty); 60extern int line_open(struct tty_struct *tty, struct file *filp);
61extern int line_install(struct tty_driver *driver, struct tty_struct *tty,
62 struct line *line);
63extern void line_cleanup(struct tty_struct *tty);
64extern void line_hangup(struct tty_struct *tty);
63extern int line_setup(char **conf, unsigned nlines, char **def, 65extern int line_setup(char **conf, unsigned nlines, char **def,
64 char *init, char *name); 66 char *init, char *name);
65extern int line_write(struct tty_struct *tty, const unsigned char *buf, 67extern 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);
70extern void line_flush_buffer(struct tty_struct *tty); 72extern void line_flush_buffer(struct tty_struct *tty);
71extern void line_flush_chars(struct tty_struct *tty); 73extern void line_flush_chars(struct tty_struct *tty);
72extern int line_write_room(struct tty_struct *tty); 74extern int line_write_room(struct tty_struct *tty);
73extern int line_ioctl(struct tty_struct *tty, unsigned int cmd,
74 unsigned long arg);
75extern void line_throttle(struct tty_struct *tty); 75extern void line_throttle(struct tty_struct *tty);
76extern void line_unthrottle(struct tty_struct *tty); 76extern 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
90static int ssl_open(struct tty_struct *tty, struct file *filp) 90static 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
102static void ssl_flush_buffer(struct tty_struct *tty)
103{
104 return;
105}
106
107static void ssl_stop(struct tty_struct *tty)
108{
109 printk(KERN_ERR "Someone should implement ssl_stop\n");
110}
111
112static void ssl_start(struct tty_struct *tty)
113{
114 printk(KERN_ERR "Someone should implement ssl_start\n");
115}
116
117void ssl_hangup(struct tty_struct *tty)
118{ 91{
92 return line_install(driver, tty, &serial_lines[tty->index]);
119} 93}
120#endif
121 94
122static const struct tty_operations ssl_ops = { 95static 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
92static 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 */
103static int con_init_done = 0; 93static int con_init_done = 0;
104 94
95static int con_install(struct tty_driver *driver, struct tty_struct *tty)
96{
97 return line_install(driver, tty, &vts[tty->index]);
98}
99
105static const struct tty_operations console_ops = { 100static 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
120static void uml_console_write(struct console *console, const char *string, 117static 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
38extern int arch_copy_tls(struct task_struct *new); 38extern int arch_copy_tls(struct task_struct *new);
39extern void clear_flushed_tls(struct task_struct *task); 39extern void clear_flushed_tls(struct task_struct *task);
40extern void syscall_trace_enter(struct pt_regs *regs);
41extern 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
61extern int linux_main(int argc, char **argv); 61extern int linux_main(int argc, char **argv);
62 62
63extern void (*sig_info[])(int, struct uml_pt_regs *); 63struct siginfo;
64extern 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
21enum { IRQ_READ, IRQ_WRITE }; 21enum { IRQ_READ, IRQ_WRITE };
22 22
23extern void sigio_handler(int sig, struct uml_pt_regs *regs); 23struct siginfo;
24extern void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
24extern void free_irq_by_fd(int fd); 25extern void free_irq_by_fd(int fd);
25extern void reactivate_fd(int fd, int irqnum); 26extern void reactivate_fd(int fd, int irqnum);
26extern void deactivate_fd(int fd, int irqnum); 27extern 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
12struct siginfo;
13
12extern int uml_exitcode; 14extern int uml_exitcode;
13 15
14extern int ncpus; 16extern int ncpus;
@@ -22,7 +24,7 @@ extern void free_stack(unsigned long stack, int order);
22 24
23extern int do_signal(void); 25extern int do_signal(void);
24extern void interrupt_end(void); 26extern void interrupt_end(void);
25extern void relay_signal(int sig, struct uml_pt_regs *regs); 27extern void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs);
26 28
27extern unsigned long segv(struct faultinfo fi, unsigned long ip, 29extern 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);
33extern int smp_sigio_handler(void); 35extern int smp_sigio_handler(void);
34extern void initial_thread_cb(void (*proc)(void *), void *arg); 36extern void initial_thread_cb(void (*proc)(void *), void *arg);
35extern int is_syscall(unsigned long addr); 37extern int is_syscall(unsigned long addr);
36extern void timer_handler(int sig, struct uml_pt_regs *regs);
37 38
38extern void timer_handler(int sig, struct uml_pt_regs *regs); 39extern void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
39 40
40extern int start_uml(void); 41extern int start_uml(void);
41extern void paging_init(void); 42extern void paging_init(void);
@@ -59,9 +60,9 @@ extern unsigned long from_irq_stack(int nested);
59extern void syscall_trace(struct uml_pt_regs *regs, int entryexit); 60extern void syscall_trace(struct uml_pt_regs *regs, int entryexit);
60extern int singlestepping(void *t); 61extern int singlestepping(void *t);
61 62
62extern void segv_handler(int sig, struct uml_pt_regs *regs); 63extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
63extern void bus_handler(int sig, struct uml_pt_regs *regs); 64extern void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs);
64extern void winch(int sig, struct uml_pt_regs *regs); 65extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
65extern void fatal_sigsegv(void) __attribute__ ((noreturn)); 66extern 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
31extern void free_irqs(void); 31extern void free_irqs(void);
32 32
33void sigio_handler(int sig, struct uml_pt_regs *regs) 33void 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, &current->thread.exec_buf); 153 n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
154 if (n == 1) { 154 if (n == 1)
155 /* Handle any immediate reschedules or signals */
156 interrupt_end();
157 userspace(&current->thread.regs.regs); 155 userspace(&current->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(&current->thread.regs.regs); 176 userspace(&current->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, &regs->regs, 189 memcpy(&p->thread.regs.regs, &regs->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 */
165void syscall_trace(struct uml_pt_regs *regs, int entryexit) 166void 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(&regs->regs),
169 170 UPT_SYSCALL_ARG1(&regs->regs),
170 if (!entryexit) 171 UPT_SYSCALL_ARG2(&regs->regs),
171 audit_syscall_entry(HOST_AUDIT_ARCH, 172 UPT_SYSCALL_ARG3(&regs->regs),
172 UPT_SYSCALL_NR(regs), 173 UPT_SYSCALL_ARG4(&regs->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 /* 181void 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, &regs->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
16void timer_handler(int sig, struct uml_pt_regs *regs) 16void 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
175void segv_handler(int sig, struct uml_pt_regs *regs) 175void 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
261void relay_signal(int sig, struct uml_pt_regs *regs) 261void 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
276void bus_handler(int sig, struct uml_pt_regs *regs) 300void 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
283void winch(int sig, struct uml_pt_regs *regs) 308void 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
17void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { 18void (*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
27static void sig_handler_common(int sig, mcontext_t *mc) 28static 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)
60static int signals_enabled; 61static int signals_enabled;
61static unsigned int signals_pending; 62static unsigned int signals_pending;
62 63
63void sig_handler(int sig, mcontext_t *mc) 64void 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(&regs, mc); 86 get_regs_from_mc(&regs, mc);
86 regs.is_user = 0; 87 regs.is_user = 0;
87 unblock_signals(); 88 unblock_signals();
88 timer_handler(SIGVTALRM, &regs); 89 timer_handler(SIGVTALRM, NULL, &regs);
89} 90}
90 91
91void alarm_handler(int sig, mcontext_t *mc) 92void 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
122static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = { 123static 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
135static void hard_handler(int sig, siginfo_t *info, void *p) 136static 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 &regs->faultinfo); 419 &regs->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
88static void deliver_alarm(void) 88static void deliver_alarm(void)
89{ 89{
90 alarm_handler(SIGVTALRM, NULL); 90 alarm_handler(SIGVTALRM, NULL, NULL);
91} 91}
92 92
93static unsigned long long sleep_time(unsigned long long nsecs) 93static 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
35static inline long regs_return_value(struct uml_pt_regs *regs) 35static 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 */