blob: 2e9852c0d487449911fc289e3520a90e6306f9b9 [file] [log] [blame]
Jeff Dike995473a2006-09-27 01:50:40 -07001/*
Jeff Dikeba180fd2007-10-16 01:27:00 -07002 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
Jeff Dike995473a2006-09-27 01:50:40 -07003 * Licensed under the GPL
4 */
5
Jeff Dike995473a2006-09-27 01:50:40 -07006#include "linux/init.h"
Jeff Dikeba180fd2007-10-16 01:27:00 -07007#include "linux/sched.h"
Jeff Dike4ff83ce2007-05-06 14:51:08 -07008#include "as-layout.h"
Jeff Dike3e6f2ac2008-02-04 22:30:58 -08009#include "kern.h"
Jeff Dike995473a2006-09-27 01:50:40 -070010#include "os.h"
Jeff Dikeba180fd2007-10-16 01:27:00 -070011#include "skas.h"
Jeff Dike995473a2006-09-27 01:50:40 -070012
Jeff Dike995473a2006-09-27 01:50:40 -070013int new_mm(unsigned long stack)
14{
Jeff Dike3e6f2ac2008-02-04 22:30:58 -080015 int fd, err;
Jeff Dike995473a2006-09-27 01:50:40 -070016
17 fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
Jeff Dikeba180fd2007-10-16 01:27:00 -070018 if (fd < 0)
Jeff Dike77bf4402007-10-16 01:26:58 -070019 return fd;
Jeff Dike995473a2006-09-27 01:50:40 -070020
Jeff Dike3e6f2ac2008-02-04 22:30:58 -080021 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 Dike995473a2006-09-27 01:50:40 -070028
Jeff Dike77bf4402007-10-16 01:26:58 -070029 return fd;
Jeff Dike995473a2006-09-27 01:50:40 -070030}
31
32extern void start_kernel(void);
33
Jeff Dike97a1fcb2007-07-23 18:43:48 -070034static int __init start_kernel_proc(void *unused)
Jeff Dike995473a2006-09-27 01:50:40 -070035{
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 Dike77bf4402007-10-16 01:26:58 -070047 return 0;
Jeff Dike995473a2006-09-27 01:50:40 -070048}
49
50extern int userspace_pid[];
51
Jeff Dikec14b8492007-05-10 22:22:34 -070052extern char cpu0_irqstack[];
53
Jeff Dike77bf4402007-10-16 01:26:58 -070054int __init start_uml(void)
Jeff Dike995473a2006-09-27 01:50:40 -070055{
Jeff Dikec14b8492007-05-10 22:22:34 -070056 stack_protections((unsigned long) &cpu0_irqstack);
57 set_sigstack(cpu0_irqstack, THREAD_SIZE);
Jeff Dike3e6f2ac2008-02-04 22:30:58 -080058 if (proc_mm) {
Jeff Dike995473a2006-09-27 01:50:40 -070059 userspace_pid[0] = start_userspace(0);
Jeff Dike3e6f2ac2008-02-04 22:30:58 -080060 if (userspace_pid[0] < 0) {
61 printf("start_uml - start_userspace returned %d\n",
62 userspace_pid[0]);
63 exit(1);
64 }
65 }
Jeff Dike995473a2006-09-27 01:50:40 -070066
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 Dike77bf4402007-10-16 01:26:58 -070071 return start_idle_thread(task_stack_page(&init_task),
72 &init_task.thread.switch_buf);
Jeff Dike995473a2006-09-27 01:50:40 -070073}
74
75unsigned long current_stub_stack(void)
76{
Jeff Dikeba180fd2007-10-16 01:27:00 -070077 if (current->mm == NULL)
Jeff Dike77bf4402007-10-16 01:26:58 -070078 return 0;
Jeff Dike995473a2006-09-27 01:50:40 -070079
Jeff Dike6c738ff2007-10-16 01:27:06 -070080 return current->mm->context.id.stack;
Jeff Dike995473a2006-09-27 01:50:40 -070081}