base: introduce Local_rm for local Region_map

The new 'Local_rm' type offers a narrow interface for the interaction
with the component-local address space, managing the lifetime of
attachments by using the 'Allocation' API.

Fixes #5516
This commit is contained in:
Norman Feske 2025-04-07 00:13:47 +02:00
parent 8c4bd7d9da
commit 1ef80e86e2
214 changed files with 1075 additions and 952 deletions

View File

@ -4,7 +4,7 @@ GEN_SRC_DIR := $(realpath $(GEN_CORE_DIR)/..)
SRC_CC += stack_area.cc \
core_log.cc \
core_log_out.cc \
core_region_map.cc \
core_local_rm.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
cpu_thread_component.cc \
@ -62,7 +62,7 @@ vpath capability_space.cc $(GEN_CORE_DIR)
vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR)
vpath ram_dataspace_factory.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)
vpath core_region_map.cc $(GEN_CORE_DIR)
vpath core_local_rm.cc $(GEN_CORE_DIR)
vpath pd_session_support.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath region_map_component.cc $(GEN_CORE_DIR)

View File

@ -62,7 +62,7 @@ class Core::Platform_thread : Interface
* Constructor
*/
Platform_thread(Platform_pd &pd, Rpc_entrypoint &, Ram_allocator &,
Region_map &, size_t, const char *name, unsigned,
Local_rm &, size_t, const char *name, unsigned,
Affinity::Location, addr_t)
: _name(name), _pd(pd) { }

View File

@ -6,7 +6,7 @@ SRC_CC += stack_area.cc \
stack_area_addr.cc \
core_log.cc \
core_log_out.cc \
core_region_map.cc \
core_local_rm.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
cpu_session_support.cc \
@ -70,7 +70,7 @@ vpath ram_dataspace_factory.cc $(GEN_CORE_DIR)
vpath signal_transmitter_proxy.cc $(GEN_CORE_DIR)
vpath signal_receiver.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)
vpath core_region_map.cc $(GEN_CORE_DIR)
vpath core_local_rm.cc $(GEN_CORE_DIR)
vpath platform_rom_modules.cc $(GEN_CORE_DIR)
vpath heartbeat.cc $(GEN_CORE_DIR)
vpath vm_session_common.cc $(GEN_CORE_DIR)

View File

