2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
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"
20 #include "user_util.h"
25 #include "registers.h"
27 void *switch_to_skas(void *prev
, void *next
)
29 struct task_struct
*from
, *to
;
34 /* XXX need to check runqueues[cpu].idle */
38 to
->thread
.prev_sched
= from
;
41 switch_threads(&from
->thread
.mode
.skas
.switch_buf
,
42 to
->thread
.mode
.skas
.switch_buf
);
47 return(current
->thread
.prev_sched
);
50 extern void schedule_tail(struct task_struct
*prev
);
52 void new_thread_handler(int sig
)
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
);
63 if(current
->thread
.prev_sched
!= NULL
)
64 schedule_tail(current
->thread
.prev_sched
);
65 current
->thread
.prev_sched
= NULL
;
67 /* The return value is 1 if the kernel thread execs a process,
70 n
= run_kernel_thread(fn
, arg
, ¤t
->thread
.exec_buf
);
72 /* Handle any immediate reschedules or signals */
74 userspace(¤t
->thread
.regs
.regs
);
79 void new_thread_proc(void *stack
, void (*handler
)(int sig
))
81 init_new_thread_stack(stack
, handler
);
82 os_usr1_process(os_getpid());
85 void release_thread_skas(struct task_struct
*task
)
89 void fork_handler(int sig
)
91 change_sig(SIGUSR1
, 1);
92 thread_wait(¤t
->thread
.mode
.skas
.switch_buf
,
93 current
->thread
.mode
.skas
.fork_buf
);
96 if(current
->thread
.prev_sched
== NULL
)
99 schedule_tail(current
->thread
.prev_sched
);
100 current
->thread
.prev_sched
= NULL
;
102 /* Handle any immediate reschedules or signals */
104 userspace(¤t
->thread
.regs
.regs
);
107 int copy_thread_skas(int nr
, unsigned long clone_flags
, unsigned long sp
,
108 unsigned long stack_top
, struct task_struct
* p
,
109 struct pt_regs
*regs
)
111 void (*handler
)(int);
113 if(current
->thread
.forking
){
114 memcpy(&p
->thread
.regs
.regs
.skas
, ®s
->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
;
119 handler
= fork_handler
;
122 init_thread_registers(&p
->thread
.regs
.regs
);
123 p
->thread
.request
.u
.thread
= current
->thread
.request
.u
.thread
;
124 handler
= new_thread_handler
;
127 new_thread(p
->thread_info
, &p
->thread
.mode
.skas
.switch_buf
,
128 &p
->thread
.mode
.skas
.fork_buf
, handler
);
132 extern void map_stub_pages(int fd
, unsigned long code
,
133 unsigned long data
, unsigned long stack
);
134 int new_mm(int from
, unsigned long stack
)
136 struct proc_mm_op copy
;
139 fd
= os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
144 copy
= ((struct proc_mm_op
) { .op
= MM_COPY_SEGMENTS
,
146 { .copy_segments
= from
} } );
147 n
= os_write_file(fd
, ©
, sizeof(copy
));
148 if(n
!= sizeof(copy
))
149 printk("new_mm : /proc/mm copy_segments failed, "
153 if(!ptrace_faultinfo
)
154 map_stub_pages(fd
, CONFIG_STUB_CODE
, CONFIG_STUB_DATA
, stack
);
159 void init_idle_skas(void)
161 cpu_tasks
[current_thread
->cpu
].pid
= os_getpid();
165 extern void start_kernel(void);
167 static int start_kernel_proc(void *unused
)
174 cpu_tasks
[0].pid
= pid
;
175 cpu_tasks
[0].task
= current
;
177 cpu_online_map
= cpumask_of_cpu(0);
183 extern int userspace_pid
[];
185 int start_uml_skas(void)
188 userspace_pid
[0] = start_userspace(0);
190 init_new_thread_signals(1);
192 init_task
.thread
.request
.u
.thread
.proc
= start_kernel_proc
;
193 init_task
.thread
.request
.u
.thread
.arg
= NULL
;
194 return(start_idle_thread(init_task
.thread_info
,
195 &init_task
.thread
.mode
.skas
.switch_buf
,
196 &init_task
.thread
.mode
.skas
.fork_buf
));
199 int external_pid_skas(struct task_struct
*task
)
201 #warning Need to look up userspace_pid by cpu
202 return(userspace_pid
[0]);
205 int thread_pid_skas(struct task_struct
*task
)
207 #warning Need to look up userspace_pid by cpu
208 return(userspace_pid
[0]);
211 void kill_off_processes_skas(void)
214 #warning need to loop over userspace_pids in kill_off_processes_skas
215 os_kill_ptraced_process(userspace_pid
[0], 1);
217 struct task_struct
*p
;
225 pid
= p
->mm
->context
.skas
.id
.u
.pid
;
226 os_kill_ptraced_process(pid
, 1);
231 unsigned long current_stub_stack(void)
233 if(current
->mm
== NULL
)
236 return(current
->mm
->context
.skas
.id
.stack
);