Fix: don't deference stale pager pointer in core
Reset pager pointer in platform_thread if pager object is removed. Fixes #532
This commit is contained in:
parent
1720e04fdc
commit
fa2cbdc7cb
|
@ -157,7 +157,10 @@ void Platform_thread::unbind()
|
||||||
void Platform_thread::pager(Pager_object *pager_obj)
|
void Platform_thread::pager(Pager_object *pager_obj)
|
||||||
{
|
{
|
||||||
_pager_obj = pager_obj;
|
_pager_obj = pager_obj;
|
||||||
_pager.local = pager_obj->cap();
|
if (_pager_obj)
|
||||||
|
_pager.local = pager_obj->cap();
|
||||||
|
else
|
||||||
|
_pager.local = Native_capability();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,14 +20,26 @@
|
||||||
#include <base/signal.h>
|
#include <base/signal.h>
|
||||||
#include <pager/capability.h>
|
#include <pager/capability.h>
|
||||||
#include <cap_session/cap_session.h>
|
#include <cap_session/cap_session.h>
|
||||||
|
#include <thread/capability.h>
|
||||||
|
|
||||||
namespace Genode {
|
namespace Genode {
|
||||||
|
|
||||||
struct Pager_object
|
struct Pager_object
|
||||||
{
|
{
|
||||||
|
Thread_capability _thread_cap;
|
||||||
|
|
||||||
virtual ~Pager_object() { }
|
virtual ~Pager_object() { }
|
||||||
|
|
||||||
void exception_handler(Signal_context_capability) { }
|
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 { };
|
class Pager_activation_base { };
|
||||||
|
|
|
@ -65,6 +65,8 @@ namespace Genode {
|
||||||
bool singlestep;
|
bool singlestep;
|
||||||
} _state;
|
} _state;
|
||||||
|
|
||||||
|
Thread_capability _thread_cap;
|
||||||
|
|
||||||
void _copy_state(Nova::Utcb * utcb);
|
void _copy_state(Nova::Utcb * utcb);
|
||||||
|
|
||||||
static void _page_fault_handler();
|
static void _page_fault_handler();
|
||||||
|
@ -176,6 +178,13 @@ namespace Genode {
|
||||||
void client_set_ec(addr_t ec) { _state.sel_client_ec = ec; }
|
void client_set_ec(addr_t ec) { _state.sel_client_ec = ec; }
|
||||||
|
|
||||||
void single_step(bool on) { _state.singlestep = on; }
|
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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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();
|
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(),
|
unmap_local((Nova::Utcb *)Thread_base::myself()->utcb(),
|
||||||
ds->core_local_addr(),
|
ds->core_local_addr(),
|
||||||
page_rounded_size >> get_page_size_log2());
|
page_rounded_size >> get_page_size_log2());
|
||||||
|
@ -76,8 +80,8 @@ void Ram_session_component::_clear_ds(Dataspace_component *ds)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose_ram_ds)
|
if (verbose_ram_ds)
|
||||||
printf("-- ram ds size=%zx phys %lx has core-local addr %p\n",
|
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);
|
page_rounded_size, ds->phys_addr(), virt_addr, Thread_base::myself()->utcb());
|
||||||
|
|
||||||
/* map the dataspace's physical pages to local addresses */
|
/* map the dataspace's physical pages to local addresses */
|
||||||
const Nova::Rights rights(true, true, true);
|
const Nova::Rights rights(true, true, true);
|
||||||
|
|
|
@ -43,6 +43,8 @@ namespace Genode {
|
||||||
*/
|
*/
|
||||||
unsigned long _badge;
|
unsigned long _badge;
|
||||||
|
|
||||||
|
Thread_capability _thread_cap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User-level signal handler registered for this pager object via
|
* User-level signal handler registered for this pager object via
|
||||||
* 'Cpu_session::exception_handler()'.
|
* 'Cpu_session::exception_handler()'.
|
||||||
|
@ -97,6 +99,13 @@ namespace Genode {
|
||||||
Signal_transmitter transmitter(_exception_sigh);
|
Signal_transmitter transmitter(_exception_sigh);
|
||||||
transmitter.submit();
|
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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -81,6 +81,8 @@ int Cpu_session_component::set_pager(Thread_capability thread_cap,
|
||||||
if (!p) return -2;
|
if (!p) return -2;
|
||||||
|
|
||||||
thread->platform_thread()->pager(p);
|
thread->platform_thread()->pager(p);
|
||||||
|
p->thread_cap(thread->cap());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -756,6 +756,15 @@ Rm_session_component::~Rm_session_component()
|
||||||
|
|
||||||
/* remove all clients */
|
/* remove all clients */
|
||||||
while (Rm_client *cl = _client_slab.raw()->first_object()) {
|
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<Cpu_thread_component *>
|
||||||
|
(_thread_ep->obj_by_cap(thread_cap));
|
||||||
|
if (cpu_thread)
|
||||||
|
cpu_thread->platform_thread()->pager(0);
|
||||||
|
}
|
||||||
|
|
||||||
_lock.unlock();
|
_lock.unlock();
|
||||||
cl->dissolve_from_faulting_rm_session();
|
cl->dissolve_from_faulting_rm_session();
|
||||||
this->dissolve(cl);
|
this->dissolve(cl);
|
||||||
|
|
Loading…
Reference in New Issue