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/stack_allocator.cc
SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.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
* 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"); }
};

View File

@ -107,6 +107,15 @@ namespace Genode {
*/
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'
*

View File

@ -19,7 +19,7 @@
/* Genode includes */
#include <base/stdint.h>
#include <base/printf.h>
#include <rm_session/rm_session.h>
#include <region_map/region_map.h>
#include <util/touch.h>
/* base-internal includes */
@ -100,13 +100,13 @@ namespace Genode {
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,
Rm_session::Fault_type pf_type,
Region_map::State::Fault_type pf_type,
unsigned long badge)
{
Fiasco::l4_threadid_t tid;
tid.raw = badge;
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,
(int)tid.id.task, (int)tid.id.lthread);
}

View File

@ -28,8 +28,8 @@ SRC_CC += stack_area.cc \
platform_thread.cc \
ram_session_component.cc \
ram_session_support.cc \
rm_session_component.cc \
rm_session_support.cc \
region_map_component.cc \
region_map_support.cc \
rom_session_component.cc \
signal_source_component.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 pd_assign_pci.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_support.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/thread_utcb.cc
SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.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())
throw Cpu_session::Thread_creation_failed();
env()->pd_session()->bind_thread(_thread_cap);
env()->pd_session()->bind_thread(_thread_cap);
return;
}
/* adjust values whose computation differs for a main thread */
@ -80,7 +80,11 @@ void Thread_base::start()
using namespace Fiasco;
/* 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);
/* 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
* 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"); }
};

View File

@ -125,6 +125,15 @@ namespace Genode {
*/
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'
*

View File

@ -97,11 +97,11 @@ namespace Genode {
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,
Rm_session::Fault_type pf_type,
Region_map::State::Fault_type pf_type,
unsigned long badge)
{
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);
}

View File

@ -32,8 +32,8 @@ SRC_CC += stack_area.cc \
platform_thread.cc \
ram_session_component.cc \
ram_session_support.cc \
rm_session_component.cc \
rm_session_support.cc \
region_map_component.cc \
region_map_support.cc \
rom_session_component.cc \
signal_source_component.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_upgrade_ram_quota.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 trace_session_component.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 += kernel/interface.cc
SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.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 += cpu_session_component.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_rpc_cap_alloc.cc
SRC_CC += dataspace_component.cc
@ -36,12 +36,12 @@ SRC_CC += platform_thread.cc
SRC_CC += stack_area.cc
SRC_CC += ram_session_component.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 += trace_session_component.cc
SRC_CC += thread_start.cc
SRC_CC += env.cc
SRC_CC += rm_session_support.cc
SRC_CC += region_map_support.cc
SRC_CC += pager.cc
SRC_CC += _main.cc
SRC_CC += component_construct.cc

View File

