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:
parent
e143683196
commit
040cd95580
|
@ -95,12 +95,11 @@ class Noux_connection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the capability of the local context-area RM session
|
* 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()
|
Genode::Rm_session_capability context_area_rm_session(void * const ptr) {
|
||||||
{
|
return _connection.lookup_rm_session((Genode::addr_t)ptr); }
|
||||||
int on_stack;
|
|
||||||
return _connection.lookup_rm_session((Genode::addr_t)&on_stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
Noux::Session *session() { return &_connection; }
|
Noux::Session *session() { return &_connection; }
|
||||||
Noux::Sysio *sysio() { return _sysio; }
|
Noux::Sysio *sysio() { return _sysio; }
|
||||||
|
@ -507,6 +506,7 @@ extern "C" int select(int nfds, fd_set *readfds, fd_set *writefds,
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void * stack_in_context_area;
|
||||||
static jmp_buf fork_jmp_buf;
|
static jmp_buf fork_jmp_buf;
|
||||||
static Genode::Capability<Genode::Parent>::Raw new_parent;
|
static Genode::Capability<Genode::Parent>::Raw new_parent;
|
||||||
|
|
||||||
|
@ -532,6 +532,10 @@ extern "C" void fork_trampoline()
|
||||||
/* reinitialize noux connection */
|
/* reinitialize noux connection */
|
||||||
construct_at<Noux_connection>(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 */
|
/* apply processor state that the forker had when he did the fork */
|
||||||
longjmp(fork_jmp_buf, 1);
|
longjmp(fork_jmp_buf, 1);
|
||||||
}
|
}
|
||||||
|
@ -548,15 +552,17 @@ extern "C" pid_t fork(void)
|
||||||
/*
|
/*
|
||||||
* We got here via longjmp from 'fork_trampoline'.
|
* 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;
|
return 0;
|
||||||
|
|
||||||
} else {
|
} 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 */
|
/* got here during the normal control flow of the fork call */
|
||||||
sysio()->fork_in.ip = (Genode::addr_t)(&fork_trampoline);
|
sysio()->fork_in.ip = (Genode::addr_t)(&fork_trampoline);
|
||||||
sysio()->fork_in.sp = (Genode::addr_t)(&stack[STACK_SIZE]);
|
sysio()->fork_in.sp = (Genode::addr_t)(&stack[STACK_SIZE]);
|
||||||
|
|
Loading…
Reference in New Issue