noux: fix context-area re-initialization in fork

With commit e74b53d5dd 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
This commit is contained in:
Stefan Kalkowski 2016-01-18 10:08:06 +01:00 committed by Christian Helmuth
parent e143683196
commit 040cd95580
1 changed files with 16 additions and 10 deletions

View File

@ -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 <setjmp.h>
static void * stack_in_context_area;
static jmp_buf fork_jmp_buf;
static Genode::Capability<Genode::Parent>::Raw new_parent;
@ -532,6 +532,10 @@ extern "C" void fork_trampoline()
/* reinitialize noux connection */
construct_at<Noux_connection>(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]);