mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 15:18:20 +00:00
@ -21,7 +21,7 @@
|
|||||||
/* base-internal includes */
|
/* base-internal includes */
|
||||||
#include <base/internal/stack_allocator.h>
|
#include <base/internal/stack_allocator.h>
|
||||||
#include <base/internal/native_utcb.h>
|
#include <base/internal/native_utcb.h>
|
||||||
#include <base/internal/platform_env_common.h>
|
#include <base/internal/globals.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
@ -180,8 +180,7 @@ namespace Genode {
|
|||||||
** Support for Platform_env_base::Region_map_mmap **
|
** Support for Platform_env_base::Region_map_mmap **
|
||||||
****************************************************/
|
****************************************************/
|
||||||
|
|
||||||
Genode::size_t
|
size_t Region_map_mmap::_dataspace_size(Capability<Dataspace> ds_cap)
|
||||||
Platform_env_base::Region_map_mmap::_dataspace_size(Capability<Dataspace> ds_cap)
|
|
||||||
{
|
{
|
||||||
if (!ds_cap.valid())
|
if (!ds_cap.valid())
|
||||||
return Local_capability<Dataspace>::deref(ds_cap)->size();
|
return Local_capability<Dataspace>::deref(ds_cap)->size();
|
||||||
@ -201,7 +200,7 @@ Platform_env_base::Region_map_mmap::_dataspace_size(Capability<Dataspace> ds_cap
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Platform_env_base::Region_map_mmap::_dataspace_fd(Capability<Dataspace> ds_cap)
|
int Region_map_mmap::_dataspace_fd(Capability<Dataspace> ds_cap)
|
||||||
{
|
{
|
||||||
if (!core_env()->entrypoint()->is_myself()) {
|
if (!core_env()->entrypoint()->is_myself()) {
|
||||||
/* release Region_map_mmap::_lock during RPC */
|
/* release Region_map_mmap::_lock during RPC */
|
||||||
@ -227,7 +226,7 @@ int Platform_env_base::Region_map_mmap::_dataspace_fd(Capability<Dataspace> ds_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Platform_env_base::Region_map_mmap::_dataspace_writable(Dataspace_capability ds_cap)
|
bool Region_map_mmap::_dataspace_writable(Dataspace_capability ds_cap)
|
||||||
{
|
{
|
||||||
if (!core_env()->entrypoint()->is_myself()) {
|
if (!core_env()->entrypoint()->is_myself()) {
|
||||||
/* release Region_map_mmap::_lock during RPC */
|
/* release Region_map_mmap::_lock during RPC */
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
/* base-internal includes */
|
/* base-internal includes */
|
||||||
#include <base/internal/stack_area.h>
|
#include <base/internal/stack_area.h>
|
||||||
#include <base/internal/platform_env_common.h>
|
#include <base/internal/globals.h>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
69
repos/base-linux/src/include/base/internal/local_parent.h
Normal file
69
repos/base-linux/src/include/base/internal/local_parent.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* \brief Component-local implementation of the parent interface
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2016-04-29
|
||||||
|
*
|
||||||
|
* On Linux, we intercept the parent interface to implement services that are
|
||||||
|
* concerned with virtual-memory management locally within the component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE__BASE__INTERNAL__LOCAL_PARENT_H_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__LOCAL_PARENT_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/allocator.h>
|
||||||
|
|
||||||
|
/* base-internal includes */
|
||||||
|
#include <base/internal/expanding_parent_client.h>
|
||||||
|
|
||||||
|
namespace Genode { class Local_parent; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 Genode::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 &);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__LOCAL_PARENT_H_ */
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* \brief Component-local implementation of a PD session
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2016-04-29
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE__BASE__INTERNAL__LOCAL_PD_SESSION_H_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__LOCAL_PD_SESSION_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <pd_session/client.h>
|
||||||
|
#include <linux_native_cpu/client.h>
|
||||||
|
|
||||||
|
/* base-internal includes */
|
||||||
|
#include <base/internal/local_capability.h>
|
||||||
|
#include <base/internal/region_map_mmap.h>
|
||||||
|
#include <base/internal/stack_area.h>
|
||||||
|
|
||||||
|
namespace Genode { struct Local_pd_session; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Genode::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 };
|
||||||
|
|
||||||
|
Local_pd_session(Pd_session_capability pd) : Pd_session_client(pd) { }
|
||||||
|
|
||||||
|
Capability<Region_map> address_space()
|
||||||
|
{
|
||||||
|
return Local_capability<Region_map>::local_cap(&_address_space);
|
||||||
|
}
|
||||||
|
|
||||||
|
Capability<Region_map> stack_area()
|
||||||
|
{
|
||||||
|
return Local_capability<Region_map>::local_cap(&_stack_area);
|
||||||
|
}
|
||||||
|
|
||||||
|
Capability<Region_map> linker_area()
|
||||||
|
{
|
||||||
|
return Local_capability<Region_map>::local_cap(&_linker_area);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__LOCAL_PD_SESSION_H_ */
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* \brief Component-local implementation of a RM session
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2016-04-19
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE__BASE__INTERNAL__LOCAL_RM_SESSION_H_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__LOCAL_RM_SESSION_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <rm_session/rm_session.h>
|
||||||
|
#include <base/allocator.h>
|
||||||
|
|
||||||
|
/* base-internal includes */
|
||||||
|
#include <base/internal/region_map_mmap.h>
|
||||||
|
#include <base/internal/local_capability.h>
|
||||||
|
|
||||||
|
namespace Genode { struct Local_rm_session; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Genode::Local_rm_session : Rm_session
|
||||||
|
{
|
||||||
|
Allocator &md_alloc;
|
||||||
|
|
||||||
|
Local_rm_session(Allocator &md_alloc) : md_alloc(md_alloc) { }
|
||||||
|
|
||||||
|
Capability<Region_map> create(size_t size)
|
||||||
|
{
|
||||||
|
Region_map *rm = new (md_alloc) Region_map_mmap(true, size);
|
||||||
|
return Local_capability<Region_map>::local_cap(rm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy(Capability<Region_map> cap)
|
||||||
|
{
|
||||||
|
Region_map *rm = Local_capability<Region_map>::deref(cap);
|
||||||
|
Genode::destroy(md_alloc, rm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__LOCAL_RM_SESSION_H_ */
|
@ -15,342 +15,31 @@
|
|||||||
#ifndef _INCLUDE__BASE__INTERNAL__PLATFORM_ENV_H_
|
#ifndef _INCLUDE__BASE__INTERNAL__PLATFORM_ENV_H_
|
||||||
#define _INCLUDE__BASE__INTERNAL__PLATFORM_ENV_H_
|
#define _INCLUDE__BASE__INTERNAL__PLATFORM_ENV_H_
|
||||||
|
|
||||||
/* Linux includes */
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <util/misc_math.h>
|
|
||||||
#include <base/heap.h>
|
#include <base/heap.h>
|
||||||
#include <linux_native_cpu/client.h>
|
|
||||||
|
|
||||||
/* base-internal includes */
|
/* base-internal includes */
|
||||||
#include <base/internal/local_capability.h>
|
#include <base/internal/expanding_cpu_session_client.h>
|
||||||
#include <base/internal/platform_env_common.h>
|
#include <base/internal/expanding_region_map_client.h>
|
||||||
|
#include <base/internal/expanding_ram_session_client.h>
|
||||||
|
#include <base/internal/expanding_parent_client.h>
|
||||||
|
#include <base/internal/region_map_mmap.h>
|
||||||
|
#include <base/internal/local_rm_session.h>
|
||||||
|
#include <base/internal/local_pd_session.h>
|
||||||
|
#include <base/internal/local_parent.h>
|
||||||
|
|
||||||
namespace Genode {
|
namespace Genode {
|
||||||
struct Expanding_cpu_session_client;
|
|
||||||
class Platform_env_base;
|
class Platform_env_base;
|
||||||
class Platform_env;
|
class Platform_env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Genode::Expanding_cpu_session_client
|
|
||||||
:
|
|
||||||
Upgradeable_client<Genode::Cpu_session_client>
|
|
||||||
{
|
|
||||||
Expanding_cpu_session_client(Genode::Capability<Cpu_session> cap)
|
|
||||||
: Upgradeable_client<Genode::Cpu_session_client>(cap) { }
|
|
||||||
|
|
||||||
Thread_capability create_thread(Pd_session_capability pd, size_t weight,
|
|
||||||
Name const &name, Affinity::Location affinity,
|
|
||||||
addr_t utcb)
|
|
||||||
{
|
|
||||||
return retry<Cpu_session::Out_of_metadata>(
|
|
||||||
[&] () { return Cpu_session_client::create_thread(pd, weight, name, affinity, utcb); },
|
|
||||||
[&] () { upgrade_ram(8*1024); });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common base class of the 'Platform_env' implementations for core and
|
* Common base class of the 'Platform_env' implementations for core and
|
||||||
* non-core processes.
|
* non-core processes.
|
||||||
*/
|
*/
|
||||||
class Genode::Platform_env_base : public Env_deprecated
|
class Genode::Platform_env_base : public Env_deprecated
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
|
|
||||||
/**************************
|
|
||||||
** Local region manager **
|
|
||||||
**************************/
|
|
||||||
|
|
||||||
class Region
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
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 ®ion)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
Region_map *rm = new (md_alloc) Region_map_mmap(true, size);
|
|
||||||
return Local_capability<Region_map>::local_cap(rm);
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy(Capability<Region_map> cap)
|
|
||||||
{
|
|
||||||
Region_map *rm = Local_capability<Region_map>::deref(cap);
|
|
||||||
Genode::destroy(md_alloc, rm);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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 };
|
|
||||||
|
|
||||||
Local_pd_session(Pd_session_capability pd) : Pd_session_client(pd) { }
|
|
||||||
|
|
||||||
Capability<Region_map> address_space()
|
|
||||||
{
|
|
||||||
return Local_capability<Region_map>::local_cap(&_address_space);
|
|
||||||
}
|
|
||||||
|
|
||||||
Capability<Region_map> stack_area()
|
|
||||||
{
|
|
||||||
return Local_capability<Region_map>::local_cap(&_stack_area);
|
|
||||||
}
|
|
||||||
|
|
||||||
Capability<Region_map> linker_area()
|
|
||||||
{
|
|
||||||
return Local_capability<Region_map>::local_cap(&_linker_area);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Ram_session_capability _ram_session_cap;
|
Ram_session_capability _ram_session_cap;
|
||||||
@ -409,51 +98,11 @@ class Genode::Platform_env_base : public Env_deprecated
|
|||||||
/**
|
/**
|
||||||
* 'Platform_env' used by all processes except for core
|
* 'Platform_env' used by all processes except for core
|
||||||
*/
|
*/
|
||||||
class Genode::Platform_env : public Platform_env_base, public Emergency_ram_reserve
|
class Genode::Platform_env : public Platform_env_base,
|
||||||
|
public Expanding_parent_client::Emergency_ram_reserve
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
|
||||||
* Local interceptor of parent requests
|
|
||||||
*
|
|
||||||
* On Linux, we need to intercept calls to the parent interface to
|
|
||||||
* implement the RM service locally. This particular service is
|
|
||||||
* used for creating managed dataspaces, which allow the
|
|
||||||
* reservation of parts of the local address space from being
|
|
||||||
* automatically managed by the 'env()->rm_session()'.
|
|
||||||
*
|
|
||||||
* All requests that do not refer to the RM service are passed
|
|
||||||
* through the real parent interface.
|
|
||||||
*/
|
|
||||||
class Local_parent : public Expanding_parent_client
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
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
|
* Return instance of parent interface
|
||||||
*/
|
*/
|
||||||
@ -469,11 +118,6 @@ class Genode::Platform_env : public Platform_env_base, public Emergency_ram_rese
|
|||||||
constexpr static size_t _emergency_ram_size() { return 8*1024; }
|
constexpr static size_t _emergency_ram_size() { return 8*1024; }
|
||||||
Ram_dataspace_capability _emergency_ram_ds;
|
Ram_dataspace_capability _emergency_ram_ds;
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
|
||||||
** Linux-specific helper functions **
|
|
||||||
*************************************/
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
150
repos/base-linux/src/include/base/internal/region_map_mmap.h
Normal file
150
repos/base-linux/src/include/base/internal/region_map_mmap.h
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
* \brief Component-local region-map implementation based on mmap
|
||||||
|
* \author Norman Feske
|
||||||
|
* \author Christian Helmuth
|
||||||
|
* \date 2006-07-28
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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__BASE__INTERNAL__REGION_MAP_MMAP_H_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__REGION_MAP_MMAP_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/env.h>
|
||||||
|
#include <region_map/region_map.h>
|
||||||
|
#include <dataspace/client.h>
|
||||||
|
|
||||||
|
/* base-internal includes */
|
||||||
|
#include <base/internal/local_capability.h>
|
||||||
|
#include <base/internal/region_registry.h>
|
||||||
|
|
||||||
|
namespace Genode { class Region_map_mmap; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On Linux, we use a locally implemented region map that attaches dataspaces
|
||||||
|
* via mmap to the local address space.
|
||||||
|
*/
|
||||||
|
class Genode::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,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map dataspace into local address space
|
||||||
|
*/
|
||||||
|
void *_map_local(Dataspace_capability ds,
|
||||||
|
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);
|
||||||
|
|
||||||
|
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); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__REGION_MAP_MMAP_H_ */
|
130
repos/base-linux/src/include/base/internal/region_registry.h
Normal file
130
repos/base-linux/src/include/base/internal/region_registry.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* \brief Registry of virtual-memory regions
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2016-04-29
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE__BASE__INTERNAL__REGION_REGISTRY_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__REGION_REGISTRY_
|
||||||
|
|
||||||
|
#include <dataspace/capability.h>
|
||||||
|
#include <base/printf.h>
|
||||||
|
|
||||||
|
namespace Genode {
|
||||||
|
class Region;
|
||||||
|
class Region_registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Genode::Region
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Genode::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 ®ion)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__REGION_REGISTRY_ */
|
@ -20,6 +20,7 @@
|
|||||||
/* base-internal includes */
|
/* base-internal includes */
|
||||||
#include <base/internal/platform_env.h>
|
#include <base/internal/platform_env.h>
|
||||||
#include <base/internal/native_thread.h>
|
#include <base/internal/native_thread.h>
|
||||||
|
#include <base/internal/globals.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
@ -28,8 +29,7 @@ using namespace Genode;
|
|||||||
** Support for Platform_env_base::Rm_session_mmap **
|
** Support for Platform_env_base::Rm_session_mmap **
|
||||||
****************************************************/
|
****************************************************/
|
||||||
|
|
||||||
Genode::size_t
|
size_t Region_map_mmap::_dataspace_size(Dataspace_capability ds)
|
||||||
Platform_env_base::Region_map_mmap::_dataspace_size(Dataspace_capability ds)
|
|
||||||
{
|
{
|
||||||
if (ds.valid())
|
if (ds.valid())
|
||||||
return Dataspace_client(ds).size();
|
return Dataspace_client(ds).size();
|
||||||
@ -38,31 +38,26 @@ Platform_env_base::Region_map_mmap::_dataspace_size(Dataspace_capability ds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Platform_env_base::Region_map_mmap::_dataspace_fd(Dataspace_capability ds)
|
int Region_map_mmap::_dataspace_fd(Dataspace_capability ds)
|
||||||
{
|
{
|
||||||
return Linux_dataspace_client(ds).fd().dst().socket;
|
return Linux_dataspace_client(ds).fd().dst().socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool Region_map_mmap::_dataspace_writable(Dataspace_capability ds)
|
||||||
Platform_env_base::Region_map_mmap::_dataspace_writable(Dataspace_capability ds)
|
|
||||||
{
|
{
|
||||||
return Dataspace_client(ds).writable();
|
return Dataspace_client(ds).writable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/********************************
|
/******************
|
||||||
** Platform_env::Local_parent **
|
** Local_parent **
|
||||||
********************************/
|
******************/
|
||||||
|
|
||||||
static inline size_t get_page_size_log2() { return 12; }
|
Session_capability Local_parent::session(Service_name const &service_name,
|
||||||
|
Session_args const &args,
|
||||||
|
Affinity const &affinity)
|
||||||
Session_capability
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -75,7 +70,7 @@ Platform_env::Local_parent::session(Service_name const &service_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Platform_env::Local_parent::close(Session_capability session)
|
void Local_parent::close(Session_capability session)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Handle non-local capabilities
|
* Handle non-local capabilities
|
||||||
@ -94,9 +89,9 @@ void Platform_env::Local_parent::close(Session_capability session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Platform_env::Local_parent::Local_parent(Parent_capability parent_cap,
|
Local_parent::Local_parent(Parent_capability parent_cap,
|
||||||
Emergency_ram_reserve &reserve,
|
Emergency_ram_reserve &reserve,
|
||||||
Allocator &alloc)
|
Allocator &alloc)
|
||||||
:
|
:
|
||||||
Expanding_parent_client(parent_cap, reserve), _alloc(alloc)
|
Expanding_parent_client(parent_cap, reserve), _alloc(alloc)
|
||||||
{ }
|
{ }
|
||||||
@ -139,7 +134,7 @@ static Parent_capability obtain_parent_cap()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Platform_env::Local_parent &Platform_env::_parent()
|
Local_parent &Platform_env::_parent()
|
||||||
{
|
{
|
||||||
static Local_parent local_parent(obtain_parent_cap(), *this, _heap);
|
static Local_parent local_parent(obtain_parent_cap(), *this, _heap);
|
||||||
return local_parent;
|
return local_parent;
|
||||||
|
@ -32,6 +32,12 @@
|
|||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Linux includes */
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/thread.h>
|
#include <base/thread.h>
|
||||||
#include <linux_dataspace/client.h>
|
#include <linux_dataspace/client.h>
|
||||||
@ -39,7 +45,7 @@
|
|||||||
|
|
||||||
/* base-internal includes */
|
/* base-internal includes */
|
||||||
#include <base/internal/local_capability.h>
|
#include <base/internal/local_capability.h>
|
||||||
#include <base/internal/platform_env.h>
|
#include <base/internal/region_map_mmap.h>
|
||||||
#include <base/internal/stack_area.h>
|
#include <base/internal/stack_area.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
@ -54,9 +60,9 @@ static bool is_sub_rm_session(Dataspace_capability ds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addr_t Platform_env_base::Region_map_mmap::_reserve_local(bool use_local_addr,
|
addr_t Region_map_mmap::_reserve_local(bool use_local_addr,
|
||||||
addr_t local_addr,
|
addr_t local_addr,
|
||||||
Genode::size_t size)
|
Genode::size_t size)
|
||||||
{
|
{
|
||||||
/* special handling for stack area */
|
/* special handling for stack area */
|
||||||
if (use_local_addr
|
if (use_local_addr
|
||||||
@ -101,14 +107,13 @@ addr_t Platform_env_base::Region_map_mmap::_reserve_local(bool use_loc
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *Region_map_mmap::_map_local(Dataspace_capability ds,
|
||||||
Platform_env_base::Region_map_mmap::_map_local(Dataspace_capability ds,
|
Genode::size_t size,
|
||||||
Genode::size_t size,
|
addr_t offset,
|
||||||
addr_t offset,
|
bool use_local_addr,
|
||||||
bool use_local_addr,
|
addr_t local_addr,
|
||||||
addr_t local_addr,
|
bool executable,
|
||||||
bool executable,
|
bool overmap)
|
||||||
bool overmap)
|
|
||||||
{
|
{
|
||||||
int const fd = _dataspace_fd(ds);
|
int const fd = _dataspace_fd(ds);
|
||||||
bool const writable = _dataspace_writable(ds);
|
bool const writable = _dataspace_writable(ds);
|
||||||
@ -143,7 +148,7 @@ Platform_env_base::Region_map_mmap::_map_local(Dataspace_capability ds,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Platform_env::Region_map_mmap::_add_to_rmap(Region const ®ion)
|
void Region_map_mmap::_add_to_rmap(Region const ®ion)
|
||||||
{
|
{
|
||||||
if (_rmap.add_region(region) < 0) {
|
if (_rmap.add_region(region) < 0) {
|
||||||
PERR("_add_to_rmap: could not add region to sub RM session");
|
PERR("_add_to_rmap: could not add region to sub RM session");
|
||||||
@ -152,12 +157,11 @@ void Platform_env::Region_map_mmap::_add_to_rmap(Region const ®ion)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Region_map::Local_addr
|
Region_map::Local_addr Region_map_mmap::attach(Dataspace_capability ds,
|
||||||
Platform_env::Region_map_mmap::attach(Dataspace_capability ds,
|
size_t size, off_t offset,
|
||||||
size_t size, off_t offset,
|
bool use_local_addr,
|
||||||
bool use_local_addr,
|
Region_map::Local_addr local_addr,
|
||||||
Region_map::Local_addr local_addr,
|
bool executable)
|
||||||
bool executable)
|
|
||||||
{
|
{
|
||||||
Lock::Guard lock_guard(_lock);
|
Lock::Guard lock_guard(_lock);
|
||||||
|
|
||||||
@ -299,7 +303,7 @@ Platform_env::Region_map_mmap::attach(Dataspace_capability ds,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Platform_env::Region_map_mmap::detach(Region_map::Local_addr local_addr)
|
void Region_map_mmap::detach(Region_map::Local_addr local_addr)
|
||||||
{
|
{
|
||||||
Lock::Guard lock_guard(_lock);
|
Lock::Guard lock_guard(_lock);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
/* base-internal includes */
|
/* base-internal includes */
|
||||||
#include <base/internal/stack_area.h>
|
#include <base/internal/stack_area.h>
|
||||||
#include <base/internal/platform_env_common.h>
|
#include <base/internal/globals.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
#include <pd_session/pd_session.h>
|
#include <pd_session/pd_session.h>
|
||||||
#include <util/arg_string.h>
|
#include <util/arg_string.h>
|
||||||
|
|
||||||
|
/* base-internal includes */
|
||||||
|
#include <base/internal/stack_area.h>
|
||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <platform_pd.h>
|
#include <platform_pd.h>
|
||||||
#include <signal_broker.h>
|
#include <signal_broker.h>
|
||||||
@ -30,9 +33,6 @@
|
|||||||
#include <region_map_component.h>
|
#include <region_map_component.h>
|
||||||
#include <platform_generic.h>
|
#include <platform_generic.h>
|
||||||
|
|
||||||
/* base-internal includes */
|
|
||||||
#include <base/internal/platform_env_common.h>
|
|
||||||
|
|
||||||
namespace Genode { class Pd_session_component; }
|
namespace Genode { class Pd_session_component; }
|
||||||
|
|
||||||
|
|
||||||
|
43
repos/base/src/include/base/internal/attached_stack_area.h
Normal file
43
repos/base/src/include/base/internal/attached_stack_area.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* \brief Stack area attached to the local address space
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2013-09-25
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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__BASE__INTERNAL__ATTACHED_STACK_AREA_H_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__ATTACHED_STACK_AREA_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <parent/client.h>
|
||||||
|
#include <region_map/client.h>
|
||||||
|
#include <pd_session/client.h>
|
||||||
|
|
||||||
|
/* base-internal includes */
|
||||||
|
#include <base/internal/stack_area.h>
|
||||||
|
#include <base/internal/expanding_region_map_client.h>
|
||||||
|
|
||||||
|
namespace Genode { struct Attached_stack_area; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Genode::Attached_stack_area : Expanding_region_map_client
|
||||||
|
{
|
||||||
|
Attached_stack_area(Parent &parent, Pd_session_capability pd)
|
||||||
|
:
|
||||||
|
Expanding_region_map_client(pd, Pd_session_client(pd).stack_area())
|
||||||
|
{
|
||||||
|
Region_map_client address_space(Pd_session_client(pd).address_space());
|
||||||
|
|
||||||
|
address_space.attach_at(Expanding_region_map_client::dataspace(),
|
||||||
|
stack_area_virtual_base(),
|
||||||
|
stack_area_virtual_size());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__ATTACHED_STACK_AREA_H_ */
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* \brief CPU-session client that upgrades its session quota on demand
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2006-07-28
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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__BASE__INTERNAL__EXPANDING_CPU_SESSION_CLIENT_H_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__EXPANDING_CPU_SESSION_CLIENT_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <util/retry.h>
|
||||||
|
#include <base/printf.h>
|
||||||
|
#include <cpu_session/client.h>
|
||||||
|
|
||||||
|
/* base-internal includes */
|
||||||
|
#include <base/internal/upgradeable_client.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Genode { struct Expanding_cpu_session_client; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Genode::Expanding_cpu_session_client : Upgradeable_client<Genode::Cpu_session_client>
|
||||||
|
{
|
||||||
|
Expanding_cpu_session_client(Genode::Cpu_session_capability cap)
|
||||||
|
:
|
||||||
|
/*
|
||||||
|
* We need to upcast the capability because on some platforms (i.e.,
|
||||||
|
* NOVA), 'Cpu_session_client' refers to a platform-specific session
|
||||||
|
* interface ('Nova_cpu_session').
|
||||||
|
*/
|
||||||
|
Upgradeable_client<Genode::Cpu_session_client>
|
||||||
|
(static_cap_cast<Genode::Cpu_session_client::Rpc_interface>(cap))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Thread_capability
|
||||||
|
create_thread(Pd_session_capability pd, size_t quota, Name const &name,
|
||||||
|
Affinity::Location location, addr_t utcb)
|
||||||
|
{
|
||||||
|
return retry<Cpu_session::Out_of_metadata>(
|
||||||
|
[&] () {
|
||||||
|
return Cpu_session_client::create_thread(pd, quota, name,
|
||||||
|
location, utcb); },
|
||||||
|
[&] () { upgrade_ram(8*1024); });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__EXPANDING_CPU_SESSION_CLIENT_H_ */
|
@ -1,9 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* \brief Platform environment of Genode process
|
* \brief Parent client that issues resource requests on demand
|
||||||
* \author Norman Feske
|
* \author Norman Feske
|
||||||
* \date 2013-09-25
|
* \date 2013-09-25
|
||||||
*
|
|
||||||
* Parts of 'Platform_env' shared accross all base platforms.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -13,161 +11,30 @@
|
|||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _INCLUDE__BASE__INTERNAL__PLATFORM_ENV_COMMON_H_
|
#ifndef _INCLUDE__BASE__INTERNAL__EXPANDING_PARENT_CLIENT_H_
|
||||||
#define _INCLUDE__BASE__INTERNAL__PLATFORM_ENV_COMMON_H_
|
#define _INCLUDE__BASE__INTERNAL__EXPANDING_PARENT_CLIENT_H_
|
||||||
|
|
||||||
#include <base/env.h>
|
/* Genode includes */
|
||||||
|
#include <base/signal.h>
|
||||||
#include <util/arg_string.h>
|
#include <util/arg_string.h>
|
||||||
#include <util/retry.h>
|
#include <util/retry.h>
|
||||||
#include <parent/client.h>
|
#include <parent/client.h>
|
||||||
#include <ram_session/client.h>
|
|
||||||
#include <region_map/client.h>
|
|
||||||
#include <cpu_session/client.h>
|
|
||||||
#include <pd_session/client.h>
|
|
||||||
|
|
||||||
|
/* base-internal includes */
|
||||||
|
#include <base/internal/upgradeable_client.h>
|
||||||
|
|
||||||
#include <base/internal/stack_area.h>
|
namespace Genode { class Expanding_parent_client; }
|
||||||
|
|
||||||
namespace Genode {
|
|
||||||
|
|
||||||
class Expanding_region_map_client;
|
|
||||||
class Expanding_ram_session_client;
|
|
||||||
class Expanding_cpu_session_client;
|
|
||||||
class Expanding_parent_client;
|
|
||||||
|
|
||||||
struct Attached_stack_area;
|
|
||||||
|
|
||||||
Parent_capability parent_cap();
|
|
||||||
|
|
||||||
extern Region_map *env_stack_area_region_map;
|
|
||||||
extern Ram_session *env_stack_area_ram_session;
|
|
||||||
|
|
||||||
void init_signal_thread();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Client object for a session that may get its session quota upgraded
|
|
||||||
*/
|
|
||||||
template <typename CLIENT>
|
|
||||||
struct Upgradeable_client : CLIENT
|
|
||||||
{
|
|
||||||
typedef Genode::Capability<typename CLIENT::Rpc_interface> Capability;
|
|
||||||
|
|
||||||
Capability _cap;
|
|
||||||
|
|
||||||
Upgradeable_client(Capability cap) : CLIENT(cap), _cap(cap) { }
|
|
||||||
|
|
||||||
void upgrade_ram(Genode::size_t quota)
|
|
||||||
{
|
|
||||||
PINF("upgrading quota donation for Env::%s (%zu bytes)",
|
|
||||||
CLIENT::Rpc_interface::service_name(), quota);
|
|
||||||
|
|
||||||
char buf[128];
|
|
||||||
Genode::snprintf(buf, sizeof(buf), "ram_quota=%zu", quota);
|
|
||||||
|
|
||||||
Genode::env()->parent()->upgrade(_cap, buf);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct Genode::Expanding_region_map_client : Region_map_client
|
|
||||||
{
|
|
||||||
Upgradeable_client<Genode::Pd_session_client> _pd_client;
|
|
||||||
|
|
||||||
Expanding_region_map_client(Pd_session_capability pd, Capability<Region_map> rm)
|
|
||||||
: Region_map_client(rm), _pd_client(pd) { }
|
|
||||||
|
|
||||||
Local_addr attach(Dataspace_capability ds, size_t size, off_t offset,
|
|
||||||
bool use_local_addr, Local_addr local_addr,
|
|
||||||
bool executable) override
|
|
||||||
{
|
|
||||||
return retry<Region_map::Out_of_metadata>(
|
|
||||||
[&] () {
|
|
||||||
return Region_map_client::attach(ds, size, offset,
|
|
||||||
use_local_addr,
|
|
||||||
local_addr,
|
|
||||||
executable); },
|
|
||||||
[&] () { _pd_client.upgrade_ram(8*1024); });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_session_client>
|
|
||||||
{
|
|
||||||
Expanding_ram_session_client(Ram_session_capability cap)
|
|
||||||
: Upgradeable_client<Genode::Ram_session_client>(cap) { }
|
|
||||||
|
|
||||||
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached = UNCACHED) override
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If the RAM session runs out of quota, issue a resource request
|
|
||||||
* to the parent and retry.
|
|
||||||
*/
|
|
||||||
enum { NUM_ATTEMPTS = 2 };
|
|
||||||
return retry<Ram_session::Quota_exceeded>(
|
|
||||||
[&] () {
|
|
||||||
/*
|
|
||||||
* If the RAM session runs out of meta data, upgrade the
|
|
||||||
* session quota and retry.
|
|
||||||
*/
|
|
||||||
return retry<Ram_session::Out_of_metadata>(
|
|
||||||
[&] () { return Ram_session_client::alloc(size, cached); },
|
|
||||||
[&] () { upgrade_ram(8*1024); });
|
|
||||||
},
|
|
||||||
[&] () {
|
|
||||||
char buf[128];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The RAM service withdraws the meta data for the allocator
|
|
||||||
* from the RAM quota. In the worst case, a new slab block
|
|
||||||
* may be needed. To cover the worst case, we need to take
|
|
||||||
* this possible overhead into account when requesting
|
|
||||||
* additional RAM quota from the parent.
|
|
||||||
*
|
|
||||||
* Because the worst case almost never happens, we request
|
|
||||||
* a bit too much quota for the most time.
|
|
||||||
*/
|
|
||||||
enum { ALLOC_OVERHEAD = 4096U };
|
|
||||||
Genode::snprintf(buf, sizeof(buf), "ram_quota=%zu",
|
|
||||||
size + ALLOC_OVERHEAD);
|
|
||||||
env()->parent()->resource_request(buf);
|
|
||||||
},
|
|
||||||
NUM_ATTEMPTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
int transfer_quota(Ram_session_capability ram_session, size_t amount) override
|
|
||||||
{
|
|
||||||
enum { NUM_ATTEMPTS = 2 };
|
|
||||||
int ret = -1;
|
|
||||||
for (unsigned i = 0; i < NUM_ATTEMPTS; i++) {
|
|
||||||
|
|
||||||
ret = Ram_session_client::transfer_quota(ram_session, amount);
|
|
||||||
if (ret != -3) break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The transfer failed because we don't have enough quota. Request
|
|
||||||
* the needed amount from the parent.
|
|
||||||
*
|
|
||||||
* XXX Let transfer_quota throw 'Ram_session::Quota_exceeded'
|
|
||||||
*/
|
|
||||||
char buf[128];
|
|
||||||
Genode::snprintf(buf, sizeof(buf), "ram_quota=%zu", amount);
|
|
||||||
env()->parent()->resource_request(buf);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct Emergency_ram_reserve
|
|
||||||
{
|
|
||||||
virtual void release() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Genode::Expanding_parent_client : public Parent_client
|
class Genode::Expanding_parent_client : public Parent_client
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct Emergency_ram_reserve
|
||||||
|
{
|
||||||
|
virtual void release() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -328,19 +195,4 @@ class Genode::Expanding_parent_client : public Parent_client
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__EXPANDING_PARENT_CLIENT_H_ */
|
||||||
struct Genode::Attached_stack_area : Genode::Expanding_region_map_client
|
|
||||||
{
|
|
||||||
Attached_stack_area(Parent &parent, Pd_session_capability pd)
|
|
||||||
:
|
|
||||||
Expanding_region_map_client(pd, Pd_session_client(pd).stack_area())
|
|
||||||
{
|
|
||||||
Region_map_client address_space(Pd_session_client(pd).address_space());
|
|
||||||
|
|
||||||
address_space.attach_at(Expanding_region_map_client::dataspace(),
|
|
||||||
stack_area_virtual_base(),
|
|
||||||
stack_area_virtual_size());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _INCLUDE__BASE__INTERNAL__PLATFORM_ENV_COMMON_H_ */
|
|
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* \brief RAM-session client that upgrades its session quota on demand
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2013-09-25
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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__BASE__INTERNAL__EXPANDING_RAM_SESSION_CLIENT_H_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__EXPANDING_RAM_SESSION_CLIENT_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <util/retry.h>
|
||||||
|
#include <ram_session/client.h>
|
||||||
|
|
||||||
|
/* base-internal includes */
|
||||||
|
#include <base/internal/upgradeable_client.h>
|
||||||
|
|
||||||
|
namespace Genode { class Expanding_ram_session_client; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_session_client>
|
||||||
|
{
|
||||||
|
Expanding_ram_session_client(Ram_session_capability cap)
|
||||||
|
: Upgradeable_client<Genode::Ram_session_client>(cap) { }
|
||||||
|
|
||||||
|
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached = UNCACHED) override
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If the RAM session runs out of quota, issue a resource request
|
||||||
|
* to the parent and retry.
|
||||||
|
*/
|
||||||
|
enum { NUM_ATTEMPTS = 2 };
|
||||||
|
return retry<Ram_session::Quota_exceeded>(
|
||||||
|
[&] () {
|
||||||
|
/*
|
||||||
|
* If the RAM session runs out of meta data, upgrade the
|
||||||
|
* session quota and retry.
|
||||||
|
*/
|
||||||
|
return retry<Ram_session::Out_of_metadata>(
|
||||||
|
[&] () { return Ram_session_client::alloc(size, cached); },
|
||||||
|
[&] () { upgrade_ram(8*1024); });
|
||||||
|
},
|
||||||
|
[&] () {
|
||||||
|
char buf[128];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The RAM service withdraws the meta data for the allocator
|
||||||
|
* from the RAM quota. In the worst case, a new slab block
|
||||||
|
* may be needed. To cover the worst case, we need to take
|
||||||
|
* this possible overhead into account when requesting
|
||||||
|
* additional RAM quota from the parent.
|
||||||
|
*
|
||||||
|
* Because the worst case almost never happens, we request
|
||||||
|
* a bit too much quota for the most time.
|
||||||
|
*/
|
||||||
|
enum { ALLOC_OVERHEAD = 4096U };
|
||||||
|
Genode::snprintf(buf, sizeof(buf), "ram_quota=%zu",
|
||||||
|
size + ALLOC_OVERHEAD);
|
||||||
|
env()->parent()->resource_request(buf);
|
||||||
|
},
|
||||||
|
NUM_ATTEMPTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int transfer_quota(Ram_session_capability ram_session, size_t amount) override
|
||||||
|
{
|
||||||
|
enum { NUM_ATTEMPTS = 2 };
|
||||||
|
int ret = -1;
|
||||||
|
for (unsigned i = 0; i < NUM_ATTEMPTS; i++) {
|
||||||
|
|
||||||
|
ret = Ram_session_client::transfer_quota(ram_session, amount);
|
||||||
|
if (ret != -3) break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The transfer failed because we don't have enough quota. Request
|
||||||
|
* the needed amount from the parent.
|
||||||
|
*
|
||||||
|
* XXX Let transfer_quota throw 'Ram_session::Quota_exceeded'
|
||||||
|
*/
|
||||||
|
char buf[128];
|
||||||
|
Genode::snprintf(buf, sizeof(buf), "ram_quota=%zu", amount);
|
||||||
|
env()->parent()->resource_request(buf);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__EXPANDING_RAM_SESSION_CLIENT_H_ */
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* \brief Region-map client that upgrades PD-session quota on demand
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2013-09-25
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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__BASE__INTERNAL__EXPANDING_REGION_MAP_CLIENT_H_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__EXPANDING_REGION_MAP_CLIENT_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <util/retry.h>
|
||||||
|
#include <region_map/client.h>
|
||||||
|
#include <pd_session/client.h>
|
||||||
|
|
||||||
|
/* base-internal includes */
|
||||||
|
#include <base/internal/upgradeable_client.h>
|
||||||
|
|
||||||
|
namespace Genode { class Expanding_region_map_client; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Genode::Expanding_region_map_client : Region_map_client
|
||||||
|
{
|
||||||
|
Upgradeable_client<Genode::Pd_session_client> _pd_client;
|
||||||
|
|
||||||
|
Expanding_region_map_client(Pd_session_capability pd, Capability<Region_map> rm)
|
||||||
|
: Region_map_client(rm), _pd_client(pd) { }
|
||||||
|
|
||||||
|
Local_addr attach(Dataspace_capability ds, size_t size, off_t offset,
|
||||||
|
bool use_local_addr, Local_addr local_addr,
|
||||||
|
bool executable) override
|
||||||
|
{
|
||||||
|
return retry<Region_map::Out_of_metadata>(
|
||||||
|
[&] () {
|
||||||
|
return Region_map_client::attach(ds, size, offset,
|
||||||
|
use_local_addr,
|
||||||
|
local_addr,
|
||||||
|
executable); },
|
||||||
|
[&] () { _pd_client.upgrade_ram(8*1024); });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__EXPANDING_REGION_MAP_CLIENT_H__ */
|
31
repos/base/src/include/base/internal/globals.h
Normal file
31
repos/base/src/include/base/internal/globals.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* \brief Interfaces to library-global objects
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2016-04-29
|
||||||
|
*
|
||||||
|
* \deprecated This header should be removed once we have completed the
|
||||||
|
* transition to the modernized API.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE__BASE__INTERNAL__GLOBALS_H_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__GLOBALS_H_
|
||||||
|
|
||||||
|
namespace Genode {
|
||||||
|
|
||||||
|
class Region_map;
|
||||||
|
class Ram_session;
|
||||||
|
|
||||||
|
extern Region_map *env_stack_area_region_map;
|
||||||
|
extern Ram_session *env_stack_area_ram_session;
|
||||||
|
|
||||||
|
void init_signal_thread();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__GLOBALS_H_ */
|
21
repos/base/src/include/base/internal/parent_cap.h
Normal file
21
repos/base/src/include/base/internal/parent_cap.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* \brief Interface to obtain the parent capability for the component
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2013-09-25
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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__BASE__INTERNAL__PARENT_CAP_H_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_
|
||||||
|
|
||||||
|
#include <parent/capability.h>
|
||||||
|
|
||||||
|
namespace Genode { Parent_capability parent_cap(); }
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ */
|
@ -26,42 +26,20 @@
|
|||||||
#include <base/heap.h>
|
#include <base/heap.h>
|
||||||
|
|
||||||
/* base-internal includes */
|
/* base-internal includes */
|
||||||
#include <base/internal/platform_env_common.h>
|
#include <base/internal/globals.h>
|
||||||
|
#include <base/internal/parent_cap.h>
|
||||||
|
#include <base/internal/attached_stack_area.h>
|
||||||
|
#include <base/internal/expanding_cpu_session_client.h>
|
||||||
|
#include <base/internal/expanding_region_map_client.h>
|
||||||
|
#include <base/internal/expanding_ram_session_client.h>
|
||||||
|
#include <base/internal/expanding_parent_client.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Genode {
|
namespace Genode { class Platform_env; }
|
||||||
struct Expanding_cpu_session_client;
|
|
||||||
class Platform_env;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct Genode::Expanding_cpu_session_client : Upgradeable_client<Genode::Cpu_session_client>
|
class Genode::Platform_env : public Env_deprecated,
|
||||||
{
|
public Expanding_parent_client::Emergency_ram_reserve
|
||||||
Expanding_cpu_session_client(Genode::Cpu_session_capability cap)
|
|
||||||
:
|
|
||||||
/*
|
|
||||||
* We need to upcast the capability because on some platforms (i.e.,
|
|
||||||
* NOVA), 'Cpu_session_client' refers to a platform-specific session
|
|
||||||
* interface ('Nova_cpu_session').
|
|
||||||
*/
|
|
||||||
Upgradeable_client<Genode::Cpu_session_client>
|
|
||||||
(static_cap_cast<Genode::Cpu_session_client::Rpc_interface>(cap))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Thread_capability
|
|
||||||
create_thread(Pd_session_capability pd, size_t quota, Name const &name,
|
|
||||||
Affinity::Location affinity, addr_t utcb)
|
|
||||||
{
|
|
||||||
return retry<Cpu_session::Out_of_metadata>(
|
|
||||||
[&] () {
|
|
||||||
return Cpu_session_client::create_thread(pd, quota, name, affinity, utcb); },
|
|
||||||
[&] () { upgrade_ram(8*1024); });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Genode::Platform_env : public Genode::Env_deprecated,
|
|
||||||
public Emergency_ram_reserve
|
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
46
repos/base/src/include/base/internal/upgradeable_client.h
Normal file
46
repos/base/src/include/base/internal/upgradeable_client.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* \brief Utility for using a dynamically upgradeable session
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2013-09-25
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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__BASE__INTERNAL__UPGRADEABLE_CLIENT_H_
|
||||||
|
#define _INCLUDE__BASE__INTERNAL__UPGRADEABLE_CLIENT_H_
|
||||||
|
|
||||||
|
#include <base/env.h>
|
||||||
|
|
||||||
|
namespace Genode { template <typename> struct Upgradeable_client; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client object for a session that may get its session quota upgraded
|
||||||
|
*/
|
||||||
|
template <typename CLIENT>
|
||||||
|
struct Genode::Upgradeable_client : CLIENT
|
||||||
|
{
|
||||||
|
typedef Genode::Capability<typename CLIENT::Rpc_interface> Capability;
|
||||||
|
|
||||||
|
Capability _cap;
|
||||||
|
|
||||||
|
Upgradeable_client(Capability cap) : CLIENT(cap), _cap(cap) { }
|
||||||
|
|
||||||
|
void upgrade_ram(size_t quota)
|
||||||
|
{
|
||||||
|
PINF("upgrading quota donation for Env::%s (%zu bytes)",
|
||||||
|
CLIENT::Rpc_interface::service_name(), quota);
|
||||||
|
|
||||||
|
char buf[128];
|
||||||
|
snprintf(buf, sizeof(buf), "ram_quota=%zu", quota);
|
||||||
|
|
||||||
|
env()->parent()->upgrade(_cap, buf);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__BASE__INTERNAL__UPGRADEABLE_CLIENT_H_ */
|
@ -11,9 +11,12 @@
|
|||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <region_map/region_map.h>
|
||||||
|
#include <ram_session/ram_session.h>
|
||||||
|
|
||||||
/* base-internal includes */
|
/* base-internal includes */
|
||||||
#include <base/internal/platform_env_common.h>
|
#include <base/internal/globals.h>
|
||||||
#include <base/internal/stack_area.h>
|
|
||||||
|
|
||||||
namespace Genode {
|
namespace Genode {
|
||||||
Region_map *env_stack_area_region_map;
|
Region_map *env_stack_area_region_map;
|
||||||
|
@ -25,7 +25,7 @@ addr_t init_main_thread_result;
|
|||||||
|
|
||||||
extern void init_exception_handling();
|
extern void init_exception_handling();
|
||||||
|
|
||||||
namespace Genode { extern Region_map * const env_stack_area_region_map; }
|
namespace Genode { extern Region_map * env_stack_area_region_map; }
|
||||||
|
|
||||||
void prepare_init_main_thread();
|
void prepare_init_main_thread();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user