From 8c66a4b1be286679b881dac68ecfca03025708eb Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Sat, 7 Feb 2015 21:02:50 +0100 Subject: [PATCH] base: support phys range specifier in ram_session Fixes #696 --- repos/base/include/ram_session/connection.h | 37 ++++++++++--------- .../src/core/include/ram_session_component.h | 2 + repos/base/src/core/ram_session_component.cc | 13 ++++++- repos/os/include/init/child.h | 16 ++++++-- repos/os/include/init/child_policy.h | 35 ++++++++++++++++++ 5 files changed, 80 insertions(+), 23 deletions(-) diff --git a/repos/base/include/ram_session/connection.h b/repos/base/include/ram_session/connection.h index b8b877c4b2..85329a55fc 100644 --- a/repos/base/include/ram_session/connection.h +++ b/repos/base/include/ram_session/connection.h @@ -18,23 +18,26 @@ #include namespace Genode { - - struct Ram_connection : Connection, Ram_session_client - { - enum { RAM_QUOTA = 64*1024 }; - /** - * Constructor - * - * \param label session label - */ - Ram_connection(const char *label = "") - : - Connection( - session("ram_quota=64K, label=\"%s\"", label)), - - Ram_session_client(cap()) - { } - }; + struct Ram_connection; } +struct Genode::Ram_connection : Connection, Ram_session_client +{ + enum { RAM_QUOTA = 64*1024 }; + /** + * Constructor + * + * \param label session label + */ + Ram_connection(const char *label = "", unsigned long phys_start = 0UL, + unsigned long phys_size = 0UL) + : + Connection( + session("ram_quota=64K, phys_start=0x%lx, phys_size=0x%lx, " + "label=\"%s\"", phys_start, phys_size, label)), + + Ram_session_client(cap()) + { } +}; + #endif /* _INCLUDE__RAM_SESSION__CONNECTION_H_ */ diff --git a/repos/base/src/core/include/ram_session_component.h b/repos/base/src/core/include/ram_session_component.h index 8204ed6841..0c6c031a6f 100644 --- a/repos/base/src/core/include/ram_session_component.h +++ b/repos/base/src/core/include/ram_session_component.h @@ -51,6 +51,8 @@ namespace Genode { Allocator_guard _md_alloc; /* guarded meta-data allocator */ Ds_slab _ds_slab; /* meta-data allocator */ Ram_session_component *_ref_account; /* reference ram session */ + addr_t _phys_start; + addr_t _phys_end; enum { MAX_LABEL_LEN = 64 }; char _label[MAX_LABEL_LEN]; diff --git a/repos/base/src/core/ram_session_component.cc b/repos/base/src/core/ram_session_component.cc index db67484dc9..13b89e1265 100644 --- a/repos/base/src/core/ram_session_component.cc +++ b/repos/base/src/core/ram_session_component.cc @@ -146,7 +146,8 @@ Ram_dataspace_capability Ram_session_component::alloc(size_t ds_size, Cache_attr void *ds_addr = 0; bool alloc_succeeded = false; for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { - if (_ram_alloc->alloc_aligned(ds_size, &ds_addr, align_log2).is_ok()) { + if (_ram_alloc->alloc_aligned(ds_size, &ds_addr, align_log2, + _phys_start, _phys_end).is_ok()) { alloc_succeeded = true; break; } @@ -265,9 +266,17 @@ Ram_session_component::Ram_session_component(Rpc_entrypoint *ds_ep, _ds_ep(ds_ep), _ram_session_ep(ram_session_ep), _ram_alloc(ram_alloc), _quota_limit(quota_limit), _payload(0), _md_alloc(md_alloc, Arg_string::find_arg(args, "ram_quota").long_value(0)), - _ds_slab(&_md_alloc), _ref_account(0) + _ds_slab(&_md_alloc), _ref_account(0), + _phys_start(Arg_string::find_arg(args, "phys_start").long_value(0)) { Arg_string::find_arg(args, "label").string(_label, sizeof(_label), ""); + + size_t phys_size = Arg_string::find_arg(args, "phys_size").long_value(0); + /* sanitize overflow and interpret phys_size==0 as maximum phys address */ + if (_phys_start + phys_size <= _phys_start) + _phys_end = ~0UL; + else + _phys_end = _phys_start + phys_size - 1; } diff --git a/repos/os/include/init/child.h b/repos/os/include/init/child.h index 9a30d00c7b..03d24edc51 100644 --- a/repos/os/include/init/child.h +++ b/repos/os/include/init/child.h @@ -396,17 +396,21 @@ namespace Init { Genode::printf(" Proceeding with a quota of %zu.\n", avail); } - Read_quota(Genode::Xml_node start_node, Genode::size_t & ram_quota, - Genode::size_t & cpu_quota) + Read_quota(Genode::Xml_node start_node, + Genode::size_t & ram_quota, + Genode::size_t & cpu_quota, + bool & constrain_phys) { Genode::Number_of_bytes ram_bytes = 0; Genode::size_t cpu_percent = 0; + try { Genode::Xml_node rsc = start_node.sub_node("resource"); for (;; rsc = rsc.next("resource")) { try { if (rsc.attribute("name").has_value("RAM")) { rsc.attribute("quantum").value(&ram_bytes); + constrain_phys = rsc.attribute("constrain_phys").has_value("yes"); } else if (rsc.attribute("name").has_value("CPU")) { rsc.attribute("quantum").value(&cpu_percent); } } catch (...) { } @@ -445,6 +449,7 @@ namespace Init { Genode::Affinity affinity; Genode::size_t ram_quota; Genode::size_t cpu_quota; + bool constrain_phys; Genode::Ram_connection ram; Genode::Cpu_connection cpu; Genode::Rm_connection rm; @@ -453,7 +458,7 @@ namespace Init { long prio_levels_log2, Genode::Affinity::Space const &affinity_space) : - Read_quota(start_node, ram_quota, cpu_quota), + Read_quota(start_node, ram_quota, cpu_quota, constrain_phys), prio_levels_log2(prio_levels_log2), priority(read_priority(start_node)), affinity(affinity_space, @@ -517,6 +522,7 @@ namespace Init { Init::Child_policy_provide_rom_file _binary_policy; Init::Child_policy_redirect_rom_file _configfile_policy; Init::Child_policy_pd_args _pd_args_policy; + Init::Child_policy_ram_phys _ram_session_policy; public: @@ -550,7 +556,8 @@ namespace Init { _config_policy("config", _config.dataspace(), &_entrypoint), _binary_policy("binary", _binary_rom_ds, &_entrypoint), _configfile_policy("config", _config.filename()), - _pd_args_policy(&_pd_args) + _pd_args_policy(&_pd_args), + _ram_session_policy(_resources.constrain_phys) { using namespace Genode; @@ -706,6 +713,7 @@ namespace Init { _priority_policy. filter_session_args(service, args, args_len); _configfile_policy.filter_session_args(service, args, args_len); _pd_args_policy. filter_session_args(service, args, args_len); + _ram_session_policy.filter_session_args(service, args, args_len); } Genode::Affinity filter_session_affinity(Genode::Affinity const &session_affinity) diff --git a/repos/os/include/init/child_policy.h b/repos/os/include/init/child_policy.h index 1d98f1233f..8bddf90d05 100644 --- a/repos/os/include/init/child_policy.h +++ b/repos/os/include/init/child_policy.h @@ -23,6 +23,41 @@ namespace Init { + class Child_policy_ram_phys + { + private: + + bool _constrain_phys; + + public: + + Child_policy_ram_phys(bool constrain_phys) + : _constrain_phys(constrain_phys) { } + + /** + * Filter arguments of session request + * + * This function removes phys_start and phys_size ram_session + * parameters if the child configuration does not explicitly + * permits this. + */ + void filter_session_args(const char *service, char *args, + Genode::size_t args_len) + { + using namespace Genode; + + /* intercept only RAM session requests */ + if (Genode::strcmp(service, "RAM")) + return; + + if (_constrain_phys) + return; + + Arg_string::remove_arg(args, "phys_start"); + Arg_string::remove_arg(args, "phys_size"); + } + }; + /** * Policy for prepending the child name to the 'label' argument *