nova: delay UTCB revocation on thread destruction

On NOVA, a Genode thread currently cannot destroy itself by destroying its
own 'Thread' object, because in 'Thread_base::_deinit_platform_thread()'
it cannot call 'Cpu_session::kill_thread()' anymore after it has revoked
its own UTCB.

As solution, the revocation of the UTCB can be delayed until its location
in the context area is needed by a new thread.

Fixes 
This commit is contained in:
Christian Prochaska 2015-04-30 15:28:25 +02:00 committed by Christian Helmuth
parent 65d8d4461f
commit e8f82a1da3

@ -89,6 +89,19 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
return;
}
/*
* Revoke possible left-over UTCB of a previously destroyed thread
* which used this context location.
*
* This cannot be done in '_deinit_platform_thread()', because a
* self-destructing thread needs its UTCB to call
* 'Cpu_session::kill_thread()' and is not able to revoke the UTCB
* afterwards.
*/
Rights rwx(true, true, true);
addr_t utcb = reinterpret_cast<addr_t>(&_context->utcb);
revoke(Mem_crd(utcb >> 12, 0, rwx));
_tid.exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
if (_tid.exc_pt_sel == Native_thread::INVALID_INDEX)
throw Cpu_session::Thread_creation_failed();
@ -124,11 +137,6 @@ void Thread_base::_deinit_platform_thread()
revoke(Obj_crd(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2));
cap_map()->remove(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2, false);
/* revoke utcb */
Rights rwx(true, true, true);
addr_t utcb = reinterpret_cast<addr_t>(&_context->utcb);
revoke(Mem_crd(utcb >> 12, 0, rwx));
/* de-announce thread */
if (_thread_cap.valid())
_cpu_session->kill_thread(_thread_cap);