Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+210 -306
+1
MAINTAINERS
··· 7382 7382 S: Maintained 7383 7383 F: Documentation/virtual/uml/ 7384 7384 F: arch/um/ 7385 + F: arch/x86/um/ 7385 7386 F: fs/hostfs/ 7386 7387 F: fs/hppfs/ 7387 7388
+1 -1
arch/um/defconfig
··· 163 163 CONFIG_FAIR_GROUP_SCHED=y 164 164 # CONFIG_CFS_BANDWIDTH is not set 165 165 # CONFIG_RT_GROUP_SCHED is not set 166 - CONFIG_BLK_CGROUP=m 166 + CONFIG_BLK_CGROUP=y 167 167 # CONFIG_DEBUG_BLK_CGROUP is not set 168 168 # CONFIG_CHECKPOINT_RESTORE is not set 169 169 CONFIG_NAMESPACES=y
+3 -1
arch/um/drivers/chan_kern.c
··· 150 150 static void line_timer_cb(struct work_struct *work) 151 151 { 152 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 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 160 int enable_chan(struct line *line)
+67 -159
arch/um/drivers/line.c
··· 19 19 { 20 20 struct chan *chan = data; 21 21 struct line *line = chan->line; 22 + struct tty_struct *tty = tty_port_tty_get(&line->port); 22 23 23 24 if (line) 24 - chan_interrupt(line, line->tty, irq); 25 + chan_interrupt(line, tty, irq); 26 + tty_kref_put(tty); 25 27 return IRQ_HANDLED; 26 28 } 27 29 ··· 221 219 /* nothing */ 222 220 } 223 221 224 - static const struct { 225 - int cmd; 226 - char *level; 227 - char *name; 228 - } tty_ioctls[] = { 229 - /* don't print these, they flood the log ... */ 230 - { TCGETS, NULL, "TCGETS" }, 231 - { TCSETS, NULL, "TCSETS" }, 232 - { TCSETSW, NULL, "TCSETSW" }, 233 - { TCFLSH, NULL, "TCFLSH" }, 234 - { TCSBRK, NULL, "TCSBRK" }, 235 - 236 - /* general tty stuff */ 237 - { TCSETSF, KERN_DEBUG, "TCSETSF" }, 238 - { TCGETA, KERN_DEBUG, "TCGETA" }, 239 - { TIOCMGET, KERN_DEBUG, "TIOCMGET" }, 240 - { TCSBRKP, KERN_DEBUG, "TCSBRKP" }, 241 - { TIOCMSET, KERN_DEBUG, "TIOCMSET" }, 242 - 243 - /* linux-specific ones */ 244 - { TIOCLINUX, KERN_INFO, "TIOCLINUX" }, 245 - { KDGKBMODE, KERN_INFO, "KDGKBMODE" }, 246 - { KDGKBTYPE, KERN_INFO, "KDGKBTYPE" }, 247 - { KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" }, 248 - }; 249 - 250 - int line_ioctl(struct tty_struct *tty, unsigned int cmd, 251 - unsigned long arg) 252 - { 253 - int ret; 254 - int i; 255 - 256 - ret = 0; 257 - switch(cmd) { 258 - #ifdef TIOCGETP 259 - case TIOCGETP: 260 - case TIOCSETP: 261 - case TIOCSETN: 262 - #endif 263 - #ifdef TIOCGETC 264 - case TIOCGETC: 265 - case TIOCSETC: 266 - #endif 267 - #ifdef TIOCGLTC 268 - case TIOCGLTC: 269 - case TIOCSLTC: 270 - #endif 271 - /* Note: these are out of date as we now have TCGETS2 etc but this 272 - whole lot should probably go away */ 273 - case TCGETS: 274 - case TCSETSF: 275 - case TCSETSW: 276 - case TCSETS: 277 - case TCGETA: 278 - case TCSETAF: 279 - case TCSETAW: 280 - case TCSETA: 281 - case TCXONC: 282 - case TCFLSH: 283 - case TIOCOUTQ: 284 - case TIOCINQ: 285 - case TIOCGLCKTRMIOS: 286 - case TIOCSLCKTRMIOS: 287 - case TIOCPKT: 288 - case TIOCGSOFTCAR: 289 - case TIOCSSOFTCAR: 290 - return -ENOIOCTLCMD; 291 - #if 0 292 - case TCwhatever: 293 - /* do something */ 294 - break; 295 - #endif 296 - default: 297 - for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++) 298 - if (cmd == tty_ioctls[i].cmd) 299 - break; 300 - if (i == ARRAY_SIZE(tty_ioctls)) { 301 - printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n", 302 - __func__, tty->name, cmd); 303 - } 304 - ret = -ENOIOCTLCMD; 305 - break; 306 - } 307 - return ret; 308 - } 309 - 310 222 void line_throttle(struct tty_struct *tty) 311 223 { 312 224 struct line *line = tty->driver_data; ··· 249 333 { 250 334 struct chan *chan = data; 251 335 struct line *line = chan->line; 252 - struct tty_struct *tty = line->tty; 336 + struct tty_struct *tty; 253 337 int err; 254 338 255 339 /* ··· 268 352 } 269 353 spin_unlock(&line->lock); 270 354 355 + tty = tty_port_tty_get(&line->port); 271 356 if (tty == NULL) 272 357 return IRQ_NONE; 273 358 274 359 tty_wakeup(tty); 360 + tty_kref_put(tty); 361 + 275 362 return IRQ_HANDLED; 276 363 } 277 364 ··· 296 377 return err; 297 378 } 298 379 299 - /* 300 - * Normally, a driver like this can rely mostly on the tty layer 301 - * locking, particularly when it comes to the driver structure. 302 - * However, in this case, mconsole requests can come in "from the 303 - * side", and race with opens and closes. 304 - * 305 - * mconsole config requests will want to be sure the device isn't in 306 - * use, and get_config, open, and close will want a stable 307 - * configuration. The checking and modification of the configuration 308 - * is done under a spinlock. Checking whether the device is in use is 309 - * line->tty->count > 1, also under the spinlock. 310 - * 311 - * line->count serves to decide whether the device should be enabled or 312 - * disabled on the host. If it's equal to 0, then we are doing the 313 - * first open or last close. Otherwise, open and close just return. 314 - */ 315 - 316 - int line_open(struct line *lines, struct tty_struct *tty) 380 + static int line_activate(struct tty_port *port, struct tty_struct *tty) 317 381 { 318 - struct line *line = &lines[tty->index]; 319 - int err = -ENODEV; 382 + int ret; 383 + struct line *line = tty->driver_data; 320 384 321 - mutex_lock(&line->count_lock); 322 - if (!line->valid) 323 - goto out_unlock; 324 - 325 - err = 0; 326 - if (line->count++) 327 - goto out_unlock; 328 - 329 - BUG_ON(tty->driver_data); 330 - tty->driver_data = line; 331 - line->tty = tty; 332 - 333 - err = enable_chan(line); 334 - if (err) /* line_close() will be called by our caller */ 335 - goto out_unlock; 385 + ret = enable_chan(line); 386 + if (ret) 387 + return ret; 336 388 337 389 if (!line->sigio) { 338 390 chan_enable_winch(line->chan_out, tty); ··· 311 421 } 312 422 313 423 chan_window_size(line, &tty->winsize.ws_row, 314 - &tty->winsize.ws_col); 315 - out_unlock: 316 - mutex_unlock(&line->count_lock); 317 - return err; 424 + &tty->winsize.ws_col); 425 + 426 + return 0; 427 + } 428 + 429 + static const struct tty_port_operations line_port_ops = { 430 + .activate = line_activate, 431 + }; 432 + 433 + int line_open(struct tty_struct *tty, struct file *filp) 434 + { 435 + struct line *line = tty->driver_data; 436 + 437 + return tty_port_open(&line->port, tty, filp); 438 + } 439 + 440 + int line_install(struct tty_driver *driver, struct tty_struct *tty, 441 + struct line *line) 442 + { 443 + int ret; 444 + 445 + ret = tty_standard_install(driver, tty); 446 + if (ret) 447 + return ret; 448 + 449 + tty->driver_data = line; 450 + 451 + return 0; 318 452 } 319 453 320 454 static void unregister_winch(struct tty_struct *tty); 321 455 322 - void line_close(struct tty_struct *tty, struct file * filp) 456 + void line_cleanup(struct tty_struct *tty) 323 457 { 324 458 struct line *line = tty->driver_data; 325 - 326 - /* 327 - * If line_open fails (and tty->driver_data is never set), 328 - * tty_open will call line_close. So just return in this case. 329 - */ 330 - if (line == NULL) 331 - return; 332 - 333 - /* We ignore the error anyway! */ 334 - flush_buffer(line); 335 - 336 - mutex_lock(&line->count_lock); 337 - BUG_ON(!line->valid); 338 - 339 - if (--line->count) 340 - goto out_unlock; 341 - 342 - line->tty = NULL; 343 - tty->driver_data = NULL; 344 459 345 460 if (line->sigio) { 346 461 unregister_winch(tty); 347 462 line->sigio = 0; 348 463 } 464 + } 349 465 350 - out_unlock: 351 - mutex_unlock(&line->count_lock); 466 + void line_close(struct tty_struct *tty, struct file * filp) 467 + { 468 + struct line *line = tty->driver_data; 469 + 470 + tty_port_close(&line->port, tty, filp); 471 + } 472 + 473 + void line_hangup(struct tty_struct *tty) 474 + { 475 + struct line *line = tty->driver_data; 476 + 477 + tty_port_hangup(&line->port); 352 478 } 353 479 354 480 void close_lines(struct line *lines, int nlines) ··· 382 476 struct tty_driver *driver = line->driver->driver; 383 477 int err = -EINVAL; 384 478 385 - mutex_lock(&line->count_lock); 386 - 387 - if (line->count) { 479 + if (line->port.count) { 388 480 *error_out = "Device is already open"; 389 481 goto out; 390 482 } ··· 423 519 } 424 520 } 425 521 out: 426 - mutex_unlock(&line->count_lock); 427 522 return err; 428 523 } 429 524 ··· 510 607 511 608 line = &lines[dev]; 512 609 513 - mutex_lock(&line->count_lock); 514 610 if (!line->valid) 515 611 CONFIG_CHUNK(str, size, n, "none", 1); 516 - else if (line->tty == NULL) 517 - CONFIG_CHUNK(str, size, n, line->init_str, 1); 518 - else n = chan_config_string(line, str, size, error_out); 519 - mutex_unlock(&line->count_lock); 612 + else { 613 + struct tty_struct *tty = tty_port_tty_get(&line->port); 614 + if (tty == NULL) { 615 + CONFIG_CHUNK(str, size, n, line->init_str, 1); 616 + } else { 617 + n = chan_config_string(line, str, size, error_out); 618 + tty_kref_put(tty); 619 + } 620 + } 520 621 521 622 return n; 522 623 } ··· 570 663 driver->init_termios = tty_std_termios; 571 664 572 665 for (i = 0; i < nlines; i++) { 666 + tty_port_init(&lines[i].port); 667 + lines[i].port.ops = &line_port_ops; 573 668 spin_lock_init(&lines[i].lock); 574 - mutex_init(&lines[i].count_lock); 575 669 lines[i].driver = line_driver; 576 670 INIT_LIST_HEAD(&lines[i].chan_list); 577 671 }
+6 -6
arch/um/drivers/line.h
··· 32 32 }; 33 33 34 34 struct line { 35 - struct tty_struct *tty; 36 - struct mutex count_lock; 37 - unsigned long count; 35 + struct tty_port port; 38 36 int valid; 39 37 40 38 char *init_str; ··· 57 59 }; 58 60 59 61 extern void line_close(struct tty_struct *tty, struct file * filp); 60 - extern int line_open(struct line *lines, struct tty_struct *tty); 62 + extern int line_open(struct tty_struct *tty, struct file *filp); 63 + extern int line_install(struct tty_driver *driver, struct tty_struct *tty, 64 + struct line *line); 65 + extern void line_cleanup(struct tty_struct *tty); 66 + extern void line_hangup(struct tty_struct *tty); 61 67 extern int line_setup(char **conf, unsigned nlines, char **def, 62 68 char *init, char *name); 63 69 extern int line_write(struct tty_struct *tty, const unsigned char *buf, ··· 72 70 extern void line_flush_buffer(struct tty_struct *tty); 73 71 extern void line_flush_chars(struct tty_struct *tty); 74 72 extern int line_write_room(struct tty_struct *tty); 75 - extern int line_ioctl(struct tty_struct *tty, unsigned int cmd, 76 - unsigned long arg); 77 73 extern void line_throttle(struct tty_struct *tty); 78 74 extern void line_unthrottle(struct tty_struct *tty); 79 75
+6 -36
arch/um/drivers/ssl.c
··· 87 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 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; 92 + return line_install(driver, tty, &serial_lines[tty->index]); 99 93 } 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 - { 119 - } 120 - #endif 121 94 122 95 static const struct tty_operations ssl_ops = { 123 - .open = ssl_open, 96 + .open = line_open, 124 97 .close = line_close, 125 98 .write = line_write, 126 99 .put_char = line_put_char, ··· 102 129 .flush_buffer = line_flush_buffer, 103 130 .flush_chars = line_flush_chars, 104 131 .set_termios = line_set_termios, 105 - .ioctl = line_ioctl, 106 132 .throttle = line_throttle, 107 133 .unthrottle = line_unthrottle, 108 - #if 0 109 - .stop = ssl_stop, 110 - .start = ssl_start, 111 - .hangup = ssl_hangup, 112 - #endif 134 + .install = ssl_install, 135 + .cleanup = line_cleanup, 136 + .hangup = line_hangup, 113 137 }; 114 138 115 139 /* Changed by ssl_init and referenced by ssl_exit, which are both serialized
+9 -12
arch/um/drivers/stdio_console.c
··· 89 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 92 /* Set in an initcall, checked in an exitcall */ 103 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 100 static const struct tty_operations console_ops = { 106 - .open = con_open, 101 + .open = line_open, 102 + .install = con_install, 107 103 .close = line_close, 108 104 .write = line_write, 109 105 .put_char = line_put_char, ··· 108 112 .flush_buffer = line_flush_buffer, 109 113 .flush_chars = line_flush_chars, 110 114 .set_termios = line_set_termios, 111 - .ioctl = line_ioctl, 112 115 .throttle = line_throttle, 113 116 .unthrottle = line_unthrottle, 117 + .cleanup = line_cleanup, 118 + .hangup = line_hangup, 114 119 }; 115 120 116 121 static void uml_console_write(struct console *console, const char *string,
+1 -1
arch/um/drivers/ubd_kern.c
··· 514 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 518 if (fd < 0) 519 519 return fd; 520 520
+2
arch/um/include/asm/ptrace-generic.h
··· 37 37 38 38 extern int arch_copy_tls(struct task_struct *new); 39 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 43 #endif 42 44
+2 -1
arch/um/include/shared/as-layout.h
··· 60 60 61 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 66 #endif 66 67
+2 -1
arch/um/include/shared/irq_user.h
··· 20 20 21 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 25 extern void free_irq_by_fd(int fd); 25 26 extern void reactivate_fd(int fd, int irqnum); 26 27 extern void deactivate_fd(int fd, int irqnum);
+7 -6
arch/um/include/shared/kern_util.h
··· 9 9 #include "sysdep/ptrace.h" 10 10 #include "sysdep/faultinfo.h" 11 11 12 + struct siginfo; 13 + 12 14 extern int uml_exitcode; 13 15 14 16 extern int ncpus; ··· 24 22 25 23 extern int do_signal(void); 26 24 extern void interrupt_end(void); 27 - extern void relay_signal(int sig, struct uml_pt_regs *regs); 25 + extern void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs); 28 26 29 27 extern unsigned long segv(struct faultinfo fi, unsigned long ip, 30 28 int is_user, struct uml_pt_regs *regs); ··· 35 33 extern int smp_sigio_handler(void); 36 34 extern void initial_thread_cb(void (*proc)(void *), void *arg); 37 35 extern int is_syscall(unsigned long addr); 38 - extern void timer_handler(int sig, struct uml_pt_regs *regs); 39 36 40 - extern void timer_handler(int sig, struct uml_pt_regs *regs); 37 + extern void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); 41 38 42 39 extern int start_uml(void); 43 40 extern void paging_init(void); ··· 60 59 extern void syscall_trace(struct uml_pt_regs *regs, int entryexit); 61 60 extern int singlestepping(void *t); 62 61 63 - extern void segv_handler(int sig, struct uml_pt_regs *regs); 64 - extern void bus_handler(int sig, struct uml_pt_regs *regs); 65 - extern void winch(int sig, struct uml_pt_regs *regs); 62 + extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); 63 + extern void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs); 64 + extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs); 66 65 extern void fatal_sigsegv(void) __attribute__ ((noreturn)); 67 66 68 67
+1 -1
arch/um/kernel/irq.c
··· 30 30 31 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 35 struct irq_fd *irq_fd; 36 36 int n;
+4 -9
arch/um/kernel/process.c
··· 151 151 * 0 if it just exits 152 152 */ 153 153 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) 157 155 userspace(&current->thread.regs.regs); 158 - } 159 - else do_exit(0); 156 + else 157 + do_exit(0); 160 158 } 161 159 162 160 /* Called magically, see new_thread_handler above */ ··· 173 175 174 176 current->thread.prev_sched = NULL; 175 177 176 - /* Handle any immediate reschedules or signals */ 177 - interrupt_end(); 178 - 179 178 userspace(&current->thread.regs.regs); 180 179 } 181 180 ··· 188 193 if (current->thread.forking) { 189 194 memcpy(&p->thread.regs.regs, &regs->regs, 190 195 sizeof(p->thread.regs.regs)); 191 - UPT_SET_SYSCALL_RETURN(&p->thread.regs.regs, 0); 196 + PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0); 192 197 if (sp != 0) 193 198 REGS_SP(p->thread.regs.regs.gp) = sp; 194 199
+30 -41
arch/um/kernel/ptrace.c
··· 3 3 * Licensed under the GPL 4 4 */ 5 5 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> 11 12 12 13 13 14 ··· 163 162 * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and 164 163 * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check 165 164 */ 166 - void syscall_trace(struct uml_pt_regs *regs, int entryexit) 165 + void syscall_trace_enter(struct pt_regs *regs) 167 166 { 168 - int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit; 169 - int tracesysgood; 170 - 171 - if (!entryexit) 172 - audit_syscall_entry(HOST_AUDIT_ARCH, 173 - UPT_SYSCALL_NR(regs), 174 - UPT_SYSCALL_ARG1(regs), 175 - UPT_SYSCALL_ARG2(regs), 176 - UPT_SYSCALL_ARG3(regs), 177 - UPT_SYSCALL_ARG4(regs)); 178 - else 179 - audit_syscall_exit(regs); 180 - 181 - /* Fake a debug trap */ 182 - if (is_singlestep) 183 - send_sigtrap(current, regs, 0); 167 + audit_syscall_entry(HOST_AUDIT_ARCH, 168 + UPT_SYSCALL_NR(&regs->regs), 169 + UPT_SYSCALL_ARG1(&regs->regs), 170 + UPT_SYSCALL_ARG2(&regs->regs), 171 + UPT_SYSCALL_ARG3(&regs->regs), 172 + UPT_SYSCALL_ARG4(&regs->regs)); 184 173 185 174 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 186 175 return; 187 176 188 - if (!(current->ptrace & PT_PTRACED)) 177 + tracehook_report_syscall_entry(regs); 178 + } 179 + 180 + void syscall_trace_leave(struct pt_regs *regs) 181 + { 182 + int ptraced = current->ptrace; 183 + 184 + audit_syscall_exit(regs); 185 + 186 + /* Fake a debug trap */ 187 + if (ptraced & PT_DTRACE) 188 + send_sigtrap(current, &regs->regs, 0); 189 + 190 + if (!test_thread_flag(TIF_SYSCALL_TRACE)) 189 191 return; 190 192 191 - /* 192 - * the 0x80 provides a way for the tracing parent to distinguish 193 - * between a syscall stop and SIGTRAP delivery 194 - */ 195 - tracesysgood = (current->ptrace & PT_TRACESYSGOOD); 196 - ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); 197 - 198 - if (entryexit) /* force do_signal() --> is_syscall() */ 193 + tracehook_report_syscall_exit(regs, 0); 194 + /* force do_signal() --> is_syscall() */ 195 + if (ptraced & PT_PTRACED) 199 196 set_thread_flag(TIF_SIGPENDING); 200 - 201 - /* 202 - * this isn't the same as continuing with a signal, but it will do 203 - * for normal use. strace only continues with a signal if the 204 - * stopping signal is not SIGTRAP. -brl 205 - */ 206 - if (current->exit_code) { 207 - send_sig(current->exit_code, current, 1); 208 - current->exit_code = 0; 209 - } 210 197 }
+3 -3
arch/um/kernel/skas/syscall.c
··· 18 18 long result; 19 19 int syscall; 20 20 21 - syscall_trace(r, 0); 21 + syscall_trace_enter(regs); 22 22 23 23 /* 24 24 * This should go in the declaration of syscall, but when I do that, ··· 34 34 result = -ENOSYS; 35 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 }
+1 -1
arch/um/kernel/time.c
··· 13 13 #include "kern_util.h" 14 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 18 unsigned long flags; 19 19
+32 -7
arch/um/kernel/trap.c
··· 172 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 177 struct faultinfo * fi = UPT_FAULTINFO(regs); 178 178 ··· 258 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 266 if (!UPT_IS_USER(regs)) { 264 267 if (sig == SIGBUS) 265 268 printk(KERN_ERR "Bus error - the host /dev/shm or /tmp " ··· 272 269 273 270 arch_examine_signal(sig, regs); 274 271 275 - current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); 276 - force_sig(sig, current); 272 + memset(&clean_si, 0, sizeof(clean_si)); 273 + clean_si.si_signo = si->si_signo; 274 + clean_si.si_errno = si->si_errno; 275 + clean_si.si_code = si->si_code; 276 + switch (sig) { 277 + case SIGILL: 278 + case SIGFPE: 279 + case SIGSEGV: 280 + case SIGBUS: 281 + case SIGTRAP: 282 + fi = UPT_FAULTINFO(regs); 283 + clean_si.si_addr = (void __user *) FAULT_ADDRESS(*fi); 284 + current->thread.arch.faultinfo = *fi; 285 + #ifdef __ARCH_SI_TRAPNO 286 + clean_si.si_trapno = si->si_trapno; 287 + #endif 288 + break; 289 + default: 290 + printk(KERN_ERR "Attempted to relay unknown signal %d (si_code = %d)\n", 291 + sig, si->si_code); 292 + } 293 + 294 + force_sig_info(sig, &clean_si, current); 277 295 } 278 296 279 - void bus_handler(int sig, struct uml_pt_regs *regs) 297 + void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs) 280 298 { 281 299 if (current->thread.fault_catcher != NULL) 282 300 UML_LONGJMP(current->thread.fault_catcher, 1); 283 - else relay_signal(sig, regs); 301 + else 302 + relay_signal(sig, si, regs); 284 303 } 285 304 286 - void winch(int sig, struct uml_pt_regs *regs) 305 + void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs) 287 306 { 288 307 do_IRQ(WINCH_IRQ, regs); 289 308 }
+1 -1
arch/um/os-Linux/internal.h
··· 1 - void alarm_handler(int, mcontext_t *); 1 + void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc);
+15 -11
arch/um/os-Linux/signal.c
··· 13 13 #include "kern_util.h" 14 14 #include "os.h" 15 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 19 [SIGTRAP] = relay_signal, 19 20 [SIGFPE] = relay_signal, 20 21 [SIGILL] = relay_signal, ··· 25 24 [SIGIO] = sigio_handler, 26 25 [SIGVTALRM] = timer_handler }; 27 26 28 - static void sig_handler_common(int sig, mcontext_t *mc) 27 + static void sig_handler_common(int sig, siginfo_t *si, mcontext_t *mc) 29 28 { 30 29 struct uml_pt_regs r; 31 30 int save_errno = errno; ··· 41 40 if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM)) 42 41 unblock_signals(); 43 42 44 - (*sig_info[sig])(sig, &r); 43 + (*sig_info[sig])(sig, si, &r); 45 44 46 45 errno = save_errno; 47 46 } ··· 61 60 static int signals_enabled; 62 61 static unsigned int signals_pending; 63 62 64 - void sig_handler(int sig, mcontext_t *mc) 63 + void sig_handler(int sig, siginfo_t *si, mcontext_t *mc) 65 64 { 66 65 int enabled; 67 66 ··· 73 72 74 73 block_signals(); 75 74 76 - sig_handler_common(sig, mc); 75 + sig_handler_common(sig, si, mc); 77 76 78 77 set_signals(enabled); 79 78 } ··· 86 85 get_regs_from_mc(&regs, mc); 87 86 regs.is_user = 0; 88 87 unblock_signals(); 89 - timer_handler(SIGVTALRM, &regs); 88 + timer_handler(SIGVTALRM, NULL, &regs); 90 89 } 91 90 92 - void alarm_handler(int sig, mcontext_t *mc) 91 + void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc) 93 92 { 94 93 int enabled; 95 94 ··· 120 119 panic("enabling signal stack failed, errno = %d\n", errno); 121 120 } 122 121 123 - static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = { 122 + static void (*handlers[_NSIG])(int sig, siginfo_t *si, mcontext_t *mc) = { 124 123 [SIGSEGV] = sig_handler, 125 124 [SIGBUS] = sig_handler, 126 125 [SIGILL] = sig_handler, ··· 133 132 }; 134 133 135 134 136 - static void hard_handler(int sig, siginfo_t *info, void *p) 135 + static void hard_handler(int sig, siginfo_t *si, void *p) 137 136 { 138 137 struct ucontext *uc = p; 139 138 mcontext_t *mc = &uc->uc_mcontext; ··· 162 161 while ((sig = ffs(pending)) != 0){ 163 162 sig--; 164 163 pending &= ~(1 << sig); 165 - (*handlers[sig])(sig, mc); 164 + (*handlers[sig])(sig, si, mc); 166 165 } 167 166 168 167 /* ··· 274 273 * Deal with SIGIO first because the alarm handler might 275 274 * schedule, leaving the pending SIGIO stranded until we come 276 275 * back here. 276 + * 277 + * SIGIO's handler doesn't use siginfo or mcontext, 278 + * so they can be NULL. 277 279 */ 278 280 if (save_pending & SIGIO_MASK) 279 - sig_handler_common(SIGIO, NULL); 281 + sig_handler_common(SIGIO, NULL, NULL); 280 282 281 283 if (save_pending & SIGVTALRM_MASK) 282 284 real_alarm_handler(NULL);
+12 -4
arch/um/os-Linux/skas/process.c
··· 346 346 int err, status, op, pid = userspace_pid[0]; 347 347 /* To prevent races if using_sysemu changes under us.*/ 348 348 int local_using_sysemu; 349 + siginfo_t si; 350 + 351 + /* Handle any immediate reschedules or signals */ 352 + interrupt_end(); 349 353 350 354 if (getitimer(ITIMER_VIRTUAL, &timer)) 351 355 printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno); ··· 408 404 409 405 if (WIFSTOPPED(status)) { 410 406 int sig = WSTOPSIG(status); 407 + 408 + ptrace(PTRACE_GETSIGINFO, pid, 0, &si); 409 + 411 410 switch (sig) { 412 411 case SIGSEGV: 413 412 if (PTRACE_FULL_FAULTINFO || 414 413 !ptrace_faultinfo) { 415 414 get_skas_faultinfo(pid, 416 415 &regs->faultinfo); 417 - (*sig_info[SIGSEGV])(SIGSEGV, regs); 416 + (*sig_info[SIGSEGV])(SIGSEGV, &si, 417 + regs); 418 418 } 419 419 else handle_segv(pid, regs); 420 420 break; ··· 426 418 handle_trap(pid, regs, local_using_sysemu); 427 419 break; 428 420 case SIGTRAP: 429 - relay_signal(SIGTRAP, regs); 421 + relay_signal(SIGTRAP, &si, regs); 430 422 break; 431 423 case SIGVTALRM: 432 424 now = os_nsecs(); 433 425 if (now < nsecs) 434 426 break; 435 427 block_signals(); 436 - (*sig_info[sig])(sig, regs); 428 + (*sig_info[sig])(sig, &si, regs); 437 429 unblock_signals(); 438 430 nsecs = timer.it_value.tv_sec * 439 431 UM_NSEC_PER_SEC + ··· 447 439 case SIGFPE: 448 440 case SIGWINCH: 449 441 block_signals(); 450 - (*sig_info[sig])(sig, regs); 442 + (*sig_info[sig])(sig, &si, regs); 451 443 unblock_signals(); 452 444 break; 453 445 default:
+1 -1
arch/um/os-Linux/time.c
··· 87 87 88 88 static void deliver_alarm(void) 89 89 { 90 - alarm_handler(SIGVTALRM, NULL); 90 + alarm_handler(SIGVTALRM, NULL, NULL); 91 91 } 92 92 93 93 static unsigned long long sleep_time(unsigned long long nsecs)
+3 -3
arch/x86/um/asm/ptrace.h
··· 30 30 #define profile_pc(regs) PT_REGS_IP(regs) 31 31 32 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 39 #endif /* __UM_X86_PTRACE_H */