]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ux/task-ux.cpp
46f5f2eec9dbd75e1f7f7ef2a01be3175ae62bb3
[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::host_init()
15 {
16   mem_space()->set_pid (Hostproc::create());
17 }
18
19 PRIVATE inline
20 bool
21 Task::invoke_arch(L4_msg_tag &tag, Utcb *utcb)
22 {
23
24   switch (utcb->values[0])
25     {
26     case Ldt_set_x86:
27         {
28           enum
29           {
30             Utcb_values_per_ldt_entry
31               = Cpu::Ldt_entry_size / sizeof(utcb->values[0]),
32           };
33           if (EXPECT_FALSE(tag.words() < 3
34                            || tag.words() % Utcb_values_per_ldt_entry))
35             {
36               tag = commit_result(-L4_err::EInval);
37               return true;
38             }
39
40           unsigned entry_number  = utcb->values[1];
41           unsigned idx           = 2;
42           Mword *trampoline_page = (Mword *)Kmem::phys_to_virt
43                                        (Mem_layout::Trampoline_frame);
44
45           for (; idx < tag.words()
46               ; idx += Utcb_values_per_ldt_entry,
47               ++entry_number)
48             {
49               Gdt_entry *d = (Gdt_entry *)&utcb->values[idx];
50               if (!d->limit())
51                 continue;
52
53               Ldt_user_desc info;
54               info.entry_number    = entry_number;
55               info.base_addr       =  d->base();
56               info.limit           =  d->limit();
57               info.seg_32bit       =  d->seg32();
58               info.contents        =  d->contents();
59               info.read_exec_only  = !d->writable();
60               info.limit_in_pages  =  d->granularity();
61               info.seg_not_present = !d->present();
62               info.useable         =  d->avl();
63
64
65               // Set up data on trampoline
66               for (unsigned i = 0; i < sizeof(info) / sizeof(Mword); i++)
67                 *(trampoline_page + i + 1) = *(((Mword *)&info) + i);
68
69               // Call modify_ldt for given user process
70               Trampoline::syscall(pid(), __NR_modify_ldt,
71                                   1, // write LDT
72                                   Mem_layout::Trampoline_page + sizeof(Mword),
73                                   sizeof(info));
74
75               // Also set this for the fiasco kernel so that
76               // segment registers can be set, this is necessary for signal
77               // handling, esp. for sigreturn to work in the Fiasco kernel
78               // with the context of the client (gs/fs values).
79               if (*(trampoline_page + 1))
80                 Emulation::modify_ldt(*(trampoline_page + 1), // entry
81                                       0,                      // base
82                                       1);                     // size
83             }
84         }
85       return true;
86     }
87
88   return false;
89 }
90
91 /** Map tracebuffer into each userland task for easy access. */
92 IMPLEMENT
93 void
94 Task::map_tbuf ()
95 {
96   return; // FIXME
97 #if 0
98   if (id() != Config::sigma0_taskno)
99     {
100       mem_map (sigma0_task, 
101           L4_fpage(0, 1, Config::PAGE_SHIFT, 
102             Kmem::virt_to_phys ((const void*)(Mem_layout::Tbuf_status_page))),
103           nonull_static_cast<Space*>(this),    // to: space
104           L4_fpage(0, 0, Config::PAGE_SHIFT,
105             Mem_layout::Tbuf_ustatus_page, L4_fpage::Cached), 0);
106
107       for (Address size=0; size<Jdb_tbuf::size(); size+=Config::PAGE_SIZE)
108         {
109           mem_map (sigma0_task,                            // from: space
110               L4_fpage(0, 1, Config::PAGE_SHIFT,
111                 Kmem::virt_to_phys ((const void*)
112                   (Mem_layout::Tbuf_buffer_area+size))),
113               nonull_static_cast<Space*>(this),    // to: space
114               L4_fpage(0, 0, Config::PAGE_SHIFT, 
115                 Mem_layout::Tbuf_ubuffer_area+size, L4_fpage::Cached), 0);
116         }
117     }
118 #endif
119 }
120
121 IMPLEMENT
122 Task::~Task()
123 {
124   free_utcbs();
125   //_state = Dying;
126   //unregister_space();
127   //shutdown();
128   //dequeue_at_parent();
129
130 #if 0
131   if (id() == Config::kernel_taskno)
132     {
133       reset_dirty();            // Must not deallocate kernel pagetable.
134       return;                   // No need to kill kernel process.
135     }
136 #endif
137
138   Lock_guard<Cpu_lock> guard (&cpu_lock);
139
140   pid_t hostpid = pid();
141   ptrace (PTRACE_KILL, hostpid, NULL, NULL);
142
143   while (waitpid (hostpid, NULL, 0) != hostpid)
144     ;
145 }
146
147
148 IMPLEMENT
149 void
150 Task::map_utcb_ptr_page()
151 {
152   //Mem_space::Status res =
153         mem_space()->v_insert(
154             Mem_space::Phys_addr::create(Mem_layout::Utcb_ptr_frame),
155             Mem_space::Addr::create(Mem_layout::Utcb_ptr_page_user),
156             Mem_space::Size::create(Config::PAGE_SIZE),
157             Mem_space::Page_writable
158             | Mem_space::Page_user_accessible
159             | Mem_space::Page_cacheable);
160 }
161