History

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

Linus Torvalds committed 14 years ago

Commit 1871e842 parents a6dc772 b07098923 files · +206 −302Browse files

Unified · Split

23 files
  1. MAINTAINERS +1 −0
  2. arch/um/defconfig +1 −1
  3. arch/um/drivers/chan_kern.c +3 −1
  4. arch/um/drivers/line.c +63 −155
  5. arch/um/drivers/line.h +6 −6
  6. arch/um/drivers/ssl.c +6 −36
  7. arch/um/drivers/stdio_console.c +9 −12
  8. arch/um/drivers/ubd_kern.c +1 −1
  9. arch/um/include/asm/ptrace-generic.h +2 −0
  10. arch/um/include/shared/as-layout.h +2 −1
  11. arch/um/include/shared/irq_user.h +2 −1
  12. arch/um/include/shared/kern_util.h +7 −6
  13. arch/um/kernel/irq.c +1 −1
  14. arch/um/kernel/process.c +4 −9
  15. arch/um/kernel/ptrace.c +30 −41
  16. arch/um/kernel/skas/syscall.c +3 −3
  17. arch/um/kernel/time.c +1 −1
  18. arch/um/kernel/trap.c +32 −7
  19. arch/um/os-Linux/internal.h +1 −1
  20. arch/um/os-Linux/signal.c +15 −11
  21. arch/um/os-Linux/skas/process.c +12 −4
  22. arch/um/os-Linux/time.c +1 −1
  23. arch/x86/um/asm/ptrace.h +3 −3
