From 040cd9558055f24a53f180a4594edf547020c9d3 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Mon, 18 Jan 2016 10:08:06 +0100 Subject: [PATCH] noux: fix context-area re-initialization in fork With commit e74b53d5dd92cc0f9f636b0233de9f32376010b6 the fork semantic in noux changed slightly, and broke platforms like hw & sel4, where the UTCB is mapped directly into the thread's context area. The change moved the re-initialization to a point where the new noux process' thread stack-pointer was already switched back to the context area. But to re-initialize the context area RPC calls must be done, and the UTCB must be used therefore. On the other side the UTCB is found implicitly by the stack-pointer, whereby a stack-pointer located in the context-area refers to a UTCB that is expected to reside in the context-area as well. But the UTCB gets overlayed inside the context area by the context-area's re-initialization - we've come round in a circle. This commit rolls back the move of the re-initialization routine. To preserve the intention of the original commit, the context-area location is stored in a static variable, so that the Native_config API is not needed anymore. Fix #1851 --- repos/ports/src/lib/libc_noux/plugin.cc | 26 +++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/repos/ports/src/lib/libc_noux/plugin.cc b/repos/ports/src/lib/libc_noux/plugin.cc index d27c8f810..bd27ae167 100644 --- a/repos/ports/src/lib/libc_noux/plugin.cc +++ b/repos/ports/src/lib/libc_noux/plugin.cc @@ -95,12 +95,11 @@ class Noux_connection /** * Return the capability of the local context-area RM session + * + * \param ptr some address within the context-area */ - Genode::Rm_session_capability context_area_rm_session() - { - int on_stack; - return _connection.lookup_rm_session((Genode::addr_t)&on_stack); - } + Genode::Rm_session_capability context_area_rm_session(void * const ptr) { + return _connection.lookup_rm_session((Genode::addr_t)ptr); } Noux::Session *session() { return &_connection; } Noux::Sysio *sysio() { return _sysio; } @@ -507,6 +506,7 @@ extern "C" int select(int nfds, fd_set *readfds, fd_set *writefds, #include +static void * stack_in_context_area; static jmp_buf fork_jmp_buf; static Genode::Capability::Raw new_parent; @@ -532,6 +532,10 @@ extern "C" void fork_trampoline() /* reinitialize noux connection */ construct_at(noux_connection()); + /* reinitialize main-thread object which implies reinit of context area */ + auto context_area_rm = noux_connection()->context_area_rm_session(stack_in_context_area); + Genode::env()->reinit_main_thread(context_area_rm); + /* apply processor state that the forker had when he did the fork */ longjmp(fork_jmp_buf, 1); } @@ -548,15 +552,17 @@ extern "C" pid_t fork(void) /* * We got here via longjmp from 'fork_trampoline'. */ - - /* reinitialize main-thread object which implies reinit of context area */ - auto context_area_rm = noux_connection()->context_area_rm_session(); - Genode::env()->reinit_main_thread(context_area_rm); - return 0; } else { + /* + * save the current stack address used for re-initializing + * the context-area during process bootstrap + */ + int dummy; + stack_in_context_area = &dummy; + /* got here during the normal control flow of the fork call */ sysio()->fork_in.ip = (Genode::addr_t)(&fork_trampoline); sysio()->fork_in.sp = (Genode::addr_t)(&stack[STACK_SIZE]);