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(&regs->regs);
	SC_START_SYSCALL(sc);

	syscall_trace(&regs->regs, 0);

	current->thread.nsyscalls++;
	nsyscalls++;
	syscall = UPT_SYSCALL_NR(&regs->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(&regs->regs) = sc;

	SC_SET_SYSCALL_RETURN(sc, result);

	syscall_trace(&regs->regs, 1);
#ifdef CONFIG_SYSCALL_DEBUG
  	record_syscall_end(index, result);
#endif
}
예제 #2
0
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(&regs->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);
}