diff --git a/base-foc/src/core/platform_thread.cc b/base-foc/src/core/platform_thread.cc index 845010600..eda3db243 100644 --- a/base-foc/src/core/platform_thread.cc +++ b/base-foc/src/core/platform_thread.cc @@ -157,7 +157,10 @@ void Platform_thread::unbind() void Platform_thread::pager(Pager_object *pager_obj) { _pager_obj = pager_obj; - _pager.local = pager_obj->cap(); + if (_pager_obj) + _pager.local = pager_obj->cap(); + else + _pager.local = Native_capability(); } diff --git a/base-linux/include/base/pager.h b/base-linux/include/base/pager.h index e72723039..b8aea16c0 100644 --- a/base-linux/include/base/pager.h +++ b/base-linux/include/base/pager.h @@ -20,14 +20,26 @@ #include #include #include +#include namespace Genode { struct Pager_object { + Thread_capability _thread_cap; + virtual ~Pager_object() { } void exception_handler(Signal_context_capability) { } + + public: + + /** + * Remember thread cap so that rm_session can tell thread that + * rm_client is gone. + */ + Thread_capability thread_cap() { return _thread_cap; } const + void thread_cap(Thread_capability cap) { _thread_cap = cap; } }; class Pager_activation_base { }; diff --git a/base-nova/include/base/pager.h b/base-nova/include/base/pager.h index 154491005..c03257d64 100644 --- a/base-nova/include/base/pager.h +++ b/base-nova/include/base/pager.h @@ -65,6 +65,8 @@ namespace Genode { bool singlestep; } _state; + Thread_capability _thread_cap; + void _copy_state(Nova::Utcb * utcb); static void _page_fault_handler(); @@ -176,6 +178,13 @@ namespace Genode { void client_set_ec(addr_t ec) { _state.sel_client_ec = ec; } void single_step(bool on) { _state.singlestep = on; } + + /** + * Remember thread cap so that rm_session can tell thread that + * rm_client is gone. + */ + Thread_capability thread_cap() { return _thread_cap; } const + void thread_cap(Thread_capability cap) { _thread_cap = cap; } }; diff --git a/base-nova/src/core/ram_session_support.cc b/base-nova/src/core/ram_session_support.cc index 89c139d0b..47f2adf44 100644 --- a/base-nova/src/core/ram_session_support.cc +++ b/base-nova/src/core/ram_session_support.cc @@ -34,6 +34,10 @@ void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { size_t page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask(); + if (verbose_ram_ds) + printf("-- revoke - ram ds size=0x%8zx phys 0x%8lx has core-local addr 0x%8lx - thread 0x%8p\n", + page_rounded_size, ds->phys_addr(), ds->core_local_addr(), Thread_base::myself()->utcb()); + unmap_local((Nova::Utcb *)Thread_base::myself()->utcb(), ds->core_local_addr(), page_rounded_size >> get_page_size_log2()); @@ -76,8 +80,8 @@ void Ram_session_component::_clear_ds(Dataspace_component *ds) } if (verbose_ram_ds) - printf("-- ram ds size=%zx phys %lx has core-local addr %p\n", - page_rounded_size, ds->phys_addr(), virt_addr); + printf("-- map - ram ds size=0x%8zx phys 0x%8lx has core-local addr 0x%8p - thread 0x%8p\n", + page_rounded_size, ds->phys_addr(), virt_addr, Thread_base::myself()->utcb()); /* map the dataspace's physical pages to local addresses */ const Nova::Rights rights(true, true, true); diff --git a/base/include/base/pager.h b/base/include/base/pager.h index 0afee2cc5..b71051419 100644 --- a/base/include/base/pager.h +++ b/base/include/base/pager.h @@ -43,6 +43,8 @@ namespace Genode { */ unsigned long _badge; + Thread_capability _thread_cap; + /** * User-level signal handler registered for this pager object via * 'Cpu_session::exception_handler()'. @@ -97,6 +99,13 @@ namespace Genode { Signal_transmitter transmitter(_exception_sigh); transmitter.submit(); } + + /** + * Remember thread cap so that rm_session can tell thread that + * rm_client is gone. + */ + Thread_capability thread_cap() { return _thread_cap; } const + void thread_cap(Thread_capability cap) { _thread_cap = cap; } }; /** diff --git a/base/src/core/cpu_session_component.cc b/base/src/core/cpu_session_component.cc index 54af04ec0..74bfdfdf3 100644 --- a/base/src/core/cpu_session_component.cc +++ b/base/src/core/cpu_session_component.cc @@ -81,6 +81,8 @@ int Cpu_session_component::set_pager(Thread_capability thread_cap, if (!p) return -2; thread->platform_thread()->pager(p); + p->thread_cap(thread->cap()); + return 0; } diff --git a/base/src/core/rm_session_component.cc b/base/src/core/rm_session_component.cc index 1c37969a1..aae4c315f 100644 --- a/base/src/core/rm_session_component.cc +++ b/base/src/core/rm_session_component.cc @@ -756,6 +756,15 @@ Rm_session_component::~Rm_session_component() /* remove all clients */ while (Rm_client *cl = _client_slab.raw()->first_object()) { + Thread_capability thread_cap = cl->thread_cap(); + if (thread_cap.valid()) { + /* lookup thread and reset pager pointer */ + Cpu_thread_component *cpu_thread = dynamic_cast + (_thread_ep->obj_by_cap(thread_cap)); + if (cpu_thread) + cpu_thread->platform_thread()->pager(0); + } + _lock.unlock(); cl->dissolve_from_faulting_rm_session(); this->dissolve(cl);