]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ux/hostproc.cpp
dcde10e6f893a40cd7f68bc07ed2c1599761567c
[l4.git] / kernel / fiasco / src / kern / ux / hostproc.cpp
1
2 /*
3  * Fiasco-UX
4  * Functions for setting up host processes implementing tasks
5  */
6
7 INTERFACE:
8
9 class Hostproc
10 {};
11
12 IMPLEMENTATION:
13
14 #include <asm/unistd.h>
15 #include <sys/mman.h>
16 #include <sys/ptrace.h>
17 #include <sys/types.h>
18 #include <sys/wait.h>
19 #include <cassert>
20 #include <csignal>
21 #include <cstdio>
22 #include <cstring>
23 #include <unistd.h>
24 #include "boot_info.h"
25 #include "config.h"
26 #include "cpu_lock.h"
27 #include "globals.h"
28 #include "lock_guard.h"
29 #include "mem_layout.h"
30 #include "panic.h"
31 #include "trampoline.h"
32
33 PRIVATE static
34 void
35 Hostproc::setup()
36 {
37   char **args = Boot_info::args();
38   size_t arglen = 0;
39
40   // Zero all args, making ps output pretty
41   do arglen += strlen (*args) + 1; while (*++args);
42   memset (*Boot_info::args(), 0, arglen); 
43
44   // Put task number into argv[0] for ps
45   snprintf (*Boot_info::args(), arglen, "[Task]");
46
47   fclose (stdin);
48   fclose (stdout);
49   fclose (stderr);
50
51   sigset_t mask;
52   sigfillset (&mask);
53   check (!sigprocmask (SIG_UNBLOCK, &mask, NULL));
54
55   stack_t stack;
56   stack.ss_sp    = (void *) Mem_layout::Trampoline_page;
57   stack.ss_size  = Config::PAGE_SIZE;
58   stack.ss_flags = 0;
59   check (!sigaltstack (&stack, NULL));
60
61   struct sigaction action;
62   sigfillset (&action.sa_mask);
63   action.sa_flags     = SA_ONSTACK | SA_SIGINFO;
64   action.sa_restorer  = (void (*)()) 0xDEADC0DE;
65   action.sa_sigaction = (void (*)(int,siginfo_t*,void*)) 
66                             Mem_layout::Trampoline_page;
67   check (!sigaction (SIGSEGV, &action, NULL));
68
69   // Map trampoline page
70   check (mmap ((void *) Mem_layout::Trampoline_page,
71          Config::PAGE_SIZE,
72              PROT_READ | PROT_WRITE | PROT_EXEC,
73              MAP_SHARED | MAP_FIXED,
74          Boot_info::fd(),
75          Mem_layout::Trampoline_frame) != MAP_FAILED);
76
77   ptrace (PTRACE_TRACEME, 0, NULL, NULL);
78
79   raise (SIGUSR1);
80 }
81
82 PUBLIC static
83 unsigned
84 Hostproc::create()
85 {
86   Lock_guard <Cpu_lock> guard (&cpu_lock);
87
88   static pid_t pid;
89   static unsigned esp;
90
91   /*
92    * Careful with local variables here because we are changing the
93    * stack pointer for the fork system call. This ensures that the
94    * child gets its own COW stack rather than running on the parent
95    * stack.
96    */      
97   asm volatile ("movl %%esp, %0; movl %1, %%esp" :
98                 "=m" (esp), "=m" (boot_stack));
99
100   // Make sure the child doesn't inherit any of our unflushed output
101   fflush (NULL);
102
103   switch (pid = fork())
104     {
105       case -1:                            // Failed
106         return 0;
107       
108       case 0:                             // Child
109         setup();
110         _exit(1);                        // unreached
111         
112       default:                            // Parent
113         asm volatile ("movl %0, %%esp" : : "m" (esp));
114       
115         int status;
116         check (waitpid (pid, &status, 0) == pid);
117         assert (WIFSTOPPED (status) && WSTOPSIG (status) == SIGUSR1);
118       
119         Trampoline::syscall (pid, __NR_munmap, 0, Mem_layout::Trampoline_page);
120         return pid;
121     }
122 }