| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 1 | /* | 
| Jeff Dike | ba180fd | 2007-10-16 01:27:00 -0700 | [diff] [blame] | 2 |  * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 3 |  * Licensed under the GPL | 
 | 4 |  */ | 
 | 5 |  | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 6 | #include "linux/init.h" | 
| Jeff Dike | ba180fd | 2007-10-16 01:27:00 -0700 | [diff] [blame] | 7 | #include "linux/sched.h" | 
| Jeff Dike | 4ff83ce | 2007-05-06 14:51:08 -0700 | [diff] [blame] | 8 | #include "as-layout.h" | 
| Jeff Dike | 3e6f2ac | 2008-02-04 22:30:58 -0800 | [diff] [blame] | 9 | #include "kern.h" | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 10 | #include "os.h" | 
| Jeff Dike | ba180fd | 2007-10-16 01:27:00 -0700 | [diff] [blame] | 11 | #include "skas.h" | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 12 |  | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 13 | int new_mm(unsigned long stack) | 
 | 14 | { | 
| Jeff Dike | 3e6f2ac | 2008-02-04 22:30:58 -0800 | [diff] [blame] | 15 | 	int fd, err; | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 16 |  | 
 | 17 | 	fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0); | 
| Jeff Dike | ba180fd | 2007-10-16 01:27:00 -0700 | [diff] [blame] | 18 | 	if (fd < 0) | 
| Jeff Dike | 77bf440 | 2007-10-16 01:26:58 -0700 | [diff] [blame] | 19 | 		return fd; | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 20 |  | 
| Jeff Dike | 3e6f2ac | 2008-02-04 22:30:58 -0800 | [diff] [blame] | 21 | 	if (skas_needs_stub) { | 
 | 22 | 		err = map_stub_pages(fd, STUB_CODE, STUB_DATA, stack); | 
 | 23 | 		if (err) { | 
 | 24 | 			os_close_file(fd); | 
 | 25 | 			return err; | 
 | 26 | 		} | 
 | 27 | 	} | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 28 |  | 
| Jeff Dike | 77bf440 | 2007-10-16 01:26:58 -0700 | [diff] [blame] | 29 | 	return fd; | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 30 | } | 
 | 31 |  | 
 | 32 | extern void start_kernel(void); | 
 | 33 |  | 
| Jeff Dike | 97a1fcb | 2007-07-23 18:43:48 -0700 | [diff] [blame] | 34 | static int __init start_kernel_proc(void *unused) | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 35 | { | 
 | 36 | 	int pid; | 
 | 37 |  | 
 | 38 | 	block_signals(); | 
 | 39 | 	pid = os_getpid(); | 
 | 40 |  | 
 | 41 | 	cpu_tasks[0].pid = pid; | 
 | 42 | 	cpu_tasks[0].task = current; | 
 | 43 | #ifdef CONFIG_SMP | 
 | 44 | 	cpu_online_map = cpumask_of_cpu(0); | 
 | 45 | #endif | 
 | 46 | 	start_kernel(); | 
| Jeff Dike | 77bf440 | 2007-10-16 01:26:58 -0700 | [diff] [blame] | 47 | 	return 0; | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 48 | } | 
 | 49 |  | 
 | 50 | extern int userspace_pid[]; | 
 | 51 |  | 
| Jeff Dike | c14b849 | 2007-05-10 22:22:34 -0700 | [diff] [blame] | 52 | extern char cpu0_irqstack[]; | 
 | 53 |  | 
| Jeff Dike | 77bf440 | 2007-10-16 01:26:58 -0700 | [diff] [blame] | 54 | int __init start_uml(void) | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 55 | { | 
| Jeff Dike | c14b849 | 2007-05-10 22:22:34 -0700 | [diff] [blame] | 56 | 	stack_protections((unsigned long) &cpu0_irqstack); | 
 | 57 | 	set_sigstack(cpu0_irqstack, THREAD_SIZE); | 
| Jeff Dike | 3e6f2ac | 2008-02-04 22:30:58 -0800 | [diff] [blame] | 58 | 	if (proc_mm) { | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 59 | 		userspace_pid[0] = start_userspace(0); | 
| Jeff Dike | 3e6f2ac | 2008-02-04 22:30:58 -0800 | [diff] [blame] | 60 | 		if (userspace_pid[0] < 0) { | 
 | 61 | 			printf("start_uml - start_userspace returned %d\n", | 
 | 62 | 			       userspace_pid[0]); | 
 | 63 | 			exit(1); | 
 | 64 | 		} | 
 | 65 | 	} | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 66 |  | 
 | 67 | 	init_new_thread_signals(); | 
 | 68 |  | 
 | 69 | 	init_task.thread.request.u.thread.proc = start_kernel_proc; | 
 | 70 | 	init_task.thread.request.u.thread.arg = NULL; | 
| Jeff Dike | 77bf440 | 2007-10-16 01:26:58 -0700 | [diff] [blame] | 71 | 	return start_idle_thread(task_stack_page(&init_task), | 
 | 72 | 				 &init_task.thread.switch_buf); | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 73 | } | 
 | 74 |  | 
 | 75 | unsigned long current_stub_stack(void) | 
 | 76 | { | 
| Jeff Dike | ba180fd | 2007-10-16 01:27:00 -0700 | [diff] [blame] | 77 | 	if (current->mm == NULL) | 
| Jeff Dike | 77bf440 | 2007-10-16 01:26:58 -0700 | [diff] [blame] | 78 | 		return 0; | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 79 |  | 
| Jeff Dike | 6c738ff | 2007-10-16 01:27:06 -0700 | [diff] [blame] | 80 | 	return current->mm->context.id.stack; | 
| Jeff Dike | 995473a | 2006-09-27 01:50:40 -0700 | [diff] [blame] | 81 | } |