void syscall_handler_tt(int sig, struct pt_regs *regs) { void *sc; long result; int syscall; #ifdef CONFIG_SYSCALL_DEBUG int index; index = record_syscall_start(syscall); #endif sc = UPT_SC(®s->regs); SC_START_SYSCALL(sc); syscall_trace(®s->regs, 0); current->thread.nsyscalls++; nsyscalls++; syscall = UPT_SYSCALL_NR(®s->regs); if((syscall >= NR_syscalls) || (syscall < 0)) result = -ENOSYS; else result = EXECUTE_SYSCALL(syscall, regs); /* regs->sc may have changed while the system call ran (there may * have been an interrupt or segfault), so it needs to be refreshed. */ UPT_SC(®s->regs) = sc; SC_SET_SYSCALL_RETURN(sc, result); syscall_trace(®s->regs, 1); #ifdef CONFIG_SYSCALL_DEBUG record_syscall_end(index, result); #endif }
int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, unsigned long stack_top, struct task_struct * p, struct pt_regs *regs) { int (*tramp)(void *); int new_pid, err; unsigned long stack; if(current->thread.forking) tramp = fork_tramp; else { tramp = new_thread_proc; p->thread.request.u.thread = current->thread.request.u.thread; } err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1); if(err < 0){ printk("copy_thread : pipe failed, err = %d\n", -err); return(err); } stack = alloc_stack(0, 0); if(stack == 0){ printk(KERN_ERR "copy_thread : failed to allocate " "temporary stack\n"); return(-ENOMEM); } clone_flags &= CLONE_VM; p->thread.temp_stack = stack; new_pid = start_fork_tramp(task_stack_page(p), stack, clone_flags, tramp); if(new_pid < 0){ printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", -new_pid); return(new_pid); } if(current->thread.forking){ sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(®s->regs)); SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0); if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp; } p->thread.mode.tt.extern_pid = new_pid; current->thread.request.op = OP_FORK; current->thread.request.u.fork.pid = new_pid; os_usr1_process(os_getpid()); /* Enable the signal and then disable it to ensure that it is handled * here, and nowhere else. */ change_sig(SIGUSR1, 1); change_sig(SIGUSR1, 0); err = 0; return(err); }