aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/os-Linux/skas/process.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 31c9be2c2bdd..819d68656673 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -108,7 +108,7 @@ static void get_skas_faultinfo(int pid, struct faultinfo *fi)
108 wait_stub_done(pid); 108 wait_stub_done(pid);
109 109
110 /* 110 /*
111 * faultinfo is prepared by the stub-segv-handler at start of 111 * faultinfo is prepared by the stub_segv_handler at start of
112 * the stub stack page. We just have to copy it. 112 * the stub stack page. We just have to copy it.
113 */ 113 */
114 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); 114 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
@@ -175,6 +175,21 @@ static void handle_trap(int pid, struct uml_pt_regs *regs,
175 175
176extern char __syscall_stub_start[]; 176extern char __syscall_stub_start[];
177 177
178/**
179 * userspace_tramp() - userspace trampoline
180 * @stack: pointer to the new userspace stack page, can be NULL, if? FIXME:
181 *
182 * The userspace trampoline is used to setup a new userspace process in start_userspace() after it was clone()'ed.
183 * This function will run on a temporary stack page.
184 * It ptrace()'es itself, then
185 * Two pages are mapped into the userspace address space:
186 * - STUB_CODE (with EXEC), which contains the skas stub code
187 * - STUB_DATA (with R/W), which contains a data page that is used to transfer certain data between the UML userspace process and the UML kernel.
188 * Also for the userspace process a SIGSEGV handler is installed to catch pagefaults in the userspace process.
189 * And last the process stops itself to give control to the UML kernel for this userspace process.
190 *
191 * Return: Always zero, otherwise the current userspace process is ended with non null exit() call
192 */
178static int userspace_tramp(void *stack) 193static int userspace_tramp(void *stack)
179{ 194{
180 void *addr; 195 void *addr;
@@ -236,12 +251,24 @@ static int userspace_tramp(void *stack)
236 251
237int userspace_pid[NR_CPUS]; 252int userspace_pid[NR_CPUS];
238 253
254/**
255 * start_userspace() - prepare a new userspace process
256 * @stub_stack: pointer to the stub stack. Can be NULL, if? FIXME:
257 *
258 * Setups a new temporary stack page that is used while userspace_tramp() runs
259 * Clones the kernel process into a new userspace process, with FDs only.
260 *
261 * Return: When positive: the process id of the new userspace process,
262 * when negative: an error number.
263 * FIXME: can PIDs become negative?!
264 */
239int start_userspace(unsigned long stub_stack) 265int start_userspace(unsigned long stub_stack)
240{ 266{
241 void *stack; 267 void *stack;
242 unsigned long sp; 268 unsigned long sp;
243 int pid, status, n, flags, err; 269 int pid, status, n, flags, err;
244 270
271 /* setup a temporary stack page */
245 stack = mmap(NULL, UM_KERN_PAGE_SIZE, 272 stack = mmap(NULL, UM_KERN_PAGE_SIZE,
246 PROT_READ | PROT_WRITE | PROT_EXEC, 273 PROT_READ | PROT_WRITE | PROT_EXEC,
247 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 274 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
@@ -252,10 +279,12 @@ int start_userspace(unsigned long stub_stack)
252 return err; 279 return err;
253 } 280 }
254 281
282 /* set stack pointer to the end of the stack page, so it can grow downwards */
255 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); 283 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
256 284
257 flags = CLONE_FILES | SIGCHLD; 285 flags = CLONE_FILES | SIGCHLD;
258 286
287 /* clone into new userspace process */
259 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); 288 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
260 if (pid < 0) { 289 if (pid < 0) {
261 err = -errno; 290 err = -errno;