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);