MAINTAINERS+1−0
@@ -7382,6 +7382,7 @@ W: http://user-mode-linux.sourceforge.net · 7381 unmodified lines
73827382 S: Maintained
73837383 F: Documentation/virtual/uml/
73847384 F: arch/um/
7385+F: arch/x86/um/
73857386 F: fs/hostfs/
73867387 F: fs/hppfs/
73877388
arch/um/defconfig+1−1
@@ -163,7 +163,7 @@ CONFIG_CGROUP_SCHED=y · 162 unmodified lines
163163 CONFIG_FAIR_GROUP_SCHED=y
164164 # CONFIG_CFS_BANDWIDTH is not set
165165 # CONFIG_RT_GROUP_SCHED is not set
166−CONFIG_BLK_CGROUP=m
166+CONFIG_BLK_CGROUP=y
167167 # CONFIG_DEBUG_BLK_CGROUP is not set
168168 # CONFIG_CHECKPOINT_RESTORE is not set
169169 CONFIG_NAMESPACES=y
arch/um/drivers/chan_kern.c+3−1
@@ -150,9 +150,11 @@ void chan_enable_winch(struct chan *chan, struct tty_struct *tty) · 149 unmodified lines
150150 static void line_timer_cb(struct work_struct *work)
151151 {
152152 struct line *line = container_of(work, struct line, task.work);
153+ struct tty_struct *tty = tty_port_tty_get(&line->port);
153154
154155 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);
156158 }
157159
158160 int enable_chan(struct line *line)
arch/um/drivers/line.c+63−155
@@ -19,9 +19,11 @@ static irqreturn_t line_interrupt(int irq, void *data) · 18 unmodified lines
1919 {
2020 struct chan *chan = data;
2121 struct line *line = chan->line;
22+ struct tty_struct *tty = tty_port_tty_get(&line->port);
2223
2324 if (line)
24− chan_interrupt(line, line->tty, irq);
25+ chan_interrupt(line, tty, irq);
26+ tty_kref_put(tty);
2527 return IRQ_HANDLED;
2628 }
2729
@@ -219,92 +221,6 @@ void line_set_termios(struct tty_struct *tty, struct ktermios * old) · 191 unmodified lines
219221 /* nothing */
220222 }
221223
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−
308224 void line_throttle(struct tty_struct *tty)
309225 {
310226 struct line *line = tty->driver_data;
@@ -333,7 +249,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) · 22 unmodified lines
333249 {
334250 struct chan *chan = data;
335251 struct line *line = chan->line;
336− struct tty_struct *tty = line->tty;
252+ struct tty_struct *tty;
337253 int err;
338254
339255 /*
@@ -352,10 +268,13 @@ static irqreturn_t line_write_interrupt(int irq, void *data) · 12 unmodified lines
352268 }
353269 spin_unlock(&line->lock);
354270
271+ tty = tty_port_tty_get(&line->port);
355272 if (tty == NULL)
356273 return IRQ_NONE;
357274
358275 tty_wakeup(tty);
276+ tty_kref_put(tty);
277+
359278 return IRQ_HANDLED;
360279 }
361280
@@ -377,43 +296,14 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) · 15 unmodified lines
377296 return err;
378297 }
379298
380−/*
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)
299+static int line_activate(struct tty_port *port, struct tty_struct *tty)
398300 {
399− struct line *line = &lines[tty->index];
400− int err = -ENODEV;
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;
301+ int ret;
302+ struct line *line = tty->driver_data;
413303
414− err = enable_chan(line);
415− if (err) /* line_close() will be called by our caller */
416− goto out_unlock;
304+ ret = enable_chan(line);
305+ if (ret)
306+ return ret;
417307
418308 if (!line->sigio) {
419309 chan_enable_winch(line->chan_out, tty);
@@ -421,44 +311,60 @@ int line_open(struct line *lines, struct tty_struct *tty) · 1 unmodified line
421311 }
422312
423313 chan_window_size(line, &tty->winsize.ws_row,
424− &tty->winsize.ws_col);
425−out_unlock:
426− mutex_unlock(&line->count_lock);
427− return err;
314+ &tty->winsize.ws_col);
315+
316+ return 0;
428317 }
429318
430−static void unregister_winch(struct tty_struct *tty);
319+static const struct tty_port_operations line_port_ops = {
320+ .activate = line_activate,
321+};
431322
432−void line_close(struct tty_struct *tty, struct file * filp)
323+int line_open(struct tty_struct *tty, struct file *filp)
433324 {
434325 struct line *line = tty->driver_data;
435326
436− /*
437− * If line_open fails (and tty->driver_data is never set),
438− * tty_open will call line_close. So just return in this case.
439− */
440− if (line == NULL)
441− return;
327+ return tty_port_open(&line->port, tty, filp);
328+}
442329
443− /* We ignore the error anyway! */
444− flush_buffer(line);
330+int line_install(struct tty_driver *driver, struct tty_struct *tty,
331+ struct line *line)
332+{
333+ int ret;
445334
446− mutex_lock(&line->count_lock);
447− BUG_ON(!line->valid);
335+ ret = tty_standard_install(driver, tty);
336+ if (ret)
337+ return ret;
448338
449− if (--line->count)
450− goto out_unlock;
339+ tty->driver_data = line;
451340
452− line->tty = NULL;
453− tty->driver_data = NULL;
341+ return 0;
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;
454349
455350 if (line->sigio) {
456351 unregister_winch(tty);
457352 line->sigio = 0;
458353 }
354+}
355+
356+void line_close(struct tty_struct *tty, struct file * filp)
357+{
358+ struct line *line = tty->driver_data;
459359
460−out_unlock:
461− mutex_unlock(&line->count_lock);
360+ tty_port_close(&line->port, tty, filp);
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);
462368 }
463369
464370 void close_lines(struct line *lines, int nlines)
@@ -476,9 +382,7 @@ int setup_one_line(struct line *lines, int n, char *init, · 11 unmodified lines
476382 struct tty_driver *driver = line->driver->driver;
477383 int err = -EINVAL;
478384
479− mutex_lock(&line->count_lock);
480−
481− if (line->count) {
385+ if (line->port.count) {
482386 *error_out = "Device is already open";
483387 goto out;
484388 }
@@ -519,7 +423,6 @@ int setup_one_line(struct line *lines, int n, char *init, · 34 unmodified lines
519423 }
520424 }
521425 out:
522− mutex_unlock(&line->count_lock);
523426 return err;
524427 }
525428
@@ -607,13 +510,17 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, · 81 unmodified lines
607510
608511 line = &lines[dev];
609512
610− mutex_lock(&line->count_lock);
611513 if (!line->valid)
612514 CONFIG_CHUNK(str, size, n, "none", 1);
613− else if (line->tty == NULL)
614− CONFIG_CHUNK(str, size, n, line->init_str, 1);
615− else n = chan_config_string(line, str, size, error_out);
616− mutex_unlock(&line->count_lock);
515+ else {
516+ struct tty_struct *tty = tty_port_tty_get(&line->port);
517+ if (tty == NULL) {
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+ }
617524
618525 return n;
619526 }
@@ -663,8 +570,9 @@ int register_lines(struct line_driver *line_driver, · 43 unmodified lines
663570 driver->init_termios = tty_std_termios;
664571
665572 for (i = 0; i < nlines; i++) {
573+ tty_port_init(&lines[i].port);
574+ lines[i].port.ops = &line_port_ops;
666575 spin_lock_init(&lines[i].lock);
667− mutex_init(&lines[i].count_lock);
668576 lines[i].driver = line_driver;
669577 INIT_LIST_HEAD(&lines[i].chan_list);
670578 }
arch/um/drivers/line.h+6−6
@@ -32,9 +32,7 @@ struct line_driver { · 31 unmodified lines
3232 };
3333
3434 struct line {
35− struct tty_struct *tty;
36− struct mutex count_lock;
37− unsigned long count;
35+ struct tty_port port;
3836 int valid;
3937
4038 char *init_str;
@@ -59,7 +57,11 @@ struct line { · 18 unmodified lines
5957 };
6058
6159 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);
6365 extern int line_setup(char **conf, unsigned nlines, char **def,
6466 char *init, char *name);
6567 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); · 4 unmodified lines
7072 extern void line_flush_buffer(struct tty_struct *tty);
7173 extern void line_flush_chars(struct tty_struct *tty);
7274 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);
7575 extern void line_throttle(struct tty_struct *tty);
7676 extern void line_unthrottle(struct tty_struct *tty);
7777
arch/um/drivers/ssl.c+6−36
@@ -87,40 +87,13 @@ static int ssl_remove(int n, char **error_out) · 86 unmodified lines
8787 error_out);
8888 }
8989
90−static int ssl_open(struct tty_struct *tty, struct file *filp)
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)
90+static int ssl_install(struct tty_driver *driver, struct tty_struct *tty)
11891 {
92+ return line_install(driver, tty, &serial_lines[tty->index]);
11993 }
120−#endif
12194
12295 static const struct tty_operations ssl_ops = {
123− .open = ssl_open,
96+ .open = line_open,
12497 .close = line_close,
12598 .write = line_write,
12699 .put_char = line_put_char,
@@ -129,14 +102,11 @@ static const struct tty_operations ssl_ops = { · 2 unmodified lines
129102 .flush_buffer = line_flush_buffer,
130103 .flush_chars = line_flush_chars,
131104 .set_termios = line_set_termios,
132− .ioctl = line_ioctl,
133105 .throttle = line_throttle,
134106 .unthrottle = line_unthrottle,
135−#if 0
136− .stop = ssl_stop,
137− .start = ssl_start,
138− .hangup = ssl_hangup,
139−#endif
107+ .install = ssl_install,
108+ .cleanup = line_cleanup,
109+ .hangup = line_hangup,
140110 };
141111
142112 /* Changed by ssl_init and referenced by ssl_exit, which are both serialized
arch/um/drivers/stdio_console.c+9−12
@@ -89,21 +89,17 @@ static int con_remove(int n, char **error_out) · 88 unmodified lines
8989 return line_remove(vts, ARRAY_SIZE(vts), n, error_out);
9090 }
9191
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−
10292 /* Set in an initcall, checked in an exitcall */
10393 static int con_init_done = 0;
10494
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+
105100 static const struct tty_operations console_ops = {
106− .open = con_open,
101+ .open = line_open,
102+ .install = con_install,
107103 .close = line_close,
108104 .write = line_write,
109105 .put_char = line_put_char,
@@ -112,9 +108,10 @@ static const struct tty_operations console_ops = { · 2 unmodified lines
112108 .flush_buffer = line_flush_buffer,
113109 .flush_chars = line_flush_chars,
114110 .set_termios = line_set_termios,
115− .ioctl = line_ioctl,
116111 .throttle = line_throttle,
117112 .unthrottle = line_unthrottle,
113+ .cleanup = line_cleanup,
114+ .hangup = line_hangup,
118115 };
119116
120117 static void uml_console_write(struct console *console, const char *string,
arch/um/drivers/ubd_kern.c+1−1
@@ -514,7 +514,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) · 513 unmodified lines
514514 goto out;
515515 }
516516
517− fd = os_open_file(ubd_dev->file, global_openflags, 0);
517+ fd = os_open_file(ubd_dev->file, of_read(OPENFLAGS()), 0);
518518 if (fd < 0)
519519 return fd;
520520
arch/um/include/asm/ptrace-generic.h+2−0
@@ -37,6 +37,8 @@ extern int putreg(struct task_struct *child, int regno, unsigned long value); · 36 unmodified lines
3737
3838 extern int arch_copy_tls(struct task_struct *new);
3939 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);
4042
4143 #endif
4244
arch/um/include/shared/as-layout.h+2−1
@@ -60,7 +60,8 @@ extern unsigned long host_task_size; · 59 unmodified lines
6060
6161 extern int linux_main(int argc, char **argv);
6262
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 *);
6465
6566 #endif
6667
arch/um/include/shared/irq_user.h+2−1
@@ -20,7 +20,8 @@ struct irq_fd { · 19 unmodified lines
2020
2121 enum { IRQ_READ, IRQ_WRITE };
2222
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);
2425 extern void free_irq_by_fd(int fd);
2526 extern void reactivate_fd(int fd, int irqnum);
2627 extern void deactivate_fd(int fd, int irqnum);
arch/um/include/shared/kern_util.h+7−6
@@ -9,6 +9,8 @@ · 8 unmodified lines
99 #include "sysdep/ptrace.h"
1010 #include "sysdep/faultinfo.h"
1111
12+struct siginfo;
13+
1214 extern int uml_exitcode;
1315
1416 extern int ncpus;
@@ -22,7 +24,7 @@ extern void free_stack(unsigned long stack, int order); · 7 unmodified lines
2224
2325 extern int do_signal(void);
2426 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);
2628
2729 extern unsigned long segv(struct faultinfo fi, unsigned long ip,
2830 int is_user, struct uml_pt_regs *regs);
@@ -33,9 +35,8 @@ extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs); · 4 unmodified lines
3335 extern int smp_sigio_handler(void);
3436 extern void initial_thread_cb(void (*proc)(void *), void *arg);
3537 extern int is_syscall(unsigned long addr);
36−extern void timer_handler(int sig, struct uml_pt_regs *regs);
3738
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);
3940
4041 extern int start_uml(void);
4142 extern void paging_init(void);
@@ -59,9 +60,9 @@ extern unsigned long from_irq_stack(int nested); · 17 unmodified lines
5960 extern void syscall_trace(struct uml_pt_regs *regs, int entryexit);
6061 extern int singlestepping(void *t);
6162
62−extern void segv_handler(int sig, struct uml_pt_regs *regs);
63−extern void bus_handler(int sig, struct uml_pt_regs *regs);
64−extern void winch(int sig, struct uml_pt_regs *regs);
63+extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
64+extern void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs);
65+extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
6566 extern void fatal_sigsegv(void) __attribute__ ((noreturn));
6667
6768
arch/um/kernel/irq.c+1−1
@@ -30,7 +30,7 @@ static struct irq_fd **last_irq_ptr = &active_fds; · 29 unmodified lines
3030
3131 extern void free_irqs(void);
3232
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)
3434 {
3535 struct irq_fd *irq_fd;
3636 int n;
arch/um/kernel/process.c+4−9
@@ -151,12 +151,10 @@ void new_thread_handler(void) · 150 unmodified lines
151151 * 0 if it just exits
152152 */
153153 n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
154− if (n == 1) {
155− /* Handle any immediate reschedules or signals */
156− interrupt_end();
154+ if (n == 1)
157155 userspace(&current->thread.regs.regs);
158− }
159− else do_exit(0);
156+ else
157+ do_exit(0);
160158 }
161159
162160 /* Called magically, see new_thread_handler above */
@@ -175,9 +173,6 @@ void fork_handler(void) · 12 unmodified lines
175173
176174 current->thread.prev_sched = NULL;
177175
178− /* Handle any immediate reschedules or signals */
179− interrupt_end();
180−
181176 userspace(&current->thread.regs.regs);
182177 }
183178
@@ -193,7 +188,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, · 9 unmodified lines
193188 if (current->thread.forking) {
194189 memcpy(&p->thread.regs.regs, &regs->regs,
195190 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);
197192 if (sp != 0)
198193 REGS_SP(p->thread.regs.regs.gp) = sp;
199194
arch/um/kernel/ptrace.c+30−41
@@ -3,11 +3,12 @@ · 2 unmodified lines
33 * Licensed under the GPL
44 */
55
6−#include "linux/audit.h"
7−#include "linux/ptrace.h"
8−#include "linux/sched.h"
9−#include "asm/uaccess.h"
10−#include "skas_ptrace.h"
6+#include <linux/audit.h>
7+#include <linux/ptrace.h>
8+#include <linux/sched.h>
9+#include <linux/tracehook.h>
10+#include <asm/uaccess.h>
11+#include <skas_ptrace.h>
1112
1213
1314
@@ -162,48 +163,36 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, · 148 unmodified lines
162163 * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
163164 * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
164165 */
165−void syscall_trace(struct uml_pt_regs *regs, int entryexit)
166+void syscall_trace_enter(struct pt_regs *regs)
166167 {
167− int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit;
168− int tracesysgood;
169−
170− if (!entryexit)
171− audit_syscall_entry(HOST_AUDIT_ARCH,
172− UPT_SYSCALL_NR(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);
168+ audit_syscall_entry(HOST_AUDIT_ARCH,
169+ UPT_SYSCALL_NR(&regs->regs),
170+ UPT_SYSCALL_ARG1(&regs->regs),
171+ UPT_SYSCALL_ARG2(&regs->regs),
172+ UPT_SYSCALL_ARG3(&regs->regs),
173+ UPT_SYSCALL_ARG4(&regs->regs));
183174
184175 if (!test_thread_flag(TIF_SYSCALL_TRACE))
185176 return;
186177
187− if (!(current->ptrace & PT_PTRACED))
188− return;
178+ tracehook_report_syscall_entry(regs);
179+}
189180
190− /*
191− * the 0x80 provides a way for the tracing parent to distinguish
192− * between a syscall stop and SIGTRAP delivery
193− */
194− tracesysgood = (current->ptrace & PT_TRACESYSGOOD);
195− ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));
181+void syscall_trace_leave(struct pt_regs *regs)
182+{
183+ int ptraced = current->ptrace;
196184
197− if (entryexit) /* force do_signal() --> is_syscall() */
198− set_thread_flag(TIF_SIGPENDING);
185+ audit_syscall_exit(regs);
199186
200− /*
201− * this isn't the same as continuing with a signal, but it will do
202− * for normal use. strace only continues with a signal if the
203− * stopping signal is not SIGTRAP. -brl
204− */
205− if (current->exit_code) {
206− send_sig(current->exit_code, current, 1);
207− current->exit_code = 0;
208− }
187+ /* Fake a debug trap */
188+ if (ptraced & PT_DTRACE)
189+ send_sigtrap(current, &regs->regs, 0);
190+
191+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
192+ return;
193+
194+ tracehook_report_syscall_exit(regs, 0);
195+ /* force do_signal() --> is_syscall() */
196+ if (ptraced & PT_PTRACED)
197+ set_thread_flag(TIF_SIGPENDING);
209198 }
arch/um/kernel/skas/syscall.c+3−3
@@ -18,7 +18,7 @@ void handle_syscall(struct uml_pt_regs *r) · 17 unmodified lines
1818 long result;
1919 int syscall;
2020
21− syscall_trace(r, 0);
21+ syscall_trace_enter(regs);
2222
2323 /*
2424 * 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) · 9 unmodified lines
3434 result = -ENOSYS;
3535 else result = EXECUTE_SYSCALL(syscall, regs);
3636
37− UPT_SET_SYSCALL_RETURN(r, result);
37+ PT_REGS_SET_SYSCALL_RETURN(regs, result);
3838
39− syscall_trace(r, 1);
39+ syscall_trace_leave(regs);
4040 }
arch/um/kernel/time.c+1−1
@@ -13,7 +13,7 @@ · 12 unmodified lines
1313 #include "kern_util.h"
1414 #include "os.h"
1515
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)
1717 {
1818 unsigned long flags;
1919
arch/um/kernel/trap.c+32−7
@@ -172,7 +172,7 @@ void fatal_sigsegv(void) · 171 unmodified lines
172172 os_dump_core();
173173 }
174174
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)
176176 {
177177 struct faultinfo * fi = UPT_FAULTINFO(regs);
178178
@@ -258,8 +258,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, · 79 unmodified lines
258258 return 0;
259259 }
260260
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)
262262 {
263+ struct faultinfo *fi;
264+ struct siginfo clean_si;
265+
263266 if (!UPT_IS_USER(regs)) {
264267 if (sig == SIGBUS)
265268 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) · 3 unmodified lines
269272
270273 arch_examine_signal(sig, regs);
271274
272− current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
273− force_sig(sig, current);
275+ memset(&clean_si, 0, sizeof(clean_si));
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);
274298 }
275299
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)
277301 {
278302 if (current->thread.fault_catcher != NULL)
279303 UML_LONGJMP(current->thread.fault_catcher, 1);
280− else relay_signal(sig, regs);
304+ else
305+ relay_signal(sig, si, regs);
281306 }
282307
283−void winch(int sig, struct uml_pt_regs *regs)
308+void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
284309 {
285310 do_IRQ(WINCH_IRQ, regs);
286311 }
arch/um/os-Linux/internal.h+1−1
@@ -1 +1 @@
1−void alarm_handler(int, mcontext_t *);
1+void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc);
arch/um/os-Linux/signal.c+15−11
@@ -13,8 +13,9 @@ · 12 unmodified lines
1313 #include "kern_util.h"
1414 #include "os.h"
1515 #include "sysdep/mcontext.h"
16+#include "internal.h"
1617
17−void (*sig_info[NSIG])(int, struct uml_pt_regs *) = {
18+void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = {
1819 [SIGTRAP] = relay_signal,
1920 [SIGFPE] = relay_signal,
2021 [SIGILL] = relay_signal,
@@ -24,7 +25,7 @@ void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { · 3 unmodified lines
2425 [SIGIO] = sigio_handler,
2526 [SIGVTALRM] = timer_handler };
2627
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)
2829 {
2930 struct uml_pt_regs r;
3031 int save_errno = errno;
@@ -40,7 +41,7 @@ static void sig_handler_common(int sig, mcontext_t *mc) · 9 unmodified lines
4041 if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM))
4142 unblock_signals();
4243
43− (*sig_info[sig])(sig, &r);
44+ (*sig_info[sig])(sig, si, &r);
4445
4546 errno = save_errno;
4647 }
@@ -60,7 +61,7 @@ static void sig_handler_common(int sig, mcontext_t *mc) · 13 unmodified lines
6061 static int signals_enabled;
6162 static unsigned int signals_pending;
6263
63−void sig_handler(int sig, mcontext_t *mc)
64+void sig_handler(int sig, siginfo_t *si, mcontext_t *mc)
6465 {
6566 int enabled;
6667
@@ -72,7 +73,7 @@ void sig_handler(int sig, mcontext_t *mc) · 5 unmodified lines
7273
7374 block_signals();
7475
75− sig_handler_common(sig, mc);
76+ sig_handler_common(sig, si, mc);
7677
7778 set_signals(enabled);
7879 }
@@ -85,10 +86,10 @@ static void real_alarm_handler(mcontext_t *mc) · 6 unmodified lines
8586 get_regs_from_mc(&regs, mc);
8687 regs.is_user = 0;
8788 unblock_signals();
88− timer_handler(SIGVTALRM, &regs);
89+ timer_handler(SIGVTALRM, NULL, &regs);
8990 }
9091
91−void alarm_handler(int sig, mcontext_t *mc)
92+void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
9293 {
9394 int enabled;
9495
@@ -119,7 +120,7 @@ void set_sigstack(void *sig_stack, int size) · 24 unmodified lines
119120 panic("enabling signal stack failed, errno = %d\n", errno);
120121 }
121122
122−static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = {
123+static void (*handlers[_NSIG])(int sig, siginfo_t *si, mcontext_t *mc) = {
123124 [SIGSEGV] = sig_handler,
124125 [SIGBUS] = sig_handler,
125126 [SIGILL] = sig_handler,
@@ -132,7 +133,7 @@ static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = { · 6 unmodified lines
132133 };
133134
134135
135−static void hard_handler(int sig, siginfo_t *info, void *p)
136+static void hard_handler(int sig, siginfo_t *si, void *p)
136137 {
137138 struct ucontext *uc = p;
138139 mcontext_t *mc = &uc->uc_mcontext;
@@ -161,7 +162,7 @@ static void hard_handler(int sig, siginfo_t *info, void *p) · 22 unmodified lines
161162 while ((sig = ffs(pending)) != 0){
162163 sig--;
163164 pending &= ~(1 << sig);
164− (*handlers[sig])(sig, mc);
165+ (*handlers[sig])(sig, si, mc);
165166 }
166167
167168 /*
@@ -273,9 +274,12 @@ void unblock_signals(void) · 105 unmodified lines
273274 * Deal with SIGIO first because the alarm handler might
274275 * schedule, leaving the pending SIGIO stranded until we come
275276 * back here.
277+ *
278+ * SIGIO's handler doesn't use siginfo or mcontext,
279+ * so they can be NULL.
276280 */
277281 if (save_pending & SIGIO_MASK)
278− sig_handler_common(SIGIO, NULL);
282+ sig_handler_common(SIGIO, NULL, NULL);
279283
280284 if (save_pending & SIGVTALRM_MASK)
281285 real_alarm_handler(NULL);
arch/um/os-Linux/skas/process.c+12−4
@@ -346,6 +346,10 @@ void userspace(struct uml_pt_regs *regs) · 345 unmodified lines
346346 int err, status, op, pid = userspace_pid[0];
347347 /* To prevent races if using_sysemu changes under us.*/
348348 int local_using_sysemu;
349+ siginfo_t si;
350+
351+ /* Handle any immediate reschedules or signals */
352+ interrupt_end();
349353
350354 if (getitimer(ITIMER_VIRTUAL, &timer))
351355 printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno);
@@ -404,13 +408,17 @@ void userspace(struct uml_pt_regs *regs) · 52 unmodified lines
404408
405409 if (WIFSTOPPED(status)) {
406410 int sig = WSTOPSIG(status);
411+
412+ ptrace(PTRACE_GETSIGINFO, pid, 0, &si);
413+
407414 switch (sig) {
408415 case SIGSEGV:
409416 if (PTRACE_FULL_FAULTINFO ||
410417 !ptrace_faultinfo) {
411418 get_skas_faultinfo(pid,
412419 &regs->faultinfo);
413− (*sig_info[SIGSEGV])(SIGSEGV, regs);
420+ (*sig_info[SIGSEGV])(SIGSEGV, &si,
421+ regs);
414422 }
415423 else handle_segv(pid, regs);
416424 break;
@@ -418,14 +426,14 @@ void userspace(struct uml_pt_regs *regs) · 1 unmodified line
418426 handle_trap(pid, regs, local_using_sysemu);
419427 break;
420428 case SIGTRAP:
421− relay_signal(SIGTRAP, regs);
429+ relay_signal(SIGTRAP, &si, regs);
422430 break;
423431 case SIGVTALRM:
424432 now = os_nsecs();
425433 if (now < nsecs)
426434 break;
427435 block_signals();
428− (*sig_info[sig])(sig, regs);
436+ (*sig_info[sig])(sig, &si, regs);
429437 unblock_signals();
430438 nsecs = timer.it_value.tv_sec *
431439 UM_NSEC_PER_SEC +
@@ -439,7 +447,7 @@ void userspace(struct uml_pt_regs *regs) · 7 unmodified lines
439447 case SIGFPE:
440448 case SIGWINCH:
441449 block_signals();
442− (*sig_info[sig])(sig, regs);
450+ (*sig_info[sig])(sig, &si, regs);
443451 unblock_signals();
444452 break;
445453 default:
arch/um/os-Linux/time.c+1−1
@@ -87,7 +87,7 @@ static int after_sleep_interval(struct timespec *ts) · 86 unmodified lines
8787
8888 static void deliver_alarm(void)
8989 {
90− alarm_handler(SIGVTALRM, NULL);
90+ alarm_handler(SIGVTALRM, NULL, NULL);
9191 }
9292
9393 static unsigned long long sleep_time(unsigned long long nsecs)
arch/x86/um/asm/ptrace.h+3−3
@@ -30,10 +30,10 @@ · 29 unmodified lines
3030 #define profile_pc(regs) PT_REGS_IP(regs)
3131
3232 #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))
3434
35−static inline long regs_return_value(struct uml_pt_regs *regs)
35+static inline long regs_return_value(struct pt_regs *regs)
3636 {
37− return UPT_AX(regs);
37+ return PT_REGS_AX(regs);
3838 }
3939 #endif /* __UM_X86_PTRACE_H */