core: Introduce 'Address_space' interface

The new core-internal 'Address_space' interface enables cores RM service
to flush mappings of a PD in which a given 'Rm_client' thread resides.
Prior this patch, each platform invented their own way to flush mappings
in the respective 'rm_session_support.cc' implementation. However, those
implementations used to deal poorly with some corner cases. In
particular, if a PD session was destroyed prior a RM session, the RM
session would try to use no longer existing PD session. The new
'Address_space' uses the just added weak-pointer mechanism to deal with
this issue.

Furthermore, the generic 'Rm_session_component::detach' function has
been improved to avoid duplicated unmap operations for platforms that
implement the 'Address_space' interface. Therefore, it is related to
issue #595. Right now, this is OKL4 only, but other platforms will follow.
This commit is contained in:
Norman Feske
2013-03-08 11:54:12 +01:00
parent 352f58b94b
commit 21de42c45d
30 changed files with 351 additions and 91 deletions

View File

@ -16,6 +16,7 @@
/* core includes */
#include <platform_thread.h>
#include <address_space.h>
/* Codezero includes */
#include <codezero/syscalls.h>
@ -23,7 +24,7 @@
namespace Genode {
class Platform_thread;
class Platform_pd
class Platform_pd : public Address_space
{
private:
@ -37,7 +38,6 @@ namespace Genode {
public:
/**
* Constructors
*/
@ -68,6 +68,13 @@ namespace Genode {
* Assign parent interface to protection domain
*/
int assign_parent(Native_capability parent) { return 0; }
/*****************************
** Address-space interface **
*****************************/
void flush(addr_t, size_t) { PDBG("not implemented"); }
};
}

View File

@ -19,6 +19,9 @@
#include <base/thread_state.h>
#include <base/native_types.h>
/* core includes */
#include <address_space.h>
namespace Genode {
class Platform_pd;
@ -30,19 +33,25 @@ namespace Genode {
enum { PD_NAME_MAX_LEN = 64 };
unsigned _tid; /* global codezero thread ID */
unsigned _space_id;
addr_t _utcb;
char _name[PD_NAME_MAX_LEN];
Pager_object *_pager;
unsigned _tid; /* global codezero thread ID */
unsigned _space_id;
Weak_ptr<Address_space> _address_space;
addr_t _utcb;
char _name[PD_NAME_MAX_LEN];
Pager_object *_pager;
/**
* Assign physical thread ID and UTCB address to thread
*
* This function is called from 'Platform_pd::bind_thread'.
*/
void _assign_physical_thread(unsigned tid, unsigned space_id, addr_t utcb) {
_tid = tid; _space_id = space_id; _utcb = utcb; }
void _assign_physical_thread(unsigned tid, unsigned space_id,
addr_t utcb,
Weak_ptr<Address_space> address_space)
{
_tid = tid; _space_id = space_id; _utcb = utcb;
_address_space = address_space;
}
public:
@ -100,6 +109,11 @@ namespace Genode {
*/
Thread_state state();
/**
* Return the address space to which the thread is bound
*/
Weak_ptr<Address_space> address_space();
/************************
** Accessor functions **

View File

@ -67,7 +67,8 @@ int Platform_pd::bind_thread(Platform_thread *thread)
}
addr_t utcb_addr = UTCB_VIRT_BASE + utcb_idx*sizeof(struct utcb);
thread->_assign_physical_thread(ids.tid, _space_id, utcb_addr);
thread->_assign_physical_thread(ids.tid, _space_id, utcb_addr,
this->Address_space::weak_ptr());
return 0;
}

View File

@ -98,6 +98,12 @@ void Platform_thread::cancel_blocking()
}
Weak_ptr<Address_space> Platform_thread::address_space()
{
return _address_space;
}
Platform_thread::Platform_thread(const char *name, unsigned, addr_t,
int thread_id)
: _tid(THREAD_INVALID)