@ -21,11 +21,10 @@
/* base-internal includes */
#include <base/internal/stack_allocator.h>
#include <base/internal/native_utcb.h>
#include <base/internal/platform_env_common.h>
using namespace Genode;
namespace Genode { extern Rm_session * const env_stack_area_rm_session; }
namespace Hw {
extern Ram_dataspace_capability _main_thread_utcb_ds;
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);
addr_t const stack_area = stack_area_virtual_base();
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); }
@ -78,7 +77,7 @@ void Thread_base::_deinit_platform_thread()
size_t const size = sizeof(_stack->utcb());
addr_t utcb = Stack_allocator::addr_to_base(_stack) +
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()) {
env()->rm_session()->remove_client(_pager_cap);
@ -101,7 +100,7 @@ void Thread_base::start()
size_t const size = sizeof(_stack->utcb());
addr_t dst = Stack_allocator::addr_to_base(_stack) +
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 (...) {
PERR("failed to attach userland stack");
sleep_forever();

View File

@ -16,17 +16,17 @@
/* core includes */
#include <platform.h>
#include <core_rm_session.h>
#include <core_region_map.h>
#include <map_local.h>
#include <util.h>
#include <base/heap.h>
using namespace Genode;
Rm_session::Local_addr
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
Region_map::Local_addr
Core_region_map::attach(Dataspace_capability ds_cap, size_t size,
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 {
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 */
#include <translation_table_allocator_tpl.h>
#include <platform_generic.h>
#include <core_rm_session.h>
#include <core_region_map.h>
#include <core_mem_alloc.h>
namespace Genode {

View File

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

View File

@ -16,12 +16,13 @@ SRC_CC += child/child.cc
SRC_CC += process/process.cc
SRC_CC += elf/elf_binary.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 += server/server.cc server/common.cc
SRC_CC += thread/trace.cc thread/thread_env.cc thread/stack_allocator.cc
SRC_CC += irq/platform.cc
SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.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
@ -20,7 +20,7 @@ install_config {
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<start name="test-rm_session_mmap">
<start name="test-region_map_mmap">
<resource name="RAM" quantum="2M"/>
</start>
@ -34,7 +34,7 @@ install_config {
</start>
</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

View File

@ -29,7 +29,7 @@ using namespace Genode;
****************************************************/
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())
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;
}
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();
}
/********************************
** Platform_env::Local_parent **
********************************/
@ -63,22 +64,11 @@ Platform_env::Local_parent::session(Service_name const &service_name,
Session_args const &args,
Affinity const &affinity)
{
if (strcmp(service_name.string(),
Rm_session::service_name()) == 0)
if (strcmp(service_name.string(), Rm_session::service_name()) == 0)
{
size_t size =
Arg_string::find_arg(args.string(),"size")
.ulong_value(~0);
Local_rm_session *session = new (_alloc) Local_rm_session(_alloc);
if (size == 0)
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 Local_capability<Session>::local_cap(session);
}
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
*/
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<Pd_session> (_parent().session("Env::pd_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()))
{
/* 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_rm_session = &_stack_area;
/* register TID and PID of the main thread at core */
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
* \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,
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))) {
PERR("_reserve_local: lx_mmap failed (addr_in=%p,addr_out=%p/%ld)",
addr_in, addr_out, (long)addr_out);
throw Rm_session::Region_conflict();
throw Region_map::Region_conflict();
}
return (addr_t) addr_out;
@ -102,7 +102,7 @@ addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_loc
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,
addr_t offset,
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))) {
PERR("_map_local: lx_mmap failed (addr_in=%p,addr_out=%p/%ld) overmap=%d",
addr_in, addr_out, (long)addr_out, overmap);
throw Rm_session::Region_conflict();
throw Region_map::Region_conflict();
}
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) {
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
Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
Region_map::Local_addr
Platform_env::Region_map_mmap::attach(Dataspace_capability ds,
size_t size, off_t offset,
bool use_local_addr,
Rm_session::Local_addr local_addr,
Region_map::Local_addr local_addr,
bool executable)
{
Lock::Guard lock_guard(_lock);
/* only support attach_at for sub RM sessions */
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();
}
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();
}
@ -200,7 +200,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
* Case 4
*/
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();
}
@ -209,7 +209,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
* sub RM session
*/
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();
}
@ -234,7 +234,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability 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)
throw Invalid_dataspace();
@ -245,7 +245,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
* Detect if sub RM session is already attached
*/
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();
}
@ -264,7 +264,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds,
* been populated with dataspaces. Go through all regions and map
* 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);
if (!region.used())
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);
@ -357,7 +357,7 @@ void Platform_env::Rm_session_mmap::detach(Rm_session::Local_addr local_addr)
if (is_sub_rm_session(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)
rm->_base = 0;
}

View File

