⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
void prepare_to_copy(struct task_struct *tsk){	struct pt_regs *regs = tsk->thread.regs;	if (regs == NULL)		return;	preempt_disable();	if (regs->msr & MSR_FP)		giveup_fpu(current);#ifdef CONFIG_ALTIVEC	if (regs->msr & MSR_VEC)		giveup_altivec(current);#endif /* CONFIG_ALTIVEC */#ifdef CONFIG_SPE	if (regs->msr & MSR_SPE)		giveup_spe(current);#endif /* CONFIG_SPE */	preempt_enable();}/* * Copy a thread.. */intcopy_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, *kregs;	extern void ret_from_fork(void);	unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;	unsigned long childframe;	p->set_child_tid = p->clear_child_tid = NULL;	CHECK_FULL_REGS(regs);	/* Copy registers */	sp -= sizeof(struct pt_regs);	childregs = (struct pt_regs *) sp;	*childregs = *regs;	if ((childregs->msr & MSR_PR) == 0) {		/* for kernel thread, set `current' and stackptr in new task */		childregs->gpr[1] = sp + sizeof(struct pt_regs);		childregs->gpr[2] = (unsigned long) p;		p->thread.regs = NULL;	/* no user register state */	} else {		childregs->gpr[1] = usp;		p->thread.regs = childregs;		if (clone_flags & CLONE_SETTLS)			childregs->gpr[2] = childregs->gpr[6];	}	childregs->gpr[3] = 0;  /* Result from fork() */	sp -= STACK_FRAME_OVERHEAD;	childframe = sp;	/*	 * The way this works is that at some point in the future	 * some task will call _switch to switch to the new task.	 * That will pop off the stack frame created below and start	 * the new task running at ret_from_fork.  The new task will	 * do some house keeping and then return from the fork or clone	 * system call, using the stack frame created above.	 */	sp -= sizeof(struct pt_regs);	kregs = (struct pt_regs *) sp;	sp -= STACK_FRAME_OVERHEAD;	p->thread.ksp = sp;	kregs->nip = (unsigned long)ret_from_fork;	p->thread.last_syscall = -1;	return 0;}/* * Set up a thread for executing a new program */void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp){	set_fs(USER_DS);	memset(regs->gpr, 0, sizeof(regs->gpr));	regs->ctr = 0;	regs->link = 0;	regs->xer = 0;	regs->ccr = 0;	regs->mq = 0;	regs->nip = nip;	regs->gpr[1] = sp;	regs->msr = MSR_USER;	if (last_task_used_math == current)		last_task_used_math = NULL;	if (last_task_used_altivec == current)		last_task_used_altivec = NULL;	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));	current->thread.fpscr = 0;#ifdef CONFIG_ALTIVEC	memset(current->thread.vr, 0, sizeof(current->thread.vr));	memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));	current->thread.vrsave = 0;	current->thread.used_vr = 0;#endif /* CONFIG_ALTIVEC */#ifdef CONFIG_SPE	memset(current->thread.evr, 0, sizeof(current->thread.evr));	current->thread.acc = 0;	current->thread.spefscr = 0;	current->thread.used_spe = 0;#endif /* CONFIG_SPE */}#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \		| PR_FP_EXC_RES | PR_FP_EXC_INV)int set_fpexc_mode(struct task_struct *tsk, unsigned int val){	struct pt_regs *regs = tsk->thread.regs;	/* This is a bit hairy.  If we are an SPE enabled  processor	 * (have embedded fp) we store the IEEE exception enable flags in	 * fpexc_mode.  fpexc_mode is also used for setting FP exception	 * mode (asyn, precise, disabled) for 'Classic' FP. */	if (val & PR_FP_EXC_SW_ENABLE) {#ifdef CONFIG_SPE		tsk->thread.fpexc_mode = val &			(PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);#else		return -EINVAL;#endif	} else {		/* on a CONFIG_SPE this does not hurt us.  The bits that		 * __pack_fe01 use do not overlap with bits used for		 * PR_FP_EXC_SW_ENABLE.  Additionally, the MSR[FE0,FE1] bits		 * on CONFIG_SPE implementations are reserved so writing to		 * them does not change anything */		if (val > PR_FP_EXC_PRECISE)			return -EINVAL;		tsk->thread.fpexc_mode = __pack_fe01(val);		if (regs != NULL && (regs->msr & MSR_FP) != 0)			regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))				| tsk->thread.fpexc_mode;	}	return 0;}int get_fpexc_mode(struct task_struct *tsk, unsigned long adr){	unsigned int val;	if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)#ifdef CONFIG_SPE		val = tsk->thread.fpexc_mode;#else		return -EINVAL;#endif	else		val = __unpack_fe01(tsk->thread.fpexc_mode);	return put_user(val, (unsigned int __user *) adr);}int sys_clone(unsigned long clone_flags, unsigned long usp,	      int __user *parent_tidp, void __user *child_threadptr,	      int __user *child_tidp, int p6,	      struct pt_regs *regs){	CHECK_FULL_REGS(regs);	if (usp == 0)		usp = regs->gpr[1];	/* stack pointer for child */ 	return do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0,			parent_tidp, child_tidp);}int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,	     struct pt_regs *regs){	CHECK_FULL_REGS(regs);	return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);}int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,	      struct pt_regs *regs){	CHECK_FULL_REGS(regs);	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1],			regs, 0, NULL, NULL);}int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,	       unsigned long a3, unsigned long a4, unsigned long a5,	       struct pt_regs *regs){	int error;	char * filename;	filename = getname((char __user *) a0);	error = PTR_ERR(filename);	if (IS_ERR(filename))		goto out;	preempt_disable();	if (regs->msr & MSR_FP)		giveup_fpu(current);#ifdef CONFIG_ALTIVEC	if (regs->msr & MSR_VEC)		giveup_altivec(current);#endif /* CONFIG_ALTIVEC */#ifdef CONFIG_SPE	if (regs->msr & MSR_SPE)		giveup_spe(current);#endif /* CONFIG_SPE */	preempt_enable();	error = do_execve(filename, (char __user *__user *) a1,			  (char __user *__user *) a2, regs);	if (error == 0)		current->ptrace &= ~PT_DTRACE;	putname(filename);out:	return error;}void dump_stack(void){	show_stack(current, NULL);}EXPORT_SYMBOL(dump_stack);void show_stack(struct task_struct *tsk, unsigned long *stack){	unsigned long sp, stack_top, prev_sp, ret;	int count = 0;	unsigned long next_exc = 0;	struct pt_regs *regs;	extern char ret_from_except, ret_from_except_full, ret_from_syscall;	sp = (unsigned long) stack;	if (tsk == NULL)		tsk = current;	if (sp == 0) {		if (tsk == current)			asm("mr %0,1" : "=r" (sp));		else			sp = tsk->thread.ksp;	}	prev_sp = (unsigned long) (tsk->thread_info + 1);	stack_top = (unsigned long) tsk->thread_info + THREAD_SIZE;	while (count < 16 && sp > prev_sp && sp < stack_top && (sp & 3) == 0) {		if (count == 0) {			printk("Call trace:");#ifdef CONFIG_KALLSYMS			printk("\n");#endif		} else {			if (next_exc) {				ret = next_exc;				next_exc = 0;			} else				ret = *(unsigned long *)(sp + 4);			printk(" [%08lx] ", ret);#ifdef CONFIG_KALLSYMS			print_symbol("%s", ret);			printk("\n");#endif			if (ret == (unsigned long) &ret_from_except			    || ret == (unsigned long) &ret_from_except_full			    || ret == (unsigned long) &ret_from_syscall) {				/* sp + 16 points to an exception frame */				regs = (struct pt_regs *) (sp + 16);				if (sp + 16 + sizeof(*regs) <= stack_top)					next_exc = regs->nip;			}		}		++count;		sp = *(unsigned long *)sp;	}#if !CONFIG_KALLSYMS	if (count > 0)		printk("\n");#endif}#if 0/* * Low level print for debugging - Cort */int __init ll_printk(const char *fmt, ...){        va_list args;	char buf[256];        int i;        va_start(args, fmt);        i=vsprintf(buf,fmt,args);	ll_puts(buf);        va_end(args);        return i;}int lines = 24, cols = 80;int orig_x = 0, orig_y = 0;void puthex(unsigned long val){	unsigned char buf[10];	int i;	for (i = 7;  i >= 0;  i--)	{		buf[i] = "0123456789ABCDEF"[val & 0x0F];		val >>= 4;	}	buf[8] = '\0';	prom_print(buf);}void __init ll_puts(const char *s){	int x,y;	char *vidmem = (char *)/*(_ISA_MEM_BASE + 0xB8000) */0xD00B8000;	char c;	extern int mem_init_done;	if ( mem_init_done ) /* assume this means we can printk */	{		printk(s);		return;	}#if 0	if ( have_of )	{		prom_print(s);		return;	}#endif	/*	 * can't ll_puts on chrp without openfirmware yet.	 * vidmem just needs to be setup for it.	 * -- Cort	 */	if ( _machine != _MACH_prep )		return;	x = orig_x;	y = orig_y;	while ( ( c = *s++ ) != '\0' ) {		if ( c == '\n' ) {			x = 0;			if ( ++y >= lines ) {				/*scroll();*/				/*y--;*/				y = 0;			}		} else {			vidmem [ ( x + cols * y ) * 2 ] = c;			if ( ++x >= cols ) {				x = 0;				if ( ++y >= lines ) {					/*scroll();*/					/*y--;*/					y = 0;				}			}		}	}	orig_x = x;	orig_y = y;}#endifunsigned long get_wchan(struct task_struct *p){	unsigned long ip, sp;	unsigned long stack_page = (unsigned long) p->thread_info;	int count = 0;	if (!p || p == current || p->state == TASK_RUNNING)		return 0;	sp = p->thread.ksp;	do {		sp = *(unsigned long *)sp;		if (sp < stack_page || sp >= stack_page + 8188)			return 0;		if (count > 0) {			ip = *(unsigned long *)(sp + 4);			if (!in_sched_functions(ip))				return ip;		}	} while (count++ < 16);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -