77 |
Pistachio Patch |
Pistachio Patch |
78 |
--------------- |
--------------- |
79 |
|
|
80 |
|
There are a couple of patches you need to apply to the L4 kernel to be |
81 |
|
able to use it with the Hurd on L4 servers. These patches add missing |
82 |
|
features, or tweak the kernel interfaces to meet our requirements. |
83 |
|
|
84 |
|
You can apply all patches in one go by changing your working directory |
85 |
|
to the pistachio source tree, and feed this README file through patch: |
86 |
|
|
87 |
|
$ cd pistachio |
88 |
|
$ patch -p1 < /my/path/to/hurd-l4/README |
89 |
|
|
90 |
The following patch fixes a problem with IPC propagation and with |
The following patch fixes a problem with IPC propagation and with |
91 |
receiving from any local thread. |
receiving from any local thread. |
92 |
|
|
108 |
RCS file: /public-cvs/pistachio/kernel/src/api/v4/ipc.cc,v |
RCS file: /public-cvs/pistachio/kernel/src/api/v4/ipc.cc,v |
109 |
retrieving revision 1.57.4.6 |
retrieving revision 1.57.4.6 |
110 |
diff -u -r1.57.4.6 ipc.cc |
diff -u -r1.57.4.6 ipc.cc |
111 |
--- kernel/src/api/v4/ipc.cc 3 Jun 2004 13:58:57 -0000 1.57.4.6 |
--- pistachio/kernel/src/api/v4/ipc.cc 3 Jun 2004 13:58:57 -0000 1.57.4.6 |
112 |
+++ kernel/src/api/v4/ipc.cc 23 Oct 2004 00:33:45 -0000 |
+++ pistachio/kernel/src/api/v4/ipc.cc 23 Oct 2004 00:33:45 -0000 |
113 |
@@ -292,6 +292,9 @@ |
@@ -292,6 +292,9 @@ |
114 |
&& (current->get_space() == virt_sender->get_space() || |
&& (current->get_space() == virt_sender->get_space() || |
115 |
current->get_space() == to_tcb->get_space())) |
current->get_space() == to_tcb->get_space())) |
158 |
|
|
159 |
TRACE_IPC("receive phase curr=%t, from=%t\n", current, from_tcb); |
TRACE_IPC("receive phase curr=%t, from=%t\n", current, from_tcb); |
160 |
|
|
161 |
|
|
162 |
|
The following patch adds support for the ELF TLS ABI to |
163 |
|
L4Ka::Pistachio. |
164 |
|
|
165 |
|
This is based on Espen's suggestion to use %gs:4 instead of %gs:0 for |
166 |
|
the UTCB, to free %gs:0 for the ELF thread pointer. |
167 |
|
|
168 |
|
I am not sure this patch helps anybody here. It certainly won't do |
169 |
|
the trick for the L4Linux guys. But it opens a compromise path were |
170 |
|
L4 still supports the ELF standard (although not the GNU variant) on |
171 |
|
ia32. |
172 |
|
|
173 |
|
I am posting this patch just so that you know what I am up to, and to |
174 |
|
define more precisely one of the possible options in the stale-mate |
175 |
|
ELF TLS ABI vs L4 ABI discussion. I will also work on alternatives to |
176 |
|
this, so this is not the last word. |
177 |
|
|
178 |
|
I chose to not save/restore the value in %gs:0, but to add a system |
179 |
|
call to set it. This is the simplest approach I can think of, and |
180 |
|
should also be the fastest for now, as setting the value is rare (if |
181 |
|
you have one user thread per kernel thread). I also put the value |
182 |
|
into the kernel tcb, not in the UTCB, because I think this matches |
183 |
|
existing precedence (ie, on ia64, gr13 is also not preserved across |
184 |
|
IPC). |
185 |
|
|
186 |
|
So, this is a really simple patch. Doesn't do much, but works for me. |
187 |
|
|
188 |
|
The costs (apart from setting up the desired value) is writing the |
189 |
|
value from the ktcb to %gs:0 on every thread switch except fast path |
190 |
|
of IPC. That's all. |
191 |
|
|
192 |
|
I suck at hand-written assembler. So the ordering of the commands |
193 |
|
possibly can be further optimized (move the pop %edx down a bit?). |
194 |
|
|
195 |
|
===File l4-tls-ia32.patch=============== |
196 |
|
2004-11-19 Marcus Brinkmann <marcus@gnu.org> |
197 |
|
|
198 |
|
* kernel/include/glue/v4-ia32/config.h (ARCH_SYSCALL0): New macro. |
199 |
|
(user_set_gs0) [!ASSEMBLY && __cplusplus]: Define prototype. |
200 |
|
* kernel/include/glue/v4-ia32/ktcb.h (arch_ktcb_t): Add new |
201 |
|
member user_gs0. |
202 |
|
* kernel/include/glue/v4-ia32/syscalls.h (sys_set_gs0): New |
203 |
|
prototype. |
204 |
|
* kernel/include/glue/v4-ia32/tcb.h (tcb_t::init_stack): |
205 |
|
Initialize ARCH.user_gs0. |
206 |
|
(tcb_t::switch_to): Use %gs:4 for the UTCB, and set %gs:0 to |
207 |
|
the user-settable value DEST->get_arch()->user_gs0. |
208 |
|
* kernel/src/glue/v4-ia32/gs0.cc: New file. |
209 |
|
* kernel/src/glue/v4-ia32/init.cc: Make the IA32_UTCB segment |
210 |
|
two words large. |
211 |
|
* kernel/src/glue/v4-ia32/Makeconf (SOURCES): Add gs0.cc. |
212 |
|
* kernel/src/glue/v4-ia32/trap.S: Use %gs:4 for the UTCB. |
213 |
|
* kernel/src/glue/v4-ia32/user.cc (SYSCALL_STUB(system_clock)): |
214 |
|
Use %gs:4 for the UTCB. |
215 |
|
(SYSCALL_STUB(set_gs0)): New syscall stub. |
216 |
|
(exc_user_syscall): Handle SYSCALL_STUB(set_gs0). |
217 |
|
* user/include/l4/ia32/vregs.h (__L4_X86_Utcb): Use %gs:4 |
218 |
|
instead of %gs:0. |
219 |
|
|
220 |
|
diff -rupN pistachio/kernel/include/glue/v4-ia32/config.h pistachio/kernel/include/glue/v4-ia32/config.h |
221 |
|
--- pistachio/kernel/include/glue/v4-ia32/config.h 2005-01-22 01:45:47.000000000 +0100 |
222 |
|
+++ pistachio/kernel/include/glue/v4-ia32/config.h 2005-01-22 02:14:14.000000000 +0100 |
223 |
|
@@ -54,6 +54,11 @@ |
224 |
|
#define KIP_ARCH_PAGEINFO {SHUFFLE2(rwx:6, size_mask:((1 << IA32_PAGE_BITS)) >> 10)} |
225 |
|
#endif |
226 |
|
#define KIP_SYSCALL(x) ((u8_t*)(x) - (u8_t*)&kip) |
227 |
|
+#define ARCH_SYSCALL0 KIP_SYSCALL (user_set_gs0) |
228 |
|
+ |
229 |
|
+#if !defined(ASSEMBLY) && defined(__cplusplus) |
230 |
|
+extern "C" void SECTION (".user.syscall.set_gs0") user_set_gs0 (void); |
231 |
|
+#endif |
232 |
|
|
233 |
|
/* configuration for KTCBs |
234 |
|
* make sure the KTCBs fit entirely into the TCB area |
235 |
|
@@ -103,7 +108,7 @@ |
236 |
|
#define PAGEDIR_STUFF_END (THREAD_COUNT + IA32_PAGEDIR_SIZE) |
237 |
|
#endif |
238 |
|
|
239 |
|
-/* V4 UTCB addressed via %gs:0 */ |
240 |
|
+/* V4 UTCB addressed via %gs:4 */ |
241 |
|
#define MYUTCB_MAPPING __UL(0xDF000000) |
242 |
|
|
243 |
|
/* trampoline to set up segment registers after sysexit */ |
244 |
|
diff -rupN pistachio/kernel/include/glue/v4-ia32/ktcb.h pistachio/kernel/include/glue/v4-ia32/ktcb.h |
245 |
|
--- pistachio/kernel/include/glue/v4-ia32/ktcb.h 2004-10-06 21:13:40.000000000 +0200 |
246 |
|
+++ pistachio/kernel/include/glue/v4-ia32/ktcb.h 2005-01-22 02:14:14.000000000 +0100 |
247 |
|
@@ -34,6 +34,8 @@ |
248 |
|
|
249 |
|
typedef struct |
250 |
|
{ |
251 |
|
+ /* The value the user wants to see in %gs:0. */ |
252 |
|
+ word_t user_gs0; |
253 |
|
} arch_ktcb_t; |
254 |
|
|
255 |
|
|
256 |
|
diff -rupN pistachio/kernel/include/glue/v4-ia32/syscalls.h pistachio/kernel/include/glue/v4-ia32/syscalls.h |
257 |
|
--- pistachio/kernel/include/glue/v4-ia32/syscalls.h 2003-09-24 21:12:22.000000000 +0200 |
258 |
|
+++ pistachio/kernel/include/glue/v4-ia32/syscalls.h 2005-01-22 02:14:14.000000000 +0100 |
259 |
|
@@ -184,6 +184,8 @@ |
260 |
|
#define return_memory_control() return |
261 |
|
|
262 |
|
|
263 |
|
+void sys_set_gs0 (word_t user_gs0, ia32_exceptionframe_t *__frame); |
264 |
|
+ |
265 |
|
|
266 |
|
/* entry functions for exceptions */ |
267 |
|
extern "C" void exc_user_sysipc(void); |
268 |
|
diff -rupN pistachio/kernel/include/glue/v4-ia32/tcb.h pistachio/kernel/include/glue/v4-ia32/tcb.h |
269 |
|
--- pistachio/kernel/include/glue/v4-ia32/tcb.h 2005-01-22 01:45:47.000000000 +0100 |
270 |
|
+++ pistachio/kernel/include/glue/v4-ia32/tcb.h 2005-01-22 02:14:14.000000000 +0100 |
271 |
|
@@ -173,6 +173,8 @@ INLINE void tcb_t::init_stack() |
272 |
|
{ |
273 |
|
stack = get_stack_top(); |
274 |
|
//TRACE("stack = %p\n", stack); |
275 |
|
+ |
276 |
|
+ arch.user_gs0 = 0; |
277 |
|
} |
278 |
|
|
279 |
|
|
280 |
|
@@ -254,7 +256,7 @@ INLINE void tcb_t::switch_to(tcb_t * des |
281 |
|
" jne 1f \n" |
282 |
|
" movl $1, __is_small \n" |
283 |
|
"1: popl %%eax \n" |
284 |
|
- " movl %3, %%gs:0 \n" |
285 |
|
+ " movl %3, %%gs:4 \n" |
286 |
|
" jmp *%%eax \n" |
287 |
|
|
288 |
|
"2: /* switch to large space */ \n" |
289 |
|
@@ -281,7 +283,10 @@ INLINE void tcb_t::switch_to(tcb_t * des |
290 |
|
" movl %%ecx, %%cr3 \n" |
291 |
|
|
292 |
|
"4: popl %%edx /* activation addr */ \n" |
293 |
|
- " movl %3, %%gs:0 /* update current UTCB */ \n" |
294 |
|
+ " movl %3, %%gs:4 /* update current UTCB */ \n" |
295 |
|
+ |
296 |
|
+ " movl %c8(%2), %%ecx /* get dest.arch.user_gs0 */ \n" |
297 |
|
+ " movl %%ecx, %%gs:0 /* install it */ \n" |
298 |
|
|
299 |
|
" jmp *%%edx \n" |
300 |
|
"9: movl %2, %1 /* restore 'this' */ \n" |
301 |
|
@@ -298,7 +303,8 @@ INLINE void tcb_t::switch_to(tcb_t * des |
302 |
|
"i" (OFS_TCB_PDIR_CACHE), // 6 |
303 |
|
"a" ((word_t) dest->space |
304 |
|
+ (CONFIG_SMP_MAX_CPUS * IA32_PAGE_SIZE) |
305 |
|
- + (SMALL_SPACE_ID >> IA32_PAGEDIR_BITS) * 4) // 7 |
306 |
|
+ + (SMALL_SPACE_ID >> IA32_PAGEDIR_BITS) * 4), // 7 |
307 |
|
+ "i" (OFS_TCB_ARCH) // 8 |
308 |
|
: |
309 |
|
"ecx", "edx", "memory"); |
310 |
|
|
311 |
|
@@ -330,7 +336,10 @@ INLINE void tcb_t::switch_to(tcb_t * des |
312 |
|
"movl %7, %%cr3 \n\t" /* reload pagedir */ |
313 |
|
"2: \n\t" |
314 |
|
"popl %%edx \n\t" /* load activation addr */ |
315 |
|
- "movl %3, %%gs:0 \n\t" /* update current UTCB */ |
316 |
|
+ "movl %3, %%gs:4 \n\t" /* update current UTCB */ |
317 |
|
+ |
318 |
|
+ "movl %c9(%2), %%ecx \n\t" /* get dest.arch.user_gs0 */ |
319 |
|
+ "movl %%ecx, %%gs:0 \n\t" /* install it */ |
320 |
|
|
321 |
|
"jmp *%%edx \n\t" |
322 |
|
"3: \n\t" |
323 |
|
@@ -348,10 +357,11 @@ INLINE void tcb_t::switch_to(tcb_t * des |
324 |
|
"i" (OFS_TCB_PDIR_CACHE), // 6 |
325 |
|
"a" (dest->pdir_cache), // 7 |
326 |
|
#ifdef CONFIG_CPU_IA32_P4 |
327 |
|
- "c" (this->pdir_cache) // 8 |
328 |
|
+ "c" (this->pdir_cache), // 8 |
329 |
|
#else |
330 |
|
- "c" (dest->pdir_cache) // dummy |
331 |
|
+ "c" (dest->pdir_cache), // dummy |
332 |
|
#endif |
333 |
|
+ "i" (OFS_TCB_ARCH) // 9 |
334 |
|
: "edx", "memory" |
335 |
|
); |
336 |
|
|
337 |
|
diff -rupN pistachio/kernel/src/glue/v4-ia32/gs0.cc pistachio/kernel/src/glue/v4-ia32/gs0.cc |
338 |
|
--- pistachio/kernel/src/glue/v4-ia32/gs0.cc 1970-01-01 01:00:00.000000000 +0100 |
339 |
|
+++ pistachio/kernel/src/glue/v4-ia32/gs0.cc 2005-01-22 02:14:14.000000000 +0100 |
340 |
|
@@ -0,0 +1,15 @@ |
341 |
|
+#include INC_API(tcb.h) |
342 |
|
+#include INC_ARCH(trapgate.h) |
343 |
|
+ |
344 |
|
+void |
345 |
|
+sys_set_gs0 (word_t user_gs0, |
346 |
|
+ ia32_exceptionframe_t *__frame) |
347 |
|
+{ |
348 |
|
+ get_current_tcb()->get_arch()->user_gs0 = user_gs0; |
349 |
|
+ |
350 |
|
+ asm volatile (" movl %0, %%gs:0 \n" |
351 |
|
+ : |
352 |
|
+ : "r" (user_gs0)); |
353 |
|
+ |
354 |
|
+ return; |
355 |
|
+} |
356 |
|
diff -rupN pistachio/kernel/src/glue/v4-ia32/init.cc pistachio/kernel/src/glue/v4-ia32/init.cc |
357 |
|
--- pistachio/kernel/src/glue/v4-ia32/init.cc 2005-01-22 01:45:49.000000000 +0100 |
358 |
|
+++ pistachio/kernel/src/glue/v4-ia32/init.cc 2005-01-22 02:14:14.000000000 +0100 |
359 |
|
@@ -222,12 +222,13 @@ static void setup_gdt(ia32_tss_t & tss, |
360 |
|
gdt[gdt_idx(IA32_UDS)].set_seg(0, ~0, 3, ia32_segdesc_t::data); |
361 |
|
|
362 |
|
/* MyUTCB pointer, |
363 |
|
- * we use a separate page for all processors allocated in space_t |
364 |
|
- * and have one UTCB entry per cache line in the SMP case */ |
365 |
|
+ * we use a separate page for all processors allocated in space_t |
366 |
|
+ * and have one user word and one UTCB entry per cache line in the |
367 |
|
+ * SMP case */ |
368 |
|
ASSERT(unsigned(cpuid * CACHE_LINE_SIZE) < IA32_PAGE_SIZE); |
369 |
|
gdt[gdt_idx(IA32_UTCB)].set_seg((u32_t)MYUTCB_MAPPING + |
370 |
|
(cpuid * CACHE_LINE_SIZE), |
371 |
|
- sizeof(threadid_t) - 1, |
372 |
|
+ sizeof (word_t) + sizeof(threadid_t) - 1, |
373 |
|
3, ia32_segdesc_t::data); |
374 |
|
|
375 |
|
/* the TSS |
376 |
|
diff -rupN pistachio/kernel/src/glue/v4-ia32/Makeconf pistachio/kernel/src/glue/v4-ia32/Makeconf |
377 |
|
--- pistachio/kernel/src/glue/v4-ia32/Makeconf 2004-03-16 05:05:06.000000000 +0100 |
378 |
|
+++ pistachio/kernel/src/glue/v4-ia32/Makeconf 2005-01-22 02:14:14.000000000 +0100 |
379 |
|
@@ -3,7 +3,7 @@ LDSCRIPT = $(SRCDIR)/src/glue/$(API)-$(A |
380 |
|
CURDIR = src/glue/v4-ia32 |
381 |
|
SOURCES += $(addprefix $(CURDIR)/, init.cc idt.cc exception.cc \ |
382 |
|
space.cc debug.cc resources.cc thread.cc user.cc trap.S \ |
383 |
|
- ctors.cc smp.cc trampoline.S) |
384 |
|
+ ctors.cc smp.cc trampoline.S gs0.cc) |
385 |
|
|
386 |
|
SOURCES+= src/generic/linear_ptab_walker.cc \ |
387 |
|
src/generic/mapping_alloc.cc \ |
388 |
|
diff -rupN pistachio/kernel/src/glue/v4-ia32/space.cc pistachio/kernel/src/glue/v4-ia32/space.cc |
389 |
|
--- pistachio/kernel/src/glue/v4-ia32/space.cc 2005-01-22 01:45:49.000000000 +0100 |
390 |
|
+++ pistachio/kernel/src/glue/v4-ia32/space.cc 2005-01-22 02:14:14.000000000 +0100 |
391 |
|
@@ -329,7 +329,7 @@ void SECTION(".init.memory") space_t::in |
392 |
|
|
393 |
|
/* MYUTCB mapping |
394 |
|
* allocate a full page for all myutcb pointers. |
395 |
|
- * access must be performed via gs:0, when setting up the gdt |
396 |
|
+ * access must be performed via gs:4, when setting up the gdt |
397 |
|
* each processor gets a full cache line to avoid bouncing |
398 |
|
* page is user-writable and global |
399 |
|
*/ |
400 |
|
diff -rupN pistachio/kernel/src/glue/v4-ia32/trap.S pistachio/kernel/src/glue/v4-ia32/trap.S |
401 |
|
--- pistachio/kernel/src/glue/v4-ia32/trap.S 2004-11-17 01:48:13.000000000 +0100 |
402 |
|
+++ pistachio/kernel/src/glue/v4-ia32/trap.S 2005-01-22 02:14:14.000000000 +0100 |
403 |
|
@@ -175,7 +175,7 @@ fp_save_resources_done: |
404 |
|
pushl $fp_ipc_done |
405 |
|
movl OFS_TCB_MYSELF_LOCAL(%esi), %edi // local id |
406 |
|
movl OFS_TCB_PDIR_CACHE(%esi), %eax // new PDIR |
407 |
|
- movl %edi, %gs:0 |
408 |
|
+ movl %edi, %gs:4 |
409 |
|
movl %esp, OFS_TCB_STACK(%ebx) // store stack ptr |
410 |
|
movl OFS_TCB_STACK(%esi), %esp // load stack ptr |
411 |
|
popl %ecx // load dest addr |
412 |
|
@@ -241,7 +241,7 @@ fp_save_resources_done: |
413 |
|
movl %ecx, %gs |
414 |
|
movl $1, __is_small |
415 |
|
1: popl %ecx |
416 |
|
- movl %edi, %gs:0 |
417 |
|
+ movl %edi, %gs:4 |
418 |
|
jmp *%ecx |
419 |
|
|
420 |
|
2: /* switch to large space */ |
421 |
|
@@ -268,7 +268,7 @@ fp_save_resources_done: |
422 |
|
movl %ecx, %cr3 |
423 |
|
|
424 |
|
9: popl %ecx |
425 |
|
- movl %edi, %gs:0 |
426 |
|
+ movl %edi, %gs:4 |
427 |
|
|
428 |
|
#endif /* CONFIG_IA32_SMALL_SPACES */ |
429 |
|
|
430 |
|
diff -rupN pistachio/kernel/src/glue/v4-ia32/user.cc pistachio/kernel/src/glue/v4-ia32/user.cc |
431 |
|
--- pistachio/kernel/src/glue/v4-ia32/user.cc 2005-01-22 01:45:49.000000000 +0100 |
432 |
|
+++ pistachio/kernel/src/glue/v4-ia32/user.cc 2005-01-22 02:14:14.000000000 +0100 |
433 |
|
@@ -172,7 +172,7 @@ SYSCALL_STUB(system_clock) |
434 |
|
"add %c0(%%ecx), %%ecx \n" /* procdesc */ |
435 |
|
#ifdef CONFIG_SMP |
436 |
|
/* get processor # --> allow for differently clocked CPUs */ |
437 |
|
- "mov %%gs:0, %%eax \n" /* myutcb */ |
438 |
|
+ "mov %%gs:4, %%eax \n" /* myutcb */ |
439 |
|
"mov %c2(%%eax), %%eax \n" |
440 |
|
"shl %3, %%eax \n" |
441 |
|
"add %%eax, %%ecx \n" |
442 |
|
@@ -344,6 +344,14 @@ SYSCALL_STUB(memory_control) |
443 |
|
: "i"(SYS_SYSCALL_NUM)); |
444 |
|
} |
445 |
|
|
446 |
|
+SYSCALL_STUB(set_gs0) |
447 |
|
+{ |
448 |
|
+ __asm__ __volatile__( |
449 |
|
+ SYSCALL_LABEL (set_gs0) |
450 |
|
+ : |
451 |
|
+ : "i"(SYS_SYSCALL_NUM)); |
452 |
|
+} |
453 |
|
+ |
454 |
|
|
455 |
|
#define IS_SYSCALL(x) ((frame->eip - (u32_t)get_current_space()->get_kip_page_area().get_base()) == ((u32_t)(&entry_##x) - (u32_t)get_kip() + 2)) |
456 |
|
|
457 |
|
@@ -399,6 +407,11 @@ IA32_EXC_NO_ERRORCODE(exc_user_syscall, |
458 |
|
frame); |
459 |
|
} |
460 |
|
|
461 |
|
+ else if (IS_SYSCALL(set_gs0)) |
462 |
|
+ { |
463 |
|
+ sys_set_gs0(frame->eax, frame); |
464 |
|
+ } |
465 |
|
+ |
466 |
|
else |
467 |
|
printf("unknown syscall\n"); |
468 |
|
return; |
469 |
|
diff -rupN pistachio/user/include/l4/ia32/vregs.h pistachio/user/include/l4/ia32/vregs.h |
470 |
|
--- pistachio/user/include/l4/ia32/vregs.h 2004-11-17 01:48:13.000000000 +0100 |
471 |
|
+++ pistachio/user/include/l4/ia32/vregs.h 2005-01-22 02:14:14.000000000 +0100 |
472 |
|
@@ -48,7 +48,7 @@ L4_INLINE L4_Word_t * __L4_X86_Utcb (voi |
473 |
|
|
474 |
|
__asm__ __volatile__ ( |
475 |
|
"/* __L4_X86_Utcb() */ \n" |
476 |
|
- " mov %%gs:0, %0 \n" |
477 |
|
+ " mov %%gs:4, %0 \n" |
478 |
|
|
479 |
|
: /* outputs */ |
480 |
|
"=r"(utcb) |