diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/um/kernel/skas/process_kern.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/um/kernel/skas/process_kern.c')
-rw-r--r-- | arch/um/kernel/skas/process_kern.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c new file mode 100644 index 000000000000..5d096ea63b97 --- /dev/null +++ b/arch/um/kernel/skas/process_kern.c | |||
@@ -0,0 +1,213 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include "linux/sched.h" | ||
7 | #include "linux/slab.h" | ||
8 | #include "linux/ptrace.h" | ||
9 | #include "linux/proc_fs.h" | ||
10 | #include "linux/file.h" | ||
11 | #include "linux/errno.h" | ||
12 | #include "linux/init.h" | ||
13 | #include "asm/uaccess.h" | ||
14 | #include "asm/atomic.h" | ||
15 | #include "kern_util.h" | ||
16 | #include "time_user.h" | ||
17 | #include "signal_user.h" | ||
18 | #include "skas.h" | ||
19 | #include "os.h" | ||
20 | #include "user_util.h" | ||
21 | #include "tlb.h" | ||
22 | #include "kern.h" | ||
23 | #include "mode.h" | ||
24 | #include "proc_mm.h" | ||
25 | #include "registers.h" | ||
26 | |||
27 | void *switch_to_skas(void *prev, void *next) | ||
28 | { | ||
29 | struct task_struct *from, *to; | ||
30 | |||
31 | from = prev; | ||
32 | to = next; | ||
33 | |||
34 | /* XXX need to check runqueues[cpu].idle */ | ||
35 | if(current->pid == 0) | ||
36 | switch_timers(0); | ||
37 | |||
38 | to->thread.prev_sched = from; | ||
39 | set_current(to); | ||
40 | |||
41 | switch_threads(&from->thread.mode.skas.switch_buf, | ||
42 | to->thread.mode.skas.switch_buf); | ||
43 | |||
44 | if(current->pid == 0) | ||
45 | switch_timers(1); | ||
46 | |||
47 | return(current->thread.prev_sched); | ||
48 | } | ||
49 | |||
50 | extern void schedule_tail(struct task_struct *prev); | ||
51 | |||
52 | void new_thread_handler(int sig) | ||
53 | { | ||
54 | int (*fn)(void *), n; | ||
55 | void *arg; | ||
56 | |||
57 | fn = current->thread.request.u.thread.proc; | ||
58 | arg = current->thread.request.u.thread.arg; | ||
59 | change_sig(SIGUSR1, 1); | ||
60 | thread_wait(¤t->thread.mode.skas.switch_buf, | ||
61 | current->thread.mode.skas.fork_buf); | ||
62 | |||
63 | if(current->thread.prev_sched != NULL) | ||
64 | schedule_tail(current->thread.prev_sched); | ||
65 | current->thread.prev_sched = NULL; | ||
66 | |||
67 | /* The return value is 1 if the kernel thread execs a process, | ||
68 | * 0 if it just exits | ||
69 | */ | ||
70 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); | ||
71 | if(n == 1) | ||
72 | userspace(¤t->thread.regs.regs); | ||
73 | else do_exit(0); | ||
74 | } | ||
75 | |||
76 | void new_thread_proc(void *stack, void (*handler)(int sig)) | ||
77 | { | ||
78 | init_new_thread_stack(stack, handler); | ||
79 | os_usr1_process(os_getpid()); | ||
80 | } | ||
81 | |||
82 | void release_thread_skas(struct task_struct *task) | ||
83 | { | ||
84 | } | ||
85 | |||
86 | void exit_thread_skas(void) | ||
87 | { | ||
88 | } | ||
89 | |||
90 | void fork_handler(int sig) | ||
91 | { | ||
92 | change_sig(SIGUSR1, 1); | ||
93 | thread_wait(¤t->thread.mode.skas.switch_buf, | ||
94 | current->thread.mode.skas.fork_buf); | ||
95 | |||
96 | force_flush_all(); | ||
97 | if(current->thread.prev_sched == NULL) | ||
98 | panic("blech"); | ||
99 | |||
100 | schedule_tail(current->thread.prev_sched); | ||
101 | current->thread.prev_sched = NULL; | ||
102 | |||
103 | userspace(¤t->thread.regs.regs); | ||
104 | } | ||
105 | |||
106 | int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, | ||
107 | unsigned long stack_top, struct task_struct * p, | ||
108 | struct pt_regs *regs) | ||
109 | { | ||
110 | void (*handler)(int); | ||
111 | |||
112 | if(current->thread.forking){ | ||
113 | memcpy(&p->thread.regs.regs.skas, | ||
114 | ¤t->thread.regs.regs.skas, | ||
115 | sizeof(p->thread.regs.regs.skas)); | ||
116 | REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0); | ||
117 | if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp; | ||
118 | |||
119 | handler = fork_handler; | ||
120 | } | ||
121 | else { | ||
122 | init_thread_registers(&p->thread.regs.regs); | ||
123 | p->thread.request.u.thread = current->thread.request.u.thread; | ||
124 | handler = new_thread_handler; | ||
125 | } | ||
126 | |||
127 | new_thread(p->thread_info, &p->thread.mode.skas.switch_buf, | ||
128 | &p->thread.mode.skas.fork_buf, handler); | ||
129 | return(0); | ||
130 | } | ||
131 | |||
132 | int new_mm(int from) | ||
133 | { | ||
134 | struct proc_mm_op copy; | ||
135 | int n, fd; | ||
136 | |||
137 | fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0); | ||
138 | if(fd < 0) | ||
139 | return(fd); | ||
140 | |||
141 | if(from != -1){ | ||
142 | copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS, | ||
143 | .u = | ||
144 | { .copy_segments = from } } ); | ||
145 | n = os_write_file(fd, ©, sizeof(copy)); | ||
146 | if(n != sizeof(copy)) | ||
147 | printk("new_mm : /proc/mm copy_segments failed, " | ||
148 | "err = %d\n", -n); | ||
149 | } | ||
150 | |||
151 | return(fd); | ||
152 | } | ||
153 | |||
154 | void init_idle_skas(void) | ||
155 | { | ||
156 | cpu_tasks[current_thread->cpu].pid = os_getpid(); | ||
157 | default_idle(); | ||
158 | } | ||
159 | |||
160 | extern void start_kernel(void); | ||
161 | |||
162 | static int start_kernel_proc(void *unused) | ||
163 | { | ||
164 | int pid; | ||
165 | |||
166 | block_signals(); | ||
167 | pid = os_getpid(); | ||
168 | |||
169 | cpu_tasks[0].pid = pid; | ||
170 | cpu_tasks[0].task = current; | ||
171 | #ifdef CONFIG_SMP | ||
172 | cpu_online_map = cpumask_of_cpu(0); | ||
173 | #endif | ||
174 | start_kernel(); | ||
175 | return(0); | ||
176 | } | ||
177 | |||
178 | int start_uml_skas(void) | ||
179 | { | ||
180 | start_userspace(0); | ||
181 | |||
182 | init_new_thread_signals(1); | ||
183 | uml_idle_timer(); | ||
184 | |||
185 | init_task.thread.request.u.thread.proc = start_kernel_proc; | ||
186 | init_task.thread.request.u.thread.arg = NULL; | ||
187 | return(start_idle_thread(init_task.thread_info, | ||
188 | &init_task.thread.mode.skas.switch_buf, | ||
189 | &init_task.thread.mode.skas.fork_buf)); | ||
190 | } | ||
191 | |||
192 | int external_pid_skas(struct task_struct *task) | ||
193 | { | ||
194 | #warning Need to look up userspace_pid by cpu | ||
195 | return(userspace_pid[0]); | ||
196 | } | ||
197 | |||
198 | int thread_pid_skas(struct task_struct *task) | ||
199 | { | ||
200 | #warning Need to look up userspace_pid by cpu | ||
201 | return(userspace_pid[0]); | ||
202 | } | ||
203 | |||
204 | /* | ||
205 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
206 | * Emacs will notice this stuff at the end of the file and automatically | ||
207 | * adjust the settings for this buffer only. This must remain at the end | ||
208 | * of the file. | ||
209 | * --------------------------------------------------------------------------- | ||
210 | * Local variables: | ||
211 | * c-file-style: "linux" | ||
212 | * End: | ||
213 | */ | ||