diff --git a/repos/base-linux/src/include/base/internal/local_parent.h b/repos/base-linux/src/include/base/internal/local_parent.h index 21d3b566b3..1923b47272 100644 --- a/repos/base-linux/src/include/base/internal/local_parent.h +++ b/repos/base-linux/src/include/base/internal/local_parent.h @@ -44,7 +44,9 @@ class Genode::Local_parent : public Expanding_parent_client { private: - Allocator &_alloc; + Region_map &_local_rm; + Allocator &_alloc; + Id_space _local_sessions_id_space { }; public: @@ -60,11 +62,11 @@ class Genode::Local_parent : public Expanding_parent_client /** * Constructor * - * \param parent_cap real parent capability used to - * promote requests to non-local - * services + * \param parent_cap real parent capability used to direct requests to + * non-local services + * \param local_rm region map of local address space */ - Local_parent(Parent_capability parent_cap, Allocator &); + Local_parent(Parent_capability parent_cap, Region_map &local_rm, Allocator &); }; #endif /* _INCLUDE__BASE__INTERNAL__LOCAL_PARENT_H_ */ diff --git a/repos/base-linux/src/include/base/internal/local_rm_session.h b/repos/base-linux/src/include/base/internal/local_rm_session.h index bbfec0208a..7265fc0cce 100644 --- a/repos/base-linux/src/include/base/internal/local_rm_session.h +++ b/repos/base-linux/src/include/base/internal/local_rm_session.h @@ -28,24 +28,32 @@ namespace Genode { struct Local_rm_session; } struct Genode::Local_rm_session : Rm_session, Local_session { - Allocator &md_alloc; + Region_map &_local_rm; + Allocator &_md_alloc; - Local_rm_session(Allocator &md_alloc, Id_space &id_space, - Parent::Client::Id id) + Local_rm_session(Region_map &local_rm, Allocator &md_alloc, + Id_space &id_space, Parent::Client::Id id) : - Local_session(id_space, id, *this), md_alloc(md_alloc) + Local_session(id_space, id, *this), + _local_rm(local_rm), _md_alloc(md_alloc) { } Capability create(size_t size) override { - Region_map *rm = new (md_alloc) Region_map_mmap(true, size); + Region_map *rm = new (_md_alloc) Region_map_mmap(true, size); return Local_capability::local_cap(rm); } void destroy(Capability cap) override { - Region_map *rm = Local_capability::deref(cap); - Genode::destroy(md_alloc, rm); + Region_map *rm_ptr = Local_capability::deref(cap); + + /* detach sub region map from local address space */ + Region_map_mmap &rm = static_cast(*rm_ptr); + rm.with_attached_sub_rm_base_ptr([&] (void *base_ptr) { + _local_rm.detach(base_ptr); }); + + Genode::destroy(_md_alloc, &rm); } }; diff --git a/repos/base-linux/src/include/base/internal/platform_env.h b/repos/base-linux/src/include/base/internal/platform_env.h index dbd2ea3dc1..455177e4c7 100644 --- a/repos/base-linux/src/include/base/internal/platform_env.h +++ b/repos/base-linux/src/include/base/internal/platform_env.h @@ -28,6 +28,8 @@ #include #include +#include + namespace Genode { class Platform_env_base; class Platform_env; @@ -44,7 +46,7 @@ class Genode::Platform_env_base : public Env_deprecated Cpu_session_capability _cpu_session_cap; Expanding_cpu_session_client _cpu_session_client; - Region_map_mmap _region_map_mmap; + Region_map_mmap &_region_map_mmap; Pd_session_capability _pd_session_cap; protected: @@ -59,28 +61,18 @@ class Genode::Platform_env_base : public Env_deprecated public: - /** - * Constructor - */ - Platform_env_base(Parent &parent, + Platform_env_base(Parent &parent, + Region_map_mmap &local_rm, Cpu_session_capability cpu_cap, Pd_session_capability pd_cap) : _cpu_session_cap(cpu_cap), _cpu_session_client(parent, cpu_cap, Parent::Env::cpu()), - _region_map_mmap(false), + _region_map_mmap(local_rm), _pd_session_cap(pd_cap), _local_pd_session(parent, _pd_session_cap) { } - /** - * Constructor used by 'Core_env' - */ - Platform_env_base(Parent &parent) - : - Platform_env_base(parent, Cpu_session_capability(), Pd_session_capability()) - { } - /****************************** ** Env_deprecated interface ** diff --git a/repos/base-linux/src/include/base/internal/region_map_mmap.h b/repos/base-linux/src/include/base/internal/region_map_mmap.h index b723ea622f..cd9c4e0527 100644 --- a/repos/base-linux/src/include/base/internal/region_map_mmap.h +++ b/repos/base-linux/src/include/base/internal/region_map_mmap.h @@ -19,7 +19,6 @@ #include #include #include -#include /* base-internal includes */ #include @@ -106,11 +105,11 @@ class Genode::Region_map_mmap : public Region_map, public Dataspace Region_map_mmap(bool sub_rm, size_t size = ~0) : _sub_rm(sub_rm), _size(size), _base(0) { } - ~Region_map_mmap() + template + void with_attached_sub_rm_base_ptr(FN const &fn) { - /* detach sub RM session when destructed */ if (_sub_rm && _is_attached()) - env_deprecated()->rm_session()->detach((void *)_base); + fn((void *)_base); } diff --git a/repos/base-linux/src/lib/base/platform_env.cc b/repos/base-linux/src/lib/base/platform_env.cc index 7e8a8d03e2..8d0c5fd78a 100644 --- a/repos/base-linux/src/lib/base/platform_env.cc +++ b/repos/base-linux/src/lib/base/platform_env.cc @@ -67,7 +67,7 @@ Session_capability Local_parent::session(Parent::Client::Id id, if (strcmp(service_name.string(), Rm_session::service_name()) == 0) { Local_rm_session *local_rm_session = new (_alloc) - Local_rm_session(_alloc, _local_sessions_id_space, id); + Local_rm_session(_local_rm, _alloc, _local_sessions_id_space, id); return local_rm_session->local_session_cap(); } @@ -101,9 +101,9 @@ Parent::Close_result Local_parent::close(Client::Id id) Local_parent::Local_parent(Parent_capability parent_cap, - Allocator &alloc) + Region_map &local_rm, Allocator &alloc) : - Expanding_parent_client(parent_cap), _alloc(alloc) + Expanding_parent_client(parent_cap), _local_rm(local_rm), _alloc(alloc) { } @@ -145,16 +145,23 @@ static Parent_capability obtain_parent_cap() } +static Region_map_mmap &local_rm() +{ + static Region_map_mmap local_rm(false); + return local_rm; +} + + Local_parent &Platform_env::_parent() { - static Local_parent local_parent(obtain_parent_cap(), _heap); + static Local_parent local_parent(obtain_parent_cap(), local_rm(), _heap); return local_parent; } Platform_env::Platform_env() : - Platform_env_base(_parent(), + Platform_env_base(_parent(), local_rm(), static_cap_cast(_parent().session_cap(Parent::Env::cpu())), static_cap_cast (_parent().session_cap(Parent::Env::pd()))), _heap(Platform_env_base::pd_session(), Platform_env_base::rm_session())