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
*