]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ux/task-ux.cpp
b78d35032f0b65562ab195b81e812db1df910563
[l4.git] / kernel / fiasco / src / kern / ux / task-ux.cpp
1 IMPLEMENTATION [ux]:
2
3 #include <sys/ptrace.h>
4 #include <sys/wait.h>
5
6 #include "cpu_lock.h"
7 #include "hostproc.h"
8 #include "lock_guard.h"
9 #include "map_util.h"
10 #include "mem_layout.h"
11
12 IMPLEMENT
13 void
14 Task::ux_init()
15 { set_pid(Hostproc::create()); }
16
17 PRIVATE inline
18 bool
19 Task::invoke_arch(L4_msg_tag &tag, Utcb *utcb)
20 {
21
22   switch (utcb->values[0])
23     {
24     case Ldt_set_x86:
25         {
26           enum
27           {
28             Utcb_values_per_ldt_entry
29               = Cpu::Ldt_entry_size / sizeof(utcb->values[0]),
30           };
31           if (EXPECT_FALSE(tag.words() < 3
32                            || tag.words() % Utcb_values_per_ldt_entry))
33             {
34               tag = commit_result(-L4_err::EInval);
35               return true;
36             }
37
38           unsigned entry_number  = utcb->values[1];
39           unsigned idx           = 2;
40           Mword *trampoline_page = (Mword *)Kmem::kernel_trampoline_page;
41
42           for (; idx < tag.words()
43               ; idx += Utcb_values_per_ldt_entry,
44               ++entry_number)
45             {
46               Gdt_entry *d = (Gdt_entry *)&utcb->values[idx];
47               if (!d->limit())
48                 continue;
49
50               Ldt_user_desc info;
51               info.entry_number    = entry_number;
52               info.base_addr       =  d->base();
53               info.limit           =  d->limit();
54               info.seg_32bit       =  d->seg32();
55               info.contents        =  d->contents();
56               info.read_exec_only  = !d->writable();
57               info.limit_in_pages  =  d->granularity();
58               info.seg_not_present = !d->present();
59               info.useable         =  d->avl();
60
61
62               // Set up data on trampoline
63               for (unsigned i = 0; i < sizeof(info) / sizeof(Mword); i++)
64                 *(trampoline_page + i + 1) = *(((Mword *)&info) + i);
65
66               // Call modify_ldt for given user process
67               Trampoline::syscall(pid(), __NR_modify_ldt,
68                                   1, // write LDT
69                                   Mem_layout::Trampoline_page + sizeof(Mword),
70                                   sizeof(info));
71
72               // Also set this for the fiasco kernel so that
73               // segment registers can be set, this is necessary for signal
74               // handling, esp. for sigreturn to work in the Fiasco kernel
75               // with the context of the client (gs/fs values).
76               if (*(trampoline_page + 1))
77                 Emulation::modify_ldt(*(trampoline_page + 1), // entry
78                                       0,                      // base
79                                       1);                     // size
80             }
81         }
82       return true;
83     }
84
85   return false;
86 }
87
88 PUBLIC
89 Task::~Task()
90 {
91   free_ku_mem();
92
93   auto guard = lock_guard(cpu_lock);
94
95   pid_t hostpid = pid();
96   ptrace (PTRACE_KILL, hostpid, NULL, NULL);
97
98   // If we crash very early in the boot process we might get a pid of 0
99   if (EXPECT_FALSE(hostpid == 0))
100     return;
101
102   while (waitpid (hostpid, NULL, 0) != hostpid)
103     ;
104 }
105
106
107 IMPLEMENT
108 void
109 Task::map_utcb_ptr_page()
110 {
111   //Mem_space::Status res =
112         static_cast<Mem_space*>(this)->v_insert(
113             Mem_space::Phys_addr::create(Mem_layout::Utcb_ptr_frame),
114             Mem_space::Addr::create(Mem_layout::Utcb_ptr_page_user),
115             Mem_space::Size::create(Config::PAGE_SIZE),
116             Mem_space::Page_writable
117             | Mem_space::Page_user_accessible
118             | Mem_space::Page_cacheable);
119 }
120