@ -56,13 +56,11 @@ Process::Process(Dataspace_capability elf_data_ds_cap,
Pd_session_capability pd_session_cap,
Ram_session_capability ram_session_cap,
Cpu_session_capability cpu_session_cap,
Rm_session_capability rm_session_cap,
Parent_capability parent_cap,
char const *name)
:
_pd_session_client(pd_session_cap),
_cpu_session_client(cpu_session_cap),
_rm_session_client(Rm_session_capability())
_cpu_session_client(cpu_session_cap)
{
/* check for dynamic program header */
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
* \date 2011-11-21
*/
@ -25,52 +25,19 @@ using namespace Genode;
*
* \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);
}
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) { }
Rm_session::Local_addr
Rm_session_client::attach(Dataspace_capability ds, size_t 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); }
Capability<Region_map> Rm_session_client::create(size_t size) {
return _local(*this)->create(size); }
Pager_capability Rm_session_client::add_client(Thread_capability thread) {
return _local(*this)->add_client(thread); }
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(); }
void Rm_session_client::destroy(Capability<Region_map> cap) {
_local(*this)->destroy(cap); }

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
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())
return Local_capability<Dataspace>::deref(ds_cap)->size();
/* use RPC if called from a different thread */
if (!core_env()->entrypoint()->is_myself()) {
/* release Rm_session_mmap::_lock during RPC */
/* release Region_map_mmap::_lock during RPC */
_lock.unlock();
Genode::size_t size = Dataspace_client(ds_cap).size();
_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()) {
/* release Rm_session_mmap::_lock during RPC */
/* release Region_map_mmap::_lock during RPC */
_lock.unlock();
int socket = Linux_dataspace_client(ds_cap).fd().dst().socket;
_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
* 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
* 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()) {
/* release Rm_session_mmap::_lock during RPC */
/* release Region_map_mmap::_lock during RPC */
_lock.unlock();
bool writable = Dataspace_client(ds_cap).writable();
_lock.lock();

View File

@ -19,21 +19,22 @@
/* base-internal includes */
#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
* organizing stacks within the stack. It "emulates" the sub address space by
* adjusting the local address argument to 'attach' with the offset of the
* stack area.
*/
class Stack_area_rm_session : public Genode::Rm_session
class Stack_area_region_map : public Genode::Region_map
{
public:
Stack_area_rm_session()
Stack_area_region_map()
{
flush_stack_area();
reserve_stack_area();
@ -105,13 +106,13 @@ class Stack_area_ram_session : public Genode::Ram_session
*/
namespace Genode {
Rm_session *env_stack_area_rm_session;
Region_map *env_stack_area_region_map;
Ram_session *env_stack_area_ram_session;
void init_stack_area()
{
static Stack_area_rm_session rm_inst;
env_stack_area_rm_session = &rm_inst;
static Stack_area_region_map rm_inst;
env_stack_area_region_map = &rm_inst;
static Stack_area_ram_session ram_inst;
env_stack_area_ram_session = &ram_inst;

View File

@ -33,6 +33,7 @@
namespace Genode {
struct Expanding_cpu_session_client;
class Platform_env_base;
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
* non-core processes.
*/
class Platform_env_base : public Env
{
private:
/**************************
** Local region manager **
**************************/
/**************************
** Local region manager **
**************************/
class Region
{
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;
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
void destroy(Capability<Region_map> cap)
{
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];
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
Capability<Region_map> address_space()
{
private:
return Local_capability<Region_map>::local_cap(&_address_space);
}
Lock _lock; /* protect '_rmap' */
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
Capability<Region_map> stack_area()
{
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:
/**********************
** Parent interface **
**********************/
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;
Region_map_mmap _region_map_mmap;
Pd_session_capability _pd_session_cap;
Session_capability session(Service_name const &,
Session_args const &,
Affinity const & = Affinity());
void close(Session_capability);
protected:
/**
* 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 &);
};
/*
* The '_local_pd_session' is protected because it is needed by
* 'Platform_env' to initialize the stack area. This must not happen
* in 'Platform_env_base' because the procedure differs between
* core and non-core components.
*/
Local_pd_session _local_pd_session { _pd_session_cap };
/**
* Return instance of parent interface
*/
Local_parent &_parent();
public:
Heap _heap;
/*
* The '_heap' must be initialized before the '_stack_area'
* because the 'Local_parent' performs a dynamic memory allocation
* due to the creation of the stack area's sub-RM session.
*/
Attached_stack_area _stack_area;
/*
* 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;
/**
* 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),
_region_map_mmap(false),
_pd_session_cap(pd_cap),
_local_pd_session(_pd_session_cap)
{ }
/*************************************
** 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
*/
Platform_env();
/**
* Destructor
*/
~Platform_env() { _parent().exit(0); }
/*
* Support functions for implementing fork on Noux.
*
* Not supported on Linux.
*/
void reinit(Native_capability::Dst, long) override { }
void reinit_main_thread(Capability<Region_map> &) override { }
};
/*************************************
** 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(); }
Heap *heap() override { return &_heap; }
};
}
public:
/**
* 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_ */

View File

@ -53,7 +53,7 @@ static inline void flush_stack_area()
int ret;
if ((ret = lx_munmap(base, size)) < 0) {
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__,
addr_in, addr_out, (long)addr_out);
throw Rm_session::Region_conflict();
throw Region_map::Region_conflict();
}
return (addr_t) addr_out;

View File

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

View File

@ -1,3 +1,3 @@
TARGET = test-rm_session_mmap
TARGET = test-region_map_mmap
LIBS = base
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/stack_allocator.cc env/cap_map.cc
SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.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 Alexander Boettcher
* \date 2016-01-22
@ -12,16 +12,16 @@
* under the terms of the GNU General Public License version 2.
*/
#include <rm_session/client.h>
#include <region_map/client.h>
using namespace Genode;
Rm_session_client::Rm_session_client(Rm_session_capability session)
: Rpc_client<Rm_session>(session) { }
Region_map_client::Region_map_client(Capability<Region_map> session)
: Rpc_client<Region_map>(session) { }
Rm_session::Local_addr
Rm_session_client::attach(Dataspace_capability ds, size_t size, off_t offset,
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)
{
@ -29,23 +29,23 @@ Rm_session_client::attach(Dataspace_capability ds, size_t size, off_t offset,
executable);
}
void Rm_session_client::detach(Local_addr local_addr) {
void Region_map_client::detach(Local_addr 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);
}
void Rm_session_client::remove_client(Pager_capability pager) {
void Region_map_client::remove_client(Pager_capability 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); }
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())
_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
* \date 2009-10-02
*/
@ -15,7 +15,7 @@
#include <base/printf.h>
/* core includes */
#include <core_rm_session.h>
#include <core_region_map.h>
#include <platform.h>
#include <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;
}
Rm_session::Local_addr
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
Region_map::Local_addr
Core_region_map::attach(Dataspace_capability ds_cap, size_t size,
off_t offset, bool use_local_addr,
Rm_session::Local_addr local_addr,
Region_map::Local_addr local_addr,
bool executable)
{
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);

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;
}
/**
* 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);
/**

View File

@ -35,11 +35,11 @@ namespace Genode {
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)
{
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,
faulter_badge,
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();
if (!kernel_hip()->is_cpu_enabled(use_cpu) || !pager_threads[use_cpu]) {
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;
@ -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,
__core_pd_sel, ec_sel, mtd, entry, obj);
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 ||
Native_thread::INVALID_INDEX == _client_exc_pt_sel)
throw Rm_session::Invalid_thread();
throw Region_map::Invalid_thread();
/* ypos information not supported by now */
if (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 */
unsigned use_cpu = location.xpos();
if (!kernel_hip()->is_cpu_enabled(use_cpu) || !pager_threads[use_cpu]) {
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;
@ -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);
if (res != Nova::NOVA_OK) {
throw Rm_session::Invalid_thread();
throw Region_map::Invalid_thread();
}
/* 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);
if (res != Nova::NOVA_OK) {
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 */
res = Nova::create_sm(sel_sm_notify(), pd_sel, 0);
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 */
res = Nova::create_sm(sel_sm_block(), pd_sel, 0);
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];
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",
pf_sp, pf_type,

View File

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

View File

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

View File

@ -18,6 +18,7 @@
#include <util/touch.h>
#include <rm_session/connection.h>
#include <region_map/client.h>
#include <os/attached_rom_dataspace.h>
#include <os/config.h>
@ -53,7 +54,8 @@ void test_pat()
Test::Capability session_cap = ep.manage(&component);
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());
/* trigger mapping of whole area */
@ -193,12 +195,14 @@ class Greedy : public Thread<4096> {
Thread<0x1000>("greedy")
{ }
void entry() {
void entry()
{
PINF("starting");
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());
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/stack_allocator.cc
SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.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
* \date 2009-04-02
*/
@ -13,16 +13,16 @@
/* core includes */
#include <platform.h>
#include <core_rm_session.h>
#include <core_region_map.h>
#include <map_local.h>
using namespace Genode;
Rm_session::Local_addr
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
Region_map::Local_addr
Core_region_map::attach(Dataspace_capability ds_cap, size_t size,
off_t offset, bool use_local_addr,
Rm_session::Local_addr, bool executable)
Region_map::Local_addr, bool executable)
{
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_thread.h>
#include <platform_pd.h>
#include <core_rm_session.h>
#include <core_region_map.h>
#include <core_mem_alloc.h>
/* 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,
Rm_session::Fault_type pf_type,
Region_map::State::Fault_type pf_type,
unsigned long faulter_badge)
{
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,
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
* \date 2009-04-10
*/
@ -15,7 +15,7 @@
#include <base/printf.h>
/* core includes */
#include <rm_session_component.h>
#include <region_map_component.h>
using namespace Genode;

View File

@ -7,7 +7,7 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC += stack_area.cc \
core_mem_alloc.cc \
core_printf.cc \
core_rm_session.cc \
core_region_map.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
cpu_session_support.cc \
@ -30,8 +30,8 @@ SRC_CC += stack_area.cc \
platform_thread.cc \
ram_session_component.cc \
ram_session_support.cc \
rm_session_component.cc \
rm_session_support.cc \
region_map_component.cc \
region_map_support.cc \
rom_session_component.cc \
signal_source_component.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_assign_pci.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_support.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/stack_allocator.cc
SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.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
* 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"); }
};

View File

@ -120,6 +120,15 @@ namespace Genode {
*/
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'
*

View File

@ -107,13 +107,13 @@ namespace Genode {
}
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)
{
Pistachio::L4_ThreadId_t tid;
tid.raw = badge;
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,
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
* \date 2009-04-10
*/

View File

@ -30,8 +30,8 @@ SRC_CC = stack_area.cc \
platform_thread.cc \
ram_session_component.cc \
ram_session_support.cc \
rm_session_component.cc \
rm_session_support.cc \
region_map_component.cc \
region_map_support.cc \
rom_session_component.cc \
signal_source_component.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 pd_assign_pci.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_support.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 += env/capability.cc
SRC_CC += sleep.cc
SRC_CC += region_map_client.cc
SRC_CC += rm_session_client.cc
SRC_CC += entrypoint/entrypoint.cc
SRC_CC += component/component.cc

View File

@ -21,12 +21,12 @@ SRC_CC += \
platform_services.cc \
platform.cc \
dataspace_component.cc \
rm_session_component.cc \
rm_session_support.cc \
region_map_component.cc \
region_map_support.cc \
irq_session_component.cc \
signal_source_component.cc \
trace_session_component.cc \
core_rm_session.cc \
core_region_map.cc \
core_mem_alloc.cc \
core_rpc_cap_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_assign_pci.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_support.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
* \date 2015-05-01
*/
@ -15,17 +15,17 @@
#include <base/printf.h>
/* core includes */
#include <core_rm_session.h>
#include <core_region_map.h>
#include <platform.h>
#include <map_local.h>
using namespace Genode;
Rm_session::Local_addr
Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
Region_map::Local_addr
Core_region_map::attach(Dataspace_capability ds_cap, size_t size,
off_t offset, bool use_local_addr,
Rm_session::Local_addr local_addr,
Region_map::Local_addr local_addr,
bool executable)
{
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
* \date 2015-05-01
*/
@ -16,15 +16,15 @@
/* Genode includes */
#include <base/printf.h>
#include <rm_session/rm_session.h>
#include <region_map/region_map.h>
/* core includes */
#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:
@ -32,7 +32,7 @@ class Genode::Core_rm_session : public Rm_session
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,
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"; }
/**
* 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 **

View File

@ -35,11 +35,11 @@ namespace Genode {
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)
{
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,
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
* \date 2015-05-01
*/

View File

@ -13,7 +13,7 @@
*/
/* Genode includes */
#include <rm_session/rm_session.h>
#include <region_map/region_map.h>
#include <ram_session/ram_session.h>
#include <base/printf.h>
#include <base/synced_allocator.h>
@ -27,6 +27,7 @@
/* base-internal includes */
#include <base/internal/stack_area.h>
#include <base/internal/platform_env_common.h>
using namespace Genode;
@ -42,7 +43,7 @@ using namespace Genode;
* place, the allocation of a dataspace has no effect, but the attachment of
* 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:
@ -135,13 +136,13 @@ class Stack_area_ram_session : public Ram_session
namespace Genode {
Rm_session *env_stack_area_rm_session;
Region_map *env_stack_area_region_map;
Ram_session *env_stack_area_ram_session;
void init_stack_area()
{
static Stack_area_rm_session rm_inst;
env_stack_area_rm_session = &rm_inst;
static Stack_area_region_map rm_inst;
env_stack_area_region_map = &rm_inst;
static 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_capability _cpu;
/* RM session representing the address space of the child */
Rm_session_capability _rm;
/* Services where the PD, RAM, CPU, and RM resources come from */
/* services where the PD, RAM, and CPU resources come from */
Service &_pd_service;
Service &_ram_service;
Service &_cpu_service;
Service &_rm_service;
/* heap for child-specific allocations using the child's quota */
Heap _heap;
@ -238,14 +234,11 @@ class Genode::Child : protected Rpc_object<Parent>
* \param pd PD session representing the protection domain
* \param ram RAM 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 policy child policy
* \param pd_service provider of the 'pd' session
* \param ram_service provider of the 'ram' 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
* 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
* 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
* the child environment. By default, we expect that these
* resources are provided by the parent.
@ -262,13 +255,11 @@ class Genode::Child : protected Rpc_object<Parent>
Pd_session_capability pd,
Ram_session_capability ram,
Cpu_session_capability cpu,
Rm_session_capability rm,
Rpc_entrypoint *entrypoint,
Child_policy *policy,
Service &pd_service = *_parent_service(),
Service &ram_service = *_parent_service(),
Service &cpu_service = *_parent_service(),
Service &rm_service = *_parent_service());
Service &cpu_service = *_parent_service());
/**
* Destructor
@ -286,7 +277,6 @@ class Genode::Child : protected Rpc_object<Parent>
Pd_session_capability pd_session_cap() const { return _pd; }
Ram_session_capability ram_session_cap() const { return _ram; }
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(); }
/**

View File

@ -57,9 +57,9 @@ struct Genode::Environment
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

View File

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

View File

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

View File

@ -19,7 +19,7 @@
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
* 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 {
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>(); }
};

View File

@ -22,7 +22,7 @@ namespace Genode { struct Pd_connection; }
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

View File

@ -21,6 +21,7 @@
#include <thread/capability.h>
#include <session/session.h>
#include <signal_source/signal_source.h>
#include <region_map/region_map.h>
namespace Genode {
@ -155,6 +156,28 @@ struct Genode::Pd_session : Session
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 **
*****************************************/
@ -180,23 +203,22 @@ struct Genode::Pd_session : Session
GENODE_RPC_THROW(Rpc_alloc_signal_source, Signal_source_capability,
alloc_signal_source, GENODE_TYPE_LIST(Out_of_metadata));
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_TYPE_LIST(Out_of_metadata, Invalid_signal_source),
Signal_source_capability, unsigned long);
GENODE_RPC(Rpc_free_context, void, free_context,
Capability<Signal_context>);
GENODE_RPC(Rpc_submit, void, submit, Capability<Signal_context>, unsigned);
GENODE_RPC_THROW(Rpc_alloc_rpc_cap, Native_capability, alloc_rpc_cap,
GENODE_TYPE_LIST(Out_of_metadata), 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);
/*
@ -212,9 +234,12 @@ struct Genode::Pd_session : Session
Meta::Type_tuple<Rpc_submit,
Meta::Type_tuple<Rpc_alloc_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::Empty>
> > > > > > > > > > Rpc_functions;
> > > > > > > > > > > > > Rpc_functions;
};
#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
{
enum { RAM_QUOTA = 64*1024 };
enum { RAM_QUOTA = 4*1024*sizeof(long) };
/**
* 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
* \author Christian Helmuth
* \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
* under the terms of the GNU General Public License version 2.
@ -18,40 +17,15 @@
#include <rm_session/capability.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);
/*
* 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 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;
Capability<Region_map> create(size_t) override;
void destroy(Capability<Region_map>) override;
};
#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 };
/**
* Constructor
*
* \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_connection() :
Connection<Rm_session>(session("ram_quota=%u", RAM_QUOTA)),
Rm_session_client(cap()) { }
};

View File

@ -1,11 +1,11 @@
/*
* \brief Region manager session interface
* \brief Region-map session interface
* \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
* under the terms of the GNU General Public License version 2.
@ -14,12 +14,7 @@
#ifndef _INCLUDE__RM_SESSION__RM_SESSION_H_
#define _INCLUDE__RM_SESSION__RM_SESSION_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>
#include <region_map/region_map.h>
#include <session/session.h>
namespace Genode { struct Rm_session; }
@ -27,194 +22,42 @@ namespace Genode { struct Rm_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"; }
/*********************
** 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
*/
virtual ~Rm_session() { }
/**
* Map dataspace into local address space
* Exception types
*
* \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
* \deprecated The following type definitions will be removed after the
* transition to the 'Region_map' API is completed.
*/
typedef Region_map::Attach_failed Attach_failed;
typedef Region_map::Out_of_metadata Out_of_metadata;
typedef Region_map::Region_conflict Region_conflict;
/**
* Create region map
*
* \param size upper bound of region map
* \return region-map capability
* \throw Out_of_metadata
*/
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;
virtual Capability<Region_map> create(size_t size) = 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,
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;
virtual void destroy(Capability<Region_map>) = 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_THROW(Rpc_create, Capability<Region_map>, create,
GENODE_TYPE_LIST(Out_of_metadata), size_t);
GENODE_RPC(Rpc_destroy, void, destroy, Capability<Region_map>);
GENODE_RPC_INTERFACE(Rpc_attach, Rpc_detach, Rpc_add_client,
Rpc_remove_client, Rpc_fault_handler, Rpc_state,
Rpc_dataspace);
GENODE_RPC_INTERFACE(Rpc_create, Rpc_destroy);
};
#endif /* _INCLUDE__RM_SESSION__RM_SESSION_H_ */

View File

@ -63,7 +63,7 @@ if {[have_include "power_on/qemu"]} {
grep_output {^\[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
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"
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
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 */
if (!strcmp("Env::ram_session", name.string())) return _ram;
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;
/* 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;
if (to_session.local_name() == _cpu.local_name())
targeted_service = &_cpu_service;
if (to_session.local_name() == _rm.local_name())
targeted_service = &_rm_service;
if (to_session.local_name() == _pd.local_name())
targeted_service = &_pd_service;
@ -419,7 +416,6 @@ void Child::close(Session_capability session_cap)
/* refuse to close the child's initial sessions */
if (session_cap.local_name() == _ram.local_name()
|| session_cap.local_name() == _cpu.local_name()
|| session_cap.local_name() == _rm.local_name()
|| session_cap.local_name() == _pd.local_name())
return;
@ -483,24 +479,21 @@ Child::Child(Dataspace_capability elf_ds,
Pd_session_capability pd,
Ram_session_capability ram,
Cpu_session_capability cpu,
Rm_session_capability rm,
Rpc_entrypoint *entrypoint,
Child_policy *policy,
Service &pd_service,
Service &ram_service,
Service &cpu_service,
Service &rm_service)
Service &cpu_service)
:
_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),
_rm_service(rm_service),
_heap(&_ram_session_client, env()->rm_session()),
_entrypoint(entrypoint),
_parent_cap(_entrypoint->manage(this)),
_policy(policy),
_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::Ram_session &ram() override { return *Genode::env()->ram_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::Entrypoint &ep() override { return _ep; }

View File

@ -78,12 +78,12 @@ void Genode::Platform_env::reinit(Native_capability::Dst dst,
void
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 */
Rm_session * const rms = env_stack_area_rm_session;
Rm_session_client * const rmc = dynamic_cast<Rm_session_client *>(rms);
construct_at<Rm_session_client>(rmc, stack_area_rm);
Region_map * const rms = env_stack_area_region_map;
Region_map_client * const rmc = dynamic_cast<Region_map_client *>(rms);
construct_at<Region_map_client>(rmc, stack_area_rm);
/* reinitialize main-thread object */
::reinit_main_thread();

View File

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

View File

@ -44,7 +44,7 @@ Heap::Dataspace_pool::~Dataspace_pool()
*/
ds->~Dataspace();
rm_session->detach(ds_local_addr);
region_map->detach(ds_local_addr);
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 */
try {
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) {
PWRN("could not allocate new dataspace of size %zu", size);
return 0;
} catch (Rm_session::Attach_failed) {
} catch (Region_map::Attach_failed) {
PWRN("could not attach dataspace");
_ds_pool.ram_session->free(new_ds_cap);
return 0;
@ -215,7 +215,7 @@ void Heap::free(void *addr, size_t size)
break;
_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);
_quota_used -= ds->size;

View File

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

View File

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