Пример #1
0
int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
		 unsigned long unused,
                 struct task_struct * p, struct pt_regs * regs)
{
	struct pt_regs * childregs;
	long childksp;
	extern void save_fp(void*);

	childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32;

	if (last_task_used_math == current)
		if (mips_cpu.options & MIPS_CPU_FPU) {
			__enable_fpu();
			save_fp(p);
		}
	/* set up new TSS. */
	childregs = (struct pt_regs *) childksp - 1;
	*childregs = *regs;
	set_gpreg(childregs, 7, 0);	/* Clear error flag */
	if(current->personality == PER_LINUX) {
		set_gpreg(childregs, 2, 0); /* Child gets zero as return value */
		set_gpreg(regs, 2, p->pid);
	} else {
		/* Under IRIX things are a little different. */
		set_gpreg(childregs, 2, 0);
		set_gpreg(childregs, 3, 1);
		set_gpreg(regs, 2, p->pid);
		set_gpreg(regs, 3, 0);
	}
	if (childregs->cp0_status & ST0_CU0) {
		set_gpreg(childregs, 28, (unsigned long) p);
		set_gpreg(childregs, 29, childksp);
		p->thread.current_ds = KERNEL_DS;
	} else {
		set_gpreg(childregs, 29, usp);
		p->thread.current_ds = USER_DS;
	}
	p->thread.reg29 = (unsigned long) childregs;
	p->thread.reg31 = (unsigned long) ret_from_fork;

	/*
	 * New tasks loose permission to use the fpu. This accelerates context
	 * switching for most programs since they don't use the fpu.
	 */
#ifdef CONFIG_PS2
	/* keep COP2 usable bit to share the VPU0 context */
	p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) &
                            ~(ST0_CU1|KU_MASK);
	childregs->cp0_status &= ~(ST0_CU1);
#else
	p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) &
                            ~(ST0_CU2|ST0_CU1|KU_MASK);
	childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
#endif

	return 0;
}
Пример #2
0
asmlinkage int sys_pipe(struct pt_regs regs)
{
	int fd[2];
	int error, res;

	lock_kernel();
	error = do_pipe(fd);
	if (error) {
		res = error;
		goto out;
	}
	set_gpreg(&regs, 3, fd[1]);
	res = fd[0];
out:
	unlock_kernel();
	return res;
}