Consolidate RM service into PD session

This patch integrates three region maps into each PD session to
reduce the session overhead and to simplify the PD creation procedure.
Please refer to the issue cited below for an elaborative discussion.

Note the API change:

With this patch, the semantics of core's RM service have changed. Now,
the service is merely a tool for creating and destroying managed
dataspaces, which are rarely needed. Regular components no longer need a
RM session. For this reason, the corresponding argument for the
'Process' and 'Child' constructors has been removed.

The former interface of the 'Rm_session' is not named 'Region_map'. As a
minor refinement, the 'Fault_type' enum values are now part of the
'Region_map::State' struct.

Issue #1938
This commit is contained in:
Norman Feske 2016-04-15 15:19:22 +02:00 committed by Christian Helmuth
parent e20bbe7002
commit 511acad507
189 changed files with 3314 additions and 2934 deletions

View File

@ -23,6 +23,7 @@ SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
SRC_CC += thread/myself.cc SRC_CC += thread/myself.cc
SRC_CC += thread/stack_allocator.cc SRC_CC += thread/stack_allocator.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.cc SRC_CC += entrypoint/entrypoint.cc
SRC_CC += component/component.cc SRC_CC += component/component.cc

View File

@ -187,7 +187,7 @@ namespace Genode {
/* /*
* On L4/Fiasco, we don't use directed unmap but rely on the * On L4/Fiasco, we don't use directed unmap but rely on the
* in-kernel mapping database. See 'rm_session_support.cc'. * in-kernel mapping database. See 'region_map_support.cc'.
*/ */
void flush(addr_t, size_t) { PDBG("not implemented"); } void flush(addr_t, size_t) { PDBG("not implemented"); }
}; };

View File

@ -107,6 +107,15 @@ namespace Genode {
*/ */
void unbind(); void unbind();
/**
* Return pointer to the thread's PD
*
* Used to validate the success of the bind operation.
*
* XXX to be removed
*/
Platform_pd *pd() { return _platform_pd; }
/** /**
* Override thread state with 's' * Override thread state with 's'
* *

View File

@ -19,7 +19,7 @@
/* Genode includes */ /* Genode includes */
#include <base/stdint.h> #include <base/stdint.h>
#include <base/printf.h> #include <base/printf.h>
#include <rm_session/rm_session.h> #include <region_map/region_map.h>
#include <util/touch.h> #include <util/touch.h>
/* base-internal includes */ /* base-internal includes */
@ -100,13 +100,13 @@ namespace Genode {
constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; } constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; }
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Rm_session::Fault_type pf_type, Region_map::State::Fault_type pf_type,
unsigned long badge) unsigned long badge)
{ {
Fiasco::l4_threadid_t tid; Fiasco::l4_threadid_t tid;
tid.raw = badge; tid.raw = badge;
printf("%s (%s pf_addr=%p pf_ip=%p from %x.%02x)\n", msg, printf("%s (%s pf_addr=%p pf_ip=%p from %x.%02x)\n", msg,
pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
(void *)pf_addr, (void *)pf_ip, (void *)pf_addr, (void *)pf_ip,
(int)tid.id.task, (int)tid.id.lthread); (int)tid.id.task, (int)tid.id.lthread);
} }

View File

@ -28,8 +28,8 @@ SRC_CC += stack_area.cc \
platform_thread.cc \ platform_thread.cc \
ram_session_component.cc \ ram_session_component.cc \
ram_session_support.cc \ ram_session_support.cc \
rm_session_component.cc \ region_map_component.cc \
rm_session_support.cc \ region_map_support.cc \
rom_session_component.cc \ rom_session_component.cc \
signal_source_component.cc \ signal_source_component.cc \
thread_start.cc \ thread_start.cc \
@ -56,7 +56,7 @@ vpath rpc_cap_factory.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR) vpath region_map_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR)
vpath signal_source_component.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR)

View File

@ -24,6 +24,7 @@ SRC_CC += thread/myself.cc
SRC_CC += thread/stack_allocator.cc SRC_CC += thread/stack_allocator.cc
SRC_CC += thread/thread_utcb.cc SRC_CC += thread/thread_utcb.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.cc SRC_CC += entrypoint/entrypoint.cc
SRC_CC += component/component.cc SRC_CC += component/component.cc

View File

@ -59,7 +59,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
if (!_thread_cap.valid()) if (!_thread_cap.valid())
throw Cpu_session::Thread_creation_failed(); throw Cpu_session::Thread_creation_failed();
env()->pd_session()->bind_thread(_thread_cap); env()->pd_session()->bind_thread(_thread_cap);
return; return;
} }
/* adjust values whose computation differs for a main thread */ /* adjust values whose computation differs for a main thread */
@ -80,7 +80,11 @@ void Thread_base::start()
using namespace Fiasco; using namespace Fiasco;
/* create new pager object and assign it to the new thread */ /* create new pager object and assign it to the new thread */
_pager_cap = env()->rm_session()->add_client(_thread_cap); try {
_pager_cap = env()->rm_session()->add_client(_thread_cap);
} catch (Region_map::Unbound_thread) {
throw Cpu_session::Thread_creation_failed(); }
_cpu_session->set_pager(_thread_cap, _pager_cap); _cpu_session->set_pager(_thread_cap, _pager_cap);
/* get gate-capability and badge of new thread */ /* get gate-capability and badge of new thread */

View File

@ -110,7 +110,7 @@ namespace Genode {
/* /*
* On Fiasco.OC, we don't use directed unmap but rely on the * On Fiasco.OC, we don't use directed unmap but rely on the
* in-kernel mapping database. See 'rm_session_support.cc'. * in-kernel mapping database. See 'region_map_support.cc'.
*/ */
void flush(addr_t, size_t) { PDBG("not implemented"); } void flush(addr_t, size_t) { PDBG("not implemented"); }
}; };

View File

@ -125,6 +125,15 @@ namespace Genode {
*/ */
void unbind(); void unbind();
/**
* Return pointer to the thread's PD
*
* Used to validate the success of the bind operation.
*
* XXX to be removed
*/
Platform_pd *pd() { return _platform_pd; }
/** /**
* Override thread state with 's' * Override thread state with 's'
* *

View File

@ -97,11 +97,11 @@ namespace Genode {
constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; } constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; }
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Rm_session::Fault_type pf_type, Region_map::State::Fault_type pf_type,
unsigned long badge) unsigned long badge)
{ {
printf("%s (%s pf_addr=%p pf_ip=%p from %lx)\n", msg, printf("%s (%s pf_addr=%p pf_ip=%p from %lx)\n", msg,
pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
(void *)pf_addr, (void *)pf_ip, badge); (void *)pf_addr, (void *)pf_ip, badge);
} }

View File

@ -32,8 +32,8 @@ SRC_CC += stack_area.cc \
platform_thread.cc \ platform_thread.cc \
ram_session_component.cc \ ram_session_component.cc \
ram_session_support.cc \ ram_session_support.cc \
rm_session_component.cc \ region_map_component.cc \
rm_session_support.cc \ region_map_support.cc \
rom_session_component.cc \ rom_session_component.cc \
signal_source_component.cc \ signal_source_component.cc \
thread_start.cc \ thread_start.cc \
@ -59,7 +59,7 @@ vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR) vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR) vpath region_map_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)

View File

@ -1,42 +0,0 @@
/*
* \brief Connection to PD service
* \author Stefan Kalkowski
* \author Norman Feske
* \date 2015-05-20
*
* This is a shadow copy of the generic header in base,
* due to higher memory donation requirements in base-hw
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__PD_SESSION__CONNECTION_H_
#define _INCLUDE__PD_SESSION__CONNECTION_H_
#include <pd_session/client.h>
#include <base/connection.h>
namespace Genode { struct Pd_connection; }
struct Genode::Pd_connection : Connection<Pd_session>, Pd_session_client
{
enum { RAM_QUOTA = 36*1024 };
/**
* Constructor
*
* \param label session label
*/
Pd_connection(char const *label = "")
: Connection<Pd_session>(session("ram_quota=%u, label=\"%s\"",
RAM_QUOTA, label)),
Pd_session_client(cap()) { }
};
#endif /* _INCLUDE__PD_SESSION__CONNECTION_H_ */

View File

@ -28,6 +28,7 @@ SRC_CC += thread/trace.cc
SRC_CC += thread/stack_allocator.cc SRC_CC += thread/stack_allocator.cc
SRC_CC += kernel/interface.cc SRC_CC += kernel/interface.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.cc SRC_CC += entrypoint/entrypoint.cc
SRC_CC += component/component.cc SRC_CC += component/component.cc

View File

@ -18,7 +18,7 @@ INC_DIR += $(REP_DIR)/src/include $(BASE_DIR)/src/include
SRC_CC += console.cc SRC_CC += console.cc
SRC_CC += cpu_session_component.cc SRC_CC += cpu_session_component.cc
SRC_CC += cpu_session_support.cc SRC_CC += cpu_session_support.cc
SRC_CC += core_rm_session.cc SRC_CC += core_region_map.cc
SRC_CC += core_mem_alloc.cc SRC_CC += core_mem_alloc.cc
SRC_CC += core_rpc_cap_alloc.cc SRC_CC += core_rpc_cap_alloc.cc
SRC_CC += dataspace_component.cc SRC_CC += dataspace_component.cc
@ -36,12 +36,12 @@ SRC_CC += platform_thread.cc
SRC_CC += stack_area.cc SRC_CC += stack_area.cc
SRC_CC += ram_session_component.cc SRC_CC += ram_session_component.cc
SRC_CC += ram_session_support.cc SRC_CC += ram_session_support.cc
SRC_CC += rm_session_component.cc SRC_CC += region_map_component.cc
SRC_CC += rom_session_component.cc SRC_CC += rom_session_component.cc
SRC_CC += trace_session_component.cc SRC_CC += trace_session_component.cc
SRC_CC += thread_start.cc SRC_CC += thread_start.cc
SRC_CC += env.cc SRC_CC += env.cc
SRC_CC += rm_session_support.cc SRC_CC += region_map_support.cc
SRC_CC += pager.cc SRC_CC += pager.cc
SRC_CC += _main.cc SRC_CC += _main.cc
SRC_CC += component_construct.cc SRC_CC += component_construct.cc

View File

