mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-12 21:53:28 +00:00
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:
parent
8c4bd7d9da
commit
1ef80e86e2
@ -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)
|
||||
|
@ -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) { }
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 &)
|
||||
:
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
@ -217,9 +217,9 @@ class Core::Guest_memory
|
||||
}
|
||||
|
||||
|
||||
Guest_memory(Accounted_ram_allocator &ram, Region_map ®ion_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())
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
);
|
||||
|
@ -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 ®ion_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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -63,15 +63,15 @@ Vm_session_component::Vm_session_component(Vmid_allocator &vmids, Rpc_entrypoint
|
||||
Label const &,
|
||||
Diag,
|
||||
Ram_allocator &ram_alloc,
|
||||
Region_map ®ion_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--;
|
||||
|
@ -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 ®ion_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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 ®ion_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();
|
||||
|
@ -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 ®ion_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();
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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_ */
|
@ -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) { }
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 &)
|
||||
{ }
|
||||
|
@ -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)) {
|
||||
|
@ -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(); }
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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>) { }
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)),
|
||||
|
@ -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)
|
||||
:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 \
|
||||
|
@ -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 &) { }
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
:
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ®ion_map);
|
||||
Sliced_heap(Ram_allocator &ram_alloc, Local_rm &local_rm);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
|
63
repos/base/include/base/local.h
Normal file
63
repos/base/include/base/local.h
Normal 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_ */
|
@ -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_ */
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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 &) { }
|
@ -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,
|
||||
|
@ -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)),
|
||||
|
37
repos/base/src/core/include/core_local_rm.h
Normal file
37
repos/base/src/core/include/core_local_rm.h
Normal 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_ */
|
@ -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_ */
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -42,7 +42,7 @@ namespace Core {
|
||||
Registry<Service> ®,
|
||||
Trace::Source_registry &trace,
|
||||
Ram_allocator &core_ram,
|
||||
Region_map &core_rm,
|
||||
Local_rm &local_rm,
|
||||
Range_allocator &io_port_ranges);
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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; }
|
||||
|
@ -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)
|
||||
:
|
||||
|
@ -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);
|
||||
|
@ -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()) {
|
||||
|
@ -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 {
|
||||
|
@ -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),
|
||||
|
@ -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();
|
||||
|
@ -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 &)
|
||||
{ }
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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() };
|
||||
|
||||
|
@ -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)
|
||||
:
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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; }
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -18,9 +18,9 @@
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Sliced_heap::Sliced_heap(Ram_allocator &ram_alloc, Region_map ®ion_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
Loading…
x
Reference in New Issue
Block a user