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

📄 process.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		err = ptrace(op, pid, 0, 0);		if (err)			panic("userspace - could not resume userspace process, "			      "pid=%d, ptrace operation = %d, errno = %d\n",			      pid, op, errno);		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL));		if (err < 0)			panic("userspace - waitpid failed, errno = %d\n",			      errno);		regs->is_user = 1;		save_registers(pid, regs);		UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */		if (WIFSTOPPED(status)) {			int sig = WSTOPSIG(status);		  	switch(sig) {			case SIGSEGV:				if (PTRACE_FULL_FAULTINFO ||				    !ptrace_faultinfo) {					get_skas_faultinfo(pid,							   &regs->faultinfo);					(*sig_info[SIGSEGV])(SIGSEGV, regs);				}				else handle_segv(pid, regs);				break;			case SIGTRAP + 0x80:			        handle_trap(pid, regs, local_using_sysemu);				break;			case SIGTRAP:				relay_signal(SIGTRAP, regs);				break;			case SIGVTALRM:				now = os_nsecs();				if(now < nsecs)					break;				block_signals();				(*sig_info[sig])(sig, regs);				unblock_signals();				nsecs = timer.it_value.tv_sec *					UM_NSEC_PER_SEC +					timer.it_value.tv_usec *					UM_NSEC_PER_USEC;				nsecs += os_nsecs();				break;			case SIGIO:			case SIGILL:			case SIGBUS:			case SIGFPE:			case SIGWINCH:				block_signals();				(*sig_info[sig])(sig, regs);				unblock_signals();				break;			default:			        printk(UM_KERN_ERR "userspace - child stopped "				       "with signal %d\n", sig);			}			pid = userspace_pid[0];			interrupt_end();			/* Avoid -ERESTARTSYS handling in host */			if (PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET)				PT_SYSCALL_NR(regs->gp) = -1;		}	}}static unsigned long thread_regs[MAX_REG_NR];static int __init init_thread_regs(void){	get_safe_registers(thread_regs);	/* Set parent's instruction pointer to start of clone-stub */	thread_regs[REGS_IP_INDEX] = STUB_CODE +				(unsigned long) stub_clone_handler -				(unsigned long) &__syscall_stub_start;	thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE -		sizeof(void *);#ifdef __SIGNAL_FRAMESIZE	thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;#endif	return 0;}__initcall(init_thread_regs);int copy_context_skas0(unsigned long new_stack, int pid){	struct timeval tv = { .tv_sec = 0, .tv_usec = UM_USEC_PER_SEC / UM_HZ };	int err;	unsigned long current_stack = current_stub_stack();	struct stub_data *data = (struct stub_data *) current_stack;	struct stub_data *child_data = (struct stub_data *) new_stack;	unsigned long long new_offset;	int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);	/*	 * prepare offset and fd of child's stack as argument for parent's	 * and child's mmap2 calls	 */	*data = ((struct stub_data) { .offset	= MMAP_OFFSET(new_offset),				      .fd	= new_fd,				      .timer    = ((struct itimerval)					           { .it_value = tv,						     .it_interval = tv }) });	err = ptrace_setregs(pid, thread_regs);	if (err < 0)		panic("copy_context_skas0 : PTRACE_SETREGS failed, "		      "pid = %d, errno = %d\n", pid, -err);	/* set a well known return code for detection of child write failure */	child_data->err = 12345678;	/*	 * Wait, until parent has finished its work: read child's pid from	 * parent's stack, and check, if bad result.	 */	err = ptrace(PTRACE_CONT, pid, 0, 0);	if (err)		panic("Failed to continue new process, pid = %d, "		      "errno = %d\n", pid, errno);	wait_stub_done(pid);	pid = data->err;	if (pid < 0)		panic("copy_context_skas0 - stub-parent reports error %d\n",		      -pid);	/*	 * Wait, until child has finished too: read child's result from	 * child's stack and check it.	 */	wait_stub_done(pid);	if (child_data->err != STUB_DATA)		panic("copy_context_skas0 - stub-child reports error %ld\n",		      child_data->err);	if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,		   (void *)PTRACE_O_TRACESYSGOOD) < 0)		panic("copy_context_skas0 : PTRACE_OLDSETOPTIONS failed, "		      "errno = %d\n", errno);	return pid;}/* * This is used only, if stub pages are needed, while proc_mm is * available. Opening /proc/mm creates a new mm_context, which lacks * the stub-pages. Thus, we map them using /proc/mm-fd */void map_stub_pages(int fd, unsigned long code,		    unsigned long data, unsigned long stack){	struct proc_mm_op mmop;	int n;	unsigned long long code_offset;	int code_fd = phys_mapping(to_phys((void *) &__syscall_stub_start),				   &code_offset);	mmop = ((struct proc_mm_op) { .op        = MM_MMAP,				      .u         =				      { .mmap    =					{ .addr    = code,					  .len     = UM_KERN_PAGE_SIZE,					  .prot    = PROT_EXEC,					  .flags   = MAP_FIXED | MAP_PRIVATE,					  .fd      = code_fd,					  .offset  = code_offset	} } });	CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));	if (n != sizeof(mmop)) {		n = errno;		printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, "		       "offset = %llx\n", code, code_fd,		       (unsigned long long) code_offset);		panic("map_stub_pages : /proc/mm map for code failed, "		      "err = %d\n", n);	}	if (stack) {		unsigned long long map_offset;		int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);		mmop = ((struct proc_mm_op)				{ .op        = MM_MMAP,				  .u         =				  { .mmap    =				    { .addr    = data,				      .len     = UM_KERN_PAGE_SIZE,				      .prot    = PROT_READ | PROT_WRITE,				      .flags   = MAP_FIXED | MAP_SHARED,				      .fd      = map_fd,				      .offset  = map_offset		} } });		CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));		if (n != sizeof(mmop))			panic("map_stub_pages : /proc/mm map for data failed, "			      "err = %d\n", errno);	}}void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)){	(*buf)[0].JB_IP = (unsigned long) handler;	(*buf)[0].JB_SP = (unsigned long) stack + UM_THREAD_SIZE -		sizeof(void *);}#define INIT_JMP_NEW_THREAD 0#define INIT_JMP_CALLBACK 1#define INIT_JMP_HALT 2#define INIT_JMP_REBOOT 3void switch_threads(jmp_buf *me, jmp_buf *you){	if (UML_SETJMP(me) == 0)		UML_LONGJMP(you, 1);}static jmp_buf initial_jmpbuf;/* XXX Make these percpu */static void (*cb_proc)(void *arg);static void *cb_arg;static jmp_buf *cb_back;int start_idle_thread(void *stack, jmp_buf *switch_buf){	int n;	set_handler(SIGWINCH, (__sighandler_t) sig_handler,		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGVTALRM, -1);	/*	 * Can't use UML_SETJMP or UML_LONGJMP here because they save	 * and restore signals, with the possible side-effect of	 * trying to handle any signals which came when they were	 * blocked, which can't be done on this stack.	 * Signals must be blocked when jumping back here and restored	 * after returning to the jumper.	 */	n = setjmp(initial_jmpbuf);	switch(n) {	case INIT_JMP_NEW_THREAD:		(*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;		(*switch_buf)[0].JB_SP = (unsigned long) stack +			UM_THREAD_SIZE - sizeof(void *);		break;	case INIT_JMP_CALLBACK:		(*cb_proc)(cb_arg);		longjmp(*cb_back, 1);		break;	case INIT_JMP_HALT:		kmalloc_ok = 0;		return 0;	case INIT_JMP_REBOOT:		kmalloc_ok = 0;		return 1;	default:		panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);	}	longjmp(*switch_buf, 1);}void initial_thread_cb_skas(void (*proc)(void *), void *arg){	jmp_buf here;	cb_proc = proc;	cb_arg = arg;	cb_back = &here;	block_signals();	if (UML_SETJMP(&here) == 0)		UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);	unblock_signals();	cb_proc = NULL;	cb_arg = NULL;	cb_back = NULL;}void halt_skas(void){	block_signals();	UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT);}void reboot_skas(void){	block_signals();	UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT);}void __switch_mm(struct mm_id *mm_idp){	int err;	/* FIXME: need cpu pid in __switch_mm */	if (proc_mm) {		err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,			     mm_idp->u.mm_fd);		if (err)			panic("__switch_mm - PTRACE_SWITCH_MM failed, "			      "errno = %d\n", errno);	}	else userspace_pid[0] = mm_idp->u.pid;}

⌨️ 快捷键说明

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