nova: set page fault handler for core threads

Ease debugging if a core thread fail.
base: throw exception if thread creation failed

Sanity check that the context area has been attached. Otherwise the code
later tries to access the context area and core dies with a unhandled page
fault.
base: catch exceptions in rm_session

For base-nova thread creation related exception can be thrown, since the
Pager_objects are threads. Catch the exception and re-throw the
expected/documented exception in rm_session.

This commit avoids that core dies with an unhandled exception if a thread
couldn't be created (e.g. because the limit has been reached).
core: don't dereference null pointer
nova: decode type of page fault in core

Ease reading debugging messages if a core thread fails.
base: keep lock during destruction in rm_session

Fixes various spurious page faults. The rm_session_component lock taken during
destruction has been untaken and taken at various places, probably to avoid
deadlocks. Unfortunately the Rm_client objects, also subject to destruction,
can be and has been obtained during this short period by other
threads running in parallel. Later the Rm_client object became deleted and the
pointers to the objects became invalid.

Fixes #549
base: apply thread.cc fix of foc to base*

With commit 1389b63050f359214b6b309c687f7cd0e280c6b2 in thread.cc for base-foc
a bug was fixed, where the memory of the context got freed up before running
the de-constructor.

Apply the fix also to base and base-mb.
base: use long in atomic function

By using long we get automatically the right bit width of the target host
(32bit 4 byte, 64bit 8 byte). With int it is ever 4 byte.
base: add memory barrier before releasing lock

When releasing a lock we must take care that all state is written back to
memory and is not cached in registers. The volatile flag of the lock variable
only means to the compiler that this value must be written immediately.
Other values changed before may be kept by the compiler in registers, which we
don't want here.

Additionally the compiler is free to reorder the code in order to optimize.
That means the code we intend to be executed inside the critical section can
get be reordered and can be executed after we reset the lock variable in the
unlock implementation. The volatile statement of the lock variable doesn't
prevent reordering of instructions which are independent.

By adding a explicit memory barrier, we force the compiler to generate code
that writes back all the register content to memory/cache (and avoid a
bunch of hard to find bugs ...)
base: extend object_pool by lookup_and_lock

Add functionality to lookup an object and lock it. Additional the case is
handled that a object may be already in-destruction and the lookup will deny
returning the object.

The object_pool generalize the lookup and lock functionality in rpc_server
and makes it obsolete. The lookup_and_lock feature is used to avoid recently
occurred races and deadlocks in base*.
base: avoid deadlock in sliced_heap

It happens that ram_session and rm_session itself are invoking alloc
respectively free on the very same sliced heap inside core.

Lock only the sliced_heap list implementation and let the session locking to
the session implementation of rm_session and ram_session.

The ram_session and rm_session must take care to proper lock since inside
both implementations already the session handling thread and the service thread
are running parallel.
base: fix deadlock in core_env on base-nova

During a ram_session->free call in 'core' the lock in core_env.h is taken.
Then in the ram_session::_free_ds implementation the dissolve function for the
dataspace is called. base-nova tries to make sure that the ds is not
accessible anymore by any kind of parallel incoming IPC by performing a
cleanup IPC. Unfortunately the dataspace_session implementation uses the very
same allocator in 'core' and may require to obtain the same lock as taken in
ram_session->free. This leads to a spurious deadlock on base-nova.

The actual free_ds implementation is mostly thread safe, since all used objects
inside there are already locked. The only missing piece is the _payload
variable. By atomically changing the _payload variable there is no need anymore
to lock the whole ram_session->free call which avoids the deadlock on
base-nova.
nova: fix cleanup handling in server object

As first step the rpc object must be freed up so that the kernel object
(portal) vanishes. Then the object must be removed from the internal object
pool list so that the object can't be obtained anymore. And then the cleanup
call can be performed (_leave_server_object) since now all names to the
rpc_object are gone.

Doing it in different order (as before the commit) there is a very very little
chance (but the bomb test triggers it occasionally) that the rpc_object can be
obtained again by an incoming IPC - even it is already scheduled for removal.
nova: fix pager cleanup handling

The cleanup call must be performed already during the _dissolve function
shortly after the object at the cap_session is freed up. Otherwise there
is the chance that an in-flight IPC will find the to be dissolved function
again.

Bomb test triggered the case, that a already dissolved rpc_object was found
by a in-flight IPC. If the rpc_object was already freed up by alloc->destroy
the thread using this stale rpc_object pointer cause page-faults in core.
base: fix dangling session pointers in rm_session

If page faults are handled concurrently (as for base-nova) the traverse lookup
call in rm_session_component must be thread safe, which it isn't.
If the faulting area is backed by nested dataspaces which are managed by
various rm_sessions then a race happens under following circumstances
(triggered occasionally by the bomb test).

The traverse lookup may return a pointer to a rm_session of a nested dataspace.
If the rm_session is in parallel subject to destruction it happened that faults
got enqueued to the faulters list of the deleted rm_session and internally to
a list of the current rm_session of the Rm_client.

During destruction of the faulting Rm_client it is tried to dissolve it from
the rm_session supposed to handle the fault, which leads to dereference the
dangling pointer of the already destructed rm_session of the nested dataspace.

On base-nova the memory of the rm_session object get unmapped eventually, so
that the de-referencing of the dangling pointer caused page faults in core.

The memory on other kernels inside core never get unmapped so that bug doesn't
trigger obviously faults.
base: fix deadlock in rm_session destruction path

First make the clients inaccessible and dissolve them from the entrypoint. If
this isn't the first step the clients may be obtained again between
the unlock and lock steps in the destructor.

The dissolve function of the entrypoint makes sure that all in-flight
page-faults of the clients are finished. The dissolve must be called
(on base-nova) without holding the rm_session lock since base-nova makes a
cleanup IPC to the Rm_client object which may try to obtain the vary same lock.
base: reset pager cap in cpu_session
test: for creating and destroying threads
nova: use experimental nova kernel branch

issue #394