diff --git a/repos/base-nova/src/base/thread/thread_nova.cc b/repos/base-nova/src/base/thread/thread_nova.cc index 6896546064..1952375cfa 100644 --- a/repos/base-nova/src/base/thread/thread_nova.cc +++ b/repos/base-nova/src/base/thread/thread_nova.cc @@ -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(&_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(&_context->utcb); - revoke(Mem_crd(utcb >> 12, 0, rwx)); - /* de-announce thread */ if (_thread_cap.valid()) _cpu_session->kill_thread(_thread_cap);