@ -75,7 +75,7 @@ class Core::Platform_thread : Interface
/**
* Constructor for non-core threads
*/
Platform_thread(Platform_pd &, Rpc_entrypoint &, Ram_allocator &, Region_map &,
Platform_thread(Platform_pd &, Rpc_entrypoint &, Ram_allocator &, Local_rm &,
size_t, const char *name, unsigned priority, Affinity::Location, addr_t);
/**

View File

@ -106,7 +106,7 @@ class Core::Vm_session_component
using Cap_quota_guard::upgrade;
Vm_session_component(Rpc_entrypoint &, Resources, Label const &,
Diag, Ram_allocator &ram, Region_map &, unsigned,
Diag, Ram_allocator &ram, Local_rm &, unsigned,
Trace::Source_registry &);
~Vm_session_component();

View File

@ -278,7 +278,7 @@ void Platform_thread::_finalize_construction()
Platform_thread::Platform_thread(Platform_pd &pd, Rpc_entrypoint &, Ram_allocator &,
Region_map &, size_t, const char *name, unsigned prio,
Local_rm &, size_t, const char *name, unsigned prio,
Affinity::Location location, addr_t)
:
_name(name),

View File

@ -24,10 +24,10 @@ void Core::platform_add_local_services(Rpc_entrypoint &ep,
Registry<Service> &services,
Trace::Source_registry &trace_sources,
Ram_allocator &core_ram,
Region_map &core_rm,
Local_rm &local_rm,
Range_allocator &io_port_ranges)
{
static Vm_root vm_root(ep, heap, core_ram, core_rm, trace_sources);
static Vm_root vm_root(ep, heap, core_ram, local_rm, trace_sources);
static Core_service<Vm_session_component> vm(services, vm_root);

View File

@ -92,7 +92,7 @@ Vm_session_component::Vm_session_component(Rpc_entrypoint &ep,
Label const &,
Diag,
Ram_allocator &ram,
Region_map &local_rm,
Local_rm &local_rm,
unsigned,
Trace::Source_registry &)
:

View File

@ -17,7 +17,7 @@ SRC_CC += cpu_session_support.cc
SRC_CC += cpu_thread_component.cc
SRC_CC += core_log.cc
SRC_CC += core_log_out.cc
SRC_CC += core_region_map.cc
SRC_CC += core_local_rm.cc
SRC_CC += core_mem_alloc.cc
SRC_CC += core_rpc_cap_alloc.cc
SRC_CC += dataspace_component.cc

View File

@ -16,22 +16,23 @@
/* core includes */
#include <platform.h>
#include <core_region_map.h>
#include <core_local_rm.h>
#include <map_local.h>
#include <util.h>
#include <dataspace_component.h>
using namespace Core;
Region_map::Attach_result
Core_region_map::attach(Dataspace_capability ds_cap, Attr const &attr)
Core_local_rm::Result
Core_local_rm::attach(Dataspace_capability ds_cap, Attach_attr const &attr)
{
using Virt_allocation = Range_allocator::Allocation;
return _ep.apply(ds_cap, [&] (Dataspace_component *ds_ptr) -> Attach_result {
return _ep.apply(ds_cap, [&] (Dataspace_component *ds_ptr) -> Result {
if (!ds_ptr)
return Attach_error::INVALID_DATASPACE;
return Error::INVALID_DATASPACE;
Dataspace_component &ds = *ds_ptr;
@ -40,7 +41,7 @@ Core_region_map::attach(Dataspace_capability ds_cap, Attr const &attr)
/* attach attributes 'use_at' and 'offset' not supported within core */
if (attr.use_at || attr.offset)
return Attach_error::REGION_CONFLICT;
return Error::REGION_CONFLICT;
unsigned const align = get_page_size_log2();
@ -51,7 +52,7 @@ Core_region_map::attach(Dataspace_capability ds_cap, Attr const &attr)
if (virt.failed()) {
error("could not allocate virtual address range in core of size ",
page_rounded_size);
return Attach_error::REGION_CONFLICT;
return Error::REGION_CONFLICT;
}
using namespace Hw;
@ -68,27 +69,27 @@ Core_region_map::attach(Dataspace_capability ds_cap, Attr const &attr)
.cacheable = ds.cacheability()
};
return virt.convert<Attach_result>(
return virt.convert<Result>(
[&] (Virt_allocation &a) -> Attach_result {
[&] (Virt_allocation &a) -> Result {
if (!map_local(ds.phys_addr(), (addr_t)a.ptr, num_pages, flags))
return Attach_error::REGION_CONFLICT;
return Error::REGION_CONFLICT;
a.deallocate = false;
return Range { .start = addr_t(a.ptr),
.num_bytes = page_rounded_size };
return { *this, { .ptr = a.ptr,
.num_bytes = page_rounded_size } };
},
[&] (Alloc_error) {
return Attach_error::REGION_CONFLICT; });
return Error::REGION_CONFLICT; });
});
}
void Core_region_map::detach(addr_t core_local_addr)
void Core_local_rm::_free(Attachment &a)
{
size_t size = platform_specific().region_alloc_size_at((void *)core_local_addr);
size_t size = platform_specific().region_alloc_size_at(a.ptr);
unmap_local(core_local_addr, size >> get_page_size_log2());
unmap_local(addr_t(a.ptr), size >> get_page_size_log2());
platform().region_alloc().free((void *)core_local_addr);
platform().region_alloc().free(a.ptr);
}

View File

@ -217,9 +217,9 @@ class Core::Guest_memory
}
Guest_memory(Accounted_ram_allocator &ram, Region_map &region_map)
Guest_memory(Accounted_ram_allocator &ram, Local_rm &local_rm)
:
_sliced_heap(ram, region_map)
_sliced_heap(ram, local_rm)
{
/* configure managed VM area */
if (_map.add_range(0UL, ~0UL).failed())

View File

@ -38,7 +38,7 @@ class Core::Phys_allocated : Genode::Noncopyable
Rpc_entrypoint &_ep;
Ram_allocator &_ram;
Region_map &_rm;
Local_rm &_rm;
Attached_ram_dataspace _ds { _ram, _rm, sizeof(T) };
public:
@ -47,7 +47,7 @@ class Core::Phys_allocated : Genode::Noncopyable
Phys_allocated(Rpc_entrypoint &ep,
Ram_allocator &ram,
Region_map &rm)
Local_rm &rm)
:
_ep(ep), _ram(ram), _rm(rm)
{
@ -56,7 +56,7 @@ class Core::Phys_allocated : Genode::Noncopyable
Phys_allocated(Rpc_entrypoint &ep,
Ram_allocator &ram,
Region_map &rm,
Local_rm &rm,
auto const &construct_fn)
:
_ep(ep), _ram(ram), _rm(rm)

View File

@ -32,7 +32,7 @@
/* base-hw core includes */
#include <platform_generic.h>
#include <core_region_map.h>
#include <core_local_rm.h>
#include <core_mem_alloc.h>
#include <assertion.h>
#include <board.h>
@ -121,7 +121,7 @@ class Core::Platform : public Platform_generic
/**
* Determine size of a core local mapping required for a
* Core_region_map::detach().
* Core_local_rm::_free().
*/
size_t region_alloc_size_at(void * addr)
{

View File

@ -29,16 +29,18 @@
using namespace Core;
addr_t Platform_thread::Utcb::_attach(Region_map &core_rm)
addr_t Platform_thread::Utcb::_attach(Local_rm &local_rm)
{
addr_t start = 0;
ds.with_result(
[&] (Ram::Allocation const &allocation) {
Region_map::Attr attr { };
attr.writeable = true;
core_rm.attach(allocation.cap, attr).with_result(
[&] (Region_map::Range range) { start = range.start; },
[&] (Region_map::Attach_error) {
local_rm.attach(allocation.cap, attr).with_result(
[&] (Local_rm::Attachment &a) {
a.deallocate = false;
start = addr_t(a.ptr); },
[&] (Local_rm::Error) {
error("failed to attach UTCB of new thread within core"); });
},
[&] (Ram::Error) { });
@ -108,7 +110,7 @@ Platform_thread::Platform_thread(Label const &label, Native_utcb &utcb)
Platform_thread::Platform_thread(Platform_pd &pd,
Rpc_entrypoint &ep,
Ram_allocator &ram,
Region_map &core_rm,
Local_rm &local_rm,
size_t const quota,
Label const &label,
unsigned const virt_prio,
@ -118,7 +120,7 @@ Platform_thread::Platform_thread(Platform_pd &pd,
_label(label),
_pd(pd),
_pager(nullptr),
_utcb(ep, ram, core_rm),
_utcb(ep, ram, local_rm),
_priority(_scale_priority(virt_prio)),
_quota((unsigned)quota),
_main_thread(!pd.has_any_thread),

View File

@ -60,8 +60,8 @@ class Core::Platform_thread : Noncopyable
struct Utcb : Noncopyable
{
struct {
Ram_allocator *_ram_ptr = nullptr;
Region_map *_core_rm_ptr = nullptr;
Ram_allocator *_ram_ptr = nullptr;
Local_rm *_local_rm_ptr = nullptr;
};
Ram_allocator::Result const ds; /* UTCB ds of non-core threads */
@ -69,7 +69,7 @@ class Core::Platform_thread : Noncopyable
addr_t const core_addr; /* UTCB address within core/kernel */
addr_t const phys_addr;
addr_t _attach(Region_map &);
addr_t _attach(Local_rm &);
static addr_t _phys(Rpc_entrypoint &ep, Dataspace_capability ds)
{
@ -92,18 +92,18 @@ class Core::Platform_thread : Noncopyable
/**
* Constructor used for threads outside of core
*/
Utcb(Rpc_entrypoint &ep, Ram_allocator &ram, Region_map &core_rm)
Utcb(Rpc_entrypoint &ep, Ram_allocator &ram, Local_rm &local_rm)
:
_core_rm_ptr(&core_rm),
_local_rm_ptr(&local_rm),
ds(ram.try_alloc(sizeof(Native_utcb), CACHED)),
core_addr(_attach(core_rm)),
core_addr(_attach(local_rm)),
phys_addr(_ds_phys(ep, ds))
{ }
~Utcb()
{
if (_core_rm_ptr)
_core_rm_ptr->detach(core_addr);
if (_local_rm_ptr)
_local_rm_ptr->detach(core_addr);
}
Ram_dataspace_capability ds_cap() const
@ -173,7 +173,7 @@ class Core::Platform_thread : Noncopyable
* \param utcb core local pointer to userland stack
*/
Platform_thread(Platform_pd &, Rpc_entrypoint &, Ram_allocator &,
Region_map &, size_t const quota, Label const &label,
Local_rm &, size_t const quota, Label const &label,
unsigned const virt_prio, Affinity::Location,
addr_t const utcb);

View File

@ -36,7 +36,7 @@ void Core::platform_add_local_services(Rpc_entrypoint &ep,
Registry<Service> &services,
Trace::Source_registry &trace_sources,
Ram_allocator &core_ram,
Region_map &core_rm,
Local_rm &local_rm,
Range_allocator &)
{
map_local(Platform::core_phys_addr((addr_t)&hypervisor_exception_vector),
@ -46,16 +46,18 @@ void Core::platform_add_local_services(Rpc_entrypoint &ep,
platform().ram_alloc().alloc_aligned(Hw::Mm::hypervisor_stack().size,
get_page_size_log2()).with_result(
[&] (void *stack) {
map_local((addr_t)stack,
[&] (Range_allocator::Allocation &stack) {
map_local((addr_t)stack.ptr,
Hw::Mm::hypervisor_stack().base,
Hw::Mm::hypervisor_stack().size / get_page_size(),
Hw::PAGE_FLAGS_KERN_DATA);
static Vm_root vm_root(ep, sh, core_ram, core_rm, trace_sources);
stack.deallocate = false;
static Vm_root vm_root(ep, sh, core_ram, local_rm, trace_sources);
static Core_service<Vm_session_component> vm_service(services, vm_root);
},
[&] (Range_allocator::Alloc_error) {
[&] (Alloc_error) {
warning("failed to allocate hypervisor stack for VM service");
}
);

View File

@ -72,10 +72,11 @@ void * Vm_session_component::_alloc_table()
/* get some aligned space for the translation table */
return cma().alloc_aligned(sizeof(Board::Vm_page_table),
Board::Vm_page_table::ALIGNM_LOG2).convert<void *>(
[&] (void *table_ptr) {
return table_ptr; },
[&] (Range_allocator::Allocation &a) {
a.deallocate = false;
return a.ptr; },
[&] (Range_allocator::Alloc_error) -> void * {
[&] (Alloc_error) -> void * {
/* XXX handle individual error conditions */
error("failed to allocate kernel object");
throw Insufficient_ram_quota(); }
@ -95,7 +96,7 @@ Vm_session_component::Vm_session_component(Vmid_allocator & vmid_alloc,
Label const &,
Diag,
Ram_allocator &ram_alloc,
Region_map &region_map,
Local_rm &local_rm,
unsigned,
Trace::Source_registry &)
:
@ -103,8 +104,8 @@ Vm_session_component::Vm_session_component(Vmid_allocator & vmid_alloc,
Cap_quota_guard(resources.cap_quota),
_ep(ds_ep),
_ram(ram_alloc, _ram_quota_guard(), _cap_quota_guard()),
_sliced_heap(_ram, region_map),
_region_map(region_map),
_sliced_heap(_ram, local_rm),
_local_rm(local_rm),
_table(*construct_at<Board::Vm_page_table>(_alloc_table())),
_table_array(*(new (cma()) Board::Vm_page_table_array([] (void * virt) {
return (addr_t)cma().phys_addr(virt);}))),
@ -112,8 +113,8 @@ Vm_session_component::Vm_session_component(Vmid_allocator & vmid_alloc,
_id({(unsigned)_vmid_alloc.alloc(), cma().phys_addr(&_table)})
{
/* configure managed VM area */
_map.add_range(0, 0UL - 0x1000);
_map.add_range(0UL - 0x1000, 0x1000);
(void)_map.add_range(0, 0UL - 0x1000);
(void)_map.add_range(0UL - 0x1000, 0x1000);
}
@ -136,7 +137,7 @@ Vm_session_component::~Vm_session_component()
Vcpu & vcpu = *_vcpus[i];
if (vcpu.state().valid())
_region_map.detach(vcpu.ds_addr);
_local_rm.detach(vcpu.ds_addr);
}
/* free guest-to-host page tables */

View File

@ -33,7 +33,7 @@ void Core::platform_add_local_services(Rpc_entrypoint &ep,
Registry<Service> &services,
Trace::Source_registry &trace_sources,
Ram_allocator &core_ram,
Region_map &core_rm,
Local_rm &local_rm,
Range_allocator &)
{
static addr_t const phys_base =
@ -42,7 +42,7 @@ void Core::platform_add_local_services(Rpc_entrypoint &ep,
map_local(phys_base, Hw::Mm::system_exception_vector().base, 1,
Hw::PAGE_FLAGS_KERN_TEXT);
static Vm_root vm_root(ep, sliced_heap, core_ram, core_rm, trace_sources);
static Vm_root vm_root(ep, sliced_heap, core_ram, local_rm, trace_sources);
static Core_service<Vm_session_component> vm_service(services, vm_root);
}

View File

@ -63,15 +63,15 @@ Vm_session_component::Vm_session_component(Vmid_allocator &vmids, Rpc_entrypoint
Label const &,
Diag,
Ram_allocator &ram_alloc,
Region_map &region_map,
Local_rm &local_rm,
unsigned, Trace::Source_registry &)
:
Ram_quota_guard(resources.ram_quota),
Cap_quota_guard(resources.cap_quota),
_ep(ep),
_ram(ram_alloc, _ram_quota_guard(), _cap_quota_guard()),
_sliced_heap(_ram, region_map),
_region_map(region_map),
_sliced_heap(_ram, local_rm),
_local_rm(local_rm),
_table(*construct_at<Board::Vm_page_table>(_alloc_table())),
_table_array(dummy_array()),
_vmid_alloc(vmids),
@ -103,7 +103,7 @@ Vm_session_component::~Vm_session_component()
Vcpu & vcpu = *_vcpus[i];
if (vcpu.state().valid())
_region_map.detach(vcpu.ds_addr);
_local_rm.detach(vcpu.ds_addr);
}
id_alloc--;

View File

@ -43,7 +43,7 @@ class Core::Vcpu : public Rpc_object<Vm_session::Native_vcpu, Vcpu>
Kernel_object<Kernel::Vm> _kobj { };
Accounted_ram_allocator &_ram;
Ram_allocator::Result _ds;
Region_map &_region_map;
Local_rm &_local_rm;
Affinity::Location _location;
Phys_allocated<Data_pages> _vcpu_data_pages;
@ -58,23 +58,24 @@ class Core::Vcpu : public Rpc_object<Vm_session::Native_vcpu, Vcpu>
Vcpu(Kernel::Vm::Identity &id,
Rpc_entrypoint &ep,
Accounted_ram_allocator &ram,
Region_map &region_map,
Local_rm &local_rm,
Affinity::Location location)
:
_id(id),
_ep(ep),
_ram(ram),
_ds( {_ram.try_alloc(vcpu_state_size(), Cache::UNCACHED)} ),
_region_map(region_map),
_local_rm(local_rm),
_location(location),
_vcpu_data_pages(ep, ram, region_map)
_vcpu_data_pages(ep, ram, local_rm)
{
_ds.with_result([&] (Ram::Allocation &allocation) {
Region_map::Attr attr { };
attr.writeable = true;
_vcpu_data.vcpu_state = _region_map.attach(allocation.cap, attr).convert<Vcpu_state *>(
[&] (Region_map::Range range) { return (Vcpu_state *)range.start; },
[&] (Region_map::Attach_error) -> Vcpu_state * {
_vcpu_data.vcpu_state = _local_rm.attach(allocation.cap, attr).convert<Vcpu_state *>(
[&] (Local_rm::Attachment &a) {
a.deallocate = false; return (Vcpu_state *)a.ptr; },
[&] (Local_rm::Error) -> Vcpu_state * {
error("failed to attach VCPU data within core");
return nullptr;
});
@ -92,7 +93,7 @@ class Core::Vcpu : public Rpc_object<Vm_session::Native_vcpu, Vcpu>
~Vcpu()
{
_region_map.detach((addr_t)_vcpu_data.vcpu_state);
_local_rm.detach((addr_t)_vcpu_data.vcpu_state);
_ep.dissolve(this);
}

View File

@ -30,12 +30,12 @@ void Core::platform_add_local_services(Rpc_entrypoint &ep,
Registry<Service> &local_services,
Trace::Source_registry &trace_sources,
Ram_allocator &core_ram,
Region_map &core_rm,
Local_rm &local_rm,
Range_allocator &io_port_ranges)
{
static Io_port_root io_port_root(io_port_ranges, sliced_heap);
static Vm_root vm_root(ep, sliced_heap, core_ram, core_rm, trace_sources);
static Vm_root vm_root(ep, sliced_heap, core_ram, local_rm, trace_sources);
static Core_service<Session_object<Vm_session>> vm_service(local_services, vm_root);

View File

@ -85,7 +85,7 @@ class Core::Svm_session_component
Rpc_entrypoint &_ep;
Accounted_ram_allocator _accounted_ram_alloc;
Region_map &_region_map;
Local_rm &_local_rm;
Heap _heap;
Phys_allocated<Vm_page_table> _table;
Phys_allocated<Vm_page_table_array> _table_array;
@ -109,28 +109,28 @@ class Core::Svm_session_component
public:
Svm_session_component(Vmid_allocator & vmid_alloc,
Rpc_entrypoint &ds_ep,
Resources resources,
Label const &label,
Diag diag,
Ram_allocator &ram_alloc,
Region_map &region_map,
Svm_session_component(Vmid_allocator &vmid_alloc,
Rpc_entrypoint &ds_ep,
Resources const &resources,
Label const &label,
Diag diag,
Ram_allocator &ram_alloc,
Local_rm &local_rm,
Trace::Source_registry &)
:
Session_object(ds_ep, resources, label, diag),
_ep(ds_ep),
_accounted_ram_alloc(ram_alloc, _ram_quota_guard(), _cap_quota_guard()),
_region_map(region_map),
_heap(_accounted_ram_alloc, region_map),
_table(_ep, _accounted_ram_alloc, _region_map),
_table_array(_ep, _accounted_ram_alloc, _region_map,
_local_rm(local_rm),
_heap(_accounted_ram_alloc, local_rm),
_table(_ep, _accounted_ram_alloc, _local_rm),
_table_array(_ep, _accounted_ram_alloc, _local_rm,
[] (Phys_allocated<Vm_page_table_array> &table_array, auto *obj_ptr) {
construct_at<Vm_page_table_array>(obj_ptr, [&] (void *virt) {
return table_array.phys_addr() + ((addr_t) obj_ptr - (addr_t)virt);
});
}),
_memory(_accounted_ram_alloc, region_map),
_memory(_accounted_ram_alloc, local_rm),
_vmid_alloc(vmid_alloc),
_id({(unsigned)_vmid_alloc.alloc(), (void *)_table.phys_addr()})
{ }
@ -224,7 +224,7 @@ class Core::Svm_session_component
_id,
_ep,
_accounted_ram_alloc,
_region_map,
_local_rm,
vcpu_location);
return vcpu.cap();

View File

@ -85,7 +85,7 @@ class Core::Vmx_session_component
Rpc_entrypoint &_ep;
Accounted_ram_allocator _accounted_ram_alloc;
Region_map &_region_map;
Local_rm &_local_rm;
Heap _heap;
Phys_allocated<Vm_page_table> _table;
Phys_allocated<Vm_page_table_array> _table_array;
@ -115,22 +115,22 @@ class Core::Vmx_session_component
Label const &label,
Diag diag,
Ram_allocator &ram_alloc,
Region_map &region_map,
Local_rm &local_rm,
Trace::Source_registry &)
:
Session_object(ds_ep, resources, label, diag),
_ep(ds_ep),
_accounted_ram_alloc(ram_alloc, _ram_quota_guard(), _cap_quota_guard()),
_region_map(region_map),
_heap(_accounted_ram_alloc, region_map),
_table(_ep, _accounted_ram_alloc, _region_map),
_table_array(_ep, _accounted_ram_alloc, _region_map,
_local_rm(local_rm),
_heap(_accounted_ram_alloc, local_rm),
_table(_ep, _accounted_ram_alloc, _local_rm),
_table_array(_ep, _accounted_ram_alloc, _local_rm,
[] (Phys_allocated<Vm_page_table_array> &table_array, auto *obj_ptr) {
construct_at<Vm_page_table_array>(obj_ptr, [&] (void *virt) {
return table_array.phys_addr() + ((addr_t) obj_ptr - (addr_t)virt);
});
}),
_memory(_accounted_ram_alloc, region_map),
_memory(_accounted_ram_alloc, local_rm),
_vmid_alloc(vmid_alloc),
_id({(unsigned)_vmid_alloc.alloc(), (void *)_table.phys_addr()})
{ }
@ -224,7 +224,7 @@ class Core::Vmx_session_component
_id,
_ep,
_accounted_ram_alloc,
_region_map,
_local_rm,
vcpu_location);
return vcpu.cap();

View File

@ -35,7 +35,7 @@ class Core::Vm_root : public Root_component<Session_object<Vm_session>>
private:
Ram_allocator &_ram_allocator;
Region_map &_local_rm;
Local_rm &_local_rm;
Trace::Source_registry &_trace_sources;
Vmid_allocator _vmid_alloc { };
@ -86,7 +86,7 @@ class Core::Vm_root : public Root_component<Session_object<Vm_session>>
Vm_root(Rpc_entrypoint &session_ep,
Allocator &md_alloc,
Ram_allocator &ram_alloc,
Region_map &local_rm,
Local_rm &local_rm,
Trace::Source_registry &trace_sources)
:
Root_component<Session_object<Vm_session>>(&session_ep, &md_alloc),

View File

@ -30,7 +30,7 @@ class Core::Vm_root : public Root_component<Vm_session_component>
private:
Ram_allocator &_ram_allocator;
Region_map &_local_rm;
Local_rm &_local_rm;
Trace::Source_registry &_trace_sources;
Vmid_allocator _vmid_alloc { };
@ -74,7 +74,7 @@ class Core::Vm_root : public Root_component<Vm_session_component>
Vm_root(Rpc_entrypoint &session_ep,
Allocator &md_alloc,
Ram_allocator &ram_alloc,
Region_map &local_rm,
Local_rm &local_rm,
Trace::Source_registry &trace_sources)
:
Root_component<Vm_session_component>(&session_ep, &md_alloc),

View File

@ -65,11 +65,14 @@ Capability<Vm_session::Native_vcpu> Vm_session_component::create_vcpu(Thread_cap
vcpu.ds.with_error([&] (Ram::Error e) { throw_exception(e); });
try {
Region_map::Attr attr { };
Local_rm::Attach_attr attr { };
attr.writeable = true;
vcpu.ds_addr = _region_map.attach(vcpu.state(), attr).convert<addr_t>(
[&] (Region_map::Range range) { return _alloc_vcpu_data(range.start); },
[&] (Region_map::Attach_error) -> addr_t {
vcpu.ds_addr = _local_rm.attach(vcpu.state(), attr).convert<addr_t>(
[&] (Local_rm::Attachment &a) {
a.deallocate = false;
return _alloc_vcpu_data(addr_t(a.ptr));
},
[&] (Local_rm::Error) -> addr_t {
error("failed to attach VCPU data within core");
_vcpus[_vcpu_id_alloc].destruct();
return 0;

View File

@ -98,7 +98,7 @@ class Core::Vm_session_component
Accounted_ram_allocator _ram;
Sliced_heap _sliced_heap;
Avl_region _map { &_sliced_heap };
Region_map &_region_map;
Local_rm &_local_rm;
Board::Vm_page_table &_table;
Board::Vm_page_table_array &_table_array;
Vmid_allocator &_vmid_alloc;
@ -128,7 +128,7 @@ class Core::Vm_session_component
Vm_session_component(Vmid_allocator &, Rpc_entrypoint &,
Resources, Label const &, Diag,
Ram_allocator &ram, Region_map &, unsigned,
Ram_allocator &ram, Local_rm &, unsigned,
Trace::Source_registry &);
~Vm_session_component();

View File

@ -14,20 +14,29 @@
#ifndef _CORE__INCLUDE__CORE_REGION_MAP_H_
#define _CORE__INCLUDE__CORE_REGION_MAP_H_
/* Genode includes */
#include <pd_session/pd_session.h>
/* base-internal includes */
#include <base/internal/region_map_mmap.h>
/* core includes */
#include <types.h>
namespace Core { class Core_region_map; }
namespace Core { class Core_local_rm; }
struct Core::Core_region_map : Region_map_mmap
struct Core::Core_local_rm : private Region_map_mmap, Pd_local_rm
{
static void init(Rpc_entrypoint &);
Core_region_map(Rpc_entrypoint &ep) : Region_map_mmap(false) { init(ep); }
Core_local_rm(Rpc_entrypoint &ep)
:
Region_map_mmap(false),
Pd_local_rm(*static_cast<Region_map_mmap *>(this))
{
init(ep);
}
};
#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */

View File

@ -69,7 +69,7 @@ class Core::Platform_thread : Noncopyable
/**
* Constructor
*/
Platform_thread(Platform_pd &, Rpc_entrypoint &, Ram_allocator &, Region_map &,
Platform_thread(Platform_pd &, Rpc_entrypoint &, Ram_allocator &, Local_rm &,
size_t, auto const &name, auto...)
: _name(name) { }

View File

@ -21,7 +21,7 @@
/* local includes */
#include <platform.h>
#include <core_region_map.h>
#include <core_local_rm.h>
#include <resource_path.h>
/* Linux includes */
@ -171,7 +171,7 @@ void Core::init_page_fault_handling(Rpc_entrypoint &) { }
static Rpc_entrypoint *_core_ep_ptr;
void Core_region_map::init(Rpc_entrypoint &ep) { _core_ep_ptr = &ep; }
void Core_local_rm::init(Rpc_entrypoint &ep) { _core_ep_ptr = &ep; }
static auto with_linux_dataspace(Capability<Dataspace> ds,

View File

@ -24,6 +24,6 @@ void Core::platform_add_local_services(Rpc_entrypoint &,
Registry<Service> &,
Trace::Source_registry &,
Ram_allocator &,
Region_map &,
Local_rm &,
Range_allocator &)
{ }

View File

@ -30,7 +30,7 @@ void Core::platform_add_local_services(Rpc_entrypoint &,
Registry<Service> &services,
Trace::Source_registry &,
Ram_allocator &,
Region_map &,
Local_rm &,
Range_allocator &io_port_ranges)
{
if (!lx_iopl(3)) {

View File

@ -34,11 +34,11 @@ namespace Genode { struct Platform; }
struct Genode::Platform
{
Region_map_mmap rm { false };
Region_map_mmap mmap_rm { false };
static Capability<Parent> _obtain_parent_cap();
Local_parent parent { _obtain_parent_cap(), rm, heap };
Local_parent parent { _obtain_parent_cap(), mmap_rm, heap };
Capability<Pd_session> pd_cap =
parent.session_cap(Parent::Env::pd()).convert<Capability<Pd_session>>(
@ -52,11 +52,12 @@ struct Genode::Platform
Local_pd_session pd { parent, pd_cap };
Pd_ram_allocator ram { pd };
Pd_local_rm local_rm { mmap_rm };
Pd_ram_allocator ram { pd };
Expanding_cpu_session_client cpu { parent, cpu_cap, Parent::Env::cpu() };
Heap heap { ram, rm };
Heap heap { ram, local_rm };
Platform() { _attach_stack_area(); }

View File

@ -59,7 +59,7 @@ Child::Start_result Child::_start_process(Dataspace_capability ldso_ds,
Pd_session &pd,
Initial_thread_base &,
Initial_thread::Start &,
Region_map &,
Local_rm &,
Region_map &,
Parent_capability)
{

View File

@ -153,10 +153,10 @@ Platform &Genode::init_platform()
init_log(platform.parent);
init_rpc_cap_alloc(platform.parent);
init_cap_slab(platform.pd, platform.parent);
init_thread(platform.cpu, platform.rm);
init_thread(platform.cpu, platform.local_rm);
init_thread_start(platform.pd.rpc_cap());
init_thread_bootstrap(platform.cpu, platform.parent.main_thread_cap());
init_exception_handling(platform.ram, platform.rm);
init_exception_handling(platform.ram, platform.local_rm);
init_signal_receiver(platform.pd, platform.parent);
return platform;

View File

@ -91,7 +91,7 @@ namespace Genode {
* For lx_hybrid programs, C++ support is initialized by the startup code
* provided by the host toolchain.
*/
void Genode::init_exception_handling(Ram_allocator &, Region_map &) { }
void Genode::init_exception_handling(Ram_allocator &, Env::Local_rm &) { }
/*
@ -409,7 +409,7 @@ static void *thread_start(void *arg)
}
void Genode::init_thread(Cpu_session &, Region_map &) { }
void Genode::init_thread(Cpu_session &, Env::Local_rm &) { }
void Genode::init_thread_start(Capability<Pd_session>) { }

View File

@ -70,11 +70,11 @@ Main::Main(Env &env) : heap(env.ram(), env.rm())
.use_at = true, .at = beg,
.executable = { }, .writeable = true
}).with_result(
[&] (Region_map::Range) {
[&] (Env::Local_rm::Attachment &) {
error("after RAM dataspace attach -- ERROR");
env.parent().exit(-1); },
[&] (Region_map::Attach_error e) {
if (e == Region_map::Attach_error::REGION_CONFLICT)
[&] (Env::Local_rm::Error e) {
if (e == Env::Local_rm::Error::REGION_CONFLICT)
log("OK caught Region_conflict exception"); }
);
@ -89,11 +89,11 @@ Main::Main(Env &env) : heap(env.ram(), env.rm())
.use_at = true, .at = beg,
.executable = { }, .writeable = true
}).with_result(
[&] (Region_map::Range) {
[&] (Env::Local_rm::Attachment &) {
error("after sub-RM dataspace attach -- ERROR");
env.parent().exit(-1); },
[&] (Region_map::Attach_error e) {
if (e == Region_map::Attach_error::REGION_CONFLICT)
[&] (Env::Local_rm::Error e) {
if (e == Env::Local_rm::Error::REGION_CONFLICT)
log("OK caught Region_conflict exception"); }
);
}
@ -107,7 +107,10 @@ Main::Main(Env &env) : heap(env.ram(), env.rm())
.size = { }, .offset = { },
.use_at = true, .at = 0x1000,
.executable = { }, .writeable = true
});
}).with_result(
[&] (Region_map::Range) { },
[&] (Region_map::Attach_error) { error("mapping to managed dataspace failed"); }
);
log("before populated sub-RM dataspace attach");
char * const addr = env.rm().attach(rm.dataspace(), {
@ -115,8 +118,11 @@ Main::Main(Env &env) : heap(env.ram(), env.rm())
.use_at = { }, .at = { },
.executable = { }, .writeable = true
}).convert<char *>(
[&] (Region_map::Range r) { return (char *)r.start + 0x1000; },
[&] (Region_map::Attach_error) { return nullptr; }
[&] (Env::Local_rm::Attachment &a) {
a.deallocate = false;
return (char *)a.ptr + 0x1000;
},
[&] (Env::Local_rm::Error) { return nullptr; }
);
log("after populated sub-RM dataspace attach / before touch");
char const val = *addr;

View File

@ -6,7 +6,7 @@ SRC_CC += stack_area.cc \
core_mem_alloc.cc \
core_log.cc \
core_log_out.cc \
core_region_map.cc \
core_local_rm.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
cpu_session_support.cc \

View File

@ -12,10 +12,11 @@
*/
/* core includes */
#include <core_region_map.h>
#include <core_local_rm.h>
#include <platform.h>
#include <util.h>
#include <nova_util.h>
#include <dataspace_component.h>
/* NOVA includes */
#include <nova/syscalls.h>
@ -51,26 +52,26 @@ static inline void * alloc_region(Dataspace_component &ds, const size_t size)
return virt_addr;
}
Region_map::Attach_result
Core_region_map::attach(Dataspace_capability ds_cap, Attr const &attr)
Core_local_rm::Result
Core_local_rm::attach(Dataspace_capability ds_cap, Attach_attr const &attr)
{
return _ep.apply(ds_cap, [&] (Dataspace_component * const ds_ptr) -> Attach_result {
return _ep.apply(ds_cap, [&] (Dataspace_component * const ds_ptr) -> Result {
if (!ds_ptr)
return Attach_error::INVALID_DATASPACE;
return Error::INVALID_DATASPACE;
Dataspace_component &ds = *ds_ptr;
/* attach attributes 'use_at' and 'offset' not supported within core */
if (attr.use_at || attr.offset)
return Attach_error::REGION_CONFLICT;
return Error::REGION_CONFLICT;
const size_t page_rounded_size = align_addr(ds.size(), get_page_size_log2());
/* allocate the virtual region contiguous for the dataspace */
void * virt_ptr = alloc_region(ds, page_rounded_size);
if (!virt_ptr)
return Attach_error::OUT_OF_RAM;
return Error::OUT_OF_RAM;
/* map it */
Nova::Utcb &utcb = *reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb());
@ -81,20 +82,19 @@ Core_region_map::attach(Dataspace_capability ds_cap, Attr const &attr)
page_rounded_size >> get_page_size_log2(), rights, true)) {
platform().region_alloc().free(virt_ptr, page_rounded_size);
return Attach_error::OUT_OF_RAM;
return Error::OUT_OF_RAM;
}
return Range { .start = addr_t(virt_ptr), .num_bytes = page_rounded_size };
return { *this, { virt_ptr, page_rounded_size } };
});
}
void Core_region_map::detach(addr_t core_local_addr)
void Core_local_rm::_free(Attachment &a)
{
size_t size = platform_specific().region_alloc_size_at((void *)core_local_addr);
size_t size = platform_specific().region_alloc_size_at(a.ptr);
unmap_local(*reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb()),
core_local_addr, size >> get_page_size_log2());
addr_t(a.ptr), size >> get_page_size_log2());
platform().region_alloc().free((void *)core_local_addr);
platform().region_alloc().free(a.ptr);
}

View File

@ -93,7 +93,7 @@ class Core::Platform_thread
/**
* Constructor
*/
Platform_thread(Platform_pd &, Rpc_entrypoint &, Ram_allocator &, Region_map &,
Platform_thread(Platform_pd &, Rpc_entrypoint &, Ram_allocator &, Local_rm &,
size_t quota, char const *name, unsigned priority,
Affinity::Location affinity, addr_t utcb);

View File

@ -131,7 +131,7 @@ class Core::Vm_session_component
using Cap_quota_guard::upgrade;
Vm_session_component(Rpc_entrypoint &, Resources, Label const &,
Diag, Ram_allocator &ram, Region_map &, unsigned,
Diag, Ram_allocator &ram, Local_rm &, unsigned,
Trace::Source_registry &);
~Vm_session_component();

View File

@ -24,10 +24,10 @@ void Core::platform_add_local_services(Rpc_entrypoint &ep,
Registry<Service> &services,
Trace::Source_registry &trace_sources,
Ram_allocator &core_ram,
Region_map &core_rm,
Local_rm &local_rm,
Range_allocator &io_port_ranges)
{
static Vm_root vm_root(ep, heap, core_ram, core_rm, trace_sources);
static Vm_root vm_root(ep, heap, core_ram, local_rm, trace_sources);
static Core_service<Vm_session_component> vm(services, vm_root);
static Io_port_root io_root(io_port_ranges, heap);

View File

@ -344,7 +344,7 @@ void Platform_thread::thread_type(Cpu_session::Native_cpu::Thread_type thread_ty
Platform_thread::Platform_thread(Platform_pd &pd, Rpc_entrypoint &, Ram_allocator &,
Region_map &, size_t, const char *name,
Local_rm &, size_t, const char *name,
unsigned prio, Affinity::Location affinity, addr_t)
:
_pd(pd), _pager(0), _id_base(cap_map().insert(2)),

View File

@ -363,7 +363,7 @@ Vm_session_component::Vm_session_component(Rpc_entrypoint &ep,
Label const &label,
Diag,
Ram_allocator &ram,
Region_map &local_rm,
Local_rm &local_rm,
unsigned const priority,
Trace::Source_registry &trace_sources)
:

View File

@ -630,8 +630,9 @@ class Greedy : public Genode::Thread {
for (unsigned i = 0; i < SUB_RM_SIZE / 4096; i++) {
addr_t const map_to = _env.rm().attach(ds, { }).convert<addr_t>(
[&] (Region_map::Range r) { return r.start; },
[&] (Region_map::Attach_error) {
[&] (Env::Local_rm::Attachment &a) {
a.deallocate = false; return addr_t(a.ptr); },
[&] (Env::Local_rm::Error) {
error("Greedy: failed to attach RAM dataspace");
return 0UL;
}

View File

@ -9,7 +9,7 @@ SRC_CC += stack_area.cc \
core_mem_alloc.cc \
core_log.cc \
core_log_out.cc \
core_region_map.cc \
core_local_rm.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
cpu_session_support.cc \

View File

@ -13,18 +13,19 @@
/* core includes */
#include <platform.h>
#include <core_region_map.h>
#include <core_local_rm.h>
#include <map_local.h>
#include <dataspace_component.h>
using namespace Core;
Region_map::Attach_result
Core_region_map::attach(Dataspace_capability ds_cap, Attr const &attr)
Core_local_rm::Result
Core_local_rm::attach(Dataspace_capability ds_cap, Attach_attr const &attr)
{
return _ep.apply(ds_cap, [&] (Dataspace_component *ds) -> Attach_result {
return _ep.apply(ds_cap, [&] (Dataspace_component *ds) -> Result {
if (!ds)
return Attach_error::INVALID_DATASPACE;
return Error::INVALID_DATASPACE;
size_t const size = (attr.size == 0) ? ds->size() : attr.size;
size_t const page_rounded_size = (size + get_page_size() - 1)
@ -32,30 +33,32 @@ Core_region_map::attach(Dataspace_capability ds_cap, Attr const &attr)
/* attach attributes 'use_at' and 'offset' not supported within core */
if (attr.use_at || attr.offset)
return Attach_error::REGION_CONFLICT;
return Error::REGION_CONFLICT;
/* allocate range in core's virtual address space */
Range_allocator &virt_alloc = platform().region_alloc();
return virt_alloc.try_alloc(page_rounded_size).convert<Attach_result>(
return virt_alloc.try_alloc(page_rounded_size).convert<Result>(
[&] (Range_allocator::Allocation &virt) -> Attach_result {
[&] (Range_allocator::Allocation &virt) -> Result {
/* map the dataspace's physical pages to virtual memory */
unsigned num_pages = page_rounded_size >> get_page_size_log2();
if (!map_local(ds->phys_addr(), (addr_t)virt.ptr, num_pages))
return Attach_error::INVALID_DATASPACE;
return Error::INVALID_DATASPACE;
virt.deallocate = false;
return Range { .start = addr_t(virt.ptr), .num_bytes = page_rounded_size };
return { *this, { .ptr = virt.ptr,
.num_bytes = page_rounded_size } };
},
[&] (Alloc_error) {
error("could not allocate virtual address range in core of size ",
page_rounded_size);
return Attach_error::REGION_CONFLICT;
return Error::REGION_CONFLICT;
});
});
}
void Core_region_map::detach(addr_t) { }
void Core_local_rm::_free(Attachment &) { }

View File

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

View File

@ -44,11 +44,9 @@ class Core::Platform_thread
Okl4::L4_ThreadId_t _l4_thread_id = Okl4::L4_nilthread;
char _name[32]; /* thread name that will be
registered at the kernel
debugger */
char _name[32]; /* thread name at the kernel debugger */
Platform_pd &_pd;
unsigned _priority = 0; /* thread priority */
unsigned _priority = 0;
Pager_object *_pager = nullptr;
bool _bound_to_pd = false;
@ -62,7 +60,7 @@ class Core::Platform_thread
* Constructor
*/
Platform_thread(Platform_pd &pd, Rpc_entrypoint &, Ram_allocator &,
Region_map &, size_t, const char *name,
Local_rm &, size_t, const char *name,
unsigned prio, Affinity::Location, addr_t)
:
_pd(pd), _priority(prio)

View File

@ -7,7 +7,7 @@ SRC_CC = stack_area.cc \
core_log.cc \
core_log_out.cc \
core_rpc_cap_alloc.cc \
core_region_map.cc \
core_local_rm.cc \
cpu_session_component.cc \
cpu_session_support.cc \
cpu_thread_component.cc \
@ -70,7 +70,7 @@ vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath default_log.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)
vpath core_region_map.cc $(GEN_CORE_DIR)
vpath core_local_rm.cc $(GEN_CORE_DIR)
vpath stack_area.cc $(GEN_CORE_DIR)
vpath pager_ep.cc $(GEN_CORE_DIR)
vpath platform_rom_modules.cc $(GEN_CORE_DIR)

View File

@ -87,7 +87,7 @@ class Core::Platform_thread : Interface
* Constructor
*/
Platform_thread(Platform_pd &pd, Rpc_entrypoint &, Ram_allocator &,
Region_map &, size_t, char const *name, unsigned priority,
Local_rm &, size_t, char const *name, unsigned priority,
Affinity::Location location, addr_t)
:
_name(name), _pd(pd), _priority(priority), _location(location)

View File

@ -27,7 +27,7 @@ GEN_SRC_CC += \
REP_SRC_CC += \
capability_space.cc \
core_log_out.cc \
core_region_map.cc \
core_local_rm.cc \
io_mem_session_support.cc \
irq_session_component.cc \
pager.cc \

View File

@ -12,56 +12,58 @@
*/
/* core includes */
#include <core_region_map.h>
#include <core_local_rm.h>
#include <platform.h>
#include <map_local.h>
#include <dataspace_component.h>
using namespace Core;
Region_map::Attach_result
Core_region_map::attach(Dataspace_capability ds_cap, Attr const &attr)
Core_local_rm::Result
Core_local_rm::attach(Dataspace_capability ds_cap, Attach_attr const &attr)
{
return _ep.apply(ds_cap, [&] (Dataspace_component *ds) -> Attach_result {
return _ep.apply(ds_cap, [&] (Dataspace_component *ds) -> Result {
if (!ds)
return Attach_error::INVALID_DATASPACE;
return Error::INVALID_DATASPACE;
size_t const size = (attr.size == 0) ? ds->size() : attr.size;
size_t const page_rounded_size = (size + get_page_size() - 1) & get_page_mask();
/* attach attributes 'use_at' and 'offset' not supported within core */
if (attr.use_at || attr.offset)
return Attach_error::REGION_CONFLICT;
return Error::REGION_CONFLICT;
/* allocate range in core's virtual address space */
return platform().region_alloc().try_alloc(page_rounded_size).convert<Attach_result>(
[&] (Range_allocator::Allocation &virt) {
return platform().region_alloc().try_alloc(page_rounded_size).convert<Result>(
[&] (Range_allocator::Allocation &virt) -> Result {
/* map the dataspace's physical pages to core-local virtual addresses */
size_t num_pages = page_rounded_size >> get_page_size_log2();
map_local(ds->phys_addr(), (addr_t)virt.ptr, num_pages);
virt.deallocate = false;
return Range { .start = addr_t(virt.ptr), .num_bytes = page_rounded_size };
return { *this, { .ptr = virt.ptr,
.num_bytes = page_rounded_size } };
},
[&] (Alloc_error) -> Attach_result {
[&] (Alloc_error) -> Result {
error("could not allocate virtual address range in core of size ",
page_rounded_size);
return Attach_error::REGION_CONFLICT;
return Error::REGION_CONFLICT;
}
);
});
}
void Core_region_map::detach(addr_t const at)
void Core_local_rm::_free(Attachment &virt)
{
size_t const size = platform_specific().region_alloc_size_at((void *)at);
size_t const size = platform_specific().region_alloc_size_at(virt.ptr);
if (!unmap_local(at, size >> get_page_size_log2())) {
error("could not unmap core virtual address ", Hex(at), " in ", __PRETTY_FUNCTION__);
if (!unmap_local(addr_t(virt.ptr), size >> get_page_size_log2())) {
error("could not unmap core virtual address ", virt.ptr, " in ", __PRETTY_FUNCTION__);
return;
}
platform().region_alloc().free((void *)at);
platform().region_alloc().free(virt.ptr);
}

View File

@ -89,7 +89,7 @@ class Core::Platform_thread : public List<Platform_thread>::Element
* Constructor
*/
Platform_thread(Platform_pd &pd, Rpc_entrypoint &, Ram_allocator &,
Region_map &, size_t, const char *name, unsigned priority,
Local_rm &, size_t, const char *name, unsigned priority,
Affinity::Location, addr_t utcb);
/**

View File

@ -105,7 +105,7 @@ class Core::Vm_session_component
using Cap_quota_guard::upgrade;
Vm_session_component(Rpc_entrypoint &, Resources, Label const &,
Diag, Ram_allocator &ram, Region_map &, unsigned,
Diag, Ram_allocator &ram, Local_rm &, unsigned,
Trace::Source_registry &);
~Vm_session_component();

View File

@ -205,7 +205,7 @@ bool Platform_thread::install_mapping(Mapping const &mapping)
Platform_thread::Platform_thread(Platform_pd &pd, Rpc_entrypoint &, Ram_allocator &,
Region_map &, size_t, const char *name,
Local_rm &, size_t, const char *name,
unsigned priority, Affinity::Location location,
addr_t utcb)
:

View File

@ -24,10 +24,10 @@ void Core::platform_add_local_services(Rpc_entrypoint &ep,
Registry<Service> &services,
Trace::Source_registry &trace_sources,
Ram_allocator &core_ram,
Region_map &core_rm,
Local_rm &local_rm,
Range_allocator &io_port_ranges)
{
static Vm_root vm_root(ep, heap, core_ram, core_rm, trace_sources);
static Vm_root vm_root(ep, heap, core_ram, local_rm, trace_sources);
static Core_service<Vm_session_component> vm(services, vm_root);

View File

@ -86,7 +86,7 @@ Vm_session_component::Vm_session_component(Rpc_entrypoint &ep,
Label const &,
Diag,
Ram_allocator &ram,
Region_map &local_rm,
Local_rm &local_rm,
unsigned,
Trace::Source_registry &)
try

View File

@ -15,7 +15,7 @@
#define _INCLUDE__BASE__ATTACHED_DATASPACE_H_
#include <dataspace/client.h>
#include <base/env.h>
#include <base/local.h>
namespace Genode { class Attached_dataspace; }
@ -29,29 +29,18 @@ class Genode::Attached_dataspace : Noncopyable
private:
Dataspace_capability _ds;
using Local_rm = Local::Constrained_region_map;
Region_map &_rm;
Dataspace_capability const _ds;
Dataspace_capability _check(Dataspace_capability ds)
{
if (ds.valid())
return ds;
throw Invalid_dataspace();
}
Region_map::Attach_result _attached = _rm.attach(_ds, {
.size = { }, .offset = { },
.use_at = { }, .at = { },
.executable = { }, .writeable = true });
Local_rm::Result _attached;
template <typename T>
T *_ptr() const
{
return _attached.convert<T *>(
[&] (Region_map::Range range) { return (T *)range.start; },
[&] (Region_map::Attach_error) { return nullptr; });
[&] (Local_rm::Attachment const &a) { return (T *)a.ptr; },
[&] (Local_rm::Error) { return nullptr; });
}
public:
@ -60,31 +49,28 @@ class Genode::Attached_dataspace : Noncopyable
* Constructor
*
* \throw Region_conflict
* \throw Invalid_dataspace
* \throw Out_of_caps
* \throw Out_of_ram
*/
Attached_dataspace(Region_map &rm, Dataspace_capability ds)
Attached_dataspace(Local_rm &rm, Dataspace_capability ds)
:
_ds(_check(ds)), _rm(rm)
_ds(ds),
_attached(rm.attach(ds, {
.size = { }, .offset = { },
.use_at = { }, .at = { },
.executable = { }, .writeable = true
}))
{
_attached.with_error([&] (Region_map::Attach_error e) {
if (e == Region_map::Attach_error::OUT_OF_RAM) throw Out_of_ram();
if (e == Region_map::Attach_error::OUT_OF_CAPS) throw Out_of_caps();
throw Region_conflict();
_attached.with_error([&] (Local_rm::Error e) {
switch (e) {
case Local_rm::Error::OUT_OF_RAM: throw Out_of_ram();
case Local_rm::Error::OUT_OF_CAPS: throw Out_of_caps();
case Local_rm::Error::REGION_CONFLICT: throw Region_conflict();
case Local_rm::Error::INVALID_DATASPACE: throw Invalid_dataspace();
}
});
}
/**
* Destructor
*/
~Attached_dataspace()
{
_attached.with_result(
[&] (Region_map::Range range) { _rm.detach(range.start); },
[&] (Region_map::Attach_error) { });
}
/**
* Return capability of the used dataspace
*/
@ -108,8 +94,8 @@ class Genode::Attached_dataspace : Noncopyable
size_t size() const
{
return _attached.convert<size_t>(
[&] (Region_map::Range range) { return range.num_bytes; },
[&] (Region_map::Attach_error) { return 0UL; });
[&] (Local_rm::Attachment const &a) { return a.num_bytes; },
[&] (Local_rm::Error) { return 0UL; });
}
/**
@ -126,7 +112,7 @@ class Genode::Attached_dataspace : Noncopyable
* removed the memory mappings of the dataspace. So we have to omit the
* detach operation in '~Attached_dataspace'.
*/
void invalidate() { _attached = Region_map::Attach_error::INVALID_DATASPACE; }
void invalidate() { _attached = Local_rm::Error::INVALID_DATASPACE; }
};
#endif /* _INCLUDE__BASE__ATTACHED_DATASPACE_H_ */

View File

@ -31,9 +31,9 @@ class Genode::Attached_io_mem_dataspace
{
private:
Region_map &_env_rm;
Io_mem_connection _mmio;
Io_mem_dataspace_capability _ds;
Env::Local_rm::Result const _attached;
addr_t const _at;
static addr_t _with_sub_page_offset(addr_t local, addr_t io_base)
@ -41,18 +41,6 @@ class Genode::Attached_io_mem_dataspace
return local | (io_base & 0xfffUL);
}
addr_t _attach()
{
return _env_rm.attach(_ds, {
.size = { }, .offset = { },
.use_at = { }, .at = { },
.executable = { }, .writeable = true
}).convert<addr_t>(
[&] (Region_map::Range range) { return range.start; },
[&] (Region_map::Attach_error) { return 0UL; }
);
}
public:
/**
@ -73,20 +61,23 @@ class Genode::Attached_io_mem_dataspace
Attached_io_mem_dataspace(Env &env, Genode::addr_t base, Genode::size_t size,
bool write_combined = false)
:
_env_rm(env.rm()),
_mmio(env, base, size, write_combined),
_ds(_mmio.dataspace()),
_at(_with_sub_page_offset(_attach(), base))
_attached(env.rm().attach(_ds, {
.size = { }, .offset = { },
.use_at = { }, .at = { },
.executable = { }, .writeable = true })),
_at(_attached.convert<addr_t>(
[&] (Env::Local_rm::Attachment const &a) {
return _with_sub_page_offset(addr_t(a.ptr), base); },
[&] (Env::Local_rm::Error) { return 0UL; }))
{
if (!_ds.valid()) throw Attached_dataspace::Invalid_dataspace();
if (!_at) throw Attached_dataspace::Region_conflict();
}
/**
* Destructor
*/
~Attached_io_mem_dataspace() { if (_at) _env_rm.detach(_at); }
/**
* Return capability of the used RAM dataspace
*/

View File

@ -35,9 +35,11 @@ class Genode::Attached_ram_dataspace
{
private:
using Local_rm = Local::Constrained_region_map;
size_t _size = 0;
Ram_allocator *_ram = nullptr;
Region_map *_rm = nullptr;
Local_rm *_rm = nullptr;
Ram_dataspace_capability _ds { };
addr_t _at = 0;
Cache const _cache = CACHED;
@ -60,15 +62,16 @@ class Genode::Attached_ram_dataspace
_ds = _ram->alloc(_size, _cache);
Region_map::Attr attr { };
Local_rm::Attach_attr attr { };
attr.writeable = true;
_rm->attach(_ds, attr).with_result(
[&] (Region_map::Range range) { _at = range.start; },
[&] (Region_map::Attach_error e) {
[&] (Local_rm::Attachment &a) {
a.deallocate = false; _at = addr_t(a.ptr); },
[&] (Local_rm::Error e) {
/* revert allocation if attaching the dataspace failed */
_ram->free(_ds, _size);
if (e == Region_map::Attach_error::OUT_OF_RAM) throw Out_of_ram();
if (e == Region_map::Attach_error::OUT_OF_CAPS) throw Out_of_caps();
if (e == Local_rm::Error::OUT_OF_RAM) throw Out_of_ram();
if (e == Local_rm::Error::OUT_OF_CAPS) throw Out_of_caps();
throw Attached_dataspace::Region_conflict();
});
@ -106,7 +109,7 @@ class Genode::Attached_ram_dataspace
* \throw Attached_dataspace::Region_conflict
* \throw Attached_dataspace::Invalid_dataspace
*/
Attached_ram_dataspace(Ram_allocator &ram, Region_map &rm,
Attached_ram_dataspace(Ram_allocator &ram, Local_rm &rm,
size_t size, Cache cache = CACHED)
:
_size(size), _ram(&ram), _rm(&rm), _cache(cache)

View File

@ -26,7 +26,9 @@ class Genode::Attached_rom_dataspace
{
private:
Region_map &_rm;
using Local_rm = Local::Constrained_region_map;
Local_rm &_rm;
Rom_connection _rom;
/*

View File

@ -268,6 +268,8 @@ class Genode::Child : protected Rpc_object<Parent>,
{
private:
using Local_rm = Local::Constrained_region_map;
struct Initial_thread_base : Interface
{
struct Start : Interface
@ -322,7 +324,7 @@ class Genode::Child : protected Rpc_object<Parent>,
/* print error message with the child's name prepended */
void _error(auto &&... args) { error(_policy.name(), ": ", args...); }
Region_map &_local_rm;
Local_rm &_local_rm;
Capability_guard _parent_cap_guard;
@ -383,7 +385,7 @@ class Genode::Child : protected Rpc_object<Parent>,
static Load_result _load_static_elf(Dataspace_capability elf_ds,
Ram_allocator &ram,
Region_map &local_rm,
Local_rm &local_rm,
Region_map &remote_rm,
Parent_capability parent_cap);
@ -393,7 +395,7 @@ class Genode::Child : protected Rpc_object<Parent>,
Pd_session &,
Initial_thread_base &,
Initial_thread::Start &,
Region_map &local_rm,
Local_rm &local_rm,
Region_map &remote_rm,
Parent_capability parent);
@ -660,7 +662,7 @@ class Genode::Child : protected Rpc_object<Parent>,
* \throw Service_denied the initial sessions for the child's
* environment could not be established
*/
Child(Region_map &rm, Rpc_entrypoint &entrypoint, Child_policy &policy);
Child(Local_rm &rm, Rpc_entrypoint &entrypoint, Child_policy &policy);
/**
* Destructor

View File

@ -18,12 +18,15 @@
#include <base/entrypoint.h>
#include <cpu_session/capability.h>
#include <pd_session/capability.h>
#include <base/local.h>
namespace Genode { struct Env; }
struct Genode::Env : Interface
{
using Local_rm = Local::Constrained_region_map;
virtual Parent &parent() = 0;
/**
@ -36,7 +39,7 @@ struct Genode::Env : Interface
/**
* Region map of the component's address space
*/
virtual Region_map &rm() = 0;
virtual Local_rm &rm() = 0;
/**
* PD session of the component as created by the parent

View File

@ -17,7 +17,7 @@
#include <util/list.h>
#include <util/reconstructible.h>
#include <base/ram_allocator.h>
#include <region_map/region_map.h>
#include <base/local.h>
#include <base/allocator_avl.h>
#include <base/mutex.h>
@ -39,6 +39,8 @@ class Genode::Heap : public Allocator
{
private:
using Local_rm = Local::Constrained_region_map;
class Dataspace : public List<Dataspace>::Element
{
private:
@ -76,17 +78,17 @@ class Genode::Heap : public Allocator
public:
Ram_allocator *ram_alloc; /* backing store */
Region_map *region_map;
Local_rm *local_rm;
Dataspace_pool(Ram_allocator *ram, Region_map *rm)
: ram_alloc(ram), region_map(rm) { }
Dataspace_pool(Ram_allocator *ram, Local_rm *rm)
: ram_alloc(ram), local_rm(rm) { }
~Dataspace_pool();
void remove_and_free(Dataspace &);
void reassign_resources(Ram_allocator *ram, Region_map *rm) {
ram_alloc = ram, region_map = rm; }
void reassign_resources(Ram_allocator *ram, Local_rm *rm) {
ram_alloc = ram, local_rm = rm; }
};
Mutex mutable _mutex { };
@ -122,12 +124,12 @@ class Genode::Heap : public Allocator
static constexpr size_t UNLIMITED = ~0;
Heap(Ram_allocator *ram_allocator,
Region_map *region_map,
Local_rm *local_rm,
size_t quota_limit = UNLIMITED,
void *static_addr = 0,
size_t static_size = 0);
Heap(Ram_allocator &ram, Region_map &rm) : Heap(&ram, &rm) { }
Heap(Ram_allocator &ram, Local_rm &rm) : Heap(&ram, &rm) { }
~Heap();
@ -142,7 +144,7 @@ class Genode::Heap : public Allocator
/**
* Re-assign RAM allocator and region map
*/
void reassign_resources(Ram_allocator *ram, Region_map *rm) {
void reassign_resources(Ram_allocator *ram, Local_rm *rm) {
_ds_pool.reassign_resources(ram, rm); }
/**
@ -182,6 +184,8 @@ class Genode::Sliced_heap : public Allocator
{
private:
using Local_rm = Local::Constrained_region_map;
/**
* Meta-data header placed in front of each allocated block
*/
@ -195,7 +199,7 @@ class Genode::Sliced_heap : public Allocator
};
Ram_allocator &_ram_alloc; /* RAM allocator for backing store */
Region_map &_region_map; /* region map of the address space */
Local_rm &_local_rm; /* region map of the address space */
size_t _consumed = 0; /* number of allocated bytes */
List<Block> _blocks { }; /* list of allocated blocks */
Mutex _mutex { }; /* serialize allocations */
@ -210,7 +214,7 @@ class Genode::Sliced_heap : public Allocator
/**
* Constructor
*/
Sliced_heap(Ram_allocator &ram_alloc, Region_map &region_map);
Sliced_heap(Ram_allocator &ram_alloc, Local_rm &local_rm);
/**
* Destructor

View File

@ -0,0 +1,63 @@
/*
* \brief Interfaces for the component-local environment
* \author Norman Feske
* \date 2025-04-05
*/
/*
* Copyright (C) 2025 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__BASE__LOCAL_H_
#define _INCLUDE__BASE__LOCAL_H_
#include <region_map/region_map.h>
#include <util/allocation.h>
namespace Genode::Local { struct Constrained_region_map; }
/**
* Access to the component-local virtual address space
*/
struct Genode::Local::Constrained_region_map : Interface, Noncopyable
{
struct Attr { void *ptr; size_t num_bytes; };
using Error = Region_map::Attach_error;
using Attachment = Allocation<Constrained_region_map>;
using Result = Attachment::Attempt;
using Attach_attr = Region_map::Attr;
/**
* Map dataspace into local address space
*
* \param ds capability of dataspace to map
* \param attr mapping attributes
*/
virtual Result attach(Capability<Dataspace> ds, Attach_attr const &attr) = 0;
/**
* Unmap attachment from local address space
*
* \noapi
*/
virtual void _free(Attachment &) = 0;
/*
* Emulation of 'Genode::Region_map', ror a gradual API transition
*
* \deprecated
* \noapi
*/
void detach(addr_t addr)
{
/* detach via '~Attachment' */
Attachment { *this, { (void *)addr, 0 } };
}
};
#endif /* _INCLUDE__BASE__LOCAL_H_ */

View File

@ -21,11 +21,13 @@
#include <session/session.h>
#include <region_map/region_map.h>
#include <base/ram_allocator.h>
#include <base/local.h>
namespace Genode {
struct Pd_account;
struct Pd_session;
struct Pd_ram_allocator;
struct Pd_local_rm;
struct Pd_session_client;
struct Parent;
struct Signal_context;
@ -445,4 +447,25 @@ struct Genode::Pd_ram_allocator : Ram_allocator
Pd_ram_allocator(Pd_session &pd) : _pd(pd) { }
};
struct Genode::Pd_local_rm : Genode::Local::Constrained_region_map
{
Region_map &_rm;
Pd_local_rm(Region_map &rm) : _rm(rm) { }
Result attach(Capability<Dataspace> ds, Attach_attr const &attr) override
{
if (!ds.valid())
return Error::INVALID_DATASPACE;
return _rm.attach(ds, attr).convert<Result>(
[&] (Region_map::Range const &r) -> Result {
return { *this, { (void *)r.start, r.num_bytes } }; },
[&] (Error e) { return e; });
}
void _free(Attachment &a) override { _rm.detach(addr_t(a.ptr)); }
};
#endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */

View File

@ -15,6 +15,7 @@
#ifndef _INCLUDE__VM_SESSION__HANDLER_H_
#define _INCLUDE__VM_SESSION__HANDLER_H_
#include <base/env.h>
#include <base/signal.h>
namespace Genode {

View File

@ -62,8 +62,8 @@ _ZN6Genode10Ipc_serverD1Ev T
_ZN6Genode10Ipc_serverD2Ev T
_ZN6Genode11Sliced_heap4freeEPvm T
_ZN6Genode11Sliced_heap9try_allocEm T
_ZN6Genode11Sliced_heapC1ERNS_13Ram_allocatorERNS_10Region_mapE T
_ZN6Genode11Sliced_heapC2ERNS_13Ram_allocatorERNS_10Region_mapE T
_ZN6Genode11Sliced_heapC1ERNS_13Ram_allocatorERNS_5Local22Constrained_region_mapE T
_ZN6Genode11Sliced_heapC2ERNS_13Ram_allocatorERNS_5Local22Constrained_region_mapE T
_ZN6Genode11Sliced_heapD0Ev T
_ZN6Genode11Sliced_heapD1Ev T
_ZN6Genode11Sliced_heapD2Ev T
@ -189,8 +189,8 @@ _ZN6Genode4Heap14Dataspace_poolD1Ev T
_ZN6Genode4Heap14Dataspace_poolD2Ev T
_ZN6Genode4Heap4freeEPvm T
_ZN6Genode4Heap9try_allocEm T
_ZN6Genode4HeapC1EPNS_13Ram_allocatorEPNS_10Region_mapEmPvm T
_ZN6Genode4HeapC2EPNS_13Ram_allocatorEPNS_10Region_mapEmPvm T
_ZN6Genode4HeapC1EPNS_13Ram_allocatorEPNS_5Local22Constrained_region_mapEmPvm T
_ZN6Genode4HeapC2EPNS_13Ram_allocatorEPNS_5Local22Constrained_region_mapEmPvm T
_ZN6Genode4HeapD0Ev T
_ZN6Genode4HeapD1Ev T
_ZN6Genode4HeapD2Ev T
@ -228,8 +228,8 @@ _ZN6Genode5Child7sessionENS_8Id_spaceINS_6Parent6ClientEE2IdERKNS_13Rpc_in_buffe
_ZN6Genode5Child7upgradeENS_8Id_spaceINS_6Parent6ClientEE2IdERKNS_13Rpc_in_bufferILm160EEE T
_ZN6Genode5Child8announceERKNS_13Rpc_in_bufferILm64EEE T
_ZN6Genode5Child9heartbeatEv T
_ZN6Genode5ChildC1ERNS_10Region_mapERNS_14Rpc_entrypointERNS_12Child_policyE T
_ZN6Genode5ChildC2ERNS_10Region_mapERNS_14Rpc_entrypointERNS_12Child_policyE T
_ZN6Genode5ChildC1ERNS_5Local22Constrained_region_mapERNS_14Rpc_entrypointERNS_12Child_policyE T
_ZN6Genode5ChildC2ERNS_5Local22Constrained_region_mapERNS_14Rpc_entrypointERNS_12Child_policyE T
_ZN6Genode5ChildD0Ev T
_ZN6Genode5ChildD1Ev T
_ZN6Genode5ChildD2Ev T

View File

@ -16,21 +16,22 @@
/* core includes */
#include <platform.h>
#include <core_region_map.h>
#include <core_local_rm.h>
#include <dataspace_component.h>
using namespace Core;
Region_map::Attach_result
Core_region_map::attach(Dataspace_capability ds_cap, Attr const &)
Core_local_rm::Result
Core_local_rm::attach(Dataspace_capability ds_cap, Attach_attr const &)
{
return _ep.apply(ds_cap, [] (Dataspace_component *ds) -> Attach_result {
return _ep.apply(ds_cap, [&] (Dataspace_component *ds) -> Result {
if (!ds)
return Attach_error::INVALID_DATASPACE;
return Error::INVALID_DATASPACE;
return Range { .start = ds->phys_addr(), .num_bytes = ds->size() };
return { *this, { (void *)ds->phys_addr(), ds->size() } };
});
}
void Core_region_map::detach(addr_t) { }
void Core_local_rm::_free(Attachment &) { }

View File

@ -251,7 +251,7 @@ Cpu_session_component::Cpu_session_component(Rpc_entrypoint &session_ep,
Label const &label,
Diag const &diag,
Ram_allocator &ram_alloc,
Region_map &local_rm,
Local_rm &local_rm,
Rpc_entrypoint &thread_ep,
Pager_entrypoint &pager_ep,
Trace::Source_registry &trace_sources,

View File

@ -30,7 +30,7 @@ class Core::Core_child : public Child_policy
Registry<Service> &_services;
Rpc_entrypoint &_ep;
Region_map &_core_rm;
Local_rm &_local_rm;
Ram_allocator &_core_ram;
Core_account &_core_account;
@ -42,17 +42,17 @@ class Core::Core_child : public Child_policy
Id_space<Parent::Server> _server_ids { };
Child _child { _core_rm, _ep, *this };
Child _child { _local_rm, _ep, *this };
public:
Core_child(Registry<Service> &services, Rpc_entrypoint &ep,
Region_map &core_rm, Ram_allocator &core_ram,
Local_rm &local_rm, Ram_allocator &core_ram,
Core_account &core_account,
Cpu_session &core_cpu, Capability<Cpu_session> core_cpu_cap,
Cap_quota cap_quota, Ram_quota ram_quota)
:
_services(services), _ep(ep), _core_rm(core_rm), _core_ram(core_ram),
_services(services), _ep(ep), _local_rm(local_rm), _core_ram(core_ram),
_core_account(core_account),
_core_cpu_cap(core_cpu_cap), _core_cpu(core_cpu),
_cap_quota(Child::effective_quota(cap_quota)),

View File

@ -0,0 +1,37 @@
/*
* \brief Core-local region map
* \author Norman Feske
* \date 2006-07-12
*/
/*
* Copyright (C) 2006-2025 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__INCLUDE__CORE_LOCAL_RM_H_
#define _CORE__INCLUDE__CORE_LOCAL_RM_H_
/* Genode includes */
#include <base/local.h>
#include <base/rpc_server.h>
/* core includes */
#include <types.h>
namespace Core { struct Core_local_rm; }
struct Core::Core_local_rm : Local::Constrained_region_map
{
Rpc_entrypoint &_ep;
Core_local_rm(Rpc_entrypoint &ep) : _ep(ep) { }
Result attach(Dataspace_capability, Attach_attr const &) override;
void _free(Attachment &) override;
};
#endif /* _CORE__INCLUDE__CORE_LOCAL_RM_H_ */

View File

@ -1,44 +0,0 @@
/*
* \brief Core-specific region map
* \author Norman Feske
* \date 2006-07-12
*/
/*
* Copyright (C) 2006-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#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 Core { class Core_region_map; }
class Core::Core_region_map : public Region_map
{
private:
Rpc_entrypoint &_ep;
public:
Core_region_map(Rpc_entrypoint &ep) : _ep(ep) { }
Attach_result attach(Dataspace_capability, Attr const &) override;
void detach(addr_t) override;
void fault_handler (Signal_context_capability) override { }
Fault fault() override { return { }; }
Dataspace_capability dataspace() override { return { }; }
};
#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */

View File

@ -28,7 +28,7 @@ class Core::Cpu_root : public Root_component<Cpu_session_component>
private:
Ram_allocator &_ram_alloc;
Region_map &_local_rm;
Local_rm &_local_rm;
Rpc_entrypoint &_thread_ep;
Pager_entrypoint &_pager_ep;
Trace::Source_registry &_trace_sources;
@ -73,7 +73,7 @@ class Core::Cpu_root : public Root_component<Cpu_session_component>
* \param md_alloc meta data allocator to be used by root component
*/
Cpu_root(Ram_allocator &ram_alloc,
Region_map &local_rm,
Local_rm &local_rm,
Rpc_entrypoint &session_ep,
Rpc_entrypoint &thread_ep,
Pager_entrypoint &pager_ep,

View File

@ -43,7 +43,7 @@ class Core::Cpu_session_component : public Session_object<Cpu_session>,
Rpc_entrypoint &_session_ep;
Rpc_entrypoint &_thread_ep;
Pager_entrypoint &_pager_ep;
Region_map &_local_rm;
Local_rm &_local_rm;
Accounted_ram_allocator _ram_alloc;
Sliced_heap _md_alloc; /* guarded meta-data allocator */
Cpu_thread_allocator _thread_alloc; /* meta-data allocator */
@ -150,7 +150,7 @@ class Core::Cpu_session_component : public Session_object<Cpu_session>,
Label const &label,
Diag const &diag,
Ram_allocator &ram_alloc,
Region_map &local_rm,
Local_rm &local_rm,
Rpc_entrypoint &thread_ep,
Pager_entrypoint &pager_ep,
Trace::Source_registry &trace_sources,

View File

@ -118,7 +118,7 @@ class Core::Cpu_thread_component : public Rpc_object<Cpu_thread>,
Cpu_thread_component(Cpu_session_capability cpu_session_cap,
Cpu_session_component &cpu,
Rpc_entrypoint &ep,
Region_map &core_rm,
Local_rm &local_rm,
Pager_entrypoint &pager_ep,
Pd_session_component &pd,
Ram_allocator &cpu_ram,
@ -139,8 +139,8 @@ class Core::Cpu_thread_component : public Rpc_object<Cpu_thread>,
_weight(weight),
_session_label(label), _name(name),
_pd_element(pd_threads, *this),
_platform_thread(platform_pd, ep, cpu_ram, core_rm, quota, name.string(),
priority, location, utcb),
_platform_thread(platform_pd, ep, cpu_ram, local_rm, quota,
name.string(), priority, location, utcb),
_trace_control_slot(trace_control_area.alloc()),
_trace_sources(trace_sources),
_managed_thread_cap(_ep, *this),

View File

@ -32,7 +32,7 @@ class Core::Pd_root : public Root_component<Pd_session_component>
Rpc_entrypoint &_signal_ep;
Pager_entrypoint &_pager_ep;
Range_allocator &_phys_alloc;
Region_map &_local_rm;
Local_rm &_local_rm;
Range_allocator &_core_mem;
System_control &_system_control;
@ -111,7 +111,7 @@ class Core::Pd_root : public Root_component<Pd_session_component>
Rpc_entrypoint &signal_ep,
Pager_entrypoint &pager_ep,
Range_allocator &phys_alloc,
Region_map &local_rm,
Local_rm &local_rm,
Allocator &md_alloc,
Range_allocator &core_mem,
System_control &system_control)

View File

@ -140,7 +140,7 @@ class Core::Pd_session_component : public Session_object<Pd_session>
Phys_range phys_range,
Virt_range virt_range,
Managing_system managing_system,
Region_map &local_rm,
Local_rm &local_rm,
Pager_entrypoint &pager_ep,
char const *args,
Range_allocator &core_mem,

View File

@ -42,7 +42,7 @@ namespace Core {
Registry<Service> &reg,
Trace::Source_registry &trace,
Ram_allocator &core_ram,
Region_map &core_rm,
Local_rm &local_rm,
Range_allocator &io_port_ranges);
}

View File

@ -29,7 +29,7 @@ class Core::Rm_root : public Root_component<Rm_session_component>
private:
Ram_allocator &_ram_alloc;
Region_map &_local_rm;
Local_rm &_local_rm;
Pager_entrypoint &_pager_ep;
protected:
@ -64,7 +64,7 @@ class Core::Rm_root : public Root_component<Rm_session_component>
Rm_root(Rpc_entrypoint &session_ep,
Allocator &md_alloc,
Ram_allocator &ram_alloc,
Region_map &local_rm,
Local_rm &local_rm,
Pager_entrypoint &pager_ep)
:
Root_component<Rm_session_component>(&session_ep, &md_alloc),

View File

@ -48,7 +48,7 @@ class Core::Rm_session_component : public Session_object<Rm_session>
Label const &label,
Diag const &diag,
Ram_allocator &ram_alloc,
Region_map &local_rm,
Local_rm &local_rm,
Pager_entrypoint &pager_ep)
:
Session_object(ep, resources, label, diag),

View File

@ -44,7 +44,7 @@ struct Genode::Trace::Control_area : Noncopyable
return fn(_area->local_addr<Control>()[i]);
}
Control_area(Ram_allocator &ram, Region_map &rm)
Control_area(Ram_allocator &ram, Core::Local_rm &rm)
{
try { _area.construct(ram, rm, SIZE); }
catch (Out_of_ram) { error = Alloc_error::OUT_OF_RAM; }

View File

@ -28,7 +28,7 @@ class Core::Trace::Root : public Root_component<Session_component>
private:
Ram_allocator &_ram;
Region_map &_local_rm;
Local_rm &_local_rm;
Source_registry &_sources;
Policy_registry &_policies;
@ -65,7 +65,7 @@ class Core::Trace::Root : public Root_component<Session_component>
*
* \param session_ep entry point for managing session objects
*/
Root(Ram_allocator &ram, Region_map &local_rm,
Root(Ram_allocator &ram, Local_rm &local_rm,
Rpc_entrypoint &session_ep, Allocator &md_alloc,
Source_registry &sources, Policy_registry &policies)
:

View File

@ -36,7 +36,7 @@ class Core::Trace::Session_component
private:
Accounted_ram_allocator _ram;
Region_map &_local_rm;
Local_rm &_local_rm;
Sliced_heap _md_alloc { _ram, _local_rm };
Tslab<Trace::Subject, 4096> _subjects_slab;
Tslab<Trace::Policy, 4096> _policies_slab;
@ -67,7 +67,7 @@ class Core::Trace::Session_component
Label const &label,
Diag const &diag,
Ram_allocator &ram,
Region_map &local_rm,
Local_rm &local_rm,
size_t arg_buffer_size,
Source_registry &sources,
Policy_registry &policies);

View File

@ -71,7 +71,7 @@ class Core::Trace::Subject
return Setup_result::DENIED;
}
Setup_result _copy_content(Region_map &local_rm, size_t num_bytes,
Setup_result _copy_content(Local_rm &local_rm, size_t num_bytes,
Dataspace_capability from_ds,
Dataspace_capability to_ds)
{
@ -104,7 +104,7 @@ class Core::Trace::Subject
* Clone dataspace into newly allocated dataspace
*/
[[nodiscard]] Setup_result setup(Ram_allocator &ram,
Region_map &local_rm,
Local_rm &local_rm,
Dataspace_capability &from_ds,
size_t size)
{
@ -194,7 +194,7 @@ class Core::Trace::Subject
*/
Trace_result trace(Policy_id policy_id, Dataspace_capability policy_ds,
Policy_size policy_size, Ram_allocator &ram,
Region_map &local_rm, Buffer_size size)
Local_rm &local_rm, Buffer_size size)
{
/* check state and return error if subject is not traceable */
switch(_state()) {

View File

@ -18,6 +18,7 @@
#include <util/reconstructible.h>
#include <util/interface.h>
#include <base/log.h>
#include <base/local.h>
namespace Core {
@ -57,6 +58,8 @@ namespace Core {
Genode::print(out, "(r", w ? "w" : "-", x ? "x" : "-", ")");
}
};
using Local_rm = Local::Constrained_region_map;
}
namespace Genode {

View File

@ -29,7 +29,7 @@ class Core::Vm_root : public Root_component<Vm_session_component>
private:
Ram_allocator &_ram_allocator;
Region_map &_local_rm;
Local_rm &_local_rm;
Trace::Source_registry &_trace_sources;
protected:
@ -71,7 +71,7 @@ class Core::Vm_root : public Root_component<Vm_session_component>
Vm_root(Rpc_entrypoint &session_ep,
Allocator &md_alloc,
Ram_allocator &ram_alloc,
Region_map &local_rm,
Local_rm &local_rm,
Trace::Source_registry &trace_sources)
:
Root_component<Vm_session_component>(&session_ep, &md_alloc),

View File

@ -19,7 +19,7 @@
/* core includes */
#include <platform.h>
#include <core_region_map.h>
#include <core_local_rm.h>
#include <core_service.h>
#include <signal_transmitter.h>
#include <system_control.h>
@ -99,11 +99,11 @@ void Genode::bootstrap_component(Genode::Platform &)
static Core_ram_allocator core_ram { core_ds_factory };
static Core_region_map core_rm { ep };
static Core_local_rm local_rm { ep };
static Rpc_entrypoint &signal_ep = core_signal_ep(ep);
init_exception_handling(core_ram, core_rm);
init_exception_handling(core_ram, local_rm);
init_core_signal_transmitter(signal_ep);
init_page_fault_handling(ep);
@ -120,7 +120,7 @@ void Genode::bootstrap_component(Genode::Platform &)
* Allocate session meta data on distinct dataspaces to enable independent
* destruction (to enable quota trading) of session component objects.
*/
static Sliced_heap sliced_heap { core_ram, core_rm };
static Sliced_heap sliced_heap { core_ram, local_rm };
/*
* Factory for creating RPC capabilities within core
@ -135,16 +135,16 @@ void Genode::bootstrap_component(Genode::Platform &)
static Core::System_control &system_control = init_system_control(sliced_heap, ep);
static Rom_root rom_root (ep, ep, rom_modules, sliced_heap);
static Rm_root rm_root (ep, sliced_heap, core_ram, core_rm, pager_ep);
static Cpu_root cpu_root (core_ram, core_rm, ep, ep, pager_ep,
static Rm_root rm_root (ep, sliced_heap, core_ram, local_rm, pager_ep);
static Cpu_root cpu_root (core_ram, local_rm, ep, ep, pager_ep,
sliced_heap, Core::Trace::sources());
static Pd_root pd_root (ep, signal_ep, pager_ep, ram_ranges, core_rm, sliced_heap,
static Pd_root pd_root (ep, signal_ep, pager_ep, ram_ranges, local_rm, sliced_heap,
platform_specific().core_mem_alloc(),
system_control);
static Log_root log_root (ep, sliced_heap);
static Io_mem_root io_mem_root (ep, ep, io_mem_ranges, ram_ranges, sliced_heap);
static Irq_root irq_root (irq_ranges, sliced_heap);
static Trace_root trace_root (core_ram, core_rm, ep, sliced_heap,
static Trace_root trace_root (core_ram, local_rm, ep, sliced_heap,
Core::Trace::sources(), trace_policies);
static Core_service<Rom_session_component> rom_service (services, rom_root);
@ -158,7 +158,7 @@ void Genode::bootstrap_component(Genode::Platform &)
/* make platform-specific services known to service pool */
platform_add_local_services(ep, sliced_heap, services, Core::Trace::sources(),
core_ram, core_rm, io_port_ranges);
core_ram, local_rm, io_port_ranges);
if (!core_account.ram_account.try_withdraw({ 224*1024 })) {
error("core preservation exceeds available RAM");
@ -179,14 +179,14 @@ void Genode::bootstrap_component(Genode::Platform &)
Session::Resources{{Cpu_session::RAM_QUOTA},
{Cpu_session::CAP_QUOTA}},
"core", Session::Diag{false},
core_ram, core_rm, ep, pager_ep, Core::Trace::sources(), "",
core_ram, local_rm, ep, pager_ep, Core::Trace::sources(), "",
Affinity::unrestricted(), Cpu_session::QUOTA_LIMIT);
log(init_ram_quota.value / (1024*1024), " MiB RAM and ",
init_cap_quota, " caps assigned to init");
static Reconstructible<Core::Core_child>
init(services, ep, core_rm, core_ram, core_account,
init(services, ep, local_rm, core_ram, core_account,
core_cpu, core_cpu.cap(), init_cap_quota, init_ram_quota);
Core::platform().wait_for_exit();

View File

@ -19,6 +19,6 @@ void Core::platform_add_local_services(Rpc_entrypoint &, Sliced_heap &,
Registry<Service> &,
Trace::Source_registry &,
Ram_allocator &,
Region_map &,
Local_rm &,
Range_allocator &)
{ }

View File

@ -29,7 +29,7 @@ void Core::platform_add_local_services(Rpc_entrypoint &,
Registry<Service> &local_services,
Trace::Source_registry &,
Ram_allocator &,
Region_map &,
Local_rm &,
Range_allocator &io_port_ranges)
{
static Io_port_root io_port_root(io_port_ranges, sliced_heap);

View File

@ -172,7 +172,7 @@ Session_component::Session_component(Rpc_entrypoint &ep,
Label const &label,
Diag const &diag,
Ram_allocator &ram,
Region_map &local_rm,
Local_rm &local_rm,
size_t arg_buffer_size,
Source_registry &sources,
Policy_registry &policies)

View File

@ -18,7 +18,10 @@
namespace Genode {
class Region_map;
namespace Local { struct Constrained_region_map; }
using Local_rm = Local::Constrained_region_map;
class Ram_allocator;
class Env;
class Platform;
@ -30,11 +33,11 @@ namespace Genode {
Platform &init_platform();
void init_stack_area();
void init_exception_handling(Ram_allocator &, Region_map &);
void init_exception_handling(Ram_allocator &, Local::Constrained_region_map &);
void init_signal_transmitter(Env &);
void init_signal_receiver(Pd_session &, Parent &);
void init_cap_slab(Pd_session &, Parent &);
void init_cxx_heap(Ram_allocator &, Region_map &);
void init_cxx_heap(Ram_allocator &, Local::Constrained_region_map &);
void init_cxx_guard();
void init_ldso_phdr(Env &);
void init_signal_thread(Env &);
@ -44,7 +47,7 @@ namespace Genode {
void init_rpc_cap_alloc(Parent &);
void init_parent_resource_requests(Env &);
void init_heartbeat_monitoring(Env &);
void init_thread(Cpu_session &, Region_map &);
void init_thread(Cpu_session &, Local_rm &);
void init_thread_start(Capability<Pd_session>);
void init_thread_bootstrap(Cpu_session &, Thread_capability);
void exec_static_constructors();

View File

@ -44,10 +44,11 @@ struct Genode::Platform : Noncopyable
Expanding_cpu_session_client cpu {
parent, _request<Cpu_session>(Parent::Env::cpu()), Parent::Env::cpu() };
Expanding_region_map_client rm {
Expanding_region_map_client pd_rm {
parent, pd.rpc_cap(), pd.address_space(), Parent::Env::pd() };
Pd_ram_allocator ram { pd };
Pd_local_rm local_rm { pd_rm };
Pd_ram_allocator ram { pd };
Attached_stack_area stack_area { parent, pd.rpc_cap() };

View File

@ -771,7 +771,7 @@ void Child::_try_construct_env_dependent_members()
if (_policy.forked()) {
_start_result = Start_result::OK;
} else {
_policy.with_address_space(_pd.session(), [&] (Region_map &address_space) {
_policy.with_address_space(_pd.session(), [&] (Genode::Region_map &address_space) {
_start_result = _start_process(_linker_dataspace(), _pd.session(),
*_initial_thread, _initial_thread_start,
_local_rm, address_space, cap());
@ -922,7 +922,7 @@ void Child::close_all_sessions()
}
Child::Child(Region_map &local_rm,
Child::Child(Local_rm &local_rm,
Rpc_entrypoint &entrypoint,
Child_policy &policy)
:

View File

@ -26,30 +26,24 @@ using namespace Genode;
Child::Load_result Child::_load_static_elf(Dataspace_capability elf_ds,
Ram_allocator &ram,
Region_map &local_rm,
Local_rm &local_rm,
Region_map &remote_rm,
Parent_capability parent_cap)
{
addr_t const elf_addr = local_rm.attach(elf_ds, Region_map::Attr{}).convert<addr_t>(
[&] (Region_map::Range range) { return range.start; },
[&] (Region_map::Attach_error const e) -> addr_t {
if (e == Region_map::Attach_error::INVALID_DATASPACE)
error("dynamic linker is an invalid dataspace");
if (e == Region_map::Attach_error::REGION_CONFLICT)
error("region conflict while attaching dynamic linker");
return 0; });
Local_rm::Result attached_elf = local_rm.attach(elf_ds, { });
if (attached_elf == Local_rm::Error::INVALID_DATASPACE)
error("dynamic linker is an invalid dataspace");
if (attached_elf == Local_rm::Error::REGION_CONFLICT)
error("region conflict while attaching dynamic linker");
addr_t const elf_addr = attached_elf.convert<addr_t>(
[&] (Local_rm::Attachment &a) { return addr_t(a.ptr); },
[&] (Local_rm::Error) { return 0UL; });
if (!elf_addr)
return Load_error::INVALID;
/* detach ELF binary from local address space when leaving the scope */
struct Elf_detach_guard
{
Region_map &local_rm;
addr_t const addr;
~Elf_detach_guard() { local_rm.detach(addr); }
} elf_detach_guard { .local_rm = local_rm, .addr = elf_addr };
Elf_binary elf(elf_addr);
Entry const entry { elf.entry() };
@ -84,71 +78,63 @@ Child::Load_result Child::_load_static_elf(Dataspace_capability elf_ds,
*/
/* alloc dataspace */
Ram_allocator::Result alloc_result = ram.try_alloc(size);
if (alloc_result.failed())
Ram_allocator::Result allocated_rw = ram.try_alloc(size);
if (allocated_rw.failed())
error("allocation of read-write segment failed");
using Alloc_error = Ram_allocator::Alloc_error;
if (allocated_rw == Alloc_error::OUT_OF_RAM) return Load_error::OUT_OF_RAM;
if (allocated_rw == Alloc_error::OUT_OF_CAPS) return Load_error::OUT_OF_CAPS;
if (allocated_rw.failed()) return Load_error::INVALID;
if (alloc_result == Alloc_error::OUT_OF_RAM) return Load_error::OUT_OF_RAM;
if (alloc_result == Alloc_error::OUT_OF_CAPS) return Load_error::OUT_OF_CAPS;
if (alloc_result.failed()) return Load_error::INVALID;
Ram::Capability ds_cap = allocated_rw.convert<Ram::Capability>(
[&] (Ram::Allocation &a) { return a.cap; },
[&] (Alloc_error) { return Ram::Capability(); });
Dataspace_capability ds_cap = alloc_result.convert<Dataspace_capability>(
[&] (Ram::Allocation &allocation) {
allocation.deallocate = false;
return allocation.cap;
},
[&] (Alloc_error) { /* handled above */ return Dataspace_capability(); });
/* attach dataspace */
/* locally attach dataspace for segment */
Region_map::Attr attr { };
attr.writeable = true;
void * const ptr = local_rm.attach(ds_cap, attr).convert<void *>(
[&] (Region_map::Range range) { return (void *)range.start; },
[&] (Region_map::Attach_error const e) {
if (e == Region_map::Attach_error::INVALID_DATASPACE)
error("attempt to attach invalid segment dataspace");
if (e == Region_map::Attach_error::REGION_CONFLICT)
error("region conflict while locally attaching ELF segment");
return nullptr; });
if (!ptr)
Local_rm::Result attached_rw = local_rm.attach(ds_cap, attr);
if (attached_rw == Local_rm::Error::INVALID_DATASPACE)
error("attempt to attach invalid segment dataspace");
if (attached_rw == Local_rm::Error::REGION_CONFLICT)
error("region conflict while locally attaching ELF segment");
if (attached_rw.failed())
return Load_error::INVALID;
addr_t const laddr = elf_addr + seg.file_offset();
attached_rw.with_result([&] (Local_rm::Attachment &dst) {
/* copy contents and fill with zeros */
memcpy(ptr, (void *)laddr, seg.file_size());
if (size > seg.file_size())
memset((void *)((addr_t)ptr + seg.file_size()),
0, size - seg.file_size());
/* copy contents and fill with zeros */
addr_t const src_addr = elf_addr + seg.file_offset();
memcpy(dst.ptr, (void *)src_addr, seg.file_size());
if (size > seg.file_size())
memset((void *)(addr_t(dst.ptr) + seg.file_size()),
0, size - seg.file_size());
/*
* We store the parent information at the beginning of the first
* data segment
*/
if (!parent_info) {
*(Untyped_capability::Raw *)ptr = parent_cap.raw();
parent_info = true;
}
/* detach dataspace */
local_rm.detach(addr_t(ptr));
/*
* We store the parent information at the beginning of the
* first data segment
*/
if (!parent_info) {
*(Untyped_capability::Raw *)dst.ptr = parent_cap.raw();
parent_info = true;
}
}, [&] (Local_rm::Error) { });
auto remote_attach_result = remote_rm.attach(ds_cap, Region_map::Attr {
.size = size,
.offset = { },
.use_at = true,
.at = addr,
.executable = false,
.writeable = true
.size = size, .offset = { },
.use_at = true, .at = addr,
.executable = false, .writeable = true
});
if (remote_attach_result.failed()) {
error("failed to remotely attach writable ELF segment");
error("addr=", (void *)addr, " size=", (void *)size);
return Load_error::INVALID;
}
/* keep allocation */
allocated_rw.with_result([] (Ram::Allocation &a) { a.deallocate = false; },
[] (Alloc_error) { });
} else {
/* read-only segment */
@ -157,12 +143,9 @@ Child::Load_result Child::_load_static_elf(Dataspace_capability elf_ds,
warning("filesz and memsz for read-only segment differ");
auto remote_attach_result = remote_rm.attach(elf_ds, Region_map::Attr {
.size = size,
.offset = seg.file_offset(),
.use_at = true,
.at = addr,
.executable = seg.flags().x,
.writeable = false
.size = size, .offset = seg.file_offset(),
.use_at = true, .at = addr,
.executable = seg.flags().x, .writeable = false
});
if (remote_attach_result.failed()) {
error("failed to remotely attach read-only ELF segment");
@ -209,7 +192,7 @@ Child::Start_result Child::_start_process(Dataspace_capability ldso_ds,
Pd_session &pd,
Initial_thread_base &initial_thread,
Initial_thread::Start &start,
Region_map &local_rm,
Local_rm &local_rm,
Region_map &remote_rm,
Parent_capability parent_cap)
{

View File

@ -42,15 +42,17 @@ struct Genode::Component_env : Env
{
Platform &_platform;
Parent &_parent = _platform.parent;
Pd_session &_pd = _platform.pd;
Cpu_session &_cpu = _platform.cpu;
Region_map &_rm = _platform.rm;
using Local_rm = Local::Constrained_region_map;
Parent &_parent = _platform.parent;
Pd_session &_pd = _platform.pd;
Cpu_session &_cpu = _platform.cpu;
Local_rm &_local_rm = _platform.local_rm;
Capability<Pd_session> _pd_cap = _platform.pd.rpc_cap();
Capability<Cpu_session> _cpu_cap = _platform.cpu.rpc_cap();
Pd_ram_allocator _ram { _pd };
Pd_ram_allocator _ram { _pd };
Entrypoint &_ep;
@ -85,7 +87,7 @@ struct Genode::Component_env : Env
Parent &parent() override { return _parent; }
Cpu_session &cpu() override { return _cpu; }
Region_map &rm() override { return _rm; }
Local_rm &rm() override { return _local_rm; }
Pd_session &pd() override { return _pd; }
Ram_allocator &ram() override { return _ram; }
Entrypoint &ep() override { return _ep; }

View File

@ -44,7 +44,7 @@ void Heap::Dataspace_pool::remove_and_free(Dataspace &ds)
*/
Ram_dataspace_capability ds_cap = ds.cap;
addr_t const at = addr_t(ds.local_addr);
void * const at = ds.local_addr;
size_t const size = ds.size;
remove(&ds);
@ -57,11 +57,12 @@ void Heap::Dataspace_pool::remove_and_free(Dataspace &ds)
*/
ds.~Dataspace();
region_map->detach(at);
{
/* deallocate via '~Allocation' */
Ram::Allocation { *ram_alloc, { ds_cap, size } };
/* detach via '~Attachment' */
Local_rm::Attachment { *local_rm, { at, size } };
}
}
@ -88,72 +89,54 @@ Heap::_allocate_dataspace(size_t size, bool enforce_separate_metadata)
using Result = Alloc_ds_result;
return _ds_pool.ram_alloc->try_alloc(size).convert<Result>(
[&] (Ram::Allocation &allocation) -> Result {
struct Attach_guard
{
Region_map &rm;
Region_map::Range range { };
bool keep = false;
Attach_guard(Region_map &rm) : rm(rm) { }
~Attach_guard() { if (!keep && range.start) rm.detach(range.start); }
} attach_guard(*_ds_pool.region_map);
Region_map::Attr attr { };
Local_rm::Attach_attr attr { };
attr.writeable = true;
Region_map::Attach_result const result = _ds_pool.region_map->attach(allocation.cap, attr);
if (result.failed()) {
using Error = Region_map::Attach_error;
return result.convert<Alloc_error>(
[&] (auto) /* never called */ { return Alloc_error::DENIED; },
[&] (Error e) {
switch (e) {
case Error::OUT_OF_RAM: return Alloc_error::OUT_OF_RAM;
case Error::OUT_OF_CAPS: return Alloc_error::OUT_OF_CAPS;
case Error::REGION_CONFLICT: break;
case Error::INVALID_DATASPACE: break;
}
return Alloc_error::DENIED;
});
}
return _ds_pool.local_rm->attach(allocation.cap, attr).convert<Result>(
[&] (Local_rm::Attachment &attachment) -> Result {
allocation.deallocate = false;
attach_guard.keep = true;
Alloc_result metadata = Alloc_error::DENIED;
result.with_result(
[&] (Region_map::Range range) { attach_guard.range = range; },
[&] (auto) { /* handled above */ });
/* allocate the 'Dataspace' structure */
if (enforce_separate_metadata) {
metadata = _unsynchronized_alloc(sizeof(Heap::Dataspace));
Alloc_result metadata = Alloc_error::DENIED;
} else {
/* allocate the 'Dataspace' structure */
if (enforce_separate_metadata) {
metadata = _unsynchronized_alloc(sizeof(Heap::Dataspace));
/* add new local address range to our local allocator */
_alloc->add_range(addr_t(attachment.ptr), size).with_result(
[&] (Ok) {
metadata = _alloc->alloc_aligned(sizeof(Heap::Dataspace), log2(16U)); },
[&] (Alloc_error error) {
metadata = error; });
}
} else {
return metadata.convert<Result>(
[&] (Allocation &md) -> Result {
md .deallocate = false;
allocation.deallocate = false;
attachment.deallocate = false;
/* add new local address range to our local allocator */
_alloc->add_range(attach_guard.range.start, size).with_result(
[&] (Ok) {
metadata = _alloc->alloc_aligned(sizeof(Heap::Dataspace), log2(16U)); },
[&] (Alloc_error error) {
metadata = error; });
}
return metadata.convert<Result>(
[&] (Allocation &md) -> Result {
md.deallocate = false;
Dataspace &ds = *construct_at<Dataspace>(md.ptr, allocation.cap,
(void *)attach_guard.range.start, size);
_ds_pool.insert(&ds);
return &ds;
Dataspace &ds = *construct_at<Dataspace>(md.ptr, allocation.cap,
attachment.ptr, size);
_ds_pool.insert(&ds);
return &ds;
},
[&] (Alloc_error error) {
return error; });
},
[&] (Alloc_error error) {
return error; });
[&] (Local_rm::Error e) {
using Error = Local_rm::Error;
switch (e) {
case Error::OUT_OF_RAM: return Alloc_error::OUT_OF_RAM;
case Error::OUT_OF_CAPS: return Alloc_error::OUT_OF_CAPS;
case Error::REGION_CONFLICT: break;
case Error::INVALID_DATASPACE: break;
}
return Alloc_error::DENIED;
}
);
},
[&] (Alloc_error error) {
return error; });
@ -317,13 +300,13 @@ void Heap::free(void *addr, size_t)
Heap::Heap(Ram_allocator *ram_alloc,
Region_map *region_map,
Local_rm *local_rm,
size_t quota_limit,
void *static_addr,
size_t static_size)
:
_alloc(nullptr),
_ds_pool(ram_alloc, region_map),
_ds_pool(ram_alloc, local_rm),
_quota_limit(quota_limit), _quota_used(0),
_chunk_size(MIN_CHUNK_SIZE)
{

View File

@ -31,7 +31,7 @@ Platform &Genode::init_platform()
init_log(platform.parent);
init_rpc_cap_alloc(platform.parent);
init_cap_slab(platform.pd, platform.parent);
init_thread(platform.cpu, platform.rm);
init_thread(platform.cpu, platform.local_rm);
init_thread_start(platform.pd.rpc_cap());
init_thread_bootstrap(platform.cpu, platform.parent.main_thread_cap());
init_signal_receiver(platform.pd, platform.parent);

View File

@ -18,9 +18,9 @@
using namespace Genode;
Sliced_heap::Sliced_heap(Ram_allocator &ram_alloc, Region_map &region_map)
Sliced_heap::Sliced_heap(Ram_allocator &ram_alloc, Local_rm &local_rm)
:
_ram_alloc(ram_alloc), _region_map(region_map)
_ram_alloc(ram_alloc), _local_rm(local_rm)
{ }
@ -40,6 +40,8 @@ Sliced_heap::~Sliced_heap()
Allocator::Alloc_result Sliced_heap::try_alloc(size_t requested_size)
{
using Result = Alloc_result;
/* allocation includes space for block meta data and is page-aligned */
size_t const size = align_addr(requested_size + sizeof(Block), 12);
@ -47,55 +49,40 @@ Allocator::Alloc_result Sliced_heap::try_alloc(size_t requested_size)
[&] (Ram::Allocation &allocation) -> Alloc_result {
struct Attach_guard
{
Region_map &rm;
Region_map::Range range { };
bool keep = false;
Attach_guard(Region_map &rm) : rm(rm) { }
~Attach_guard() { if (!keep && range.start) rm.detach(range.start); }
} attach_guard(_region_map);
Region_map::Attr attr { };
Local_rm::Attach_attr attr { };
attr.writeable = true;
Region_map::Attach_result const result = _region_map.attach(allocation.cap, attr);
if (result.failed()) {
using Error = Region_map::Attach_error;
return result.convert<Alloc_error>(
[&] (auto) /* never called */ { return Alloc_error::DENIED; },
[&] (Error e) {
switch (e) {
case Error::OUT_OF_RAM: return Alloc_error::OUT_OF_RAM;
case Error::OUT_OF_CAPS: return Alloc_error::OUT_OF_CAPS;
case Error::REGION_CONFLICT: break;
case Error::INVALID_DATASPACE: break;
}
return Alloc_error::DENIED;
});
}
return _local_rm.attach(allocation.cap, attr).convert<Result>(
result.with_result(
[&] (Region_map::Range range) { attach_guard.range = range; },
[&] (auto) { /* handled above */ });
[&] (Local_rm::Attachment &attachment) -> Result {
/* serialize access to block list */
Mutex::Guard guard(_mutex);
/* serialize access to block list */
Mutex::Guard guard(_mutex);
Block * const block = construct_at<Block>((void *)attach_guard.range.start,
allocation.cap, size);
_consumed += size;
_blocks.insert(block);
Block * const block = construct_at<Block>(attachment.ptr,
allocation.cap, size);
_consumed += size;
_blocks.insert(block);
allocation.deallocate = false;
attach_guard.keep = true;
allocation.deallocate = false;
attachment.deallocate = false;
/* skip meta data prepended to the payload portion of the block */
return { *this, { .ptr = block + 1, .num_bytes = requested_size } };
/* skip meta data prepended to the payload portion of the block */
return { *this, { .ptr = block + 1, .num_bytes = requested_size } };
},
[&] (Local_rm::Error e) {
using Error = Local_rm::Error;
switch (e) {
case Error::OUT_OF_RAM: return Alloc_error::OUT_OF_RAM;
case Error::OUT_OF_CAPS: return Alloc_error::OUT_OF_CAPS;
case Error::REGION_CONFLICT: break;
case Error::INVALID_DATASPACE: break;
}
return Alloc_error::DENIED;
}
);
},
[&] (Ram::Error e) { return e; });
[&] (Alloc_error e) { return e; });
}
@ -129,7 +116,7 @@ void Sliced_heap::free(void *addr, size_t)
block->~Block();
}
_region_map.detach(addr_t(local_addr));
_local_rm.detach(addr_t(local_addr));
{
/* deallocate via '~Allocation' */

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