@ -21,11 +21,10 @@
/* base-internal includes */ /* base-internal includes */
#include <base/internal/stack_allocator.h> #include <base/internal/stack_allocator.h>
#include <base/internal/native_utcb.h> #include <base/internal/native_utcb.h>
#include <base/internal/platform_env_common.h>
using namespace Genode; using namespace Genode;
namespace Genode { extern Rm_session * const env_stack_area_rm_session; }
namespace Hw { namespace Hw {
extern Ram_dataspace_capability _main_thread_utcb_ds; extern Ram_dataspace_capability _main_thread_utcb_ds;
extern Untyped_capability _main_thread_cap; extern Untyped_capability _main_thread_cap;
@ -51,7 +50,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
size_t const utcb_size = sizeof(Native_utcb); size_t const utcb_size = sizeof(Native_utcb);
addr_t const stack_area = stack_area_virtual_base(); addr_t const stack_area = stack_area_virtual_base();
addr_t const utcb_new = (addr_t)&_stack->utcb() - stack_area; addr_t const utcb_new = (addr_t)&_stack->utcb() - stack_area;
Rm_session * const rm = env_stack_area_rm_session; Region_map * const rm = env_stack_area_region_map;
if (type == REINITIALIZED_MAIN) { rm->detach(utcb_new); } if (type == REINITIALIZED_MAIN) { rm->detach(utcb_new); }
@ -78,7 +77,7 @@ void Thread_base::_deinit_platform_thread()
size_t const size = sizeof(_stack->utcb()); size_t const size = sizeof(_stack->utcb());
addr_t utcb = Stack_allocator::addr_to_base(_stack) + addr_t utcb = Stack_allocator::addr_to_base(_stack) +
stack_virtual_size() - size - stack_area_virtual_base(); stack_virtual_size() - size - stack_area_virtual_base();
env_stack_area_rm_session->detach(utcb); env_stack_area_region_map->detach(utcb);
if (_pager_cap.valid()) { if (_pager_cap.valid()) {
env()->rm_session()->remove_client(_pager_cap); env()->rm_session()->remove_client(_pager_cap);
@ -101,7 +100,7 @@ void Thread_base::start()
size_t const size = sizeof(_stack->utcb()); size_t const size = sizeof(_stack->utcb());
addr_t dst = Stack_allocator::addr_to_base(_stack) + addr_t dst = Stack_allocator::addr_to_base(_stack) +
stack_virtual_size() - size - stack_area_virtual_base(); stack_virtual_size() - size - stack_area_virtual_base();
env_stack_area_rm_session->attach_at(ds, dst, size); env_stack_area_region_map->attach_at(ds, dst, size);
} catch (...) { } catch (...) {
PERR("failed to attach userland stack"); PERR("failed to attach userland stack");
sleep_forever(); sleep_forever();

View File

@ -16,17 +16,17 @@
/* core includes */ /* core includes */
#include <platform.h> #include <platform.h>
#include <core_rm_session.h> #include <core_region_map.h>
#include <map_local.h> #include <map_local.h>
#include <util.h> #include <util.h>
#include <base/heap.h> #include <base/heap.h>
using namespace Genode; using namespace Genode;
Rm_session::Local_addr Region_map::Local_addr
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, Core_region_map::attach(Dataspace_capability ds_cap, size_t size,
off_t offset, bool use_local_addr, off_t offset, bool use_local_addr,
Rm_session::Local_addr, bool executable) Region_map::Local_addr, bool executable)
{ {
auto lambda = [&] (Dataspace_component *ds) -> Local_addr { auto lambda = [&] (Dataspace_component *ds) -> Local_addr {
if (!ds) if (!ds)

View File

@ -0,0 +1,57 @@
/*
* \brief Kernel-specific core-local region map
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2009-04-02
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__CORE_REGION_MAP_H_
#define _CORE__INCLUDE__CORE_REGION_MAP_H_
/* Genode includes */
#include <region_map/region_map.h>
#include <base/rpc_server.h>
/* core includes */
#include <dataspace_component.h>
namespace Genode { class Core_region_map; }
class Genode::Core_region_map : public Region_map
{
private:
Rpc_entrypoint *_ds_ep;
public:
Core_region_map(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { }
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
off_t offset=0, bool use_local_addr = false,
Local_addr local_addr = 0,
bool executable = false);
void detach(Local_addr) { }
Pager_capability add_client(Thread_capability thread) {
return Pager_capability(); }
void remove_client(Pager_capability) { }
void fault_handler(Signal_context_capability handler) { }
State state() { return State(); }
Dataspace_capability dataspace() { return Dataspace_capability(); }
};
#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */

View File

@ -1,61 +0,0 @@
/*
* \brief OKL4-specific core-local region manager session
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2009-04-02
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__CORE_RM_SESSION_H_
#define _CORE__INCLUDE__CORE_RM_SESSION_H_
/* Genode includes */
#include <rm_session/rm_session.h>
#include <base/rpc_server.h>
/* core includes */
#include <dataspace_component.h>
namespace Genode {
/**
* Region manager that uses the physical dataspace
* addresses directly as virtual addresses.
*/
class Core_rm_session : public Rm_session
{
private:
Rpc_entrypoint *_ds_ep;
public:
Core_rm_session(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { }
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
off_t offset=0, bool use_local_addr = false,
Local_addr local_addr = 0,
bool executable = false);
void detach(Local_addr) { }
Pager_capability add_client(Thread_capability thread) {
return Pager_capability(); }
void remove_client(Pager_capability) { }
void fault_handler(Signal_context_capability handler) { }
State state() { return State(); }
Dataspace_capability dataspace() { return Dataspace_capability(); }
};
}
#endif /* _CORE__INCLUDE__CORE_RM_SESSION_H_ */

View File

@ -28,7 +28,7 @@
/* core includes */ /* core includes */
#include <translation_table_allocator_tpl.h> #include <translation_table_allocator_tpl.h>
#include <platform_generic.h> #include <platform_generic.h>
#include <core_rm_session.h> #include <core_region_map.h>
#include <core_mem_alloc.h> #include <core_mem_alloc.h>
namespace Genode { namespace Genode {

View File

@ -114,7 +114,7 @@ namespace Genode
inline void print_page_fault(char const * const fault_msg, inline void print_page_fault(char const * const fault_msg,
addr_t const fault_addr, addr_t const fault_addr,
addr_t const fault_ip, addr_t const fault_ip,
Rm_session::Fault_type const fault_type, Region_map::State::Fault_type const fault_type,
unsigned const faulter_badge); unsigned const faulter_badge);
} }
@ -122,14 +122,14 @@ namespace Genode
void Genode::print_page_fault(char const * const fault_msg, void Genode::print_page_fault(char const * const fault_msg,
addr_t const fault_addr, addr_t const fault_addr,
addr_t const fault_ip, addr_t const fault_ip,
Rm_session::Fault_type const fault_type, Region_map::State::Fault_type const fault_type,
unsigned const faulter_badge) unsigned const faulter_badge)
{ {
const char read[] = "read from"; const char read[] = "read from";
const char write[] = "write to"; const char write[] = "write to";
printf("\033[31m%s\033[0m (faulter %x", fault_msg, faulter_badge); printf("\033[31m%s\033[0m (faulter %x", fault_msg, faulter_badge);
printf(" with IP %p attempts to", (void *)fault_ip); printf(" with IP %p attempts to", (void *)fault_ip);
printf(" %s", fault_type == Rm_session::READ_FAULT ? read : write); printf(" %s", fault_type == Region_map::State::READ_FAULT ? read : write);
printf(" address %p)\n", (void *)fault_addr); printf(" address %p)\n", (void *)fault_addr);
if (ACTIVITY_TABLE_ON_FAULTS) { if (ACTIVITY_TABLE_ON_FAULTS) {
printf("---------- activity table ----------\n"); printf("---------- activity table ----------\n");

View File

@ -16,12 +16,13 @@ SRC_CC += child/child.cc
SRC_CC += process/process.cc SRC_CC += process/process.cc
SRC_CC += elf/elf_binary.cc SRC_CC += elf/elf_binary.cc
SRC_CC += lock/lock.cc SRC_CC += lock/lock.cc
SRC_CC += env/rm_session_mmap.cc env/debug.cc SRC_CC += env/region_map_mmap.cc env/debug.cc
SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc
SRC_CC += server/server.cc server/common.cc SRC_CC += server/server.cc server/common.cc
SRC_CC += thread/trace.cc thread/thread_env.cc thread/stack_allocator.cc SRC_CC += thread/trace.cc thread/thread_env.cc thread/stack_allocator.cc
SRC_CC += irq/platform.cc SRC_CC += irq/platform.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.cc SRC_CC += entrypoint/entrypoint.cc
SRC_CC += component/component.cc SRC_CC += component/component.cc

View File

@ -1,4 +1,4 @@
build "core init test/rm_session_mmap drivers/timer test/signal" build "core init test/region_map_mmap drivers/timer test/signal"
create_boot_directory create_boot_directory
@ -20,7 +20,7 @@ install_config {
<default-route> <default-route>
<any-service> <parent/> <any-child/> </any-service> <any-service> <parent/> <any-child/> </any-service>
</default-route> </default-route>
<start name="test-rm_session_mmap"> <start name="test-region_map_mmap">
<resource name="RAM" quantum="2M"/> <resource name="RAM" quantum="2M"/>
</start> </start>
@ -34,7 +34,7 @@ install_config {
</start> </start>
</config>} </config>}
build_boot_image "core init test-rm_session_mmap timer test-signal" build_boot_image "core init test-region_map_mmap timer test-signal"
run_genode_until forever run_genode_until forever

View File

@ -29,7 +29,7 @@ using namespace Genode;
****************************************************/ ****************************************************/
Genode::size_t Genode::size_t
Platform_env_base::Rm_session_mmap::_dataspace_size(Dataspace_capability ds) Platform_env_base::Region_map_mmap::_dataspace_size(Dataspace_capability ds)
{ {
if (ds.valid()) if (ds.valid())
return Dataspace_client(ds).size(); return Dataspace_client(ds).size();
@ -38,19 +38,20 @@ Platform_env_base::Rm_session_mmap::_dataspace_size(Dataspace_capability ds)
} }
int Platform_env_base::Rm_session_mmap::_dataspace_fd(Dataspace_capability ds) int Platform_env_base::Region_map_mmap::_dataspace_fd(Dataspace_capability ds)
{ {
return Linux_dataspace_client(ds).fd().dst().socket; return Linux_dataspace_client(ds).fd().dst().socket;
} }
bool bool
Platform_env_base::Rm_session_mmap::_dataspace_writable(Dataspace_capability ds) Platform_env_base::Region_map_mmap::_dataspace_writable(Dataspace_capability ds)
{ {
return Dataspace_client(ds).writable(); return Dataspace_client(ds).writable();
} }
/******************************** /********************************
** Platform_env::Local_parent ** ** Platform_env::Local_parent **
********************************/ ********************************/
@ -63,22 +64,11 @@ Platform_env::Local_parent::session(Service_name const &service_name,
Session_args const &args, Session_args const &args,
Affinity const &affinity) Affinity const &affinity)
{ {
if (strcmp(service_name.string(), if (strcmp(service_name.string(), Rm_session::service_name()) == 0)
Rm_session::service_name()) == 0)
{ {
size_t size = Local_rm_session *session = new (_alloc) Local_rm_session(_alloc);
Arg_string::find_arg(args.string(),"size")
.ulong_value(~0);
if (size == 0) return Local_capability<Session>::local_cap(session);
return Expanding_parent_client::session(service_name, args, affinity);
if (size != ~0UL)
size = align_addr(size, get_page_size_log2());
Rm_session_mmap *rm = new (_alloc) Rm_session_mmap(true, size);
return Local_capability<Session>::local_cap(rm);
} }
return Expanding_parent_client::session(service_name, args, affinity); return Expanding_parent_client::session(service_name, args, affinity);
@ -98,9 +88,9 @@ void Platform_env::Local_parent::close(Session_capability session)
/* /*
* Detect capability to local RM session * Detect capability to local RM session
*/ */
Capability<Rm_session_mmap> rm = static_cap_cast<Rm_session_mmap>(session); Capability<Rm_session> rm = static_cap_cast<Rm_session>(session);
destroy(env()->heap(), Local_capability<Rm_session_mmap>::deref(rm)); destroy(_alloc, Local_capability<Rm_session>::deref(rm));
} }
@ -162,11 +152,15 @@ Platform_env::Platform_env()
static_cap_cast<Cpu_session>(_parent().session("Env::cpu_session", "")), static_cap_cast<Cpu_session>(_parent().session("Env::cpu_session", "")),
static_cap_cast<Pd_session> (_parent().session("Env::pd_session", ""))), static_cap_cast<Pd_session> (_parent().session("Env::pd_session", ""))),
_heap(Platform_env_base::ram_session(), Platform_env_base::rm_session()), _heap(Platform_env_base::ram_session(), Platform_env_base::rm_session()),
_stack_area(*parent(), *rm_session()),
_emergency_ram_ds(ram_session()->alloc(_emergency_ram_size())) _emergency_ram_ds(ram_session()->alloc(_emergency_ram_size()))
{ {
/* attach stack area to local address space */
_local_pd_session._address_space.attach_at(_local_pd_session._stack_area.dataspace(),
stack_area_virtual_base(),
stack_area_virtual_size());
env_stack_area_region_map = &_local_pd_session._stack_area;
env_stack_area_ram_session = ram_session(); env_stack_area_ram_session = ram_session();
env_stack_area_rm_session = &_stack_area;
/* register TID and PID of the main thread at core */ /* register TID and PID of the main thread at core */
Linux_native_cpu_client native_cpu(cpu_session()->native_cpu()); Linux_native_cpu_client native_cpu(cpu_session()->native_cpu());

View File

@ -1,5 +1,5 @@
/* /*
* \brief Implementation of Linux-specific local region manager * \brief Implementation of Linux-specific local region map
* \author Norman Feske * \author Norman Feske
* \date 2008-10-22 * \date 2008-10-22
* *
@ -54,7 +54,7 @@ static bool is_sub_rm_session(Dataspace_capability ds)
} }
addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_local_addr, addr_t Platform_env_base::Region_map_mmap::_reserve_local(bool use_local_addr,
addr_t local_addr, addr_t local_addr,
Genode::size_t size) Genode::size_t size)
{ {
@ -94,7 +94,7 @@ addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_loc
|| (((long)addr_out < 0) && ((long)addr_out > -4095))) { || (((long)addr_out < 0) && ((long)addr_out > -4095))) {
PERR("_reserve_local: lx_mmap failed (addr_in=%p,addr_out=%p/%ld)", PERR("_reserve_local: lx_mmap failed (addr_in=%p,addr_out=%p/%ld)",
addr_in, addr_out, (long)addr_out); addr_in, addr_out, (long)addr_out);
throw Rm_session::Region_conflict(); throw Region_map::Region_conflict();
} }
return (addr_t) addr_out; return (addr_t) addr_out;
@ -102,7 +102,7 @@ addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_loc
void * void *
Platform_env_base::Rm_session_mmap::_map_local(Dataspace_capability ds, Platform_env_base::Region_map_mmap::_map_local(Dataspace_capability ds,
Genode::size_t size, Genode::size_t size,
addr_t offset, addr_t offset,
bool use_local_addr, bool use_local_addr,
@ -136,14 +136,14 @@ Platform_env_base::Rm_session_mmap::_map_local(Dataspace_capability ds,
|| (((long)addr_out < 0) && ((long)addr_out > -4095))) { || (((long)addr_out < 0) && ((long)addr_out > -4095))) {
PERR("_map_local: lx_mmap failed (addr_in=%p,addr_out=%p/%ld) overmap=%d", PERR("_map_local: lx_mmap failed (addr_in=%p,addr_out=%p/%ld) overmap=%d",
addr_in, addr_out, (long)addr_out, overmap); addr_in, addr_out, (long)addr_out, overmap);
throw Rm_session::Region_conflict(); throw Region_map::Region_conflict();
} }
return addr_out; return addr_out;
} }
void Platform_env::Rm_session_mmap::_add_to_rmap(Region const &region) void Platform_env::Region_map_mmap::_add_to_rmap(Region const &region)
{ {
if (_rmap.add_region(region) < 0) { if (_rmap.add_region(region) < 0) {
PERR("_add_to_rmap: could not add region to sub RM session"); PERR("_add_to_rmap: could not add region to sub RM session");
@ -152,23 +152,23 @@ void Platform_env::Rm_session_mmap::_add_to_rmap(Region const &region)
} }
Rm_session::Local_addr Region_map::Local_addr
Platform_env::Rm_session_mmap::attach(Dataspace_capability ds, Platform_env::Region_map_mmap::attach(Dataspace_capability ds,
size_t size, off_t offset, size_t size, off_t offset,
bool use_local_addr, bool use_local_addr,
Rm_session::Local_addr local_addr, Region_map::Local_addr local_addr,
bool executable) bool executable)
{ {
Lock::Guard lock_guard(_lock); Lock::Guard lock_guard(_lock);
/* only support attach_at for sub RM sessions */ /* only support attach_at for sub RM sessions */
if (_sub_rm && !use_local_addr) { if (_sub_rm && !use_local_addr) {
PERR("Rm_session_mmap::attach: attaching w/o local addr not supported\n"); PERR("Region_map_mmap::attach: attaching w/o local addr not supported\n");
throw Out_of_metadata(); throw Out_of_metadata();
} }
if (offset < 0) { if (offset < 0) {
PERR("Rm_session_mmap::attach: negative offset not supported\n"); PERR("Region_map_mmap::attach: negative offset not supported\n");
throw Region_conflict(); throw Region_conflict();
} }
@ -200,7 +200,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
* Case 4 * Case 4
*/ */
if (is_sub_rm_session(ds)) { if (is_sub_rm_session(ds)) {
PERR("Rm_session_mmap::attach: nesting sub RM sessions is not supported"); PERR("Region_map_mmap::attach: nesting sub RM sessions is not supported");
throw Invalid_dataspace(); throw Invalid_dataspace();
} }
@ -209,7 +209,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
* sub RM session * sub RM session
*/ */
if (region_size + (addr_t)local_addr > _size) { if (region_size + (addr_t)local_addr > _size) {
PERR("Rm_session_mmap::attach: dataspace does not fit in sub RM session"); PERR("Region_map_mmap::attach: dataspace does not fit in sub RM session");
throw Region_conflict(); throw Region_conflict();
} }
@ -234,7 +234,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
Dataspace *ds_if = Local_capability<Dataspace>::deref(ds); Dataspace *ds_if = Local_capability<Dataspace>::deref(ds);
Rm_session_mmap *rm = dynamic_cast<Rm_session_mmap *>(ds_if); Region_map_mmap *rm = dynamic_cast<Region_map_mmap *>(ds_if);
if (!rm) if (!rm)
throw Invalid_dataspace(); throw Invalid_dataspace();
@ -245,7 +245,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
* Detect if sub RM session is already attached * Detect if sub RM session is already attached
*/ */
if (rm->_base) { if (rm->_base) {
PERR("Rm_session_mmap::attach: mapping a sub RM session twice is not supported"); PERR("Region_map_mmap::attach: mapping a sub RM session twice is not supported");
throw Out_of_metadata(); throw Out_of_metadata();
} }
@ -264,7 +264,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
* been populated with dataspaces. Go through all regions and map * been populated with dataspaces. Go through all regions and map
* each of them. * each of them.
*/ */
for (int i = 0; i < Region_map::MAX_REGIONS; i++) { for (int i = 0; i < Region_registry::MAX_REGIONS; i++) {
Region region = rm->_rmap.region(i); Region region = rm->_rmap.region(i);
if (!region.used()) if (!region.used())
continue; continue;
@ -299,7 +299,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
} }
void Platform_env::Rm_session_mmap::detach(Rm_session::Local_addr local_addr) void Platform_env::Region_map_mmap::detach(Region_map::Local_addr local_addr)
{ {
Lock::Guard lock_guard(_lock); Lock::Guard lock_guard(_lock);
@ -357,7 +357,7 @@ void Platform_env::Rm_session_mmap::detach(Rm_session::Local_addr local_addr)
if (is_sub_rm_session(region.dataspace())) { if (is_sub_rm_session(region.dataspace())) {
Dataspace *ds_if = Local_capability<Dataspace>::deref(region.dataspace()); Dataspace *ds_if = Local_capability<Dataspace>::deref(region.dataspace());
Rm_session_mmap *rm = dynamic_cast<Rm_session_mmap *>(ds_if); Region_map_mmap *rm = dynamic_cast<Region_map_mmap *>(ds_if);
if (rm) if (rm)
rm->_base = 0; rm->_base = 0;
} }

View File

@ -56,13 +56,11 @@ Process::Process(Dataspace_capability elf_data_ds_cap,
Pd_session_capability pd_session_cap, Pd_session_capability pd_session_cap,
Ram_session_capability ram_session_cap, Ram_session_capability ram_session_cap,
Cpu_session_capability cpu_session_cap, Cpu_session_capability cpu_session_cap,
Rm_session_capability rm_session_cap,
Parent_capability parent_cap, Parent_capability parent_cap,
char const *name) char const *name)
: :
_pd_session_client(pd_session_cap), _pd_session_client(pd_session_cap),
_cpu_session_client(cpu_session_cap), _cpu_session_client(cpu_session_cap)
_rm_session_client(Rm_session_capability())
{ {
/* check for dynamic program header */ /* check for dynamic program header */
if (_check_dynamic_elf(elf_data_ds_cap)) { if (_check_dynamic_elf(elf_data_ds_cap)) {

View File

@ -0,0 +1,77 @@
/*
* \brief Pseudo region map client stub targeting the process-local implementation
* \author Norman Feske
* \date 2011-11-21
*/
/*
* Copyright (C) 2011-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <region_map/client.h>
/* base-internal includes */
#include <base/internal/local_capability.h>
using namespace Genode;
/**
* Return pointer to locally implemented region map
*
* \throw Local_interface::Non_local_capability
*/
static Region_map *_local(Capability<Region_map> cap)
{
return Local_capability<Region_map>::deref(cap);
}
Region_map_client::Region_map_client(Capability<Region_map> session)
: Rpc_client<Region_map>(session) { }
Region_map::Local_addr
Region_map_client::attach(Dataspace_capability ds, size_t size,
off_t offset, bool use_local_addr,
Region_map::Local_addr local_addr,
bool executable)
{
return _local(*this)->attach(ds, size, offset, use_local_addr,
local_addr, executable);
}
void Region_map_client::detach(Local_addr local_addr) {
return _local(*this)->detach(local_addr); }
Pager_capability Region_map_client::add_client(Thread_capability thread) {
return _local(*this)->add_client(thread); }
void Region_map_client::remove_client(Pager_capability pager) {
_local(*this)->remove_client(pager); }
void Region_map_client::fault_handler(Signal_context_capability /*handler*/)
{
/*
* On Linux, page faults are never reflected to the user land. They
* are always handled by the kernel. If a segmentation fault
* occurs, this condition is being reflected as a CPU exception
* to the handler registered via 'Cpu_session::exception_handler'.
*/
}
Region_map::State Region_map_client::state() { return _local(*this)->state(); }
Dataspace_capability Region_map_client::dataspace() {
return _local(*this)->dataspace(); }

View File

@ -1,5 +1,5 @@
/* /*
* \brief Pseudo RM-session client stub targeting the process-local RM service * \brief Pseudo RM session client stub targeting the process-local implementation
* \author Norman Feske * \author Norman Feske
* \date 2011-11-21 * \date 2011-11-21
*/ */
@ -25,52 +25,19 @@ using namespace Genode;
* *
* \throw Local_interface::Non_local_capability * \throw Local_interface::Non_local_capability
*/ */
static Rm_session *_local(Rm_session_capability cap) static Rm_session *_local(Capability<Rm_session> cap)
{ {
return Local_capability<Rm_session>::deref(cap); return Local_capability<Rm_session>::deref(cap);
} }
Rm_session_client::Rm_session_client(Rm_session_capability session) Rm_session_client::Rm_session_client(Capability<Rm_session> session)
: Rpc_client<Rm_session>(session) { } : Rpc_client<Rm_session>(session) { }
Rm_session::Local_addr Capability<Region_map> Rm_session_client::create(size_t size) {
Rm_session_client::attach(Dataspace_capability ds, size_t size, return _local(*this)->create(size); }
off_t offset, bool use_local_addr,
Rm_session::Local_addr local_addr,
bool executable)
{
return _local(*this)->attach(ds, size, offset, use_local_addr,
local_addr, executable);
}
void Rm_session_client::detach(Local_addr local_addr) {
return _local(*this)->detach(local_addr); }
Pager_capability Rm_session_client::add_client(Thread_capability thread) { void Rm_session_client::destroy(Capability<Region_map> cap) {
return _local(*this)->add_client(thread); } _local(*this)->destroy(cap); }
void Rm_session_client::remove_client(Pager_capability pager) {
_local(*this)->remove_client(pager); }
void Rm_session_client::fault_handler(Signal_context_capability /*handler*/)
{
/*
* On Linux, page faults are never reflected to RM clients. They
* are always handled by the kernel. If a segmentation fault
* occurs, this condition is being reflected as a CPU exception
* to the handler registered via 'Cpu_session::exception_handler'.
*/
}
Rm_session::State Rm_session_client::state() { return _local(*this)->state(); }
Dataspace_capability Rm_session_client::dataspace() {
return _local(*this)->dataspace(); }

View File

@ -0,0 +1,74 @@
/*
* \brief Core-specific instance of the region-map interface
* \author Christian Helmuth
* \date 2006-07-17
*
* Dummies for Linux platform
*/
/*
* Copyright (C) 2006-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__REGION_MAP_COMPONENT_H_
#define _CORE__INCLUDE__REGION_MAP_COMPONENT_H_
/* Genode includes */
#include <util/list.h>
#include <base/allocator.h>
#include <base/rpc_server.h>
#include <region_map/region_map.h>
/* Core includes */
#include <pager.h>
namespace Genode {
struct Rm_client;
struct Rm_member;
class Region_map_component;
}
class Genode::Region_map_component : public Rpc_object<Region_map>,
public List<Region_map_component>::Element
{
private:
struct Rm_dataspace_component { void sub_rm(Native_capability) { } };
public:
Region_map_component(Rpc_entrypoint &, Allocator &, Pager_entrypoint &,
addr_t, size_t) { }
void upgrade_ram_quota(size_t ram_quota) { }
Local_addr attach(Dataspace_capability, size_t, off_t, bool, Local_addr, bool) {
return (addr_t)0; }
void detach(Local_addr) { }
Pager_capability add_client(Thread_capability) {
return Pager_capability(); }
void remove_client(Pager_capability) { }
void fault_handler(Signal_context_capability) { }
State state() { return State(); }
Dataspace_capability dataspace() { return Dataspace_capability(); }
Rm_dataspace_component *dataspace_component() { return 0; }
};
struct Genode::Rm_member { Region_map_component *member_rm() { return 0; } };
struct Genode::Rm_client : Pager_object, Rm_member { };
#endif /* _CORE__INCLUDE__REGION_MAP_COMPONENT_H_ */

View File

@ -1,78 +0,0 @@
/*
* \brief Core-specific instance of the RM session interface
* \author Christian Helmuth
* \date 2006-07-17
*
* Dummies for Linux platform
*/
/*
* Copyright (C) 2006-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__RM_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__RM_SESSION_COMPONENT_H_
/* Genode includes */
#include <base/allocator.h>
#include <base/rpc_server.h>
#include <rm_session/rm_session.h>
/* Core includes */
#include <pager.h>
namespace Genode {
struct Rm_client;
class Rm_session_component : public Rpc_object<Rm_session>
{
private:
class Rm_dataspace_component {
public:
void sub_rm_session(Native_capability _cap) { }
};
public:
Rm_session_component(Rpc_entrypoint *ds_ep,
Rpc_entrypoint *thread_ep,
Rpc_entrypoint *session_ep,
Allocator *md_alloc,
size_t ram_quota,
Pager_entrypoint *pager_ep,
addr_t vm_start,
size_t vm_size) { }
void upgrade_ram_quota(size_t ram_quota) { }
Local_addr attach(Dataspace_capability, size_t, off_t, bool, Local_addr, bool) {
return (addr_t)0; }
void detach(Local_addr) { }
Pager_capability add_client(Thread_capability) {
return Pager_capability(); }
void remove_client(Pager_capability) { }
void fault_handler(Signal_context_capability) { }
State state() { return State(); }
Dataspace_capability dataspace() { return Dataspace_capability(); }
Rm_dataspace_component *dataspace_component() { return 0; }
};
struct Rm_member { Rm_session_component *member_rm_session() { return 0; } };
struct Rm_client : Pager_object, Rm_member { };
}
#endif /* _CORE__INCLUDE__RM_SESSION_COMPONENT_H_ */

View File

@ -177,18 +177,18 @@ namespace Genode {
/**************************************************** /****************************************************
** Support for Platform_env_base::Rm_session_mmap ** ** Support for Platform_env_base::Region_map_mmap **
****************************************************/ ****************************************************/
Genode::size_t Genode::size_t
Platform_env_base::Rm_session_mmap::_dataspace_size(Capability<Dataspace> ds_cap) Platform_env_base::Region_map_mmap::_dataspace_size(Capability<Dataspace> ds_cap)
{ {
if (!ds_cap.valid()) if (!ds_cap.valid())
return Local_capability<Dataspace>::deref(ds_cap)->size(); return Local_capability<Dataspace>::deref(ds_cap)->size();
/* use RPC if called from a different thread */ /* use RPC if called from a different thread */
if (!core_env()->entrypoint()->is_myself()) { if (!core_env()->entrypoint()->is_myself()) {
/* release Rm_session_mmap::_lock during RPC */ /* release Region_map_mmap::_lock during RPC */
_lock.unlock(); _lock.unlock();
Genode::size_t size = Dataspace_client(ds_cap).size(); Genode::size_t size = Dataspace_client(ds_cap).size();
_lock.lock(); _lock.lock();
@ -201,10 +201,10 @@ Platform_env_base::Rm_session_mmap::_dataspace_size(Capability<Dataspace> ds_cap
} }
int Platform_env_base::Rm_session_mmap::_dataspace_fd(Capability<Dataspace> ds_cap) int Platform_env_base::Region_map_mmap::_dataspace_fd(Capability<Dataspace> ds_cap)
{ {
if (!core_env()->entrypoint()->is_myself()) { if (!core_env()->entrypoint()->is_myself()) {
/* release Rm_session_mmap::_lock during RPC */ /* release Region_map_mmap::_lock during RPC */
_lock.unlock(); _lock.unlock();
int socket = Linux_dataspace_client(ds_cap).fd().dst().socket; int socket = Linux_dataspace_client(ds_cap).fd().dst().socket;
_lock.lock(); _lock.lock();
@ -215,7 +215,7 @@ int Platform_env_base::Rm_session_mmap::_dataspace_fd(Capability<Dataspace> ds_c
/* /*
* Return a duplicate of the dataspace file descriptor, which will be freed * Return a duplicate of the dataspace file descriptor, which will be freed
* immediately after mmap'ing the file (see 'Rm_session_mmap'). * immediately after mmap'ing the file (see 'Region_map_mmap').
* *
* Handing out the original file descriptor would result in the premature * Handing out the original file descriptor would result in the premature
* release of the descriptor. So the descriptor could be reused (i.e., as a * release of the descriptor. So the descriptor could be reused (i.e., as a
@ -227,10 +227,10 @@ int Platform_env_base::Rm_session_mmap::_dataspace_fd(Capability<Dataspace> ds_c
} }
bool Platform_env_base::Rm_session_mmap::_dataspace_writable(Dataspace_capability ds_cap) bool Platform_env_base::Region_map_mmap::_dataspace_writable(Dataspace_capability ds_cap)
{ {
if (!core_env()->entrypoint()->is_myself()) { if (!core_env()->entrypoint()->is_myself()) {
/* release Rm_session_mmap::_lock during RPC */ /* release Region_map_mmap::_lock during RPC */
_lock.unlock(); _lock.unlock();
bool writable = Dataspace_client(ds_cap).writable(); bool writable = Dataspace_client(ds_cap).writable();
_lock.lock(); _lock.lock();

View File

@ -19,21 +19,22 @@
/* base-internal includes */ /* base-internal includes */
#include <base/internal/stack_area.h> #include <base/internal/stack_area.h>
#include <base/internal/platform_env_common.h>
/** /**
* Region-manager session for allocating stacks * Region-map for allocating stacks
* *
* This class corresponds to the managed dataspace that is normally used for * This class corresponds to the managed dataspace that is normally used for
* organizing stacks within the stack. It "emulates" the sub address space by * organizing stacks within the stack. It "emulates" the sub address space by
* adjusting the local address argument to 'attach' with the offset of the * adjusting the local address argument to 'attach' with the offset of the
* stack area. * stack area.
*/ */
class Stack_area_rm_session : public Genode::Rm_session class Stack_area_region_map : public Genode::Region_map
{ {
public: public:
Stack_area_rm_session() Stack_area_region_map()
{ {
flush_stack_area(); flush_stack_area();
reserve_stack_area(); reserve_stack_area();
@ -105,13 +106,13 @@ class Stack_area_ram_session : public Genode::Ram_session
*/ */
namespace Genode { namespace Genode {
Rm_session *env_stack_area_rm_session; Region_map *env_stack_area_region_map;
Ram_session *env_stack_area_ram_session; Ram_session *env_stack_area_ram_session;
void init_stack_area() void init_stack_area()
{ {
static Stack_area_rm_session rm_inst; static Stack_area_region_map rm_inst;
env_stack_area_rm_session = &rm_inst; env_stack_area_region_map = &rm_inst;
static Stack_area_ram_session ram_inst; static Stack_area_ram_session ram_inst;
env_stack_area_ram_session = &ram_inst; env_stack_area_ram_session = &ram_inst;

View File

@ -33,6 +33,7 @@
namespace Genode { namespace Genode {
struct Expanding_cpu_session_client; struct Expanding_cpu_session_client;
class Platform_env_base;
class Platform_env; class Platform_env;
} }
@ -53,418 +54,460 @@ struct Genode::Expanding_cpu_session_client
}; };
namespace Genode { /**
* Common base class of the 'Platform_env' implementations for core and
* non-core processes.
*/
class Genode::Platform_env_base : public Env
{
private:
/** /**************************
* Common base class of the 'Platform_env' implementations for core and ** Local region manager **
* non-core processes. **************************/
*/
class Platform_env_base : public Env
{
private:
/************************** class Region
** Local region manager ** {
**************************/ private:
class Region addr_t _start;
off_t _offset;
Dataspace_capability _ds;
size_t _size;
/**
* Return offset of first byte after the region
*/
addr_t _end() const { return _start + _size; }
public:
Region() : _start(0), _offset(0), _size(0) { }
Region(addr_t start, off_t offset, Dataspace_capability ds, size_t size)
: _start(start), _offset(offset), _ds(ds), _size(size) { }
bool used() const { return _size > 0; }
addr_t start() const { return _start; }
off_t offset() const { return _offset; }
size_t size() const { return _size; }
Dataspace_capability dataspace() const { return _ds; }
bool intersects(Region const &r) const
{
return (r.start() < _end()) && (_start < r._end());
}
};
/**
* Meta data about dataspaces attached to an RM session
*/
class Region_registry
{
public:
enum { MAX_REGIONS = 4096 };
private:
Region _map[MAX_REGIONS];
bool _id_valid(int id) const {
return (id >= 0 && id < MAX_REGIONS); }
public:
/**
* Add region to region map
*
* \return region ID, or
* -1 if out of metadata, or
* -2 if region conflicts existing region
*/
int add_region(Region const &region)
{
/*
* Check for region conflicts
*/
for (int i = 0; i < MAX_REGIONS; i++) {
if (_map[i].intersects(region))
return -2;
}
/*
* Allocate new region metadata
*/
int i;
for (i = 0; i < MAX_REGIONS; i++)
if (!_map[i].used()) break;
if (i == MAX_REGIONS) {
PERR("maximum number of %d regions reached",
MAX_REGIONS);
return -1;
}
_map[i] = region;
return i;
}
Region region(int id) const
{
return _id_valid(id) ? _map[id] : Region();
}
Region lookup(addr_t start)
{
for (int i = 0; i < MAX_REGIONS; i++)
if (_map[i].start() == start)
return _map[i];
return Region();
}
void remove_region(addr_t start)
{
for (int i = 0; i < MAX_REGIONS; i++)
if (_map[i].start() == start)
_map[i] = Region();
}
};
protected:
/*
* 'Region_map_mmap' is 'protected' because it is instantiated by
* 'Platform_env::Local_parent::session()'.
*/
/*
* On Linux, we use a locally implemented region map that attaches
* dataspaces via mmap to the local address space.
*/
class Region_map_mmap : public Region_map,
public Dataspace
{
private:
Lock _lock; /* protect '_rmap' */
Region_registry _rmap;
bool const _sub_rm; /* false if region map is root */
size_t const _size;
/**
* Base offset of the RM session
*
* For a normal RM session (the one that comes with the
* 'env()', this value is zero. If the RM session is
* used as nested dataspace, '_base' contains the address
* where the managed dataspace is attached in the root RM
* session.
*
* Note that a managed dataspace cannot be attached more
* than once. Furthermore, managed dataspace cannot be
* attached to another managed dataspace. The nested
* dataspace emulation is solely implemented to support
* the common use case of managed dataspaces as mechanism
* to reserve parts of the local address space from being
* populated by the 'env()->rm_session()'. (i.e., for the
* stack area, or for the placement of consecutive
* shared-library segments)
*/
addr_t _base;
bool _is_attached() const { return _base > 0; }
void _add_to_rmap(Region const &);
/**
* Reserve VM region for sub-rm dataspace
*/
addr_t _reserve_local(bool use_local_addr,
addr_t local_addr,
Genode::size_t size);
/**
* Map dataspace into local address space
*/
void *_map_local(Dataspace_capability ds,
Genode::size_t size,
addr_t offset,
bool use_local_addr,
addr_t local_addr,
bool executable,
bool overmap = false);
/**
* Determine size of dataspace
*
* For core, this function performs a local lookup of the
* 'Dataspace_component' object. For non-core programs, the
* dataspace size is determined via an RPC to core
* (calling 'Dataspace::size()').
*/
size_t _dataspace_size(Capability<Dataspace>);
/**
* Determine file descriptor of dataspace
*/
int _dataspace_fd(Capability<Dataspace>);
/**
* Determine whether dataspace is writable
*/
bool _dataspace_writable(Capability<Dataspace>);
public:
Region_map_mmap(bool sub_rm, size_t size = ~0)
: _sub_rm(sub_rm), _size(size), _base(0) { }
~Region_map_mmap()
{
/* detach sub RM session when destructed */
if (_sub_rm && _is_attached())
env()->rm_session()->detach((void *)_base);
}
/**************************
** Region map interface **
**************************/
Local_addr attach(Dataspace_capability ds, size_t size,
off_t, bool, Local_addr,
bool executable);
void detach(Local_addr local_addr);
Pager_capability add_client(Thread_capability thread) {
return Pager_capability(); }
void remove_client(Pager_capability pager) { }
void fault_handler(Signal_context_capability handler) { }
State state() { return State(); }
/*************************
** Dataspace interface **
*************************/
size_t size() { return _size; }
addr_t phys_addr() { return 0; }
bool writable() { return true; }
/**
* Return pseudo dataspace capability of the RM session
*
* The capability returned by this function is only usable
* as argument to 'Region_map_mmap::attach'. It is not a
* real capability.
*/
Dataspace_capability dataspace() {
return Local_capability<Dataspace>::local_cap(this); }
};
struct Local_rm_session : Genode::Rm_session
{
Genode::Allocator &md_alloc;
Local_rm_session(Genode::Allocator &md_alloc) : md_alloc(md_alloc) { }
Capability<Region_map> create(size_t size)
{ {
private: Region_map *rm = new (md_alloc) Region_map_mmap(true, size);
return Local_capability<Region_map>::local_cap(rm);
}
addr_t _start; void destroy(Capability<Region_map> cap)
off_t _offset;
Dataspace_capability _ds;
size_t _size;
/**
* Return offset of first byte after the region
*/
addr_t _end() const { return _start + _size; }
public:
Region() : _start(0), _offset(0), _size(0) { }
Region(addr_t start, off_t offset, Dataspace_capability ds, size_t size)
: _start(start), _offset(offset), _ds(ds), _size(size) { }
bool used() const { return _size > 0; }
addr_t start() const { return _start; }
off_t offset() const { return _offset; }
size_t size() const { return _size; }
Dataspace_capability dataspace() const { return _ds; }
bool intersects(Region const &r) const
{
return (r.start() < _end()) && (_start < r._end());
}
};
/**
* Meta data about dataspaces attached to an RM session
*/
class Region_map
{ {
public: Region_map *rm = Local_capability<Region_map>::deref(cap);
Genode::destroy(md_alloc, rm);
}
};
enum { MAX_REGIONS = 4096 }; struct Local_pd_session : Pd_session_client
{
Region_map_mmap _address_space { false };
Region_map_mmap _stack_area { true, stack_area_virtual_size() };
Region_map_mmap _linker_area { true, Pd_session::LINKER_AREA_SIZE };
private: Local_pd_session(Pd_session_capability pd) : Pd_session_client(pd) { }
Region _map[MAX_REGIONS]; Capability<Region_map> address_space()
bool _id_valid(int id) const {
return (id >= 0 && id < MAX_REGIONS); }
public:
/**
* Add region to region map
*
* \return region ID, or
* -1 if out of metadata, or
* -2 if region conflicts existing region
*/
int add_region(Region const &region)
{
/*
* Check for region conflicts
*/
for (int i = 0; i < MAX_REGIONS; i++) {
if (_map[i].intersects(region))
return -2;
}
/*
* Allocate new region metadata
*/
int i;
for (i = 0; i < MAX_REGIONS; i++)
if (!_map[i].used()) break;
if (i == MAX_REGIONS) {
PERR("maximum number of %d regions reached",
MAX_REGIONS);
return -1;
}
_map[i] = region;
return i;
}
Region region(int id) const
{
return _id_valid(id) ? _map[id] : Region();
}
Region lookup(addr_t start)
{
for (int i = 0; i < MAX_REGIONS; i++)
if (_map[i].start() == start)
return _map[i];
return Region();
}
void remove_region(addr_t start)
{
for (int i = 0; i < MAX_REGIONS; i++)
if (_map[i].start() == start)
_map[i] = Region();
}
};
protected:
/*
* 'Rm_session_mmap' is 'protected' because it is instantiated by
* 'Platform_env::Local_parent::session()'.
*/
/*
* On Linux, we use a local region manager session that attaches
* dataspaces via mmap to the local address space.
*/
class Rm_session_mmap : public Rm_session,
public Dataspace
{ {
private: return Local_capability<Region_map>::local_cap(&_address_space);
}
Lock _lock; /* protect '_rmap' */ Capability<Region_map> stack_area()
Region_map _rmap;
bool const _sub_rm; /* false if RM session is root */
size_t const _size;
/**
* Base offset of the RM session
*
* For a normal RM session (the one that comes with the
* 'env()', this value is zero. If the RM session is
* used as nested dataspace, '_base' contains the address
* where the managed dataspace is attached in the root RM
* session.
*
* Note that a managed dataspace cannot be attached more
* than once. Furthermore, managed dataspace cannot be
* attached to another managed dataspace. The nested
* dataspace emulation is solely implemented to support
* the common use case of managed dataspaces as mechanism
* to reserve parts of the local address space from being
* populated by the 'env()->rm_session()'. (i.e., for the
* stack area, or for the placement of consecutive
* shared-library segments)
*/
addr_t _base;
bool _is_attached() const { return _base > 0; }
void _add_to_rmap(Region const &);
/**
* Reserve VM region for sub-rm dataspace
*/
addr_t _reserve_local(bool use_local_addr,
addr_t local_addr,
Genode::size_t size);
/**
* Map dataspace into local address space
*/
void *_map_local(Dataspace_capability ds,
Genode::size_t size,
addr_t offset,
bool use_local_addr,
addr_t local_addr,
bool executable,
bool overmap = false);
/**
* Determine size of dataspace
*
* For core, this function performs a local lookup of the
* 'Dataspace_component' object. For non-core programs, the
* dataspace size is determined via an RPC to core
* (calling 'Dataspace::size()').
*/
size_t _dataspace_size(Capability<Dataspace>);
/**
* Determine file descriptor of dataspace
*/
int _dataspace_fd(Capability<Dataspace>);
/**
* Determine whether dataspace is writable
*/
bool _dataspace_writable(Capability<Dataspace>);
public:
Rm_session_mmap(bool sub_rm, size_t size = ~0)
: _sub_rm(sub_rm), _size(size), _base(0) { }
~Rm_session_mmap()
{
/* detach sub RM session when destructed */
if (_sub_rm && _is_attached())
env()->rm_session()->detach((void *)_base);
}
/**************************************
** Region manager session interface **
**************************************/
Local_addr attach(Dataspace_capability ds, size_t size,
off_t, bool, Local_addr,
bool executable);
void detach(Local_addr local_addr);
Pager_capability add_client(Thread_capability thread) {
return Pager_capability(); }
void remove_client(Pager_capability pager) { }
void fault_handler(Signal_context_capability handler) { }
State state() { return State(); }
/*************************
** Dataspace interface **
*************************/
size_t size() { return _size; }
addr_t phys_addr() { return 0; }
bool writable() { return true; }
/**
* Return pseudo dataspace capability of the RM session
*
* The capability returned by this function is only usable
* as argument to 'Rm_session_mmap::attach'. It is not a
* real capability.
*/
Dataspace_capability dataspace() {
return Local_capability<Dataspace>::local_cap(this); }
};
private:
Ram_session_capability _ram_session_cap;
Expanding_ram_session_client _ram_session_client;
Cpu_session_capability _cpu_session_cap;
Expanding_cpu_session_client _cpu_session_client;
Rm_session_mmap _rm_session_mmap;
Pd_session_capability _pd_session_cap;
Pd_session_client _pd_session_client;
public:
/**
* Constructor
*/
Platform_env_base(Ram_session_capability ram_cap,
Cpu_session_capability cpu_cap,
Pd_session_capability pd_cap)
:
_ram_session_cap(ram_cap),
_ram_session_client(_ram_session_cap),
_cpu_session_cap(cpu_cap),
_cpu_session_client(cpu_cap),
_rm_session_mmap(false),
_pd_session_cap(pd_cap),
_pd_session_client(_pd_session_cap)
{ }
/*******************
** Env interface **
*******************/
Ram_session *ram_session() override { return &_ram_session_client; }
Ram_session_capability ram_session_cap() override { return _ram_session_cap; }
Rm_session *rm_session() override { return &_rm_session_mmap; }
Cpu_session *cpu_session() override { return &_cpu_session_client; }
Cpu_session_capability cpu_session_cap() override { return _cpu_session_cap; }
Pd_session *pd_session() override { return &_pd_session_client; }
Pd_session_capability pd_session_cap() override { return _pd_session_cap; }
/*
* Support functions for implementing fork on Noux.
*
* Not supported on Linux.
*/
void reinit(Native_capability::Dst, long) override { }
void reinit_main_thread(Rm_session_capability &) override { }
};
/**
* 'Platform_env' used by all processes except for core
*/
class Platform_env : public Platform_env_base, public Emergency_ram_reserve
{
private:
/**
* Local interceptor of parent requests
*
* On Linux, we need to intercept calls to the parent interface to
* implement the RM service locally. This particular service is
* used for creating managed dataspaces, which allow the
* reservation of parts of the local address space from being
* automatically managed by the 'env()->rm_session()'.
*
* All requests that do not refer to the RM service are passed
* through the real parent interface.
*/
class Local_parent : public Expanding_parent_client
{ {
private: return Local_capability<Region_map>::local_cap(&_stack_area);
}
Allocator &_alloc; Capability<Region_map> linker_area()
{
return Local_capability<Region_map>::local_cap(&_linker_area);
}
};
public: private:
/********************** Ram_session_capability _ram_session_cap;
** Parent interface ** Expanding_ram_session_client _ram_session_client;
**********************/ Cpu_session_capability _cpu_session_cap;
Expanding_cpu_session_client _cpu_session_client;
Region_map_mmap _region_map_mmap;
Pd_session_capability _pd_session_cap;
Session_capability session(Service_name const &, protected:
Session_args const &,
Affinity const & = Affinity());
void close(Session_capability);
/** /*
* Constructor * The '_local_pd_session' is protected because it is needed by
* * 'Platform_env' to initialize the stack area. This must not happen
* \param parent_cap real parent capability used to * in 'Platform_env_base' because the procedure differs between
* promote requests to non-local * core and non-core components.
* services */
*/ Local_pd_session _local_pd_session { _pd_session_cap };
Local_parent(Parent_capability parent_cap,
Emergency_ram_reserve &,
Allocator &);
};
/** public:
* Return instance of parent interface
*/
Local_parent &_parent();
Heap _heap; /**
* Constructor
/* */
* The '_heap' must be initialized before the '_stack_area' Platform_env_base(Ram_session_capability ram_cap,
* because the 'Local_parent' performs a dynamic memory allocation Cpu_session_capability cpu_cap,
* due to the creation of the stack area's sub-RM session. Pd_session_capability pd_cap)
*/ :
Attached_stack_area _stack_area; _ram_session_cap(ram_cap),
_ram_session_client(_ram_session_cap),
/* _cpu_session_cap(cpu_cap),
* Emergency RAM reserve _cpu_session_client(cpu_cap),
* _region_map_mmap(false),
* See the comment of '_fallback_sig_cap()' in 'env/env.cc'. _pd_session_cap(pd_cap),
*/ _local_pd_session(_pd_session_cap)
constexpr static size_t _emergency_ram_size() { return 8*1024; } { }
Ram_dataspace_capability _emergency_ram_ds;
/************************************* /*******************
** Linux-specific helper functions ** ** Env interface **
*************************************/ *******************/
public: Ram_session *ram_session() override { return &_ram_session_client; }
Ram_session_capability ram_session_cap() override { return _ram_session_cap; }
Region_map *rm_session() override { return &_region_map_mmap; }
Cpu_session *cpu_session() override { return &_cpu_session_client; }
Cpu_session_capability cpu_session_cap() override { return _cpu_session_cap; }
Pd_session *pd_session() override { return &_local_pd_session; }
Pd_session_capability pd_session_cap() override { return _pd_session_cap; }
/** /*
* Constructor * Support functions for implementing fork on Noux.
*/ *
Platform_env(); * Not supported on Linux.
*/
/** void reinit(Native_capability::Dst, long) override { }
* Destructor void reinit_main_thread(Capability<Region_map> &) override { }
*/ };
~Platform_env() { _parent().exit(0); }
/************************************* /**
** Emergency_ram_reserve interface ** * 'Platform_env' used by all processes except for core
*************************************/ */
class Genode::Platform_env : public Platform_env_base, public Emergency_ram_reserve
{
private:
void release() { ram_session()->free(_emergency_ram_ds); } /**
* Local interceptor of parent requests
*
* On Linux, we need to intercept calls to the parent interface to
* implement the RM service locally. This particular service is
* used for creating managed dataspaces, which allow the
* reservation of parts of the local address space from being
* automatically managed by the 'env()->rm_session()'.
*
* All requests that do not refer to the RM service are passed
* through the real parent interface.
*/
class Local_parent : public Expanding_parent_client
{
private:
Allocator &_alloc;
public:
/**********************
** Parent interface **
**********************/
Session_capability session(Service_name const &,
Session_args const &,
Affinity const & = Affinity());
void close(Session_capability);
/**
* Constructor
*
* \param parent_cap real parent capability used to
* promote requests to non-local
* services
*/
Local_parent(Parent_capability parent_cap,
Emergency_ram_reserve &,
Allocator &);
};
/**
* Return instance of parent interface
*/
Local_parent &_parent();
Heap _heap;
/*
* Emergency RAM reserve
*
* See the comment of '_fallback_sig_cap()' in 'env/env.cc'.
*/
constexpr static size_t _emergency_ram_size() { return 8*1024; }
Ram_dataspace_capability _emergency_ram_ds;
/******************* /*************************************
** Env interface ** ** Linux-specific helper functions **
*******************/ *************************************/
Parent *parent() override { return &_parent(); } public:
Heap *heap() override { return &_heap; }
}; /**
} * Constructor
*/
Platform_env();
/**
* Destructor
*/
~Platform_env() { _parent().exit(0); }
/*************************************
** Emergency_ram_reserve interface **
*************************************/
void release() { ram_session()->free(_emergency_ram_ds); }
/*******************
** Env interface **
*******************/
Parent *parent() override { return &_parent(); }
Heap *heap() override { return &_heap; }
};
#endif /* _INCLUDE__BASE__INTERNAL__PLATFORM_ENV_H_ */ #endif /* _INCLUDE__BASE__INTERNAL__PLATFORM_ENV_H_ */

View File

@ -53,7 +53,7 @@ static inline void flush_stack_area()
int ret; int ret;
if ((ret = lx_munmap(base, size)) < 0) { if ((ret = lx_munmap(base, size)) < 0) {
PERR("%s: failed ret=%d", __func__, ret); PERR("%s: failed ret=%d", __func__, ret);
throw Rm_session::Region_conflict(); throw Region_map::Region_conflict();
} }
} }
@ -74,7 +74,7 @@ static inline Genode::addr_t reserve_stack_area()
PERR("%s: failed addr_in=%p addr_out=%p ret=%ld)", __func__, PERR("%s: failed addr_in=%p addr_out=%p ret=%ld)", __func__,
addr_in, addr_out, (long)addr_out); addr_in, addr_out, (long)addr_out);
throw Rm_session::Region_conflict(); throw Region_map::Region_conflict();
} }
return (addr_t) addr_out; return (addr_t) addr_out;

View File

@ -18,6 +18,7 @@
#include <base/thread.h> #include <base/thread.h>
#include <util/misc_math.h> #include <util/misc_math.h>
#include <rm_session/connection.h> #include <rm_session/connection.h>
#include <region_map/client.h>
static void blob() __attribute__((used)); static void blob() __attribute__((used));
@ -66,26 +67,28 @@ int main()
env()->rm_session()->attach_at(ds, beg); env()->rm_session()->attach_at(ds, beg);
PERR("after RAM dataspace attach -- ERROR"); PERR("after RAM dataspace attach -- ERROR");
sleep_forever(); sleep_forever();
} catch (Rm_session::Region_conflict) { } catch (Region_map::Region_conflict) {
PLOG("OK caught Region_conflict exception"); PLOG("OK caught Region_conflict exception");
} }
/* empty managed dataspace overlapping binary */ /* empty managed dataspace overlapping binary */
try { try {
Rm_connection rm(0, size); Rm_connection rm_connection;
Region_map_client rm(rm_connection.create(size));
Dataspace_capability ds(rm.dataspace()); Dataspace_capability ds(rm.dataspace());
PLOG("before sub-RM dataspace attach"); PLOG("before sub-RM dataspace attach");
env()->rm_session()->attach_at(ds, beg); env()->rm_session()->attach_at(ds, beg);
PERR("after sub-RM dataspace attach -- ERROR"); PERR("after sub-RM dataspace attach -- ERROR");
sleep_forever(); sleep_forever();
} catch (Rm_session::Region_conflict) { } catch (Region_map::Region_conflict) {
PLOG("OK caught Region_conflict exception"); PLOG("OK caught Region_conflict exception");
} }
/* sparsely populated managed dataspace in free VM area */ /* sparsely populated managed dataspace in free VM area */
try { try {
Rm_connection rm(0, 0x100000); Rm_connection rm_connection;
Region_map_client rm(rm_connection.create(0x100000));
rm.attach_at(env()->ram_session()->alloc(0x1000), 0x1000); rm.attach_at(env()->ram_session()->alloc(0x1000), 0x1000);
@ -97,7 +100,7 @@ int main()
char const val = *addr; char const val = *addr;
*addr = 0x55; *addr = 0x55;
PLOG("after touch (%x/%x)", val, *addr); PLOG("after touch (%x/%x)", val, *addr);
} catch (Rm_session::Region_conflict) { } catch (Region_map::Region_conflict) {
PERR("Caught Region_conflict exception -- ERROR"); PERR("Caught Region_conflict exception -- ERROR");
sleep_forever(); sleep_forever();
} }

View File

@ -1,5 +1,5 @@
/* /*
* \brief Linux: Test bug in rm_session_mmap.cc * \brief Linux: Test bug in region_map_mmap.cc
* \author Christian Helmuth * \author Christian Helmuth
* \date 2012-12-19 * \date 2012-12-19
*/ */

View File

@ -1,3 +1,3 @@
TARGET = test-rm_session_mmap TARGET = test-region_map_mmap
LIBS = base LIBS = base
SRC_CC = main.cc SRC_CC = main.cc

View File

@ -22,6 +22,7 @@ SRC_CC += thread/thread.cc thread/stack.cc thread/trace.cc
SRC_CC += thread/myself.cc SRC_CC += thread/myself.cc
SRC_CC += thread/stack_allocator.cc env/cap_map.cc SRC_CC += thread/stack_allocator.cc env/cap_map.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.cc SRC_CC += entrypoint/entrypoint.cc
SRC_CC += component/component.cc SRC_CC += component/component.cc

View File

@ -1,5 +1,5 @@
/* /*
* \brief Client-side region manager session interface * \brief Client-side region map stub
* \author Norman Feske * \author Norman Feske
* \author Alexander Boettcher * \author Alexander Boettcher
* \date 2016-01-22 * \date 2016-01-22
@ -12,16 +12,16 @@
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
*/ */
#include <rm_session/client.h> #include <region_map/client.h>
using namespace Genode; using namespace Genode;
Rm_session_client::Rm_session_client(Rm_session_capability session) Region_map_client::Region_map_client(Capability<Region_map> session)
: Rpc_client<Rm_session>(session) { } : Rpc_client<Region_map>(session) { }
Rm_session::Local_addr Region_map::Local_addr
Rm_session_client::attach(Dataspace_capability ds, size_t size, off_t offset, Region_map_client::attach(Dataspace_capability ds, size_t size, off_t offset,
bool use_local_addr, Local_addr local_addr, bool use_local_addr, Local_addr local_addr,
bool executable) bool executable)
{ {
@ -29,23 +29,23 @@ Rm_session_client::attach(Dataspace_capability ds, size_t size, off_t offset,
executable); executable);
} }
void Rm_session_client::detach(Local_addr local_addr) { void Region_map_client::detach(Local_addr local_addr) {
call<Rpc_detach>(local_addr); } call<Rpc_detach>(local_addr); }
Pager_capability Rm_session_client::add_client(Thread_capability thread) Pager_capability Region_map_client::add_client(Thread_capability thread)
{ {
return call<Rpc_add_client>(thread); return call<Rpc_add_client>(thread);
} }
void Rm_session_client::remove_client(Pager_capability pager) { void Region_map_client::remove_client(Pager_capability pager) {
call<Rpc_remove_client>(pager); } call<Rpc_remove_client>(pager); }
void Rm_session_client::fault_handler(Signal_context_capability cap) { void Region_map_client::fault_handler(Signal_context_capability cap) {
call<Rpc_fault_handler>(cap); } call<Rpc_fault_handler>(cap); }
Rm_session::State Rm_session_client::state() { return call<Rpc_state>(); } Region_map::State Region_map_client::state() { return call<Rpc_state>(); }
Dataspace_capability Rm_session_client::dataspace() Dataspace_capability Region_map_client::dataspace()
{ {
if (!_rm_ds_cap.valid()) if (!_rm_ds_cap.valid())
_rm_ds_cap = call<Rpc_dataspace>(); _rm_ds_cap = call<Rpc_dataspace>();

View File

@ -1,5 +1,5 @@
/* /*
* \brief Core-local RM session * \brief Core-local region map
* \author Norman Feske * \author Norman Feske
* \date 2009-10-02 * \date 2009-10-02
*/ */
@ -15,7 +15,7 @@
#include <base/printf.h> #include <base/printf.h>
/* core includes */ /* core includes */
#include <core_rm_session.h> #include <core_region_map.h>
#include <platform.h> #include <platform.h>
#include <util.h> #include <util.h>
#include <nova_util.h> #include <nova_util.h>
@ -47,10 +47,10 @@ static inline void * alloc_region(Dataspace_component *ds, const size_t size)
return virt_addr; return virt_addr;
} }
Rm_session::Local_addr Region_map::Local_addr
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, Core_region_map::attach(Dataspace_capability ds_cap, size_t size,
off_t offset, bool use_local_addr, off_t offset, bool use_local_addr,
Rm_session::Local_addr local_addr, Region_map::Local_addr local_addr,
bool executable) bool executable)
{ {
auto lambda = [&] (Dataspace_component *ds) -> Local_addr { auto lambda = [&] (Dataspace_component *ds) -> Local_addr {
@ -90,7 +90,7 @@ Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
} }
void Core_rm_session::detach(Local_addr core_local_addr) void Core_region_map::detach(Local_addr core_local_addr)
{ {
size_t size = platform_specific()->region_alloc_size_at(core_local_addr); size_t size = platform_specific()->region_alloc_size_at(core_local_addr);

View File

@ -0,0 +1,56 @@
/*
* \brief Core-local region map
* \author Norman Feske
* \date 2009-10-02
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__CORE_REGION_MAP_H_
#define _CORE__INCLUDE__CORE_REGION_MAP_H_
/* Genode includes */
#include <region_map/region_map.h>
/* core includes */
#include <dataspace_component.h>
namespace Genode { class Core_region_map; }
class Genode::Core_region_map : public Region_map
{
private:
Rpc_entrypoint *_ds_ep;
public:
Core_region_map(Rpc_entrypoint *ds_ep) : _ds_ep(ds_ep) { }
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
off_t offset=0, bool use_local_addr = false,
Local_addr local_addr = 0,
bool executable = false) override;
void detach(Local_addr) override;
Pager_capability add_client(Thread_capability thread) override {
return Pager_capability(); }
void remove_client(Pager_capability) override { }
void fault_handler(Signal_context_capability handler) override { }
State state() override { return State(); }
Dataspace_capability dataspace() override {
return Dataspace_capability(); }
};
#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */

View File

@ -1,56 +0,0 @@
/*
* \brief Core-local region manager session
* \author Norman Feske
* \date 2009-10-02
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__CORE_RM_SESSION_H_
#define _CORE__INCLUDE__CORE_RM_SESSION_H_
/* Genode includes */
#include <rm_session/rm_session.h>
/* core includes */
#include <dataspace_component.h>
namespace Genode {
class Core_rm_session : public Rm_session
{
private:
Rpc_entrypoint *_ds_ep;
public:
Core_rm_session(Rpc_entrypoint *ds_ep) : _ds_ep(ds_ep) { }
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
off_t offset=0, bool use_local_addr = false,
Local_addr local_addr = 0,
bool executable = false) override;
void detach(Local_addr) override;
Pager_capability add_client(Thread_capability thread) override {
return Pager_capability(); }
void remove_client(Pager_capability) override { }
void fault_handler(Signal_context_capability handler) override { }
State state() override { return State(); }
Dataspace_capability dataspace() override {
return Dataspace_capability(); }
};
}
#endif /* _CORE__INCLUDE__CORE_RM_SESSION_H_ */

View File

@ -172,6 +172,15 @@ namespace Genode {
if (main_thread) _features |= MAIN_THREAD; if (main_thread) _features |= MAIN_THREAD;
} }
/**
* Return pointer to the thread's PD
*
* Used to validate the success of the bind operation.
*
* XXX to be removed
*/
Platform_pd *pd() { return _pd; }
Native_capability single_step_sync(bool on); Native_capability single_step_sync(bool on);
/** /**

View File

@ -35,11 +35,11 @@ namespace Genode {
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Rm_session::Fault_type pf_type, Region_map::State::Fault_type pf_type,
unsigned long faulter_badge) unsigned long faulter_badge)
{ {
printf("%s (%s pf_addr=%p pf_ip=%p from %02lx %s)\n", msg, printf("%s (%s pf_addr=%p pf_ip=%p from %02lx %s)\n", msg,
pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
(void *)pf_addr, (void *)pf_ip, (void *)pf_addr, (void *)pf_ip,
faulter_badge, faulter_badge,
faulter_badge ? reinterpret_cast<char *>(faulter_badge) : 0); faulter_badge ? reinterpret_cast<char *>(faulter_badge) : 0);

View File

@ -444,7 +444,7 @@ void Exception_handlers::register_handler(Pager_object *obj, Mtd mtd,
unsigned use_cpu = obj->location.xpos(); unsigned use_cpu = obj->location.xpos();
if (!kernel_hip()->is_cpu_enabled(use_cpu) || !pager_threads[use_cpu]) { if (!kernel_hip()->is_cpu_enabled(use_cpu) || !pager_threads[use_cpu]) {
PWRN("invalid CPU parameter used in pager object"); PWRN("invalid CPU parameter used in pager object");
throw Rm_session::Invalid_thread(); throw Region_map::Invalid_thread();
} }
addr_t const ec_sel = pager_threads[use_cpu]->native_thread().ec_sel; addr_t const ec_sel = pager_threads[use_cpu]->native_thread().ec_sel;
@ -454,7 +454,7 @@ void Exception_handlers::register_handler(Pager_object *obj, Mtd mtd,
uint8_t res = create_portal(obj->exc_pt_sel_client() + EV, uint8_t res = create_portal(obj->exc_pt_sel_client() + EV,
__core_pd_sel, ec_sel, mtd, entry, obj); __core_pd_sel, ec_sel, mtd, entry, obj);
if (res != Nova::NOVA_OK) if (res != Nova::NOVA_OK)
throw Rm_session::Invalid_thread(); throw Region_map::Invalid_thread();
} }
@ -519,19 +519,19 @@ Pager_object::Pager_object(unsigned long badge, Affinity::Location location)
if (Native_thread::INVALID_INDEX == _selectors || if (Native_thread::INVALID_INDEX == _selectors ||
Native_thread::INVALID_INDEX == _client_exc_pt_sel) Native_thread::INVALID_INDEX == _client_exc_pt_sel)
throw Rm_session::Invalid_thread(); throw Region_map::Invalid_thread();
/* ypos information not supported by now */ /* ypos information not supported by now */
if (location.ypos()) { if (location.ypos()) {
PWRN("Unsupported location %ux%u", location.xpos(), location.ypos()); PWRN("Unsupported location %ux%u", location.xpos(), location.ypos());
throw Rm_session::Invalid_thread(); throw Region_map::Invalid_thread();
} }
/* place Pager_object on specified CPU by selecting proper pager thread */ /* place Pager_object on specified CPU by selecting proper pager thread */
unsigned use_cpu = location.xpos(); unsigned use_cpu = location.xpos();
if (!kernel_hip()->is_cpu_enabled(use_cpu) || !pager_threads[use_cpu]) { if (!kernel_hip()->is_cpu_enabled(use_cpu) || !pager_threads[use_cpu]) {
PWRN("invalid CPU parameter used in pager object"); PWRN("invalid CPU parameter used in pager object");
throw Rm_session::Invalid_thread(); throw Region_map::Invalid_thread();
} }
addr_t ec_sel = pager_threads[use_cpu]->native_thread().ec_sel; addr_t ec_sel = pager_threads[use_cpu]->native_thread().ec_sel;
@ -557,7 +557,7 @@ Pager_object::Pager_object(unsigned long badge, Affinity::Location location)
*/ */
res = Nova::create_sm(exc_pt_sel_client() + SM_SEL_EC, pd_sel, 0); res = Nova::create_sm(exc_pt_sel_client() + SM_SEL_EC, pd_sel, 0);
if (res != Nova::NOVA_OK) { if (res != Nova::NOVA_OK) {
throw Rm_session::Invalid_thread(); throw Region_map::Invalid_thread();
} }
/* create portal for final cleanup call used during destruction */ /* create portal for final cleanup call used during destruction */
@ -565,19 +565,19 @@ Pager_object::Pager_object(unsigned long badge, Affinity::Location location)
reinterpret_cast<addr_t>(_invoke_handler), this); reinterpret_cast<addr_t>(_invoke_handler), this);
if (res != Nova::NOVA_OK) { if (res != Nova::NOVA_OK) {
PERR("could not create pager cleanup portal, error = %u\n", res); PERR("could not create pager cleanup portal, error = %u\n", res);
throw Rm_session::Invalid_thread(); throw Region_map::Invalid_thread();
} }
/* used to notify caller of as soon as pause succeeded */ /* used to notify caller of as soon as pause succeeded */
res = Nova::create_sm(sel_sm_notify(), pd_sel, 0); res = Nova::create_sm(sel_sm_notify(), pd_sel, 0);
if (res != Nova::NOVA_OK) { if (res != Nova::NOVA_OK) {
throw Rm_session::Invalid_thread(); throw Region_map::Invalid_thread();
} }
/* semaphore used to block paged thread during page fault or recall */ /* semaphore used to block paged thread during page fault or recall */
res = Nova::create_sm(sel_sm_block(), pd_sel, 0); res = Nova::create_sm(sel_sm_block(), pd_sel, 0);
if (res != Nova::NOVA_OK) { if (res != Nova::NOVA_OK) {
throw Rm_session::Invalid_thread(); throw Region_map::Invalid_thread();
} }
} }

View File

@ -121,7 +121,8 @@ static void page_fault_handler()
addr_t pf_type = utcb->qual[0]; addr_t pf_type = utcb->qual[0];
print_page_fault("\nPAGE-FAULT IN CORE", pf_addr, pf_ip, print_page_fault("\nPAGE-FAULT IN CORE", pf_addr, pf_ip,
(pf_type & Ipc_pager::ERR_W) ? Rm_session::WRITE_FAULT : Rm_session::READ_FAULT, 0); (pf_type & Ipc_pager::ERR_W) ? Region_map::State::WRITE_FAULT
: Region_map::State::READ_FAULT, 0);
printf("\nstack pointer 0x%lx, qualifiers 0x%lx %s%s%s%s%s\n", printf("\nstack pointer 0x%lx, qualifiers 0x%lx %s%s%s%s%s\n",
pf_sp, pf_type, pf_sp, pf_type,

View File

@ -1,5 +1,5 @@
/* /*
* \brief RM-session implementation * \brief Region map implementation
* \author Norman Feske * \author Norman Feske
* \author Sebastian Sumpf * \author Sebastian Sumpf
* \date 2009-10-02 * \date 2009-10-02

View File

@ -6,7 +6,7 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC = stack_area.cc \ SRC_CC = stack_area.cc \
core_mem_alloc.cc \ core_mem_alloc.cc \
core_printf.cc \ core_printf.cc \
core_rm_session.cc \ core_region_map.cc \
core_rpc_cap_alloc.cc \ core_rpc_cap_alloc.cc \
cpu_session_component.cc \ cpu_session_component.cc \
cpu_session_extension.cc \ cpu_session_extension.cc \
@ -32,8 +32,8 @@ SRC_CC = stack_area.cc \
platform_thread.cc \ platform_thread.cc \
ram_session_component.cc \ ram_session_component.cc \
ram_session_support.cc \ ram_session_support.cc \
rm_session_component.cc \ region_map_component.cc \
rm_session_support.cc \ region_map_support.cc \
rom_session_component.cc \ rom_session_component.cc \
thread_start.cc \ thread_start.cc \
bios_data_area.cc \ bios_data_area.cc \
@ -53,7 +53,7 @@ vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR) vpath region_map_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath io_port_session_component.cc $(GEN_CORE_DIR)/spec/x86 vpath io_port_session_component.cc $(GEN_CORE_DIR)/spec/x86
vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR)

View File

@ -18,6 +18,7 @@
#include <util/touch.h> #include <util/touch.h>
#include <rm_session/connection.h> #include <rm_session/connection.h>
#include <region_map/client.h>
#include <os/attached_rom_dataspace.h> #include <os/attached_rom_dataspace.h>
#include <os/config.h> #include <os/config.h>
@ -53,7 +54,8 @@ void test_pat()
Test::Capability session_cap = ep.manage(&component); Test::Capability session_cap = ep.manage(&component);
Test::Client client(session_cap); Test::Client client(session_cap);
Genode::Rm_connection rm_free_area(0, 1 << (DS_ORDER + PAGE_4K)); Genode::Rm_connection rm;
Genode::Region_map_client rm_free_area(rm.create(1 << (DS_ORDER + PAGE_4K)));
addr_t remap_addr = Genode::env()->rm_session()->attach(rm_free_area.dataspace()); addr_t remap_addr = Genode::env()->rm_session()->attach(rm_free_area.dataspace());
/* trigger mapping of whole area */ /* trigger mapping of whole area */
@ -193,12 +195,14 @@ class Greedy : public Thread<4096> {
Thread<0x1000>("greedy") Thread<0x1000>("greedy")
{ } { }
void entry() { void entry()
{
PINF("starting"); PINF("starting");
enum { SUB_RM_SIZE = 2UL * 1024 * 1024 * 1024 }; enum { SUB_RM_SIZE = 2UL * 1024 * 1024 * 1024 };
Genode::Rm_connection sub_rm(0, SUB_RM_SIZE); Genode::Rm_connection rm;
Genode::Region_map_client sub_rm(rm.create(SUB_RM_SIZE));
addr_t const mem = env()->rm_session()->attach(sub_rm.dataspace()); addr_t const mem = env()->rm_session()->attach(sub_rm.dataspace());
Nova::Utcb * nova_utcb = reinterpret_cast<Nova::Utcb *>(utcb()); Nova::Utcb * nova_utcb = reinterpret_cast<Nova::Utcb *>(utcb());

View File

@ -23,6 +23,7 @@ SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
SRC_CC += thread/myself.cc SRC_CC += thread/myself.cc
SRC_CC += thread/stack_allocator.cc SRC_CC += thread/stack_allocator.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.cc SRC_CC += entrypoint/entrypoint.cc
SRC_CC += component/component.cc SRC_CC += component/component.cc

View File

@ -1,5 +1,5 @@
/* /*
* \brief OKL4-specific implementation of core-local RM session * \brief OKL4-specific implementation of core-local region map
* \author Norman Feske * \author Norman Feske
* \date 2009-04-02 * \date 2009-04-02
*/ */
@ -13,16 +13,16 @@
/* core includes */ /* core includes */
#include <platform.h> #include <platform.h>
#include <core_rm_session.h> #include <core_region_map.h>
#include <map_local.h> #include <map_local.h>
using namespace Genode; using namespace Genode;
Rm_session::Local_addr Region_map::Local_addr
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, Core_region_map::attach(Dataspace_capability ds_cap, size_t size,
off_t offset, bool use_local_addr, off_t offset, bool use_local_addr,
Rm_session::Local_addr, bool executable) Region_map::Local_addr, bool executable)
{ {
using namespace Okl4; using namespace Okl4;

View File

@ -0,0 +1,56 @@
/*
* \brief OKL4-specific core-local region map
* \author Norman Feske
* \date 2009-04-02
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__CORE_REGION_MAP_H_
#define _CORE__INCLUDE__CORE_REGION_MAP_H_
/* Genode includes */
#include <region_map/region_map.h>
#include <base/rpc_server.h>
/* core includes */
#include <dataspace_component.h>
namespace Genode { class Core_region_map; }
class Genode::Core_region_map : public Region_map
{
private:
Rpc_entrypoint *_ds_ep;
public:
Core_region_map(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { }
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
off_t offset=0, bool use_local_addr = false,
Local_addr local_addr = 0,
bool executable = false);
void detach(Local_addr) { }
Pager_capability add_client(Thread_capability thread) {
return Pager_capability(); }
void remove_client(Pager_capability) { }
void fault_handler(Signal_context_capability handler) { }
State state() { return State(); }
Dataspace_capability dataspace() { return Dataspace_capability(); }
};
#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */

View File

@ -1,60 +0,0 @@
/*
* \brief OKL4-specific core-local region manager session
* \author Norman Feske
* \date 2009-04-02
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CORE__INCLUDE__CORE_RM_SESSION_H_
#define _CORE__INCLUDE__CORE_RM_SESSION_H_
/* Genode includes */
#include <rm_session/rm_session.h>
#include <base/rpc_server.h>
/* core includes */
#include <dataspace_component.h>
namespace Genode {
/**
* Region manager that uses the physical dataspace
* addresses directly as virtual addresses.
*/
class Core_rm_session : public Rm_session
{
private:
Rpc_entrypoint *_ds_ep;
public:
Core_rm_session(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { }
Local_addr attach(Dataspace_capability ds_cap, size_t size=0,
off_t offset=0, bool use_local_addr = false,
Local_addr local_addr = 0,
bool executable = false);
void detach(Local_addr) { }
Pager_capability add_client(Thread_capability thread) {
return Pager_capability(); }
void remove_client(Pager_capability) { }
void fault_handler(Signal_context_capability handler) { }
State state() { return State(); }
Dataspace_capability dataspace() { return Dataspace_capability(); }
};
}
#endif /* _CORE__INCLUDE__CORE_RM_SESSION_H_ */

View File

@ -21,7 +21,7 @@
#include <platform_generic.h> #include <platform_generic.h>
#include <platform_thread.h> #include <platform_thread.h>
#include <platform_pd.h> #include <platform_pd.h>
#include <core_rm_session.h> #include <core_region_map.h>
#include <core_mem_alloc.h> #include <core_mem_alloc.h>
/* OKL4 includes */ /* OKL4 includes */

View File

@ -114,11 +114,11 @@ namespace Genode {
} }
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Rm_session::Fault_type pf_type, Region_map::State::Fault_type pf_type,
unsigned long faulter_badge) unsigned long faulter_badge)
{ {
printf("%s (%s pf_addr=%p pf_ip=%p from %02lx)\n", msg, printf("%s (%s pf_addr=%p pf_ip=%p from %02lx)\n", msg,
pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
(void *)pf_addr, (void *)pf_ip, (void *)pf_addr, (void *)pf_ip,
faulter_badge); faulter_badge);
} }

View File

@ -1,5 +1,5 @@
/* /*
* \brief OKL4-specific part of RM-session implementation * \brief OKL4-specific part of region-map implementation
* \author Norman Feske * \author Norman Feske
* \date 2009-04-10 * \date 2009-04-10
*/ */
@ -15,7 +15,7 @@
#include <base/printf.h> #include <base/printf.h>
/* core includes */ /* core includes */
#include <rm_session_component.h> #include <region_map_component.h>
using namespace Genode; using namespace Genode;

View File

@ -7,7 +7,7 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC += stack_area.cc \ SRC_CC += stack_area.cc \
core_mem_alloc.cc \ core_mem_alloc.cc \
core_printf.cc \ core_printf.cc \
core_rm_session.cc \ core_region_map.cc \
core_rpc_cap_alloc.cc \ core_rpc_cap_alloc.cc \
cpu_session_component.cc \ cpu_session_component.cc \
cpu_session_support.cc \ cpu_session_support.cc \
@ -30,8 +30,8 @@ SRC_CC += stack_area.cc \
platform_thread.cc \ platform_thread.cc \
ram_session_component.cc \ ram_session_component.cc \
ram_session_support.cc \ ram_session_support.cc \
rm_session_component.cc \ region_map_component.cc \
rm_session_support.cc \ region_map_support.cc \
rom_session_component.cc \ rom_session_component.cc \
signal_source_component.cc \ signal_source_component.cc \
thread_start.cc \ thread_start.cc \
@ -51,7 +51,7 @@ vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath rpc_cap_factory.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR) vpath region_map_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR)
vpath signal_source_component.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR)

View File

@ -23,6 +23,7 @@ SRC_CC += thread/thread.cc thread/trace.cc thread/thread_bootstrap.cc
SRC_CC += thread/myself.cc SRC_CC += thread/myself.cc
SRC_CC += thread/stack_allocator.cc SRC_CC += thread/stack_allocator.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.cc SRC_CC += entrypoint/entrypoint.cc
SRC_CC += component/component.cc SRC_CC += component/component.cc

View File

@ -230,7 +230,7 @@ namespace Genode {
/* /*
* On Pistachio, we don't use directed unmap but rely on the * On Pistachio, we don't use directed unmap but rely on the
* in-kernel mapping database. See 'rm_session_support.cc'. * in-kernel mapping database. See 'region_map_support.cc'.
*/ */
void flush(addr_t, size_t) { PDBG("not implemented"); } void flush(addr_t, size_t) { PDBG("not implemented"); }
}; };

View File

@ -120,6 +120,15 @@ namespace Genode {
*/ */
void unbind(); void unbind();
/**
* Return pointer to the thread's PD
*
* Used to validate the success of the bind operation.
*
* XXX to be removed
*/
Platform_pd *pd() { return _platform_pd; }
/** /**
* Override thread state with 's' * Override thread state with 's'
* *

View File

@ -107,13 +107,13 @@ namespace Genode {
} }
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Rm_session::Fault_type pf_type, Region_map::State::Fault_type pf_type,
unsigned long badge) unsigned long badge)
{ {
Pistachio::L4_ThreadId_t tid; Pistachio::L4_ThreadId_t tid;
tid.raw = badge; tid.raw = badge;
printf("%s (%s pf_addr=%p pf_ip=%p from %02lx (raw %08lx))\n", msg, printf("%s (%s pf_addr=%p pf_ip=%p from %02lx (raw %08lx))\n", msg,
pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
(void *)pf_addr, (void *)pf_ip, (void *)pf_addr, (void *)pf_ip,
Pistachio::L4_GlobalId(tid).global.X.thread_no, tid.raw); Pistachio::L4_GlobalId(tid).global.X.thread_no, tid.raw);
} }

View File

@ -1,5 +1,5 @@
/* /*
* \brief Pistachio-specific part of RM-session implementation * \brief Pistachio-specific part of region-map implementation
* \author Norman Feske * \author Norman Feske
* \date 2009-04-10 * \date 2009-04-10
*/ */

View File

@ -30,8 +30,8 @@ SRC_CC = stack_area.cc \
platform_thread.cc \ platform_thread.cc \
ram_session_component.cc \ ram_session_component.cc \
ram_session_support.cc \ ram_session_support.cc \
rm_session_component.cc \ region_map_component.cc \
rm_session_support.cc \ region_map_support.cc \
rom_session_component.cc \ rom_session_component.cc \
signal_source_component.cc \ signal_source_component.cc \
thread_start.cc \ thread_start.cc \
@ -51,7 +51,7 @@ vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath rpc_cap_factory.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR) vpath region_map_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR)
vpath signal_source_component.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR)

View File

@ -1,39 +0,0 @@
/*
* \brief Connection to PD service
* \author Norman Feske
* \date 2008-08-22
*/
/*
* Copyright (C) 2008-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__PD_SESSION__CONNECTION_H_
#define _INCLUDE__PD_SESSION__CONNECTION_H_
#include <pd_session/client.h>
#include <base/connection.h>
namespace Genode { struct Pd_connection; }
struct Genode::Pd_connection : Connection<Pd_session>, Pd_session_client
{
enum { RAM_QUOTA = 64*1024 };
/**
* Constructor
*
* \param label session label
*/
Pd_connection(char const *label = "")
: Connection<Pd_session>(session("ram_quota=%u, label=\"%s\"",
RAM_QUOTA, label)),
Pd_session_client(cap())
{ }
};
#endif /* _INCLUDE__PD_SESSION__CONNECTION_H_ */

View File

@ -25,6 +25,7 @@ SRC_CC += thread/stack_allocator.cc
SRC_CC += thread/thread_bootstrap.cc SRC_CC += thread/thread_bootstrap.cc
SRC_CC += env/capability.cc SRC_CC += env/capability.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.cc SRC_CC += entrypoint/entrypoint.cc
SRC_CC += component/component.cc SRC_CC += component/component.cc

View File

@ -21,12 +21,12 @@ SRC_CC += \
platform_services.cc \ platform_services.cc \
platform.cc \ platform.cc \
dataspace_component.cc \ dataspace_component.cc \
rm_session_component.cc \ region_map_component.cc \
rm_session_support.cc \ region_map_support.cc \
irq_session_component.cc \ irq_session_component.cc \
signal_source_component.cc \ signal_source_component.cc \
trace_session_component.cc \ trace_session_component.cc \
core_rm_session.cc \ core_region_map.cc \
core_mem_alloc.cc \ core_mem_alloc.cc \
core_rpc_cap_alloc.cc \ core_rpc_cap_alloc.cc \
dump_alloc.cc \ dump_alloc.cc \
@ -50,7 +50,7 @@ vpath cpu_session_support.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR) vpath region_map_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR)
vpath platform_services.cc $(GEN_CORE_DIR) vpath platform_services.cc $(GEN_CORE_DIR)

View File

@ -1,5 +1,5 @@
/* /*
* \brief Core-local RM session * \brief Core-local region map
* \author Norman Feske * \author Norman Feske
* \date 2015-05-01 * \date 2015-05-01
*/ */
@ -15,17 +15,17 @@
#include <base/printf.h> #include <base/printf.h>
/* core includes */ /* core includes */
#include <core_rm_session.h> #include <core_region_map.h>
#include <platform.h> #include <platform.h>
#include <map_local.h> #include <map_local.h>
using namespace Genode; using namespace Genode;
Rm_session::Local_addr Region_map::Local_addr
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, Core_region_map::attach(Dataspace_capability ds_cap, size_t size,
off_t offset, bool use_local_addr, off_t offset, bool use_local_addr,
Rm_session::Local_addr local_addr, Region_map::Local_addr local_addr,
bool executable) bool executable)
{ {
auto lambda = [&] (Dataspace_component *ds) -> Local_addr { auto lambda = [&] (Dataspace_component *ds) -> Local_addr {

View File

@ -1,5 +1,5 @@
/* /*
* \brief Core-local RM session * \brief Core-local region map
* \author Norman Feske * \author Norman Feske
* \date 2015-05-01 * \date 2015-05-01
*/ */
@ -16,15 +16,15 @@
/* Genode includes */ /* Genode includes */
#include <base/printf.h> #include <base/printf.h>
#include <rm_session/rm_session.h> #include <region_map/region_map.h>
/* core includes */ /* core includes */
#include <dataspace_component.h> #include <dataspace_component.h>
namespace Genode { class Core_rm_session; } namespace Genode { class Core_region_map; }
class Genode::Core_rm_session : public Rm_session class Genode::Core_region_map : public Region_map
{ {
private: private:
@ -32,7 +32,7 @@ class Genode::Core_rm_session : public Rm_session
public: public:
Core_rm_session(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } Core_region_map(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { }
Local_addr attach(Dataspace_capability ds_cap, size_t size = 0, Local_addr attach(Dataspace_capability ds_cap, size_t size = 0,
off_t offset = 0, bool use_local_addr = false, off_t offset = 0, bool use_local_addr = false,

View File

@ -173,6 +173,15 @@ class Genode::Platform_thread : public List<Platform_thread>::Element
*/ */
const char *name() const { return "noname"; } const char *name() const { return "noname"; }
/**
* Return pointer to the thread's PD
*
* Used to validate the success of the bind operation.
*
* XXX to be removed
*/
Platform_pd *pd() { return _pd; }
/***************************** /*****************************
** seL4-specific interface ** ** seL4-specific interface **

View File

@ -35,11 +35,11 @@ namespace Genode {
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Rm_session::Fault_type pf_type, Region_map::State::Fault_type pf_type,
unsigned long faulter_badge) unsigned long faulter_badge)
{ {
printf("%s (%s pf_addr=%p pf_ip=%p from %02lx)\n", msg, printf("%s (%s pf_addr=%p pf_ip=%p from %02lx)\n", msg,
pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
(void *)pf_addr, (void *)pf_ip, (void *)pf_addr, (void *)pf_ip,
faulter_badge); faulter_badge);
} }

View File

@ -1,5 +1,5 @@
/* /*
* \brief Kernel-specific supplements of the RM service * \brief Kernel-specific supplements of the region-map implementation
* \author Norman Feske * \author Norman Feske
* \date 2015-05-01 * \date 2015-05-01
*/ */

View File

@ -13,7 +13,7 @@
*/ */
/* Genode includes */ /* Genode includes */
#include <rm_session/rm_session.h> #include <region_map/region_map.h>
#include <ram_session/ram_session.h> #include <ram_session/ram_session.h>
#include <base/printf.h> #include <base/printf.h>
#include <base/synced_allocator.h> #include <base/synced_allocator.h>
@ -27,6 +27,7 @@
/* base-internal includes */ /* base-internal includes */
#include <base/internal/stack_area.h> #include <base/internal/stack_area.h>
#include <base/internal/platform_env_common.h>
using namespace Genode; using namespace Genode;
@ -42,7 +43,7 @@ using namespace Genode;
* place, the allocation of a dataspace has no effect, but the attachment of * place, the allocation of a dataspace has no effect, but the attachment of
* the thereby "empty" dataspace is doing both: allocation and attachment. * the thereby "empty" dataspace is doing both: allocation and attachment.
*/ */
class Stack_area_rm_session : public Rm_session class Stack_area_region_map : public Region_map
{ {
private: private:
@ -135,13 +136,13 @@ class Stack_area_ram_session : public Ram_session
namespace Genode { namespace Genode {
Rm_session *env_stack_area_rm_session; Region_map *env_stack_area_region_map;
Ram_session *env_stack_area_ram_session; Ram_session *env_stack_area_ram_session;
void init_stack_area() void init_stack_area()
{ {
static Stack_area_rm_session rm_inst; static Stack_area_region_map rm_inst;
env_stack_area_rm_session = &rm_inst; env_stack_area_region_map = &rm_inst;
static Stack_area_ram_session ram_inst; static Stack_area_ram_session ram_inst;
env_stack_area_ram_session = &ram_inst; env_stack_area_ram_session = &ram_inst;

View File

@ -165,14 +165,10 @@ class Genode::Child : protected Rpc_object<Parent>
/* CPU session that contains the quota of the child */ /* CPU session that contains the quota of the child */
Cpu_session_capability _cpu; Cpu_session_capability _cpu;
/* RM session representing the address space of the child */ /* services where the PD, RAM, and CPU resources come from */
Rm_session_capability _rm;
/* Services where the PD, RAM, CPU, and RM resources come from */
Service &_pd_service; Service &_pd_service;
Service &_ram_service; Service &_ram_service;
Service &_cpu_service; Service &_cpu_service;
Service &_rm_service;
/* heap for child-specific allocations using the child's quota */ /* heap for child-specific allocations using the child's quota */
Heap _heap; Heap _heap;
@ -238,14 +234,11 @@ class Genode::Child : protected Rpc_object<Parent>
* \param pd PD session representing the protection domain * \param pd PD session representing the protection domain
* \param ram RAM session with the child's quota * \param ram RAM session with the child's quota
* \param cpu CPU session with the child's quota * \param cpu CPU session with the child's quota
* \param rm RM session representing the address space
* of the child
* \param entrypoint server entrypoint to serve the parent interface * \param entrypoint server entrypoint to serve the parent interface
* \param policy child policy * \param policy child policy
* \param pd_service provider of the 'pd' session * \param pd_service provider of the 'pd' session
* \param ram_service provider of the 'ram' session * \param ram_service provider of the 'ram' session
* \param cpu_service provider of the 'cpu' session * \param cpu_service provider of the 'cpu' session
* \param rm_service provider of the 'rm' session
* *
* If assigning a separate entry point to each child, the host of * If assigning a separate entry point to each child, the host of
* multiple children is able to handle a blocking invocation of * multiple children is able to handle a blocking invocation of
@ -253,7 +246,7 @@ class Genode::Child : protected Rpc_object<Parent>
* service to other children, each having an independent entry * service to other children, each having an independent entry
* point. * point.
* *
* The 'ram_service', 'cpu_service', and 'rm_service' arguments are * The 'ram_service', 'cpu_service', and 'pd_service' arguments are
* needed to direct quota upgrades referring to the resources of * needed to direct quota upgrades referring to the resources of
* the child environment. By default, we expect that these * the child environment. By default, we expect that these
* resources are provided by the parent. * resources are provided by the parent.
@ -262,13 +255,11 @@ class Genode::Child : protected Rpc_object<Parent>
Pd_session_capability pd, Pd_session_capability pd,
Ram_session_capability ram, Ram_session_capability ram,
Cpu_session_capability cpu, Cpu_session_capability cpu,
Rm_session_capability rm,
Rpc_entrypoint *entrypoint, Rpc_entrypoint *entrypoint,
Child_policy *policy, Child_policy *policy,
Service &pd_service = *_parent_service(), Service &pd_service = *_parent_service(),
Service &ram_service = *_parent_service(), Service &ram_service = *_parent_service(),
Service &cpu_service = *_parent_service(), Service &cpu_service = *_parent_service());
Service &rm_service = *_parent_service());
/** /**
* Destructor * Destructor
@ -286,7 +277,6 @@ class Genode::Child : protected Rpc_object<Parent>
Pd_session_capability pd_session_cap() const { return _pd; } Pd_session_capability pd_session_cap() const { return _pd; }
Ram_session_capability ram_session_cap() const { return _ram; } Ram_session_capability ram_session_cap() const { return _ram; }
Cpu_session_capability cpu_session_cap() const { return _cpu; } Cpu_session_capability cpu_session_cap() const { return _cpu; }
Rm_session_capability rm_session_cap() const { return _rm; }
Parent_capability parent_cap() const { return cap(); } Parent_capability parent_cap() const { return cap(); }
/** /**

View File

@ -57,9 +57,9 @@ struct Genode::Environment
virtual Cpu_session &cpu() = 0; virtual Cpu_session &cpu() = 0;
/** /**
* Region-manager session of the component as created by the parent * Region map of the component's address space
*/ */
virtual Rm_session &rm() = 0; virtual Region_map &rm() = 0;
/** /**
* PD session of the component as created by the parent * PD session of the component as created by the parent

View File

@ -16,8 +16,8 @@
#include <parent/capability.h> #include <parent/capability.h>
#include <parent/parent.h> #include <parent/parent.h>
#include <rm_session/capability.h> #include <region_map/region_map.h>
#include <rm_session/rm_session.h> #include <rm_session/rm_session.h> /* deprecated, kept for API compatibility only */
#include <ram_session/ram_session.h> #include <ram_session/ram_session.h>
#include <cpu_session/cpu_session.h> #include <cpu_session/cpu_session.h>
#include <cpu_session/capability.h> #include <cpu_session/capability.h>
@ -73,8 +73,12 @@ struct Genode::Env
/** /**
* Region-manager session of the component as created by the parent * Region-manager session of the component as created by the parent
*
* \deprecated This function exists for API compatibility only.
* The functionality of the former RM service is now
* provided by the 'Region_map' interface.
*/ */
virtual Rm_session *rm_session() = 0; virtual Region_map *rm_session() = 0;
/** /**
* PD session of the component as created by the parent * PD session of the component as created by the parent
@ -113,7 +117,7 @@ struct Genode::Env
* *
* \noapi * \noapi
*/ */
virtual void reinit_main_thread(Rm_session_capability &stack_area_rm) = 0; virtual void reinit_main_thread(Capability<Region_map> &stack_area_rm) = 0;
}; };

View File

@ -17,7 +17,7 @@
#include <util/list.h> #include <util/list.h>
#include <util/volatile_object.h> #include <util/volatile_object.h>
#include <ram_session/ram_session.h> #include <ram_session/ram_session.h>
#include <rm_session/rm_session.h> #include <region_map/region_map.h>
#include <base/allocator_avl.h> #include <base/allocator_avl.h>
#include <base/lock.h> #include <base/lock.h>
@ -74,15 +74,15 @@ class Genode::Heap : public Allocator
struct Dataspace_pool : public List<Dataspace> struct Dataspace_pool : public List<Dataspace>
{ {
Ram_session *ram_session; /* RAM session for backing store */ Ram_session *ram_session; /* RAM session for backing store */
Rm_session *rm_session; Region_map *region_map;
Dataspace_pool(Ram_session *ram, Rm_session *rm) Dataspace_pool(Ram_session *ram, Region_map *rm)
: ram_session(ram), rm_session(rm) { } : ram_session(ram), region_map(rm) { }
~Dataspace_pool(); ~Dataspace_pool();
void reassign_resources(Ram_session *ram, Rm_session *rm) { void reassign_resources(Ram_session *ram, Region_map *rm) {
ram_session = ram, rm_session = rm; } ram_session = ram, region_map = rm; }
}; };
Lock _lock; Lock _lock;
@ -98,8 +98,8 @@ class Genode::Heap : public Allocator
* \param size number of bytes to allocate * \param size number of bytes to allocate
* \param enforce_separate_metadata if true, the new dataspace * \param enforce_separate_metadata if true, the new dataspace
* will not contain any meta data * will not contain any meta data
* \throw Rm_session::Invalid_dataspace, * \throw Region_map::Invalid_dataspace,
* Rm_session::Region_conflict * Region_map::Region_conflict
* \return 0 on success or negative error code * \return 0 on success or negative error code
*/ */
Heap::Dataspace *_allocate_dataspace(size_t size, bool enforce_separate_metadata); Heap::Dataspace *_allocate_dataspace(size_t size, bool enforce_separate_metadata);
@ -124,13 +124,13 @@ class Genode::Heap : public Allocator
enum { UNLIMITED = ~0 }; enum { UNLIMITED = ~0 };
Heap(Ram_session *ram_session, Heap(Ram_session *ram_session,
Rm_session *rm_session, Region_map *region_map,
size_t quota_limit = UNLIMITED, size_t quota_limit = UNLIMITED,
void *static_addr = 0, void *static_addr = 0,
size_t static_size = 0) size_t static_size = 0)
: :
_alloc(nullptr), _alloc(nullptr),
_ds_pool(ram_session, rm_session), _ds_pool(ram_session, region_map),
_quota_limit(quota_limit), _quota_used(0), _quota_limit(quota_limit), _quota_used(0),
_chunk_size(MIN_CHUNK_SIZE) _chunk_size(MIN_CHUNK_SIZE)
{ {
@ -151,7 +151,7 @@ class Genode::Heap : public Allocator
/** /**
* Re-assign RAM and RM sessions * Re-assign RAM and RM sessions
*/ */
void reassign_resources(Ram_session *ram, Rm_session *rm) { void reassign_resources(Ram_session *ram, Region_map *rm) {
_ds_pool.reassign_resources(ram, rm); } _ds_pool.reassign_resources(ram, rm); }
@ -176,18 +176,18 @@ class Genode::Sliced_heap : public Allocator
class Block; class Block;
Ram_session *_ram_session; /* RAM session for backing store */ Ram_session *_ram_session; /* RAM session for backing store */
Rm_session *_rm_session; /* region manager */ Region_map *_region_map; /* region map of the address space */
size_t _consumed; /* number of allocated bytes */ size_t _consumed; /* number of allocated bytes */
List<Block> _block_list; /* list of allocated blocks */ List<Block> _block_list; /* list of allocated blocks */
Lock _lock; /* serialize allocations */ Lock _lock; /* serialize allocations */
public: public:
/** /**
* Constructor * Constructor
*/ */
Sliced_heap(Ram_session *ram_session, Rm_session *rm_session); Sliced_heap(Ram_session *ram_session, Region_map *region_map);
/** /**
* Destructor * Destructor

View File

@ -15,7 +15,7 @@
#define _INCLUDE__BASE__PROCESS_H_ #define _INCLUDE__BASE__PROCESS_H_
#include <ram_session/capability.h> #include <ram_session/capability.h>
#include <rm_session/client.h> #include <region_map/client.h>
#include <pd_session/client.h> #include <pd_session/client.h>
#include <cpu_session/client.h> #include <cpu_session/client.h>
#include <parent/capability.h> #include <parent/capability.h>
@ -30,7 +30,6 @@ class Genode::Process
Pd_session_client _pd_session_client; Pd_session_client _pd_session_client;
Thread_capability _thread0_cap; Thread_capability _thread0_cap;
Cpu_session_client _cpu_session_client; Cpu_session_client _cpu_session_client;
Rm_session_client _rm_session_client;
static Dataspace_capability _dynamic_linker_cap; static Dataspace_capability _dynamic_linker_cap;
@ -44,7 +43,6 @@ class Genode::Process
* \param ram_session RAM session providing the BSS for the * \param ram_session RAM session providing the BSS for the
* new protection domain * new protection domain
* \param cpu_session CPU session for the new protection domain * \param cpu_session CPU session for the new protection domain
* \param rm_session RM session for the new protection domain
* \param parent parent of the new protection domain * \param parent parent of the new protection domain
* \param name name of protection domain (can be used * \param name name of protection domain (can be used
* for debugging) * for debugging)
@ -58,7 +56,6 @@ class Genode::Process
Pd_session_capability pd_session, Pd_session_capability pd_session,
Ram_session_capability ram_session, Ram_session_capability ram_session,
Cpu_session_capability cpu_session, Cpu_session_capability cpu_session,
Rm_session_capability rm_session,
Parent_capability parent, Parent_capability parent,
char const *name); char const *name);

View File

@ -19,7 +19,7 @@
namespace Genode { namespace Genode {
/* /*
* The 'Pager_capability' type is returned by 'Rm_session::add_client' and * The 'Pager_capability' type is returned by 'Region_map::add_client' and
* passed as argument to 'Cpu_session::set_pager'. It is never invoked or * passed as argument to 'Cpu_session::set_pager'. It is never invoked or
* otherwise used. * otherwise used.
*/ */

View File

@ -56,6 +56,15 @@ struct Genode::Pd_session_client : Rpc_client<Pd_session>
void free_rpc_cap(Native_capability cap) override { void free_rpc_cap(Native_capability cap) override {
call<Rpc_free_rpc_cap>(cap); } call<Rpc_free_rpc_cap>(cap); }
Capability<Region_map> address_space() override {
return call<Rpc_address_space>(); }
Capability<Region_map> stack_area() override {
return call<Rpc_stack_area>(); }
Capability<Region_map> linker_area() override {
return call<Rpc_linker_area>(); }
Capability<Native_pd> native_pd() override { return call<Rpc_native_pd>(); } Capability<Native_pd> native_pd() override { return call<Rpc_native_pd>(); }
}; };

View File

@ -22,7 +22,7 @@ namespace Genode { struct Pd_connection; }
struct Genode::Pd_connection : Connection<Pd_session>, Pd_session_client struct Genode::Pd_connection : Connection<Pd_session>, Pd_session_client
{ {
enum { RAM_QUOTA = 4*1024*sizeof(long) }; enum { RAM_QUOTA = 20*1024*sizeof(long) };
/** /**
* Constructor * Constructor

View File

@ -21,6 +21,7 @@
#include <thread/capability.h> #include <thread/capability.h>
#include <session/session.h> #include <session/session.h>
#include <signal_source/signal_source.h> #include <signal_source/signal_source.h>
#include <region_map/region_map.h>
namespace Genode { namespace Genode {
@ -155,6 +156,28 @@ struct Genode::Pd_session : Session
virtual void free_rpc_cap(Native_capability cap) = 0; virtual void free_rpc_cap(Native_capability cap) = 0;
/**************************************
** Virtual address-space management **
**************************************/
enum { LINKER_AREA_SIZE = 160*1024*1024UL };
/**
* Return region map of the PD's virtual address space
*/
virtual Capability<Region_map> address_space() = 0;
/**
* Return region map of the PD's stack area
*/
virtual Capability<Region_map> stack_area() = 0;
/**
* Return region map of the PD's linker area
*/
virtual Capability<Region_map> linker_area() = 0;
/***************************************** /*****************************************
** Access to kernel-specific interface ** ** Access to kernel-specific interface **
*****************************************/ *****************************************/
@ -180,23 +203,22 @@ struct Genode::Pd_session : Session
GENODE_RPC_THROW(Rpc_alloc_signal_source, Signal_source_capability, GENODE_RPC_THROW(Rpc_alloc_signal_source, Signal_source_capability,
alloc_signal_source, GENODE_TYPE_LIST(Out_of_metadata)); alloc_signal_source, GENODE_TYPE_LIST(Out_of_metadata));
GENODE_RPC(Rpc_free_signal_source, void, free_signal_source, Signal_source_capability); GENODE_RPC(Rpc_free_signal_source, void, free_signal_source, Signal_source_capability);
GENODE_RPC_THROW(Rpc_alloc_context, Capability<Signal_context>, alloc_context, GENODE_RPC_THROW(Rpc_alloc_context, Capability<Signal_context>, alloc_context,
GENODE_TYPE_LIST(Out_of_metadata, Invalid_signal_source), GENODE_TYPE_LIST(Out_of_metadata, Invalid_signal_source),
Signal_source_capability, unsigned long); Signal_source_capability, unsigned long);
GENODE_RPC(Rpc_free_context, void, free_context, GENODE_RPC(Rpc_free_context, void, free_context,
Capability<Signal_context>); Capability<Signal_context>);
GENODE_RPC(Rpc_submit, void, submit, Capability<Signal_context>, unsigned); GENODE_RPC(Rpc_submit, void, submit, Capability<Signal_context>, unsigned);
GENODE_RPC_THROW(Rpc_alloc_rpc_cap, Native_capability, alloc_rpc_cap, GENODE_RPC_THROW(Rpc_alloc_rpc_cap, Native_capability, alloc_rpc_cap,
GENODE_TYPE_LIST(Out_of_metadata), Native_capability); GENODE_TYPE_LIST(Out_of_metadata), Native_capability);
GENODE_RPC(Rpc_free_rpc_cap, void, free_rpc_cap, Native_capability); GENODE_RPC(Rpc_free_rpc_cap, void, free_rpc_cap, Native_capability);
GENODE_RPC(Rpc_address_space, Capability<Region_map>, address_space);
GENODE_RPC(Rpc_stack_area, Capability<Region_map>, stack_area);
GENODE_RPC(Rpc_linker_area, Capability<Region_map>, linker_area);
GENODE_RPC(Rpc_native_pd, Capability<Native_pd>, native_pd); GENODE_RPC(Rpc_native_pd, Capability<Native_pd>, native_pd);
/* /*
@ -212,9 +234,12 @@ struct Genode::Pd_session : Session
Meta::Type_tuple<Rpc_submit, Meta::Type_tuple<Rpc_submit,
Meta::Type_tuple<Rpc_alloc_rpc_cap, Meta::Type_tuple<Rpc_alloc_rpc_cap,
Meta::Type_tuple<Rpc_free_rpc_cap, Meta::Type_tuple<Rpc_free_rpc_cap,
Meta::Type_tuple<Rpc_address_space,
Meta::Type_tuple<Rpc_stack_area,
Meta::Type_tuple<Rpc_linker_area,
Meta::Type_tuple<Rpc_native_pd, Meta::Type_tuple<Rpc_native_pd,
Meta::Empty> Meta::Empty>
> > > > > > > > > > Rpc_functions; > > > > > > > > > > > > > Rpc_functions;
}; };
#endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */ #endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */

View File

@ -22,7 +22,8 @@ namespace Genode { struct Ram_connection; }
struct Genode::Ram_connection : Connection<Ram_session>, Ram_session_client struct Genode::Ram_connection : Connection<Ram_session>, Ram_session_client
{ {
enum { RAM_QUOTA = 64*1024 }; enum { RAM_QUOTA = 4*1024*sizeof(long) };
/** /**
* Constructor * Constructor
* *

View File

@ -0,0 +1,57 @@
/*
* \brief Client-side stub for region map
* \author Christian Helmuth
* \author Norman Feske
* \date 2006-07-11
*/
/*
* Copyright (C) 2006-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__REGION_MAP__CLIENT_H_
#define _INCLUDE__REGION_MAP__CLIENT_H_
#include <base/rpc_client.h>
#include <region_map/region_map.h>
namespace Genode { class Region_map_client; }
class Genode::Region_map_client : public Rpc_client<Region_map>
{
private:
/*
* Multiple calls to get the dataspace capability on NOVA lead to the
* situation that the caller gets each time a new mapping of the same
* capability at different indices. But the client/caller assumes to
* get every time the very same index, e.g., in Noux the index is used
* to look up data structures attached to the capability. Therefore, we
* cache the dataspace capability on the first request.
*
* On all other base platforms, this member variable remains unused.
*/
Dataspace_capability _rm_ds_cap;
public:
explicit Region_map_client(Capability<Region_map>);
Local_addr attach(Dataspace_capability ds, size_t size = 0,
off_t offset = 0, bool use_local_addr = false,
Local_addr local_addr = (void *)0,
bool executable = false) override;
void detach(Local_addr) override;
Pager_capability add_client(Thread_capability) override;
void remove_client(Pager_capability) override;
void fault_handler(Signal_context_capability) override;
State state() override;
Dataspace_capability dataspace() override;
};
#endif /* _INCLUDE__REGION_MAP__CLIENT_H_ */

View File

@ -0,0 +1,210 @@
/*
* \brief Region map interface
* \author Norman Feske
* \date 2006-05-15
*/
/*
* Copyright (C) 2006-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__REGION_MAP__REGION_MAP_H_
#define _INCLUDE__REGION_MAP__REGION_MAP_H_
#include <base/exception.h>
#include <base/stdint.h>
#include <base/signal.h>
#include <dataspace/capability.h>
#include <thread/capability.h>
#include <pager/capability.h>
namespace Genode { struct Region_map; }
struct Genode::Region_map
{
/**
* State of region map
*
* If a thread accesses a location outside the regions attached to its
* address space, a fault occurs and gets signalled to the registered fault
* handler. The fault handler, in turn needs the information about the
* fault address and fault type to resolve the fault. This information is
* represented by this structure.
*/
struct State
{
enum Fault_type { READY, READ_FAULT, WRITE_FAULT, EXEC_FAULT };
/**
* Type of occurred fault
*/
Fault_type type = READY;
/**
* Fault address
*/
addr_t addr = 0;
/**
* Default constructor
*/
State() { }
/**
* Constructor
*/
State(Fault_type fault_type, addr_t fault_addr)
: type(fault_type), addr(fault_addr) { }
};
/**
* Helper for tranferring the bit representation of a pointer as RPC
* argument.
*/
class Local_addr
{
private:
void *_ptr = nullptr;
public:
template <typename T>
Local_addr(T ptr) : _ptr((void *)ptr) { }
Local_addr() { }
template <typename T>
operator T () { return (T)_ptr; }
};
/*********************
** Exception types **
*********************/
class Attach_failed : public Exception { };
class Invalid_args : public Attach_failed { };
class Invalid_dataspace : public Attach_failed { };
class Region_conflict : public Attach_failed { };
class Out_of_metadata : public Attach_failed { };
class Invalid_thread : public Exception { };
class Unbound_thread : public Exception { };
/**
* Map dataspace into local address space
*
* \param ds capability of dataspace to map
* \param size size of the locally mapped region
* default (0) is the whole dataspace
* \param offset start at offset in dataspace (page-aligned)
* \param use_local_addr if set to true, attach the dataspace at
* the specified 'local_addr'
* \param local_addr local destination address
* \param executable if the mapping should be executable
*
* \throw Attach_failed if dataspace or offset is invalid,
* or on region conflict
* \throw Out_of_metadata if meta-data backing store is exhausted
*
* \return local address of mapped dataspace
*
*/
virtual Local_addr attach(Dataspace_capability ds,
size_t size = 0, off_t offset = 0,
bool use_local_addr = false,
Local_addr local_addr = (void *)0,
bool executable = false) = 0;
/**
* Shortcut for attaching a dataspace at a predefined local address
*/
Local_addr attach_at(Dataspace_capability ds, addr_t local_addr,
size_t size = 0, off_t offset = 0) {
return attach(ds, size, offset, true, local_addr); }
/**
* Shortcut for attaching a dataspace executable at a predefined local address
*/
Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr,
size_t size = 0, off_t offset = 0) {
return attach(ds, size, offset, true, local_addr, true); }
/**
* Remove region from local address space
*/
virtual void detach(Local_addr local_addr) = 0;
/**
* Add client to pager
*
* \param thread thread that will be paged
* \throw Invalid_thread
* \throw Out_of_metadata
* \throw Unbound_thread
* \return capability to be used for handling page faults
*
* This method must be called at least once to establish a valid
* communication channel between the pager part of the region manager
* and the client thread.
*/
virtual Pager_capability add_client(Thread_capability thread) = 0;
/**
* Remove client from pager
*
* \param pager pager capability of client to be removed
*/
virtual void remove_client(Pager_capability) = 0;
/**
* Register signal handler for region-manager faults
*
* On Linux, this signal is never delivered because page-fault handling
* is performed by the Linux kernel. On microkernel platforms,
* unresolvable page faults (traditionally called segmentation fault)
* will result in the delivery of the signal.
*/
virtual void fault_handler(Signal_context_capability handler) = 0;
/**
* Request current state of region map
*/
virtual State state() = 0;
/**
* Return dataspace representation of region map
*/
virtual Dataspace_capability dataspace() = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC_THROW(Rpc_attach, Local_addr, attach,
GENODE_TYPE_LIST(Invalid_dataspace, Region_conflict,
Out_of_metadata, Invalid_args),
Dataspace_capability, size_t, off_t, bool, Local_addr, bool);
GENODE_RPC(Rpc_detach, void, detach, Local_addr);
GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client,
GENODE_TYPE_LIST(Unbound_thread, Invalid_thread, Out_of_metadata),
Thread_capability);
GENODE_RPC(Rpc_remove_client, void, remove_client, Pager_capability);
GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability);
GENODE_RPC(Rpc_state, State, state);
GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace);
GENODE_RPC_INTERFACE(Rpc_attach, Rpc_detach, Rpc_add_client,
Rpc_remove_client, Rpc_fault_handler, Rpc_state,
Rpc_dataspace);
};
#endif /* _INCLUDE__REGION_MAP__REGION_MAP_H_ */

View File

@ -1,12 +1,11 @@
/* /*
* \brief Client-side region manager session interface * \brief Client-side region manager session interface
* \author Christian Helmuth
* \author Norman Feske * \author Norman Feske
* \date 2006-07-11 * \date 2016-04-15
*/ */
/* /*
* Copyright (C) 2006-2016 Genode Labs GmbH * Copyright (C) 2016 Genode Labs GmbH
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
@ -18,40 +17,15 @@
#include <rm_session/capability.h> #include <rm_session/capability.h>
#include <base/rpc_client.h> #include <base/rpc_client.h>
namespace Genode { class Rm_session_client; } namespace Genode { struct Rm_session_client; }
class Genode::Rm_session_client : public Rpc_client<Rm_session> struct Genode::Rm_session_client : Rpc_client<Rm_session>
{ {
private: explicit Rm_session_client(Rm_session_capability);
/* Capability<Region_map> create(size_t) override;
* Multiple calls to get the dataspace capability on NOVA lead to the void destroy(Capability<Region_map>) override;
* situation that the caller gets each time a new mapping of the same
* capability at different indices. But the client/caller assumes to
* get every time the very same index, e.g., in Noux the index is used
* to look up data structures attached to the capability. Therefore, we
* cache the dataspace capability on the first request.
*
* On all other base platforms, this member variable remains unused.
*/
Dataspace_capability _rm_ds_cap;
public:
explicit Rm_session_client(Rm_session_capability session);
Local_addr attach(Dataspace_capability ds, size_t size = 0,
off_t offset = 0, bool use_local_addr = false,
Local_addr local_addr = (void *)0,
bool executable = false) override;
void detach(Local_addr) override;
Pager_capability add_client(Thread_capability) override;
void remove_client(Pager_capability) override;
void fault_handler(Signal_context_capability) override;
State state() override;
Dataspace_capability dataspace() override;
}; };
#endif /* _INCLUDE__RM_SESSION__CLIENT_H_ */ #endif /* _INCLUDE__RM_SESSION__CLIENT_H_ */

View File

@ -24,16 +24,8 @@ struct Genode::Rm_connection : Connection<Rm_session>, Rm_session_client
{ {
enum { RAM_QUOTA = 64*1024 }; enum { RAM_QUOTA = 64*1024 };
/** Rm_connection() :
* Constructor Connection<Rm_session>(session("ram_quota=%u", RAM_QUOTA)),
*
* \param start start of the managed VM-region
* \param size size of the VM-region to manage
*/
Rm_connection(addr_t start = ~0UL, size_t size = 0) :
Connection<Rm_session>(
session("ram_quota=%u, start=0x%p, size=0x%zx",
RAM_QUOTA, start, size)),
Rm_session_client(cap()) { } Rm_session_client(cap()) { }
}; };

View File

@ -1,11 +1,11 @@
/* /*
* \brief Region manager session interface * \brief Region-map session interface
* \author Norman Feske * \author Norman Feske
* \date 2006-05-15 * \date 2016-04-15
*/ */
/* /*
* Copyright (C) 2006-2013 Genode Labs GmbH * Copyright (C) 2016 Genode Labs GmbH
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
@ -14,12 +14,7 @@
#ifndef _INCLUDE__RM_SESSION__RM_SESSION_H_ #ifndef _INCLUDE__RM_SESSION__RM_SESSION_H_
#define _INCLUDE__RM_SESSION__RM_SESSION_H_ #define _INCLUDE__RM_SESSION__RM_SESSION_H_
#include <base/exception.h> #include <region_map/region_map.h>
#include <base/stdint.h>
#include <base/signal.h>
#include <dataspace/capability.h>
#include <thread/capability.h>
#include <pager/capability.h>
#include <session/session.h> #include <session/session.h>
namespace Genode { struct Rm_session; } namespace Genode { struct Rm_session; }
@ -27,194 +22,42 @@ namespace Genode { struct Rm_session; }
struct Genode::Rm_session : Session struct Genode::Rm_session : Session
{ {
enum Fault_type {
READY = 0, READ_FAULT = 1, WRITE_FAULT = 2, EXEC_FAULT = 3 };
/**
* State of region-manager session
*
* If a client accesses a location outside the regions attached to
* the region-manager session, a fault occurs and gets signalled to
* the registered fault handler. The fault handler, in turn needs
* the information about the fault address and fault type to
* resolve the fault. This information is represented by this
* structure.
*/
struct State
{
/**
* Type of occurred fault
*/
Fault_type type;
/**
* Fault address
*/
addr_t addr;
/**
* Default constructor
*/
State() : type(READY), addr(0) { }
/**
* Constructor
*/
State(Fault_type fault_type, addr_t fault_addr) :
type(fault_type), addr(fault_addr) { }
};
/**
* Helper for tranferring the bit representation of a pointer as RPC
* argument.
*/
class Local_addr
{
private:
void *_ptr;
public:
template <typename T>
Local_addr(T ptr) : _ptr((void *)ptr) { }
Local_addr() : _ptr(0) { }
template <typename T>
operator T () { return (T)_ptr; }
};
static const char *service_name() { return "RM"; } static const char *service_name() { return "RM"; }
/*********************
** Exception types **
*********************/
class Attach_failed : public Exception { };
class Invalid_args : public Attach_failed { };
class Invalid_dataspace : public Attach_failed { };
class Region_conflict : public Attach_failed { };
class Out_of_metadata : public Attach_failed { };
class Invalid_thread : public Exception { };
class Unbound_thread : public Exception { };
/** /**
* Destructor * Exception types
*/
virtual ~Rm_session() { }
/**
* Map dataspace into local address space
* *
* \param ds capability of dataspace to map * \deprecated The following type definitions will be removed after the
* \param size size of the locally mapped region * transition to the 'Region_map' API is completed.
* default (0) is the whole dataspace */
* \param offset start at offset in dataspace (page-aligned) typedef Region_map::Attach_failed Attach_failed;
* \param use_local_addr if set to true, attach the dataspace at typedef Region_map::Out_of_metadata Out_of_metadata;
* the specified 'local_addr' typedef Region_map::Region_conflict Region_conflict;
* \param local_addr local destination address
* \param executable if the mapping should be executable /**
* * Create region map
* \throw Attach_failed if dataspace or offset is invalid,
* or on region conflict
* \throw Out_of_metadata if meta-data backing store is exhausted
*
* \return local address of mapped dataspace
* *
* \param size upper bound of region map
* \return region-map capability
* \throw Out_of_metadata
*/ */
virtual Local_addr attach(Dataspace_capability ds, virtual Capability<Region_map> create(size_t size) = 0;
size_t size = 0, off_t offset = 0,
bool use_local_addr = false,
Local_addr local_addr = (void *)0,
bool executable = false) = 0;
/** /**
* Shortcut for attaching a dataspace at a predefined local address * Destroy region map
*/ */
Local_addr attach_at(Dataspace_capability ds, addr_t local_addr, virtual void destroy(Capability<Region_map>) = 0;
size_t size = 0, off_t offset = 0) {
return attach(ds, size, offset, true, local_addr); }
/**
* Shortcut for attaching a dataspace executable at a predefined local address
*/
Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr,
size_t size = 0, off_t offset = 0) {
return attach(ds, size, offset, true, local_addr, true); }
/**
* Remove region from local address space
*/
virtual void detach(Local_addr local_addr) = 0;
/**
* Add client to pager
*
* \param thread thread that will be paged
* \throw Invalid_thread
* \throw Out_of_metadata
* \throw Unbound_thread
* \return capability to be used for handling page faults
*
* This method must be called at least once to establish a valid
* communication channel between the pager part of the region manager
* and the client thread.
*/
virtual Pager_capability add_client(Thread_capability thread) = 0;
/**
* Remove client from pager
*
* \param pager pager capability of client to be removed
*/
virtual void remove_client(Pager_capability) = 0;
/**
* Register signal handler for region-manager faults
*
* On Linux, this signal is never delivered because page-fault handling
* is performed by the Linux kernel. On microkernel platforms,
* unresolvable page faults (traditionally called segmentation fault)
* will result in the delivery of the signal.
*/
virtual void fault_handler(Signal_context_capability handler) = 0;
/**
* Request current state of RM session
*/
virtual State state() = 0;
/**
* Return dataspace representation of region-manager session
*/
virtual Dataspace_capability dataspace() = 0;
/********************* /*********************
** RPC declaration ** ** RPC declaration **
*********************/ *********************/
GENODE_RPC_THROW(Rpc_attach, Local_addr, attach, GENODE_RPC_THROW(Rpc_create, Capability<Region_map>, create,
GENODE_TYPE_LIST(Invalid_dataspace, Region_conflict, GENODE_TYPE_LIST(Out_of_metadata), size_t);
Out_of_metadata, Invalid_args), GENODE_RPC(Rpc_destroy, void, destroy, Capability<Region_map>);
Dataspace_capability, size_t, off_t, bool, Local_addr, bool);
GENODE_RPC(Rpc_detach, void, detach, Local_addr);
GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client,
GENODE_TYPE_LIST(Unbound_thread, Invalid_thread, Out_of_metadata),
Thread_capability);
GENODE_RPC(Rpc_remove_client, void, remove_client, Pager_capability);
GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability);
GENODE_RPC(Rpc_state, State, state);
GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace);
GENODE_RPC_INTERFACE(Rpc_attach, Rpc_detach, Rpc_add_client, GENODE_RPC_INTERFACE(Rpc_create, Rpc_destroy);
Rpc_remove_client, Rpc_fault_handler, Rpc_state,
Rpc_dataspace);
}; };
#endif /* _INCLUDE__RM_SESSION__RM_SESSION_H_ */ #endif /* _INCLUDE__RM_SESSION__RM_SESSION_H_ */

View File

@ -63,7 +63,7 @@ if {[have_include "power_on/qemu"]} {
grep_output {^\[init } grep_output {^\[init }
# remove upgrade messages from init # remove upgrade messages from init
unify_output {\[init \-\> test\-server\-mp\] upgrading quota donation for Env\:\:CPU \([0-9]+ bytes\)} "" unify_output {\[init \-\> test\-server\-mp\] upgrading quota donation for .* \([0-9]+ bytes\)} ""
trim_lines trim_lines
unify_output {transfer cap [a-f0-9]+} "transfer cap UNIFIED" unify_output {transfer cap [a-f0-9]+} "transfer cap UNIFIED"

View File

@ -0,0 +1,33 @@
if {[have_spec linux]} {
puts "Platform does not support managed dataspaces"; exit }
build "core init test/rm_nested"
create_boot_directory
install_config {
<config>
<parent-provides>
<service name="ROM"/>
<service name="RAM"/>
<service name="CPU"/>
<service name="RM"/>
<service name="CAP"/>
<service name="PD"/>
<service name="SIGNAL"/>
<service name="LOG"/>
</parent-provides>
<default-route>
<any-service> <parent/> </any-service>
</default-route>
<start name="test-rm_nested">
<resource name="RAM" quantum="10M"/>
</start>
</config>
}
build_boot_image "core init test-rm_nested"
append qemu_args "-nographic -m 64"
run_genode_until {child "test-rm_nested" exited with exit value 0.*} 300

View File

@ -22,7 +22,7 @@ build_boot_image "core init test-thread"
append qemu_args "-nographic -m 64" append qemu_args "-nographic -m 64"
run_genode_until {child "test-thread" exited with exit value .*\n} 40 run_genode_until {child "test-thread" exited with exit value .*\n} 60
# determine error code of child exit # determine error code of child exit
set exit_code [regexp -inline {child "test-thread" exited with exit value .*\n} $output] set exit_code [regexp -inline {child "test-thread" exited with exit value .*\n} $output]

View File

@ -316,7 +316,6 @@ Session_capability Child::session(Parent::Service_name const &name,
/* return sessions that we created for the child */ /* return sessions that we created for the child */
if (!strcmp("Env::ram_session", name.string())) return _ram; if (!strcmp("Env::ram_session", name.string())) return _ram;
if (!strcmp("Env::cpu_session", name.string())) return _cpu; if (!strcmp("Env::cpu_session", name.string())) return _cpu;
if (!strcmp("Env::rm_session", name.string())) return _rm;
if (!strcmp("Env::pd_session", name.string())) return _pd; if (!strcmp("Env::pd_session", name.string())) return _pd;
/* filter session arguments according to the child policy */ /* filter session arguments according to the child policy */
@ -369,8 +368,6 @@ void Child::upgrade(Session_capability to_session, Parent::Upgrade_args const &a
targeted_service = &_ram_service; targeted_service = &_ram_service;
if (to_session.local_name() == _cpu.local_name()) if (to_session.local_name() == _cpu.local_name())
targeted_service = &_cpu_service; targeted_service = &_cpu_service;
if (to_session.local_name() == _rm.local_name())
targeted_service = &_rm_service;
if (to_session.local_name() == _pd.local_name()) if (to_session.local_name() == _pd.local_name())
targeted_service = &_pd_service; targeted_service = &_pd_service;
@ -419,7 +416,6 @@ void Child::close(Session_capability session_cap)
/* refuse to close the child's initial sessions */ /* refuse to close the child's initial sessions */
if (session_cap.local_name() == _ram.local_name() if (session_cap.local_name() == _ram.local_name()
|| session_cap.local_name() == _cpu.local_name() || session_cap.local_name() == _cpu.local_name()
|| session_cap.local_name() == _rm.local_name()
|| session_cap.local_name() == _pd.local_name()) || session_cap.local_name() == _pd.local_name())
return; return;
@ -483,24 +479,21 @@ Child::Child(Dataspace_capability elf_ds,
Pd_session_capability pd, Pd_session_capability pd,
Ram_session_capability ram, Ram_session_capability ram,
Cpu_session_capability cpu, Cpu_session_capability cpu,
Rm_session_capability rm,
Rpc_entrypoint *entrypoint, Rpc_entrypoint *entrypoint,
Child_policy *policy, Child_policy *policy,
Service &pd_service, Service &pd_service,
Service &ram_service, Service &ram_service,
Service &cpu_service, Service &cpu_service)
Service &rm_service)
: :
_pd(pd), _pd_session_client(pd), _ram(ram), _ram_session_client(ram), _pd(pd), _pd_session_client(pd), _ram(ram), _ram_session_client(ram),
_cpu(cpu), _rm(rm), _pd_service(pd_service), _cpu(cpu), _pd_service(pd_service),
_ram_service(ram_service), _cpu_service(cpu_service), _ram_service(ram_service), _cpu_service(cpu_service),
_rm_service(rm_service),
_heap(&_ram_session_client, env()->rm_session()), _heap(&_ram_session_client, env()->rm_session()),
_entrypoint(entrypoint), _entrypoint(entrypoint),
_parent_cap(_entrypoint->manage(this)), _parent_cap(_entrypoint->manage(this)),
_policy(policy), _policy(policy),
_server(ram), _server(ram),
_process(elf_ds, pd, ram, cpu, rm, _parent_cap, policy->name()) _process(elf_ds, pd, ram, cpu, _parent_cap, policy->name())
{ } { }

View File

@ -28,7 +28,7 @@ namespace {
Genode::Parent &parent() override { return *Genode::env()->parent(); } Genode::Parent &parent() override { return *Genode::env()->parent(); }
Genode::Ram_session &ram() override { return *Genode::env()->ram_session(); } Genode::Ram_session &ram() override { return *Genode::env()->ram_session(); }
Genode::Cpu_session &cpu() override { return *Genode::env()->cpu_session(); } Genode::Cpu_session &cpu() override { return *Genode::env()->cpu_session(); }
Genode::Rm_session &rm() override { return *Genode::env()->rm_session(); } Genode::Region_map &rm() override { return *Genode::env()->rm_session(); }
Genode::Pd_session &pd() override { return *Genode::env()->pd_session(); } Genode::Pd_session &pd() override { return *Genode::env()->pd_session(); }
Genode::Entrypoint &ep() override { return _ep; } Genode::Entrypoint &ep() override { return _ep; }

View File

@ -78,12 +78,12 @@ void Genode::Platform_env::reinit(Native_capability::Dst dst,
void void
Genode::Platform_env:: Genode::Platform_env::
reinit_main_thread(Rm_session_capability & stack_area_rm) reinit_main_thread(Capability<Region_map> &stack_area_rm)
{ {
/* reinitialize stack area RM session */ /* reinitialize stack area RM session */
Rm_session * const rms = env_stack_area_rm_session; Region_map * const rms = env_stack_area_region_map;
Rm_session_client * const rmc = dynamic_cast<Rm_session_client *>(rms); Region_map_client * const rmc = dynamic_cast<Region_map_client *>(rms);
construct_at<Rm_session_client>(rmc, stack_area_rm); construct_at<Region_map_client>(rmc, stack_area_rm);
/* reinitialize main-thread object */ /* reinitialize main-thread object */
::reinit_main_thread(); ::reinit_main_thread();

View File

@ -16,7 +16,7 @@
#include <base/internal/stack_area.h> #include <base/internal/stack_area.h>
namespace Genode { namespace Genode {
Rm_session *env_stack_area_rm_session; Region_map *env_stack_area_region_map;
Ram_session *env_stack_area_ram_session; Ram_session *env_stack_area_ram_session;
} }

View File

@ -44,7 +44,7 @@ Heap::Dataspace_pool::~Dataspace_pool()
*/ */
ds->~Dataspace(); ds->~Dataspace();
rm_session->detach(ds_local_addr); region_map->detach(ds_local_addr);
ram_session->free(ds_cap); ram_session->free(ds_cap);
} }
} }
@ -68,11 +68,11 @@ Heap::Dataspace *Heap::_allocate_dataspace(size_t size, bool enforce_separate_me
/* make new ram dataspace available at our local address space */ /* make new ram dataspace available at our local address space */
try { try {
new_ds_cap = _ds_pool.ram_session->alloc(size); new_ds_cap = _ds_pool.ram_session->alloc(size);
ds_addr = _ds_pool.rm_session->attach(new_ds_cap); ds_addr = _ds_pool.region_map->attach(new_ds_cap);
} catch (Ram_session::Alloc_failed) { } catch (Ram_session::Alloc_failed) {
PWRN("could not allocate new dataspace of size %zu", size); PWRN("could not allocate new dataspace of size %zu", size);
return 0; return 0;
} catch (Rm_session::Attach_failed) { } catch (Region_map::Attach_failed) {
PWRN("could not attach dataspace"); PWRN("could not attach dataspace");
_ds_pool.ram_session->free(new_ds_cap); _ds_pool.ram_session->free(new_ds_cap);
return 0; return 0;
@ -215,7 +215,7 @@ void Heap::free(void *addr, size_t size)
break; break;
_ds_pool.remove(ds); _ds_pool.remove(ds);
_ds_pool.rm_session->detach(ds->local_addr); _ds_pool.region_map->detach(ds->local_addr);
_ds_pool.ram_session->free(ds->cap); _ds_pool.ram_session->free(ds->cap);
_quota_used -= ds->size; _quota_used -= ds->size;

View File

@ -57,8 +57,8 @@ namespace Genode {
using namespace Genode; using namespace Genode;
Sliced_heap::Sliced_heap(Ram_session *ram_session, Rm_session *rm_session): Sliced_heap::Sliced_heap(Ram_session *ram_session, Region_map *region_map):
_ram_session(ram_session), _rm_session(rm_session), _ram_session(ram_session), _region_map(region_map),
_consumed(0) { } _consumed(0) { }
@ -78,8 +78,8 @@ bool Sliced_heap::alloc(size_t size, void **out_addr)
try { try {
ds_cap = _ram_session->alloc(size); ds_cap = _ram_session->alloc(size);
local_addr = _rm_session->attach(ds_cap); local_addr = _region_map->attach(ds_cap);
} catch (Rm_session::Attach_failed) { } catch (Region_map::Attach_failed) {
PERR("Could not attach dataspace to local address space"); PERR("Could not attach dataspace to local address space");
_ram_session->free(ds_cap); _ram_session->free(ds_cap);
return false; return false;
@ -115,7 +115,7 @@ void Sliced_heap::free(void *addr, size_t size)
delete b; delete b;
} }
_rm_session->detach(local_addr); _region_map->detach(local_addr);
_ram_session->free(ds_cap); _ram_session->free(ds_cap);
} }

View File

@ -37,7 +37,7 @@ static bool _check_dynamic_elf(Dataspace_capability elf_ds_cap)
/* attach ELF locally */ /* attach ELF locally */
addr_t elf_addr; addr_t elf_addr;
try { elf_addr = env()->rm_session()->attach(elf_ds_cap); } try { elf_addr = env()->rm_session()->attach(elf_ds_cap); }
catch (Rm_session::Attach_failed) { return false; } catch (Region_map::Attach_failed) { return false; }
/* read program header */ /* read program header */
Elf_binary elf((addr_t)elf_addr); Elf_binary elf((addr_t)elf_addr);
@ -52,16 +52,16 @@ static bool _check_dynamic_elf(Dataspace_capability elf_ds_cap)
* \param parent_cap parent capability for child (i.e. myself) * \param parent_cap parent capability for child (i.e. myself)
* \param elf_ds_cap dataspace containing the ELF binary * \param elf_ds_cap dataspace containing the ELF binary
* \param ram RAM session of the new protection domain * \param ram RAM session of the new protection domain
* \param rm region manager session of the new protection domain * \param rm region map of the new protection domain
*/ */
static addr_t _setup_elf(Parent_capability parent_cap, static addr_t _setup_elf(Parent_capability parent_cap,
Dataspace_capability elf_ds_cap, Dataspace_capability elf_ds_cap,
Ram_session &ram, Rm_session &rm) Ram_session &ram, Region_map &rm)
{ {
/* attach ELF locally */ /* attach ELF locally */
addr_t elf_addr; addr_t elf_addr;
try { elf_addr = env()->rm_session()->attach(elf_ds_cap); } try { elf_addr = env()->rm_session()->attach(elf_ds_cap); }
catch (Rm_session::Attach_failed) { return 0; } catch (Region_map::Attach_failed) { return 0; }
/* setup ELF object and read program entry pointer */ /* setup ELF object and read program entry pointer */
Elf_binary elf((addr_t)elf_addr); Elf_binary elf((addr_t)elf_addr);
@ -108,7 +108,7 @@ static addr_t _setup_elf(Parent_capability parent_cap,
/* attach dataspace */ /* attach dataspace */
void *base; void *base;
try { base = env()->rm_session()->attach(ds_cap); } try { base = env()->rm_session()->attach(ds_cap); }
catch (Rm_session::Attach_failed) { catch (Region_map::Attach_failed) {
PERR("env()->rm_session()->attach() failed"); PERR("env()->rm_session()->attach() failed");
entry = 0; entry = 0;
break; break;
@ -140,7 +140,7 @@ static addr_t _setup_elf(Parent_capability parent_cap,
env()->rm_session()->detach(base); env()->rm_session()->detach(base);
try { out_ptr = rm.attach_at(ds_cap, addr, size, offset); } try { out_ptr = rm.attach_at(ds_cap, addr, size, offset); }
catch (Rm_session::Attach_failed) { } catch (Region_map::Attach_failed) { }
} else { } else {
@ -154,10 +154,10 @@ static addr_t _setup_elf(Parent_capability parent_cap,
if (exec) if (exec)
try { out_ptr = rm.attach_executable(ds_cap, addr, size, offset); } try { out_ptr = rm.attach_executable(ds_cap, addr, size, offset); }
catch (Rm_session::Attach_failed) { } catch (Region_map::Attach_failed) { }
else else
try { out_ptr = rm.attach_at(ds_cap, addr, size, offset); } try { out_ptr = rm.attach_at(ds_cap, addr, size, offset); }
catch (Rm_session::Attach_failed) { } catch (Region_map::Attach_failed) { }
} }
if ((addr_t)out_ptr != addr) if ((addr_t)out_ptr != addr)
@ -176,16 +176,17 @@ Process::Process(Dataspace_capability elf_ds_cap,
Pd_session_capability pd_session_cap, Pd_session_capability pd_session_cap,
Ram_session_capability ram_session_cap, Ram_session_capability ram_session_cap,
Cpu_session_capability cpu_session_cap, Cpu_session_capability cpu_session_cap,
Rm_session_capability rm_session_cap,
Parent_capability parent_cap, Parent_capability parent_cap,
char const *name) char const *name)
: _pd_session_client(pd_session_cap), : _pd_session_client(pd_session_cap),
_cpu_session_client(cpu_session_cap), _cpu_session_client(cpu_session_cap)
_rm_session_client(rm_session_cap)
{ {
if (!pd_session_cap.valid()) if (!pd_session_cap.valid())
return; return;
/* region map of the new protection domain */
Region_map_client rm(Pd_session_client(pd_session_cap).address_space());
enum Local_exception enum Local_exception
{ {
THREAD_FAIL, ELF_FAIL, THREAD_ADD_FAIL, THREAD_FAIL, ELF_FAIL, THREAD_ADD_FAIL,
@ -232,7 +233,7 @@ Process::Process(Dataspace_capability elf_ds_cap,
/* parse ELF binary and setup segment dataspaces */ /* parse ELF binary and setup segment dataspaces */
addr_t entry = 0; addr_t entry = 0;
if (elf_ds_cap.valid()) { if (elf_ds_cap.valid()) {
entry = _setup_elf(parent_cap, elf_ds_cap, ram, _rm_session_client); entry = _setup_elf(parent_cap, elf_ds_cap, ram, rm);
if (!entry) { if (!entry) {
PERR("Setup ELF failed"); PERR("Setup ELF failed");
throw ELF_FAIL; throw ELF_FAIL;
@ -248,7 +249,7 @@ Process::Process(Dataspace_capability elf_ds_cap,
/* register thread0 at region manager session */ /* register thread0 at region manager session */
Pager_capability pager; Pager_capability pager;
try { try {
pager = _rm_session_client.add_client(_thread0_cap); pager = rm.add_client(_thread0_cap);
} catch (...) { } catch (...) {
PERR("Pager setup failed"); PERR("Pager setup failed");
throw THREAD_ADD_FAIL; throw THREAD_ADD_FAIL;

View File

@ -0,0 +1,54 @@
/*
* \brief Client-side stub for region map
* \author Norman Feske
* \date 2016-01-22
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <region_map/client.h>
using namespace Genode;
Region_map_client::Region_map_client(Capability<Region_map> cap)
: Rpc_client<Region_map>(cap) { }
Region_map::Local_addr
Region_map_client::attach(Dataspace_capability ds, size_t size, off_t offset,
bool use_local_addr, Local_addr local_addr,
bool executable)
{
return call<Rpc_attach>(ds, size, offset, use_local_addr, local_addr,
executable);
}
void Region_map_client::detach(Local_addr local_addr) {
call<Rpc_detach>(local_addr); }
Pager_capability Region_map_client::add_client(Thread_capability thread)
{
return call<Rpc_add_client>(thread);
}
void Region_map_client::remove_client(Pager_capability pager) {
call<Rpc_remove_client>(pager); }
void Region_map_client::fault_handler(Signal_context_capability cap) {
call<Rpc_fault_handler>(cap); }
Region_map::State Region_map_client::state() { return call<Rpc_state>(); }
Dataspace_capability Region_map_client::dataspace() { return call<Rpc_dataspace>(); }

Some files were not shown because too many files have changed in this diff Show More