diff --git a/repos/base-fiasco/lib/mk/base-common.mk b/repos/base-fiasco/lib/mk/base-common.mk index 2920278b0e..a0a4c7daa8 100644 --- a/repos/base-fiasco/lib/mk/base-common.mk +++ b/repos/base-fiasco/lib/mk/base-common.mk @@ -23,6 +23,7 @@ SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc SRC_CC += thread/myself.cc SRC_CC += thread/stack_allocator.cc SRC_CC += sleep.cc +SRC_CC += region_map_client.cc SRC_CC += rm_session_client.cc SRC_CC += entrypoint/entrypoint.cc SRC_CC += component/component.cc diff --git a/repos/base-fiasco/src/core/include/platform_pd.h b/repos/base-fiasco/src/core/include/platform_pd.h index 6878e13690..a6ae468a1b 100644 --- a/repos/base-fiasco/src/core/include/platform_pd.h +++ b/repos/base-fiasco/src/core/include/platform_pd.h @@ -187,7 +187,7 @@ namespace Genode { /* * On L4/Fiasco, we don't use directed unmap but rely on the - * in-kernel mapping database. See 'rm_session_support.cc'. + * in-kernel mapping database. See 'region_map_support.cc'. */ void flush(addr_t, size_t) { PDBG("not implemented"); } }; diff --git a/repos/base-fiasco/src/core/include/platform_thread.h b/repos/base-fiasco/src/core/include/platform_thread.h index 52330036ee..4d157f152d 100644 --- a/repos/base-fiasco/src/core/include/platform_thread.h +++ b/repos/base-fiasco/src/core/include/platform_thread.h @@ -107,6 +107,15 @@ namespace Genode { */ void unbind(); + /** + * Return pointer to the thread's PD + * + * Used to validate the success of the bind operation. + * + * XXX to be removed + */ + Platform_pd *pd() { return _platform_pd; } + /** * Override thread state with 's' * diff --git a/repos/base-fiasco/src/core/include/util.h b/repos/base-fiasco/src/core/include/util.h index 6f927b1545..23c729025a 100644 --- a/repos/base-fiasco/src/core/include/util.h +++ b/repos/base-fiasco/src/core/include/util.h @@ -19,7 +19,7 @@ /* Genode includes */ #include #include -#include +#include #include /* base-internal includes */ @@ -100,13 +100,13 @@ namespace Genode { constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; } inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, - Rm_session::Fault_type pf_type, + Region_map::State::Fault_type pf_type, unsigned long badge) { Fiasco::l4_threadid_t tid; tid.raw = badge; printf("%s (%s pf_addr=%p pf_ip=%p from %x.%02x)\n", msg, - pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", + pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ", (void *)pf_addr, (void *)pf_ip, (int)tid.id.task, (int)tid.id.lthread); } diff --git a/repos/base-fiasco/src/core/rm_session_support.cc b/repos/base-fiasco/src/core/region_map_support.cc similarity index 100% rename from repos/base-fiasco/src/core/rm_session_support.cc rename to repos/base-fiasco/src/core/region_map_support.cc diff --git a/repos/base-fiasco/src/core/target.inc b/repos/base-fiasco/src/core/target.inc index a087fb25a7..85266de735 100644 --- a/repos/base-fiasco/src/core/target.inc +++ b/repos/base-fiasco/src/core/target.inc @@ -28,8 +28,8 @@ SRC_CC += stack_area.cc \ platform_thread.cc \ ram_session_component.cc \ ram_session_support.cc \ - rm_session_component.cc \ - rm_session_support.cc \ + region_map_component.cc \ + region_map_support.cc \ rom_session_component.cc \ signal_source_component.cc \ thread_start.cc \ @@ -56,7 +56,7 @@ vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) -vpath rm_session_component.cc $(GEN_CORE_DIR) +vpath region_map_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-foc/lib/mk/base-common.inc b/repos/base-foc/lib/mk/base-common.inc index 5c2ecd6334..30b7d61d2a 100644 --- a/repos/base-foc/lib/mk/base-common.inc +++ b/repos/base-foc/lib/mk/base-common.inc @@ -24,6 +24,7 @@ SRC_CC += thread/myself.cc SRC_CC += thread/stack_allocator.cc SRC_CC += thread/thread_utcb.cc SRC_CC += sleep.cc +SRC_CC += region_map_client.cc SRC_CC += rm_session_client.cc SRC_CC += entrypoint/entrypoint.cc SRC_CC += component/component.cc diff --git a/repos/base-foc/src/base/thread/thread_start.cc b/repos/base-foc/src/base/thread/thread_start.cc index ae337590b5..8aee5ecc5e 100644 --- a/repos/base-foc/src/base/thread/thread_start.cc +++ b/repos/base-foc/src/base/thread/thread_start.cc @@ -59,7 +59,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type) if (!_thread_cap.valid()) throw Cpu_session::Thread_creation_failed(); - env()->pd_session()->bind_thread(_thread_cap); + env()->pd_session()->bind_thread(_thread_cap); return; } /* adjust values whose computation differs for a main thread */ @@ -80,7 +80,11 @@ void Thread_base::start() using namespace Fiasco; /* create new pager object and assign it to the new thread */ - _pager_cap = env()->rm_session()->add_client(_thread_cap); + try { + _pager_cap = env()->rm_session()->add_client(_thread_cap); + } catch (Region_map::Unbound_thread) { + throw Cpu_session::Thread_creation_failed(); } + _cpu_session->set_pager(_thread_cap, _pager_cap); /* get gate-capability and badge of new thread */ diff --git a/repos/base-foc/src/core/include/platform_pd.h b/repos/base-foc/src/core/include/platform_pd.h index 7a19ee4778..b80343efe8 100644 --- a/repos/base-foc/src/core/include/platform_pd.h +++ b/repos/base-foc/src/core/include/platform_pd.h @@ -110,7 +110,7 @@ namespace Genode { /* * On Fiasco.OC, we don't use directed unmap but rely on the - * in-kernel mapping database. See 'rm_session_support.cc'. + * in-kernel mapping database. See 'region_map_support.cc'. */ void flush(addr_t, size_t) { PDBG("not implemented"); } }; diff --git a/repos/base-foc/src/core/include/platform_thread.h b/repos/base-foc/src/core/include/platform_thread.h index b200b0362d..6564de4894 100644 --- a/repos/base-foc/src/core/include/platform_thread.h +++ b/repos/base-foc/src/core/include/platform_thread.h @@ -125,6 +125,15 @@ namespace Genode { */ void unbind(); + /** + * Return pointer to the thread's PD + * + * Used to validate the success of the bind operation. + * + * XXX to be removed + */ + Platform_pd *pd() { return _platform_pd; } + /** * Override thread state with 's' * diff --git a/repos/base-foc/src/core/include/util.h b/repos/base-foc/src/core/include/util.h index 45388fd219..50a264b569 100644 --- a/repos/base-foc/src/core/include/util.h +++ b/repos/base-foc/src/core/include/util.h @@ -97,11 +97,11 @@ namespace Genode { constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; } inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, - Rm_session::Fault_type pf_type, + Region_map::State::Fault_type pf_type, unsigned long badge) { printf("%s (%s pf_addr=%p pf_ip=%p from %lx)\n", msg, - pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", + pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ", (void *)pf_addr, (void *)pf_ip, badge); } diff --git a/repos/base-foc/src/core/rm_session_support.cc b/repos/base-foc/src/core/region_map_support.cc similarity index 100% rename from repos/base-foc/src/core/rm_session_support.cc rename to repos/base-foc/src/core/region_map_support.cc diff --git a/repos/base-foc/src/core/target.inc b/repos/base-foc/src/core/target.inc index 7e8d67f097..68fff85974 100644 --- a/repos/base-foc/src/core/target.inc +++ b/repos/base-foc/src/core/target.inc @@ -32,8 +32,8 @@ SRC_CC += stack_area.cc \ platform_thread.cc \ ram_session_component.cc \ ram_session_support.cc \ - rm_session_component.cc \ - rm_session_support.cc \ + region_map_component.cc \ + region_map_support.cc \ rom_session_component.cc \ signal_source_component.cc \ thread_start.cc \ @@ -59,7 +59,7 @@ vpath pd_session_component.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath ram_session_component.cc $(GEN_CORE_DIR) -vpath rm_session_component.cc $(GEN_CORE_DIR) +vpath region_map_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) diff --git a/repos/base-hw/include/pd_session/connection.h b/repos/base-hw/include/pd_session/connection.h deleted file mode 100644 index 1d42c5a403..0000000000 --- a/repos/base-hw/include/pd_session/connection.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * \brief Connection to PD service - * \author Stefan Kalkowski - * \author Norman Feske - * \date 2015-05-20 - * - * This is a shadow copy of the generic header in base, - * due to higher memory donation requirements in base-hw - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _INCLUDE__PD_SESSION__CONNECTION_H_ -#define _INCLUDE__PD_SESSION__CONNECTION_H_ - -#include -#include - -namespace Genode { struct Pd_connection; } - - -struct Genode::Pd_connection : Connection, Pd_session_client -{ - enum { RAM_QUOTA = 36*1024 }; - - /** - * Constructor - * - * \param label session label - */ - Pd_connection(char const *label = "") - : Connection(session("ram_quota=%u, label=\"%s\"", - RAM_QUOTA, label)), - Pd_session_client(cap()) { } -}; - -#endif /* _INCLUDE__PD_SESSION__CONNECTION_H_ */ diff --git a/repos/base-hw/lib/mk/base-common.inc b/repos/base-hw/lib/mk/base-common.inc index 570bd1c738..b371cfa03e 100644 --- a/repos/base-hw/lib/mk/base-common.inc +++ b/repos/base-hw/lib/mk/base-common.inc @@ -28,6 +28,7 @@ SRC_CC += thread/trace.cc SRC_CC += thread/stack_allocator.cc SRC_CC += kernel/interface.cc SRC_CC += sleep.cc +SRC_CC += region_map_client.cc SRC_CC += rm_session_client.cc SRC_CC += entrypoint/entrypoint.cc SRC_CC += component/component.cc diff --git a/repos/base-hw/lib/mk/core.inc b/repos/base-hw/lib/mk/core.inc index 9912106da9..75420f562b 100644 --- a/repos/base-hw/lib/mk/core.inc +++ b/repos/base-hw/lib/mk/core.inc @@ -18,7 +18,7 @@ INC_DIR += $(REP_DIR)/src/include $(BASE_DIR)/src/include SRC_CC += console.cc SRC_CC += cpu_session_component.cc SRC_CC += cpu_session_support.cc -SRC_CC += core_rm_session.cc +SRC_CC += core_region_map.cc SRC_CC += core_mem_alloc.cc SRC_CC += core_rpc_cap_alloc.cc SRC_CC += dataspace_component.cc @@ -36,12 +36,12 @@ SRC_CC += platform_thread.cc SRC_CC += stack_area.cc SRC_CC += ram_session_component.cc SRC_CC += ram_session_support.cc -SRC_CC += rm_session_component.cc +SRC_CC += region_map_component.cc SRC_CC += rom_session_component.cc SRC_CC += trace_session_component.cc SRC_CC += thread_start.cc SRC_CC += env.cc -SRC_CC += rm_session_support.cc +SRC_CC += region_map_support.cc SRC_CC += pager.cc SRC_CC += _main.cc SRC_CC += component_construct.cc diff --git a/repos/base-hw/src/base/thread/start.cc b/repos/base-hw/src/base/thread/start.cc index 3341b42dcd..178ac5eb9e 100644 --- a/repos/base-hw/src/base/thread/start.cc +++ b/repos/base-hw/src/base/thread/start.cc @@ -21,11 +21,10 @@ /* base-internal includes */ #include #include +#include using namespace Genode; -namespace Genode { extern Rm_session * const env_stack_area_rm_session; } - namespace Hw { extern Ram_dataspace_capability _main_thread_utcb_ds; extern Untyped_capability _main_thread_cap; @@ -51,7 +50,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type) size_t const utcb_size = sizeof(Native_utcb); addr_t const stack_area = stack_area_virtual_base(); addr_t const utcb_new = (addr_t)&_stack->utcb() - stack_area; - Rm_session * const rm = env_stack_area_rm_session; + Region_map * const rm = env_stack_area_region_map; if (type == REINITIALIZED_MAIN) { rm->detach(utcb_new); } @@ -78,7 +77,7 @@ void Thread_base::_deinit_platform_thread() size_t const size = sizeof(_stack->utcb()); addr_t utcb = Stack_allocator::addr_to_base(_stack) + stack_virtual_size() - size - stack_area_virtual_base(); - env_stack_area_rm_session->detach(utcb); + env_stack_area_region_map->detach(utcb); if (_pager_cap.valid()) { env()->rm_session()->remove_client(_pager_cap); @@ -101,7 +100,7 @@ void Thread_base::start() size_t const size = sizeof(_stack->utcb()); addr_t dst = Stack_allocator::addr_to_base(_stack) + stack_virtual_size() - size - stack_area_virtual_base(); - env_stack_area_rm_session->attach_at(ds, dst, size); + env_stack_area_region_map->attach_at(ds, dst, size); } catch (...) { PERR("failed to attach userland stack"); sleep_forever(); diff --git a/repos/base-hw/src/core/core_rm_session.cc b/repos/base-hw/src/core/core_region_map.cc similarity index 91% rename from repos/base-hw/src/core/core_rm_session.cc rename to repos/base-hw/src/core/core_region_map.cc index 398c8f0143..1ad0c25f86 100644 --- a/repos/base-hw/src/core/core_rm_session.cc +++ b/repos/base-hw/src/core/core_region_map.cc @@ -16,17 +16,17 @@ /* core includes */ #include -#include +#include #include #include #include using namespace Genode; -Rm_session::Local_addr -Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, +Region_map::Local_addr +Core_region_map::attach(Dataspace_capability ds_cap, size_t size, off_t offset, bool use_local_addr, - Rm_session::Local_addr, bool executable) + Region_map::Local_addr, bool executable) { auto lambda = [&] (Dataspace_component *ds) -> Local_addr { if (!ds) diff --git a/repos/base-hw/src/core/include/core_region_map.h b/repos/base-hw/src/core/include/core_region_map.h new file mode 100644 index 0000000000..176cf06d01 --- /dev/null +++ b/repos/base-hw/src/core/include/core_region_map.h @@ -0,0 +1,57 @@ +/* + * \brief Kernel-specific core-local region map + * \author Norman Feske + * \author Stefan Kalkowski + * \date 2009-04-02 + */ + +/* + * Copyright (C) 2009-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _CORE__INCLUDE__CORE_REGION_MAP_H_ +#define _CORE__INCLUDE__CORE_REGION_MAP_H_ + +/* Genode includes */ +#include +#include + +/* core includes */ +#include + +namespace Genode { class Core_region_map; } + + +class Genode::Core_region_map : public Region_map +{ + private: + + Rpc_entrypoint *_ds_ep; + + public: + + Core_region_map(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } + + Local_addr attach(Dataspace_capability ds_cap, size_t size=0, + off_t offset=0, bool use_local_addr = false, + Local_addr local_addr = 0, + bool executable = false); + + void detach(Local_addr) { } + + Pager_capability add_client(Thread_capability thread) { + return Pager_capability(); } + + void remove_client(Pager_capability) { } + + void fault_handler(Signal_context_capability handler) { } + + State state() { return State(); } + + Dataspace_capability dataspace() { return Dataspace_capability(); } +}; + +#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */ diff --git a/repos/base-hw/src/core/include/core_rm_session.h b/repos/base-hw/src/core/include/core_rm_session.h deleted file mode 100644 index 58a7e000a9..0000000000 --- a/repos/base-hw/src/core/include/core_rm_session.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * \brief OKL4-specific core-local region manager session - * \author Norman Feske - * \author Stefan Kalkowski - * \date 2009-04-02 - */ - -/* - * Copyright (C) 2009-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__CORE_RM_SESSION_H_ -#define _CORE__INCLUDE__CORE_RM_SESSION_H_ - -/* Genode includes */ -#include -#include - -/* core includes */ -#include - -namespace Genode { - - /** - * Region manager that uses the physical dataspace - * addresses directly as virtual addresses. - */ - class Core_rm_session : public Rm_session - { - private: - - Rpc_entrypoint *_ds_ep; - - public: - - Core_rm_session(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } - - Local_addr attach(Dataspace_capability ds_cap, size_t size=0, - off_t offset=0, bool use_local_addr = false, - Local_addr local_addr = 0, - bool executable = false); - - void detach(Local_addr) { } - - Pager_capability add_client(Thread_capability thread) { - return Pager_capability(); } - - void remove_client(Pager_capability) { } - - void fault_handler(Signal_context_capability handler) { } - - State state() { return State(); } - - Dataspace_capability dataspace() { return Dataspace_capability(); } - }; -} - -#endif /* _CORE__INCLUDE__CORE_RM_SESSION_H_ */ diff --git a/repos/base-hw/src/core/include/platform.h b/repos/base-hw/src/core/include/platform.h index 6b68a03ef0..25b267caf1 100644 --- a/repos/base-hw/src/core/include/platform.h +++ b/repos/base-hw/src/core/include/platform.h @@ -28,7 +28,7 @@ /* core includes */ #include #include -#include +#include #include namespace Genode { diff --git a/repos/base-hw/src/core/include/util.h b/repos/base-hw/src/core/include/util.h index bfdd0499a6..9704d862ca 100644 --- a/repos/base-hw/src/core/include/util.h +++ b/repos/base-hw/src/core/include/util.h @@ -114,7 +114,7 @@ namespace Genode inline void print_page_fault(char const * const fault_msg, addr_t const fault_addr, addr_t const fault_ip, - Rm_session::Fault_type const fault_type, + Region_map::State::Fault_type const fault_type, unsigned const faulter_badge); } @@ -122,14 +122,14 @@ namespace Genode void Genode::print_page_fault(char const * const fault_msg, addr_t const fault_addr, addr_t const fault_ip, - Rm_session::Fault_type const fault_type, + Region_map::State::Fault_type const fault_type, unsigned const faulter_badge) { const char read[] = "read from"; const char write[] = "write to"; printf("\033[31m%s\033[0m (faulter %x", fault_msg, faulter_badge); printf(" with IP %p attempts to", (void *)fault_ip); - printf(" %s", fault_type == Rm_session::READ_FAULT ? read : write); + printf(" %s", fault_type == Region_map::State::READ_FAULT ? read : write); printf(" address %p)\n", (void *)fault_addr); if (ACTIVITY_TABLE_ON_FAULTS) { printf("---------- activity table ----------\n"); diff --git a/repos/base-hw/src/core/rm_session_support.cc b/repos/base-hw/src/core/region_map_support.cc similarity index 100% rename from repos/base-hw/src/core/rm_session_support.cc rename to repos/base-hw/src/core/region_map_support.cc diff --git a/repos/base-linux/lib/mk/base-common.mk b/repos/base-linux/lib/mk/base-common.mk index 18575c4619..e73a0e6294 100644 --- a/repos/base-linux/lib/mk/base-common.mk +++ b/repos/base-linux/lib/mk/base-common.mk @@ -16,12 +16,13 @@ SRC_CC += child/child.cc SRC_CC += process/process.cc SRC_CC += elf/elf_binary.cc SRC_CC += lock/lock.cc -SRC_CC += env/rm_session_mmap.cc env/debug.cc +SRC_CC += env/region_map_mmap.cc env/debug.cc SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc SRC_CC += server/server.cc server/common.cc SRC_CC += thread/trace.cc thread/thread_env.cc thread/stack_allocator.cc SRC_CC += irq/platform.cc SRC_CC += sleep.cc +SRC_CC += region_map_client.cc SRC_CC += rm_session_client.cc SRC_CC += entrypoint/entrypoint.cc SRC_CC += component/component.cc diff --git a/repos/base-linux/run/rm_session_mmap.run b/repos/base-linux/run/region_map_mmap.run similarity index 83% rename from repos/base-linux/run/rm_session_mmap.run rename to repos/base-linux/run/region_map_mmap.run index 6ac885b2c1..3dde49d0c3 100644 --- a/repos/base-linux/run/rm_session_mmap.run +++ b/repos/base-linux/run/region_map_mmap.run @@ -1,4 +1,4 @@ -build "core init test/rm_session_mmap drivers/timer test/signal" +build "core init test/region_map_mmap drivers/timer test/signal" create_boot_directory @@ -20,7 +20,7 @@ install_config { - + @@ -34,7 +34,7 @@ install_config { } -build_boot_image "core init test-rm_session_mmap timer test-signal" +build_boot_image "core init test-region_map_mmap timer test-signal" run_genode_until forever diff --git a/repos/base-linux/src/base/env/platform_env.cc b/repos/base-linux/src/base/env/platform_env.cc index 12afea271f..5e91ac7ac4 100644 --- a/repos/base-linux/src/base/env/platform_env.cc +++ b/repos/base-linux/src/base/env/platform_env.cc @@ -29,7 +29,7 @@ using namespace Genode; ****************************************************/ Genode::size_t -Platform_env_base::Rm_session_mmap::_dataspace_size(Dataspace_capability ds) +Platform_env_base::Region_map_mmap::_dataspace_size(Dataspace_capability ds) { if (ds.valid()) return Dataspace_client(ds).size(); @@ -38,19 +38,20 @@ Platform_env_base::Rm_session_mmap::_dataspace_size(Dataspace_capability ds) } -int Platform_env_base::Rm_session_mmap::_dataspace_fd(Dataspace_capability ds) +int Platform_env_base::Region_map_mmap::_dataspace_fd(Dataspace_capability ds) { return Linux_dataspace_client(ds).fd().dst().socket; } bool -Platform_env_base::Rm_session_mmap::_dataspace_writable(Dataspace_capability ds) +Platform_env_base::Region_map_mmap::_dataspace_writable(Dataspace_capability ds) { return Dataspace_client(ds).writable(); } + /******************************** ** Platform_env::Local_parent ** ********************************/ @@ -63,22 +64,11 @@ Platform_env::Local_parent::session(Service_name const &service_name, Session_args const &args, Affinity const &affinity) { - if (strcmp(service_name.string(), - Rm_session::service_name()) == 0) + if (strcmp(service_name.string(), Rm_session::service_name()) == 0) { - size_t size = - Arg_string::find_arg(args.string(),"size") - .ulong_value(~0); + Local_rm_session *session = new (_alloc) Local_rm_session(_alloc); - if (size == 0) - return Expanding_parent_client::session(service_name, args, affinity); - - if (size != ~0UL) - size = align_addr(size, get_page_size_log2()); - - Rm_session_mmap *rm = new (_alloc) Rm_session_mmap(true, size); - - return Local_capability::local_cap(rm); + return Local_capability::local_cap(session); } return Expanding_parent_client::session(service_name, args, affinity); @@ -98,9 +88,9 @@ void Platform_env::Local_parent::close(Session_capability session) /* * Detect capability to local RM session */ - Capability rm = static_cap_cast(session); + Capability rm = static_cap_cast(session); - destroy(env()->heap(), Local_capability::deref(rm)); + destroy(_alloc, Local_capability::deref(rm)); } @@ -162,11 +152,15 @@ Platform_env::Platform_env() static_cap_cast(_parent().session("Env::cpu_session", "")), static_cap_cast (_parent().session("Env::pd_session", ""))), _heap(Platform_env_base::ram_session(), Platform_env_base::rm_session()), - _stack_area(*parent(), *rm_session()), _emergency_ram_ds(ram_session()->alloc(_emergency_ram_size())) { + /* attach stack area to local address space */ + _local_pd_session._address_space.attach_at(_local_pd_session._stack_area.dataspace(), + stack_area_virtual_base(), + stack_area_virtual_size()); + + env_stack_area_region_map = &_local_pd_session._stack_area; env_stack_area_ram_session = ram_session(); - env_stack_area_rm_session = &_stack_area; /* register TID and PID of the main thread at core */ Linux_native_cpu_client native_cpu(cpu_session()->native_cpu()); diff --git a/repos/base-linux/src/base/env/rm_session_mmap.cc b/repos/base-linux/src/base/env/region_map_mmap.cc similarity index 90% rename from repos/base-linux/src/base/env/rm_session_mmap.cc rename to repos/base-linux/src/base/env/region_map_mmap.cc index ab0cb00a30..3a6d375b1c 100644 --- a/repos/base-linux/src/base/env/rm_session_mmap.cc +++ b/repos/base-linux/src/base/env/region_map_mmap.cc @@ -1,5 +1,5 @@ /* - * \brief Implementation of Linux-specific local region manager + * \brief Implementation of Linux-specific local region map * \author Norman Feske * \date 2008-10-22 * @@ -54,7 +54,7 @@ static bool is_sub_rm_session(Dataspace_capability ds) } -addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_local_addr, +addr_t Platform_env_base::Region_map_mmap::_reserve_local(bool use_local_addr, addr_t local_addr, Genode::size_t size) { @@ -94,7 +94,7 @@ addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_loc || (((long)addr_out < 0) && ((long)addr_out > -4095))) { PERR("_reserve_local: lx_mmap failed (addr_in=%p,addr_out=%p/%ld)", addr_in, addr_out, (long)addr_out); - throw Rm_session::Region_conflict(); + throw Region_map::Region_conflict(); } return (addr_t) addr_out; @@ -102,7 +102,7 @@ addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_loc void * -Platform_env_base::Rm_session_mmap::_map_local(Dataspace_capability ds, +Platform_env_base::Region_map_mmap::_map_local(Dataspace_capability ds, Genode::size_t size, addr_t offset, bool use_local_addr, @@ -136,14 +136,14 @@ Platform_env_base::Rm_session_mmap::_map_local(Dataspace_capability ds, || (((long)addr_out < 0) && ((long)addr_out > -4095))) { PERR("_map_local: lx_mmap failed (addr_in=%p,addr_out=%p/%ld) overmap=%d", addr_in, addr_out, (long)addr_out, overmap); - throw Rm_session::Region_conflict(); + throw Region_map::Region_conflict(); } return addr_out; } -void Platform_env::Rm_session_mmap::_add_to_rmap(Region const ®ion) +void Platform_env::Region_map_mmap::_add_to_rmap(Region const ®ion) { if (_rmap.add_region(region) < 0) { PERR("_add_to_rmap: could not add region to sub RM session"); @@ -152,23 +152,23 @@ void Platform_env::Rm_session_mmap::_add_to_rmap(Region const ®ion) } -Rm_session::Local_addr -Platform_env::Rm_session_mmap::attach(Dataspace_capability ds, +Region_map::Local_addr +Platform_env::Region_map_mmap::attach(Dataspace_capability ds, size_t size, off_t offset, bool use_local_addr, - Rm_session::Local_addr local_addr, + Region_map::Local_addr local_addr, bool executable) { Lock::Guard lock_guard(_lock); /* only support attach_at for sub RM sessions */ if (_sub_rm && !use_local_addr) { - PERR("Rm_session_mmap::attach: attaching w/o local addr not supported\n"); + PERR("Region_map_mmap::attach: attaching w/o local addr not supported\n"); throw Out_of_metadata(); } if (offset < 0) { - PERR("Rm_session_mmap::attach: negative offset not supported\n"); + PERR("Region_map_mmap::attach: negative offset not supported\n"); throw Region_conflict(); } @@ -200,7 +200,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds, * Case 4 */ if (is_sub_rm_session(ds)) { - PERR("Rm_session_mmap::attach: nesting sub RM sessions is not supported"); + PERR("Region_map_mmap::attach: nesting sub RM sessions is not supported"); throw Invalid_dataspace(); } @@ -209,7 +209,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds, * sub RM session */ if (region_size + (addr_t)local_addr > _size) { - PERR("Rm_session_mmap::attach: dataspace does not fit in sub RM session"); + PERR("Region_map_mmap::attach: dataspace does not fit in sub RM session"); throw Region_conflict(); } @@ -234,7 +234,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds, Dataspace *ds_if = Local_capability::deref(ds); - Rm_session_mmap *rm = dynamic_cast(ds_if); + Region_map_mmap *rm = dynamic_cast(ds_if); if (!rm) throw Invalid_dataspace(); @@ -245,7 +245,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds, * Detect if sub RM session is already attached */ if (rm->_base) { - PERR("Rm_session_mmap::attach: mapping a sub RM session twice is not supported"); + PERR("Region_map_mmap::attach: mapping a sub RM session twice is not supported"); throw Out_of_metadata(); } @@ -264,7 +264,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds, * been populated with dataspaces. Go through all regions and map * each of them. */ - for (int i = 0; i < Region_map::MAX_REGIONS; i++) { + for (int i = 0; i < Region_registry::MAX_REGIONS; i++) { Region region = rm->_rmap.region(i); if (!region.used()) continue; @@ -299,7 +299,7 @@ Platform_env::Rm_session_mmap::attach(Dataspace_capability ds, } -void Platform_env::Rm_session_mmap::detach(Rm_session::Local_addr local_addr) +void Platform_env::Region_map_mmap::detach(Region_map::Local_addr local_addr) { Lock::Guard lock_guard(_lock); @@ -357,7 +357,7 @@ void Platform_env::Rm_session_mmap::detach(Rm_session::Local_addr local_addr) if (is_sub_rm_session(region.dataspace())) { Dataspace *ds_if = Local_capability::deref(region.dataspace()); - Rm_session_mmap *rm = dynamic_cast(ds_if); + Region_map_mmap *rm = dynamic_cast(ds_if); if (rm) rm->_base = 0; } diff --git a/repos/base-linux/src/base/process/process.cc b/repos/base-linux/src/base/process/process.cc index 074d90717a..7515f68545 100644 --- a/repos/base-linux/src/base/process/process.cc +++ b/repos/base-linux/src/base/process/process.cc @@ -56,13 +56,11 @@ Process::Process(Dataspace_capability elf_data_ds_cap, Pd_session_capability pd_session_cap, Ram_session_capability ram_session_cap, Cpu_session_capability cpu_session_cap, - Rm_session_capability rm_session_cap, Parent_capability parent_cap, char const *name) : _pd_session_client(pd_session_cap), - _cpu_session_client(cpu_session_cap), - _rm_session_client(Rm_session_capability()) + _cpu_session_client(cpu_session_cap) { /* check for dynamic program header */ if (_check_dynamic_elf(elf_data_ds_cap)) { diff --git a/repos/base-linux/src/base/region_map_client.cc b/repos/base-linux/src/base/region_map_client.cc new file mode 100644 index 0000000000..e5ee05537f --- /dev/null +++ b/repos/base-linux/src/base/region_map_client.cc @@ -0,0 +1,77 @@ +/* + * \brief Pseudo region map client stub targeting the process-local implementation + * \author Norman Feske + * \date 2011-11-21 + */ + +/* + * Copyright (C) 2011-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* Genode includes */ +#include + +/* base-internal includes */ +#include + +using namespace Genode; + + +/** + * Return pointer to locally implemented region map + * + * \throw Local_interface::Non_local_capability + */ +static Region_map *_local(Capability cap) +{ + return Local_capability::deref(cap); +} + + +Region_map_client::Region_map_client(Capability session) +: Rpc_client(session) { } + + +Region_map::Local_addr +Region_map_client::attach(Dataspace_capability ds, size_t size, + off_t offset, bool use_local_addr, + Region_map::Local_addr local_addr, + bool executable) +{ + return _local(*this)->attach(ds, size, offset, use_local_addr, + local_addr, executable); +} + + +void Region_map_client::detach(Local_addr local_addr) { + return _local(*this)->detach(local_addr); } + + +Pager_capability Region_map_client::add_client(Thread_capability thread) { + return _local(*this)->add_client(thread); } + + +void Region_map_client::remove_client(Pager_capability pager) { + _local(*this)->remove_client(pager); } + + +void Region_map_client::fault_handler(Signal_context_capability /*handler*/) +{ + /* + * On Linux, page faults are never reflected to the user land. They + * are always handled by the kernel. If a segmentation fault + * occurs, this condition is being reflected as a CPU exception + * to the handler registered via 'Cpu_session::exception_handler'. + */ +} + + +Region_map::State Region_map_client::state() { return _local(*this)->state(); } + + +Dataspace_capability Region_map_client::dataspace() { + return _local(*this)->dataspace(); } + diff --git a/repos/base-linux/src/base/rm_session_client.cc b/repos/base-linux/src/base/rm_session_client.cc index 6cc58eba5d..a5826866ad 100644 --- a/repos/base-linux/src/base/rm_session_client.cc +++ b/repos/base-linux/src/base/rm_session_client.cc @@ -1,5 +1,5 @@ /* - * \brief Pseudo RM-session client stub targeting the process-local RM service + * \brief Pseudo RM session client stub targeting the process-local implementation * \author Norman Feske * \date 2011-11-21 */ @@ -25,52 +25,19 @@ using namespace Genode; * * \throw Local_interface::Non_local_capability */ -static Rm_session *_local(Rm_session_capability cap) +static Rm_session *_local(Capability cap) { return Local_capability::deref(cap); } -Rm_session_client::Rm_session_client(Rm_session_capability session) +Rm_session_client::Rm_session_client(Capability session) : Rpc_client(session) { } -Rm_session::Local_addr -Rm_session_client::attach(Dataspace_capability ds, size_t size, - off_t offset, bool use_local_addr, - Rm_session::Local_addr local_addr, - bool executable) -{ - return _local(*this)->attach(ds, size, offset, use_local_addr, - local_addr, executable); -} - -void Rm_session_client::detach(Local_addr local_addr) { - return _local(*this)->detach(local_addr); } +Capability Rm_session_client::create(size_t size) { + return _local(*this)->create(size); } -Pager_capability Rm_session_client::add_client(Thread_capability thread) { - return _local(*this)->add_client(thread); } - - -void Rm_session_client::remove_client(Pager_capability pager) { - _local(*this)->remove_client(pager); } - - -void Rm_session_client::fault_handler(Signal_context_capability /*handler*/) -{ - /* - * On Linux, page faults are never reflected to RM clients. They - * are always handled by the kernel. If a segmentation fault - * occurs, this condition is being reflected as a CPU exception - * to the handler registered via 'Cpu_session::exception_handler'. - */ -} - - -Rm_session::State Rm_session_client::state() { return _local(*this)->state(); } - - -Dataspace_capability Rm_session_client::dataspace() { - return _local(*this)->dataspace(); } - +void Rm_session_client::destroy(Capability cap) { + _local(*this)->destroy(cap); } diff --git a/repos/base-linux/src/core/include/region_map_component.h b/repos/base-linux/src/core/include/region_map_component.h new file mode 100644 index 0000000000..5942112c26 --- /dev/null +++ b/repos/base-linux/src/core/include/region_map_component.h @@ -0,0 +1,74 @@ +/* + * \brief Core-specific instance of the region-map interface + * \author Christian Helmuth + * \date 2006-07-17 + * + * Dummies for Linux platform + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _CORE__INCLUDE__REGION_MAP_COMPONENT_H_ +#define _CORE__INCLUDE__REGION_MAP_COMPONENT_H_ + +/* Genode includes */ +#include +#include +#include +#include + +/* Core includes */ +#include + +namespace Genode { + struct Rm_client; + struct Rm_member; + class Region_map_component; +} + + +class Genode::Region_map_component : public Rpc_object, + public List::Element +{ + private: + + struct Rm_dataspace_component { void sub_rm(Native_capability) { } }; + + public: + + Region_map_component(Rpc_entrypoint &, Allocator &, Pager_entrypoint &, + addr_t, size_t) { } + + void upgrade_ram_quota(size_t ram_quota) { } + + Local_addr attach(Dataspace_capability, size_t, off_t, bool, Local_addr, bool) { + return (addr_t)0; } + + void detach(Local_addr) { } + + Pager_capability add_client(Thread_capability) { + return Pager_capability(); } + + void remove_client(Pager_capability) { } + + void fault_handler(Signal_context_capability) { } + + State state() { return State(); } + + Dataspace_capability dataspace() { return Dataspace_capability(); } + + Rm_dataspace_component *dataspace_component() { return 0; } +}; + + +struct Genode::Rm_member { Region_map_component *member_rm() { return 0; } }; + + +struct Genode::Rm_client : Pager_object, Rm_member { }; + +#endif /* _CORE__INCLUDE__REGION_MAP_COMPONENT_H_ */ diff --git a/repos/base-linux/src/core/include/rm_session_component.h b/repos/base-linux/src/core/include/rm_session_component.h deleted file mode 100644 index 09479ae61b..0000000000 --- a/repos/base-linux/src/core/include/rm_session_component.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * \brief Core-specific instance of the RM session interface - * \author Christian Helmuth - * \date 2006-07-17 - * - * Dummies for Linux platform - */ - -/* - * Copyright (C) 2006-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__RM_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__RM_SESSION_COMPONENT_H_ - -/* Genode includes */ -#include -#include -#include - -/* Core includes */ -#include - -namespace Genode { - - struct Rm_client; - - class Rm_session_component : public Rpc_object - { - private: - - class Rm_dataspace_component { - - public: - - void sub_rm_session(Native_capability _cap) { } - }; - - public: - - Rm_session_component(Rpc_entrypoint *ds_ep, - Rpc_entrypoint *thread_ep, - Rpc_entrypoint *session_ep, - Allocator *md_alloc, - size_t ram_quota, - Pager_entrypoint *pager_ep, - addr_t vm_start, - size_t vm_size) { } - - void upgrade_ram_quota(size_t ram_quota) { } - - Local_addr attach(Dataspace_capability, size_t, off_t, bool, Local_addr, bool) { - return (addr_t)0; } - - void detach(Local_addr) { } - - Pager_capability add_client(Thread_capability) { - return Pager_capability(); } - - void remove_client(Pager_capability) { } - - void fault_handler(Signal_context_capability) { } - - State state() { return State(); } - - Dataspace_capability dataspace() { return Dataspace_capability(); } - - Rm_dataspace_component *dataspace_component() { return 0; } - }; - - struct Rm_member { Rm_session_component *member_rm_session() { return 0; } }; - struct Rm_client : Pager_object, Rm_member { }; -} - -#endif /* _CORE__INCLUDE__RM_SESSION_COMPONENT_H_ */ diff --git a/repos/base-linux/src/core/platform.cc b/repos/base-linux/src/core/platform.cc index 9467c06d6f..85b0f4356e 100644 --- a/repos/base-linux/src/core/platform.cc +++ b/repos/base-linux/src/core/platform.cc @@ -177,18 +177,18 @@ namespace Genode { /**************************************************** - ** Support for Platform_env_base::Rm_session_mmap ** + ** Support for Platform_env_base::Region_map_mmap ** ****************************************************/ Genode::size_t -Platform_env_base::Rm_session_mmap::_dataspace_size(Capability ds_cap) +Platform_env_base::Region_map_mmap::_dataspace_size(Capability ds_cap) { if (!ds_cap.valid()) return Local_capability::deref(ds_cap)->size(); /* use RPC if called from a different thread */ if (!core_env()->entrypoint()->is_myself()) { - /* release Rm_session_mmap::_lock during RPC */ + /* release Region_map_mmap::_lock during RPC */ _lock.unlock(); Genode::size_t size = Dataspace_client(ds_cap).size(); _lock.lock(); @@ -201,10 +201,10 @@ Platform_env_base::Rm_session_mmap::_dataspace_size(Capability ds_cap } -int Platform_env_base::Rm_session_mmap::_dataspace_fd(Capability ds_cap) +int Platform_env_base::Region_map_mmap::_dataspace_fd(Capability ds_cap) { if (!core_env()->entrypoint()->is_myself()) { - /* release Rm_session_mmap::_lock during RPC */ + /* release Region_map_mmap::_lock during RPC */ _lock.unlock(); int socket = Linux_dataspace_client(ds_cap).fd().dst().socket; _lock.lock(); @@ -215,7 +215,7 @@ int Platform_env_base::Rm_session_mmap::_dataspace_fd(Capability ds_c /* * Return a duplicate of the dataspace file descriptor, which will be freed - * immediately after mmap'ing the file (see 'Rm_session_mmap'). + * immediately after mmap'ing the file (see 'Region_map_mmap'). * * Handing out the original file descriptor would result in the premature * release of the descriptor. So the descriptor could be reused (i.e., as a @@ -227,10 +227,10 @@ int Platform_env_base::Rm_session_mmap::_dataspace_fd(Capability ds_c } -bool Platform_env_base::Rm_session_mmap::_dataspace_writable(Dataspace_capability ds_cap) +bool Platform_env_base::Region_map_mmap::_dataspace_writable(Dataspace_capability ds_cap) { if (!core_env()->entrypoint()->is_myself()) { - /* release Rm_session_mmap::_lock during RPC */ + /* release Region_map_mmap::_lock during RPC */ _lock.unlock(); bool writable = Dataspace_client(ds_cap).writable(); _lock.lock(); diff --git a/repos/base-linux/src/core/stack_area.cc b/repos/base-linux/src/core/stack_area.cc index 95f47c1afc..ee830177f9 100644 --- a/repos/base-linux/src/core/stack_area.cc +++ b/repos/base-linux/src/core/stack_area.cc @@ -19,21 +19,22 @@ /* base-internal includes */ #include +#include /** - * Region-manager session for allocating stacks + * Region-map for allocating stacks * * This class corresponds to the managed dataspace that is normally used for * organizing stacks within the stack. It "emulates" the sub address space by * adjusting the local address argument to 'attach' with the offset of the * stack area. */ -class Stack_area_rm_session : public Genode::Rm_session +class Stack_area_region_map : public Genode::Region_map { public: - Stack_area_rm_session() + Stack_area_region_map() { flush_stack_area(); reserve_stack_area(); @@ -105,13 +106,13 @@ class Stack_area_ram_session : public Genode::Ram_session */ namespace Genode { - Rm_session *env_stack_area_rm_session; + Region_map *env_stack_area_region_map; Ram_session *env_stack_area_ram_session; void init_stack_area() { - static Stack_area_rm_session rm_inst; - env_stack_area_rm_session = &rm_inst; + static Stack_area_region_map rm_inst; + env_stack_area_region_map = &rm_inst; static Stack_area_ram_session ram_inst; env_stack_area_ram_session = &ram_inst; 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 7b3892fc6b..70e4a8e173 100644 --- a/repos/base-linux/src/include/base/internal/platform_env.h +++ b/repos/base-linux/src/include/base/internal/platform_env.h @@ -33,6 +33,7 @@ namespace Genode { struct Expanding_cpu_session_client; + class Platform_env_base; class Platform_env; } @@ -53,418 +54,460 @@ struct Genode::Expanding_cpu_session_client }; -namespace Genode { +/** + * Common base class of the 'Platform_env' implementations for core and + * non-core processes. + */ +class Genode::Platform_env_base : public Env +{ + private: - /** - * Common base class of the 'Platform_env' implementations for core and - * non-core processes. - */ - class Platform_env_base : public Env - { - private: + /************************** + ** Local region manager ** + **************************/ - /************************** - ** Local region manager ** - **************************/ + class Region + { + private: - class Region + addr_t _start; + off_t _offset; + Dataspace_capability _ds; + size_t _size; + + /** + * Return offset of first byte after the region + */ + addr_t _end() const { return _start + _size; } + + public: + + Region() : _start(0), _offset(0), _size(0) { } + + Region(addr_t start, off_t offset, Dataspace_capability ds, size_t size) + : _start(start), _offset(offset), _ds(ds), _size(size) { } + + bool used() const { return _size > 0; } + addr_t start() const { return _start; } + off_t offset() const { return _offset; } + size_t size() const { return _size; } + Dataspace_capability dataspace() const { return _ds; } + + bool intersects(Region const &r) const + { + return (r.start() < _end()) && (_start < r._end()); + } + }; + + + /** + * Meta data about dataspaces attached to an RM session + */ + class Region_registry + { + public: + + enum { MAX_REGIONS = 4096 }; + + private: + + Region _map[MAX_REGIONS]; + + bool _id_valid(int id) const { + return (id >= 0 && id < MAX_REGIONS); } + + public: + + /** + * Add region to region map + * + * \return region ID, or + * -1 if out of metadata, or + * -2 if region conflicts existing region + */ + int add_region(Region const ®ion) + { + /* + * Check for region conflicts + */ + for (int i = 0; i < MAX_REGIONS; i++) { + if (_map[i].intersects(region)) + return -2; + } + + /* + * Allocate new region metadata + */ + int i; + for (i = 0; i < MAX_REGIONS; i++) + if (!_map[i].used()) break; + + if (i == MAX_REGIONS) { + PERR("maximum number of %d regions reached", + MAX_REGIONS); + return -1; + } + + _map[i] = region; + return i; + } + + Region region(int id) const + { + return _id_valid(id) ? _map[id] : Region(); + } + + Region lookup(addr_t start) + { + for (int i = 0; i < MAX_REGIONS; i++) + if (_map[i].start() == start) + return _map[i]; + return Region(); + } + + void remove_region(addr_t start) + { + for (int i = 0; i < MAX_REGIONS; i++) + if (_map[i].start() == start) + _map[i] = Region(); + } + }; + + protected: + + /* + * 'Region_map_mmap' is 'protected' because it is instantiated by + * 'Platform_env::Local_parent::session()'. + */ + + /* + * On Linux, we use a locally implemented region map that attaches + * dataspaces via mmap to the local address space. + */ + class Region_map_mmap : public Region_map, + public Dataspace + { + private: + + Lock _lock; /* protect '_rmap' */ + Region_registry _rmap; + bool const _sub_rm; /* false if region map is root */ + size_t const _size; + + /** + * Base offset of the RM session + * + * For a normal RM session (the one that comes with the + * 'env()', this value is zero. If the RM session is + * used as nested dataspace, '_base' contains the address + * where the managed dataspace is attached in the root RM + * session. + * + * Note that a managed dataspace cannot be attached more + * than once. Furthermore, managed dataspace cannot be + * attached to another managed dataspace. The nested + * dataspace emulation is solely implemented to support + * the common use case of managed dataspaces as mechanism + * to reserve parts of the local address space from being + * populated by the 'env()->rm_session()'. (i.e., for the + * stack area, or for the placement of consecutive + * shared-library segments) + */ + addr_t _base; + + bool _is_attached() const { return _base > 0; } + + void _add_to_rmap(Region const &); + + /** + * Reserve VM region for sub-rm dataspace + */ + addr_t _reserve_local(bool use_local_addr, + addr_t local_addr, + Genode::size_t size); + + /** + * Map dataspace into local address space + */ + void *_map_local(Dataspace_capability ds, + Genode::size_t size, + addr_t offset, + bool use_local_addr, + addr_t local_addr, + bool executable, + bool overmap = false); + + /** + * Determine size of dataspace + * + * For core, this function performs a local lookup of the + * 'Dataspace_component' object. For non-core programs, the + * dataspace size is determined via an RPC to core + * (calling 'Dataspace::size()'). + */ + size_t _dataspace_size(Capability); + + /** + * Determine file descriptor of dataspace + */ + int _dataspace_fd(Capability); + + /** + * Determine whether dataspace is writable + */ + bool _dataspace_writable(Capability); + + public: + + Region_map_mmap(bool sub_rm, size_t size = ~0) + : _sub_rm(sub_rm), _size(size), _base(0) { } + + ~Region_map_mmap() + { + /* detach sub RM session when destructed */ + if (_sub_rm && _is_attached()) + env()->rm_session()->detach((void *)_base); + } + + + /************************** + ** Region map interface ** + **************************/ + + Local_addr attach(Dataspace_capability ds, size_t size, + off_t, bool, Local_addr, + bool executable); + + void detach(Local_addr local_addr); + + Pager_capability add_client(Thread_capability thread) { + return Pager_capability(); } + + void remove_client(Pager_capability pager) { } + + void fault_handler(Signal_context_capability handler) { } + + State state() { return State(); } + + + /************************* + ** Dataspace interface ** + *************************/ + + size_t size() { return _size; } + + addr_t phys_addr() { return 0; } + + bool writable() { return true; } + + /** + * Return pseudo dataspace capability of the RM session + * + * The capability returned by this function is only usable + * as argument to 'Region_map_mmap::attach'. It is not a + * real capability. + */ + Dataspace_capability dataspace() { + return Local_capability::local_cap(this); } + }; + + struct Local_rm_session : Genode::Rm_session + { + Genode::Allocator &md_alloc; + + Local_rm_session(Genode::Allocator &md_alloc) : md_alloc(md_alloc) { } + + Capability create(size_t size) { - private: + Region_map *rm = new (md_alloc) Region_map_mmap(true, size); + return Local_capability::local_cap(rm); + } - addr_t _start; - off_t _offset; - Dataspace_capability _ds; - size_t _size; - - /** - * Return offset of first byte after the region - */ - addr_t _end() const { return _start + _size; } - - public: - - Region() : _start(0), _offset(0), _size(0) { } - - Region(addr_t start, off_t offset, Dataspace_capability ds, size_t size) - : _start(start), _offset(offset), _ds(ds), _size(size) { } - - bool used() const { return _size > 0; } - addr_t start() const { return _start; } - off_t offset() const { return _offset; } - size_t size() const { return _size; } - Dataspace_capability dataspace() const { return _ds; } - - bool intersects(Region const &r) const - { - return (r.start() < _end()) && (_start < r._end()); - } - }; - - - /** - * Meta data about dataspaces attached to an RM session - */ - class Region_map + void destroy(Capability cap) { - public: + Region_map *rm = Local_capability::deref(cap); + Genode::destroy(md_alloc, rm); + } + }; - enum { MAX_REGIONS = 4096 }; + struct Local_pd_session : Pd_session_client + { + Region_map_mmap _address_space { false }; + Region_map_mmap _stack_area { true, stack_area_virtual_size() }; + Region_map_mmap _linker_area { true, Pd_session::LINKER_AREA_SIZE }; - private: + Local_pd_session(Pd_session_capability pd) : Pd_session_client(pd) { } - Region _map[MAX_REGIONS]; - - bool _id_valid(int id) const { - return (id >= 0 && id < MAX_REGIONS); } - - public: - - /** - * Add region to region map - * - * \return region ID, or - * -1 if out of metadata, or - * -2 if region conflicts existing region - */ - int add_region(Region const ®ion) - { - /* - * Check for region conflicts - */ - for (int i = 0; i < MAX_REGIONS; i++) { - if (_map[i].intersects(region)) - return -2; - } - - /* - * Allocate new region metadata - */ - int i; - for (i = 0; i < MAX_REGIONS; i++) - if (!_map[i].used()) break; - - if (i == MAX_REGIONS) { - PERR("maximum number of %d regions reached", - MAX_REGIONS); - return -1; - } - - _map[i] = region; - return i; - } - - Region region(int id) const - { - return _id_valid(id) ? _map[id] : Region(); - } - - Region lookup(addr_t start) - { - for (int i = 0; i < MAX_REGIONS; i++) - if (_map[i].start() == start) - return _map[i]; - return Region(); - } - - void remove_region(addr_t start) - { - for (int i = 0; i < MAX_REGIONS; i++) - if (_map[i].start() == start) - _map[i] = Region(); - } - }; - - protected: - - /* - * 'Rm_session_mmap' is 'protected' because it is instantiated by - * 'Platform_env::Local_parent::session()'. - */ - - /* - * On Linux, we use a local region manager session that attaches - * dataspaces via mmap to the local address space. - */ - class Rm_session_mmap : public Rm_session, - public Dataspace + Capability address_space() { - private: + return Local_capability::local_cap(&_address_space); + } - Lock _lock; /* protect '_rmap' */ - Region_map _rmap; - bool const _sub_rm; /* false if RM session is root */ - size_t const _size; - - /** - * Base offset of the RM session - * - * For a normal RM session (the one that comes with the - * 'env()', this value is zero. If the RM session is - * used as nested dataspace, '_base' contains the address - * where the managed dataspace is attached in the root RM - * session. - * - * Note that a managed dataspace cannot be attached more - * than once. Furthermore, managed dataspace cannot be - * attached to another managed dataspace. The nested - * dataspace emulation is solely implemented to support - * the common use case of managed dataspaces as mechanism - * to reserve parts of the local address space from being - * populated by the 'env()->rm_session()'. (i.e., for the - * stack area, or for the placement of consecutive - * shared-library segments) - */ - addr_t _base; - - bool _is_attached() const { return _base > 0; } - - void _add_to_rmap(Region const &); - - /** - * Reserve VM region for sub-rm dataspace - */ - addr_t _reserve_local(bool use_local_addr, - addr_t local_addr, - Genode::size_t size); - - /** - * Map dataspace into local address space - */ - void *_map_local(Dataspace_capability ds, - Genode::size_t size, - addr_t offset, - bool use_local_addr, - addr_t local_addr, - bool executable, - bool overmap = false); - - /** - * Determine size of dataspace - * - * For core, this function performs a local lookup of the - * 'Dataspace_component' object. For non-core programs, the - * dataspace size is determined via an RPC to core - * (calling 'Dataspace::size()'). - */ - size_t _dataspace_size(Capability); - - /** - * Determine file descriptor of dataspace - */ - int _dataspace_fd(Capability); - - /** - * Determine whether dataspace is writable - */ - bool _dataspace_writable(Capability); - - public: - - Rm_session_mmap(bool sub_rm, size_t size = ~0) - : _sub_rm(sub_rm), _size(size), _base(0) { } - - ~Rm_session_mmap() - { - /* detach sub RM session when destructed */ - if (_sub_rm && _is_attached()) - env()->rm_session()->detach((void *)_base); - } - - - /************************************** - ** Region manager session interface ** - **************************************/ - - Local_addr attach(Dataspace_capability ds, size_t size, - off_t, bool, Local_addr, - bool executable); - - void detach(Local_addr local_addr); - - Pager_capability add_client(Thread_capability thread) { - return Pager_capability(); } - - void remove_client(Pager_capability pager) { } - - void fault_handler(Signal_context_capability handler) { } - - State state() { return State(); } - - - /************************* - ** Dataspace interface ** - *************************/ - - size_t size() { return _size; } - - addr_t phys_addr() { return 0; } - - bool writable() { return true; } - - /** - * Return pseudo dataspace capability of the RM session - * - * The capability returned by this function is only usable - * as argument to 'Rm_session_mmap::attach'. It is not a - * real capability. - */ - Dataspace_capability dataspace() { - return Local_capability::local_cap(this); } - }; - - private: - - Ram_session_capability _ram_session_cap; - Expanding_ram_session_client _ram_session_client; - Cpu_session_capability _cpu_session_cap; - Expanding_cpu_session_client _cpu_session_client; - Rm_session_mmap _rm_session_mmap; - Pd_session_capability _pd_session_cap; - Pd_session_client _pd_session_client; - - public: - - /** - * Constructor - */ - Platform_env_base(Ram_session_capability ram_cap, - Cpu_session_capability cpu_cap, - Pd_session_capability pd_cap) - : - _ram_session_cap(ram_cap), - _ram_session_client(_ram_session_cap), - _cpu_session_cap(cpu_cap), - _cpu_session_client(cpu_cap), - _rm_session_mmap(false), - _pd_session_cap(pd_cap), - _pd_session_client(_pd_session_cap) - { } - - - /******************* - ** Env interface ** - *******************/ - - Ram_session *ram_session() override { return &_ram_session_client; } - Ram_session_capability ram_session_cap() override { return _ram_session_cap; } - Rm_session *rm_session() override { return &_rm_session_mmap; } - Cpu_session *cpu_session() override { return &_cpu_session_client; } - Cpu_session_capability cpu_session_cap() override { return _cpu_session_cap; } - Pd_session *pd_session() override { return &_pd_session_client; } - Pd_session_capability pd_session_cap() override { return _pd_session_cap; } - - /* - * Support functions for implementing fork on Noux. - * - * Not supported on Linux. - */ - void reinit(Native_capability::Dst, long) override { } - void reinit_main_thread(Rm_session_capability &) override { } - }; - - - /** - * 'Platform_env' used by all processes except for core - */ - class Platform_env : public Platform_env_base, public Emergency_ram_reserve - { - private: - - /** - * Local interceptor of parent requests - * - * On Linux, we need to intercept calls to the parent interface to - * implement the RM service locally. This particular service is - * used for creating managed dataspaces, which allow the - * reservation of parts of the local address space from being - * automatically managed by the 'env()->rm_session()'. - * - * All requests that do not refer to the RM service are passed - * through the real parent interface. - */ - class Local_parent : public Expanding_parent_client + Capability stack_area() { - private: + return Local_capability::local_cap(&_stack_area); + } - Allocator &_alloc; + Capability linker_area() + { + return Local_capability::local_cap(&_linker_area); + } + }; - public: + private: - /********************** - ** Parent interface ** - **********************/ + Ram_session_capability _ram_session_cap; + Expanding_ram_session_client _ram_session_client; + Cpu_session_capability _cpu_session_cap; + Expanding_cpu_session_client _cpu_session_client; + Region_map_mmap _region_map_mmap; + Pd_session_capability _pd_session_cap; - Session_capability session(Service_name const &, - Session_args const &, - Affinity const & = Affinity()); - void close(Session_capability); + protected: - /** - * Constructor - * - * \param parent_cap real parent capability used to - * promote requests to non-local - * services - */ - Local_parent(Parent_capability parent_cap, - Emergency_ram_reserve &, - Allocator &); - }; + /* + * The '_local_pd_session' is protected because it is needed by + * 'Platform_env' to initialize the stack area. This must not happen + * in 'Platform_env_base' because the procedure differs between + * core and non-core components. + */ + Local_pd_session _local_pd_session { _pd_session_cap }; - /** - * Return instance of parent interface - */ - Local_parent &_parent(); + public: - Heap _heap; - - /* - * The '_heap' must be initialized before the '_stack_area' - * because the 'Local_parent' performs a dynamic memory allocation - * due to the creation of the stack area's sub-RM session. - */ - Attached_stack_area _stack_area; - - /* - * Emergency RAM reserve - * - * See the comment of '_fallback_sig_cap()' in 'env/env.cc'. - */ - constexpr static size_t _emergency_ram_size() { return 8*1024; } - Ram_dataspace_capability _emergency_ram_ds; + /** + * Constructor + */ + Platform_env_base(Ram_session_capability ram_cap, + Cpu_session_capability cpu_cap, + Pd_session_capability pd_cap) + : + _ram_session_cap(ram_cap), + _ram_session_client(_ram_session_cap), + _cpu_session_cap(cpu_cap), + _cpu_session_client(cpu_cap), + _region_map_mmap(false), + _pd_session_cap(pd_cap), + _local_pd_session(_pd_session_cap) + { } - /************************************* - ** Linux-specific helper functions ** - *************************************/ + /******************* + ** Env interface ** + *******************/ - public: + Ram_session *ram_session() override { return &_ram_session_client; } + Ram_session_capability ram_session_cap() override { return _ram_session_cap; } + Region_map *rm_session() override { return &_region_map_mmap; } + Cpu_session *cpu_session() override { return &_cpu_session_client; } + Cpu_session_capability cpu_session_cap() override { return _cpu_session_cap; } + Pd_session *pd_session() override { return &_local_pd_session; } + Pd_session_capability pd_session_cap() override { return _pd_session_cap; } - /** - * Constructor - */ - Platform_env(); - - /** - * Destructor - */ - ~Platform_env() { _parent().exit(0); } + /* + * Support functions for implementing fork on Noux. + * + * Not supported on Linux. + */ + void reinit(Native_capability::Dst, long) override { } + void reinit_main_thread(Capability &) override { } +}; - /************************************* - ** Emergency_ram_reserve interface ** - *************************************/ +/** + * 'Platform_env' used by all processes except for core + */ +class Genode::Platform_env : public Platform_env_base, public Emergency_ram_reserve +{ + private: - void release() { ram_session()->free(_emergency_ram_ds); } + /** + * Local interceptor of parent requests + * + * On Linux, we need to intercept calls to the parent interface to + * implement the RM service locally. This particular service is + * used for creating managed dataspaces, which allow the + * reservation of parts of the local address space from being + * automatically managed by the 'env()->rm_session()'. + * + * All requests that do not refer to the RM service are passed + * through the real parent interface. + */ + class Local_parent : public Expanding_parent_client + { + private: + + Allocator &_alloc; + + public: + + /********************** + ** Parent interface ** + **********************/ + + Session_capability session(Service_name const &, + Session_args const &, + Affinity const & = Affinity()); + void close(Session_capability); + + /** + * Constructor + * + * \param parent_cap real parent capability used to + * promote requests to non-local + * services + */ + Local_parent(Parent_capability parent_cap, + Emergency_ram_reserve &, + Allocator &); + }; + + /** + * Return instance of parent interface + */ + Local_parent &_parent(); + + Heap _heap; + + /* + * Emergency RAM reserve + * + * See the comment of '_fallback_sig_cap()' in 'env/env.cc'. + */ + constexpr static size_t _emergency_ram_size() { return 8*1024; } + Ram_dataspace_capability _emergency_ram_ds; - /******************* - ** Env interface ** - *******************/ + /************************************* + ** Linux-specific helper functions ** + *************************************/ - Parent *parent() override { return &_parent(); } - Heap *heap() override { return &_heap; } - }; -} + public: + + /** + * Constructor + */ + Platform_env(); + + /** + * Destructor + */ + ~Platform_env() { _parent().exit(0); } + + + /************************************* + ** Emergency_ram_reserve interface ** + *************************************/ + + void release() { ram_session()->free(_emergency_ram_ds); } + + + /******************* + ** Env interface ** + *******************/ + + Parent *parent() override { return &_parent(); } + Heap *heap() override { return &_heap; } +}; #endif /* _INCLUDE__BASE__INTERNAL__PLATFORM_ENV_H_ */ diff --git a/repos/base-linux/src/include/base/internal/stack_area.h b/repos/base-linux/src/include/base/internal/stack_area.h index 8c30662491..76f7f4a32e 100644 --- a/repos/base-linux/src/include/base/internal/stack_area.h +++ b/repos/base-linux/src/include/base/internal/stack_area.h @@ -53,7 +53,7 @@ static inline void flush_stack_area() int ret; if ((ret = lx_munmap(base, size)) < 0) { PERR("%s: failed ret=%d", __func__, ret); - throw Rm_session::Region_conflict(); + throw Region_map::Region_conflict(); } } @@ -74,7 +74,7 @@ static inline Genode::addr_t reserve_stack_area() PERR("%s: failed addr_in=%p addr_out=%p ret=%ld)", __func__, addr_in, addr_out, (long)addr_out); - throw Rm_session::Region_conflict(); + throw Region_map::Region_conflict(); } return (addr_t) addr_out; diff --git a/repos/base-linux/src/test/lx_rmap/main.cc b/repos/base-linux/src/test/lx_rmap/main.cc index 6f8cedebdd..33f31384d3 100644 --- a/repos/base-linux/src/test/lx_rmap/main.cc +++ b/repos/base-linux/src/test/lx_rmap/main.cc @@ -18,6 +18,7 @@ #include #include #include +#include static void blob() __attribute__((used)); @@ -66,26 +67,28 @@ int main() env()->rm_session()->attach_at(ds, beg); PERR("after RAM dataspace attach -- ERROR"); sleep_forever(); - } catch (Rm_session::Region_conflict) { + } catch (Region_map::Region_conflict) { PLOG("OK caught Region_conflict exception"); } /* empty managed dataspace overlapping binary */ try { - Rm_connection rm(0, size); + Rm_connection rm_connection; + Region_map_client rm(rm_connection.create(size)); Dataspace_capability ds(rm.dataspace()); PLOG("before sub-RM dataspace attach"); env()->rm_session()->attach_at(ds, beg); PERR("after sub-RM dataspace attach -- ERROR"); sleep_forever(); - } catch (Rm_session::Region_conflict) { + } catch (Region_map::Region_conflict) { PLOG("OK caught Region_conflict exception"); } /* sparsely populated managed dataspace in free VM area */ try { - Rm_connection rm(0, 0x100000); + Rm_connection rm_connection; + Region_map_client rm(rm_connection.create(0x100000)); rm.attach_at(env()->ram_session()->alloc(0x1000), 0x1000); @@ -97,7 +100,7 @@ int main() char const val = *addr; *addr = 0x55; PLOG("after touch (%x/%x)", val, *addr); - } catch (Rm_session::Region_conflict) { + } catch (Region_map::Region_conflict) { PERR("Caught Region_conflict exception -- ERROR"); sleep_forever(); } diff --git a/repos/base-linux/src/test/rm_session_mmap/main.cc b/repos/base-linux/src/test/region_map_mmap/main.cc similarity index 95% rename from repos/base-linux/src/test/rm_session_mmap/main.cc rename to repos/base-linux/src/test/region_map_mmap/main.cc index 7ec6b0af16..2aeeca07e9 100644 --- a/repos/base-linux/src/test/rm_session_mmap/main.cc +++ b/repos/base-linux/src/test/region_map_mmap/main.cc @@ -1,5 +1,5 @@ /* - * \brief Linux: Test bug in rm_session_mmap.cc + * \brief Linux: Test bug in region_map_mmap.cc * \author Christian Helmuth * \date 2012-12-19 */ diff --git a/repos/base-linux/src/test/rm_session_mmap/target.mk b/repos/base-linux/src/test/region_map_mmap/target.mk similarity index 50% rename from repos/base-linux/src/test/rm_session_mmap/target.mk rename to repos/base-linux/src/test/region_map_mmap/target.mk index 158a121125..5f55e7deaa 100644 --- a/repos/base-linux/src/test/rm_session_mmap/target.mk +++ b/repos/base-linux/src/test/region_map_mmap/target.mk @@ -1,3 +1,3 @@ -TARGET = test-rm_session_mmap +TARGET = test-region_map_mmap LIBS = base SRC_CC = main.cc diff --git a/repos/base-nova/lib/mk/base-common.mk b/repos/base-nova/lib/mk/base-common.mk index 48b53b96eb..5109da58cf 100644 --- a/repos/base-nova/lib/mk/base-common.mk +++ b/repos/base-nova/lib/mk/base-common.mk @@ -22,6 +22,7 @@ SRC_CC += thread/thread.cc thread/stack.cc thread/trace.cc SRC_CC += thread/myself.cc SRC_CC += thread/stack_allocator.cc env/cap_map.cc SRC_CC += sleep.cc +SRC_CC += region_map_client.cc SRC_CC += rm_session_client.cc SRC_CC += entrypoint/entrypoint.cc SRC_CC += component/component.cc diff --git a/repos/base-nova/src/base/rm_session_client.cc b/repos/base-nova/src/base/region_map_client.cc similarity index 55% rename from repos/base-nova/src/base/rm_session_client.cc rename to repos/base-nova/src/base/region_map_client.cc index 0f2b3bcb4b..5f252691c4 100644 --- a/repos/base-nova/src/base/rm_session_client.cc +++ b/repos/base-nova/src/base/region_map_client.cc @@ -1,5 +1,5 @@ /* - * \brief Client-side region manager session interface + * \brief Client-side region map stub * \author Norman Feske * \author Alexander Boettcher * \date 2016-01-22 @@ -12,16 +12,16 @@ * under the terms of the GNU General Public License version 2. */ -#include +#include using namespace Genode; -Rm_session_client::Rm_session_client(Rm_session_capability session) -: Rpc_client(session) { } +Region_map_client::Region_map_client(Capability session) +: Rpc_client(session) { } -Rm_session::Local_addr -Rm_session_client::attach(Dataspace_capability ds, size_t size, off_t offset, +Region_map::Local_addr +Region_map_client::attach(Dataspace_capability ds, size_t size, off_t offset, bool use_local_addr, Local_addr local_addr, bool executable) { @@ -29,23 +29,23 @@ Rm_session_client::attach(Dataspace_capability ds, size_t size, off_t offset, executable); } -void Rm_session_client::detach(Local_addr local_addr) { +void Region_map_client::detach(Local_addr local_addr) { call(local_addr); } -Pager_capability Rm_session_client::add_client(Thread_capability thread) +Pager_capability Region_map_client::add_client(Thread_capability thread) { return call(thread); } -void Rm_session_client::remove_client(Pager_capability pager) { +void Region_map_client::remove_client(Pager_capability pager) { call(pager); } -void Rm_session_client::fault_handler(Signal_context_capability cap) { +void Region_map_client::fault_handler(Signal_context_capability cap) { call(cap); } - Rm_session::State Rm_session_client::state() { return call(); } + Region_map::State Region_map_client::state() { return call(); } -Dataspace_capability Rm_session_client::dataspace() +Dataspace_capability Region_map_client::dataspace() { if (!_rm_ds_cap.valid()) _rm_ds_cap = call(); diff --git a/repos/base-nova/src/core/core_rm_session.cc b/repos/base-nova/src/core/core_region_map.cc similarity index 90% rename from repos/base-nova/src/core/core_rm_session.cc rename to repos/base-nova/src/core/core_region_map.cc index 2129497377..23b006ca2a 100644 --- a/repos/base-nova/src/core/core_rm_session.cc +++ b/repos/base-nova/src/core/core_region_map.cc @@ -1,5 +1,5 @@ /* - * \brief Core-local RM session + * \brief Core-local region map * \author Norman Feske * \date 2009-10-02 */ @@ -15,7 +15,7 @@ #include /* core includes */ -#include +#include #include #include #include @@ -47,10 +47,10 @@ static inline void * alloc_region(Dataspace_component *ds, const size_t size) return virt_addr; } -Rm_session::Local_addr -Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, +Region_map::Local_addr +Core_region_map::attach(Dataspace_capability ds_cap, size_t size, off_t offset, bool use_local_addr, - Rm_session::Local_addr local_addr, + Region_map::Local_addr local_addr, bool executable) { auto lambda = [&] (Dataspace_component *ds) -> Local_addr { @@ -90,7 +90,7 @@ Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, } -void Core_rm_session::detach(Local_addr core_local_addr) +void Core_region_map::detach(Local_addr core_local_addr) { size_t size = platform_specific()->region_alloc_size_at(core_local_addr); diff --git a/repos/base-nova/src/core/include/core_region_map.h b/repos/base-nova/src/core/include/core_region_map.h new file mode 100644 index 0000000000..9f995243cc --- /dev/null +++ b/repos/base-nova/src/core/include/core_region_map.h @@ -0,0 +1,56 @@ +/* + * \brief Core-local region map + * \author Norman Feske + * \date 2009-10-02 + */ + +/* + * Copyright (C) 2009-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _CORE__INCLUDE__CORE_REGION_MAP_H_ +#define _CORE__INCLUDE__CORE_REGION_MAP_H_ + +/* Genode includes */ +#include + +/* core includes */ +#include + +namespace Genode { class Core_region_map; } + + +class Genode::Core_region_map : public Region_map +{ + private: + + Rpc_entrypoint *_ds_ep; + + public: + + Core_region_map(Rpc_entrypoint *ds_ep) : _ds_ep(ds_ep) { } + + Local_addr attach(Dataspace_capability ds_cap, size_t size=0, + off_t offset=0, bool use_local_addr = false, + Local_addr local_addr = 0, + bool executable = false) override; + + void detach(Local_addr) override; + + Pager_capability add_client(Thread_capability thread) override { + return Pager_capability(); } + + void remove_client(Pager_capability) override { } + + void fault_handler(Signal_context_capability handler) override { } + + State state() override { return State(); } + + Dataspace_capability dataspace() override { + return Dataspace_capability(); } +}; + +#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */ diff --git a/repos/base-nova/src/core/include/core_rm_session.h b/repos/base-nova/src/core/include/core_rm_session.h deleted file mode 100644 index ed7c484667..0000000000 --- a/repos/base-nova/src/core/include/core_rm_session.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * \brief Core-local region manager session - * \author Norman Feske - * \date 2009-10-02 - */ - -/* - * Copyright (C) 2009-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__CORE_RM_SESSION_H_ -#define _CORE__INCLUDE__CORE_RM_SESSION_H_ - -/* Genode includes */ -#include - -/* core includes */ -#include - -namespace Genode { - - class Core_rm_session : public Rm_session - { - private: - - Rpc_entrypoint *_ds_ep; - - public: - - Core_rm_session(Rpc_entrypoint *ds_ep) : _ds_ep(ds_ep) { } - - Local_addr attach(Dataspace_capability ds_cap, size_t size=0, - off_t offset=0, bool use_local_addr = false, - Local_addr local_addr = 0, - bool executable = false) override; - - void detach(Local_addr) override; - - Pager_capability add_client(Thread_capability thread) override { - return Pager_capability(); } - - void remove_client(Pager_capability) override { } - - void fault_handler(Signal_context_capability handler) override { } - - State state() override { return State(); } - - Dataspace_capability dataspace() override { - return Dataspace_capability(); } - }; -} - -#endif /* _CORE__INCLUDE__CORE_RM_SESSION_H_ */ diff --git a/repos/base-nova/src/core/include/platform_thread.h b/repos/base-nova/src/core/include/platform_thread.h index 820d7c8692..899e3c90b8 100644 --- a/repos/base-nova/src/core/include/platform_thread.h +++ b/repos/base-nova/src/core/include/platform_thread.h @@ -172,6 +172,15 @@ namespace Genode { if (main_thread) _features |= MAIN_THREAD; } + /** + * Return pointer to the thread's PD + * + * Used to validate the success of the bind operation. + * + * XXX to be removed + */ + Platform_pd *pd() { return _pd; } + Native_capability single_step_sync(bool on); /** diff --git a/repos/base-nova/src/core/include/util.h b/repos/base-nova/src/core/include/util.h index 3e24d08825..7dbf9ea464 100644 --- a/repos/base-nova/src/core/include/util.h +++ b/repos/base-nova/src/core/include/util.h @@ -35,11 +35,11 @@ namespace Genode { inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, - Rm_session::Fault_type pf_type, + Region_map::State::Fault_type pf_type, unsigned long faulter_badge) { printf("%s (%s pf_addr=%p pf_ip=%p from %02lx %s)\n", msg, - pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", + pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ", (void *)pf_addr, (void *)pf_ip, faulter_badge, faulter_badge ? reinterpret_cast(faulter_badge) : 0); diff --git a/repos/base-nova/src/core/pager.cc b/repos/base-nova/src/core/pager.cc index 3f4e656d48..0e73d8ecaa 100644 --- a/repos/base-nova/src/core/pager.cc +++ b/repos/base-nova/src/core/pager.cc @@ -444,7 +444,7 @@ void Exception_handlers::register_handler(Pager_object *obj, Mtd mtd, unsigned use_cpu = obj->location.xpos(); if (!kernel_hip()->is_cpu_enabled(use_cpu) || !pager_threads[use_cpu]) { PWRN("invalid CPU parameter used in pager object"); - throw Rm_session::Invalid_thread(); + throw Region_map::Invalid_thread(); } addr_t const ec_sel = pager_threads[use_cpu]->native_thread().ec_sel; @@ -454,7 +454,7 @@ void Exception_handlers::register_handler(Pager_object *obj, Mtd mtd, uint8_t res = create_portal(obj->exc_pt_sel_client() + EV, __core_pd_sel, ec_sel, mtd, entry, obj); if (res != Nova::NOVA_OK) - throw Rm_session::Invalid_thread(); + throw Region_map::Invalid_thread(); } @@ -519,19 +519,19 @@ Pager_object::Pager_object(unsigned long badge, Affinity::Location location) if (Native_thread::INVALID_INDEX == _selectors || Native_thread::INVALID_INDEX == _client_exc_pt_sel) - throw Rm_session::Invalid_thread(); + throw Region_map::Invalid_thread(); /* ypos information not supported by now */ if (location.ypos()) { PWRN("Unsupported location %ux%u", location.xpos(), location.ypos()); - throw Rm_session::Invalid_thread(); + throw Region_map::Invalid_thread(); } /* place Pager_object on specified CPU by selecting proper pager thread */ unsigned use_cpu = location.xpos(); if (!kernel_hip()->is_cpu_enabled(use_cpu) || !pager_threads[use_cpu]) { PWRN("invalid CPU parameter used in pager object"); - throw Rm_session::Invalid_thread(); + throw Region_map::Invalid_thread(); } addr_t ec_sel = pager_threads[use_cpu]->native_thread().ec_sel; @@ -557,7 +557,7 @@ Pager_object::Pager_object(unsigned long badge, Affinity::Location location) */ res = Nova::create_sm(exc_pt_sel_client() + SM_SEL_EC, pd_sel, 0); if (res != Nova::NOVA_OK) { - throw Rm_session::Invalid_thread(); + throw Region_map::Invalid_thread(); } /* create portal for final cleanup call used during destruction */ @@ -565,19 +565,19 @@ Pager_object::Pager_object(unsigned long badge, Affinity::Location location) reinterpret_cast(_invoke_handler), this); if (res != Nova::NOVA_OK) { PERR("could not create pager cleanup portal, error = %u\n", res); - throw Rm_session::Invalid_thread(); + throw Region_map::Invalid_thread(); } /* used to notify caller of as soon as pause succeeded */ res = Nova::create_sm(sel_sm_notify(), pd_sel, 0); if (res != Nova::NOVA_OK) { - throw Rm_session::Invalid_thread(); + throw Region_map::Invalid_thread(); } /* semaphore used to block paged thread during page fault or recall */ res = Nova::create_sm(sel_sm_block(), pd_sel, 0); if (res != Nova::NOVA_OK) { - throw Rm_session::Invalid_thread(); + throw Region_map::Invalid_thread(); } } diff --git a/repos/base-nova/src/core/platform.cc b/repos/base-nova/src/core/platform.cc index 52ee95b5ca..5c603f1658 100644 --- a/repos/base-nova/src/core/platform.cc +++ b/repos/base-nova/src/core/platform.cc @@ -121,7 +121,8 @@ static void page_fault_handler() addr_t pf_type = utcb->qual[0]; print_page_fault("\nPAGE-FAULT IN CORE", pf_addr, pf_ip, - (pf_type & Ipc_pager::ERR_W) ? Rm_session::WRITE_FAULT : Rm_session::READ_FAULT, 0); + (pf_type & Ipc_pager::ERR_W) ? Region_map::State::WRITE_FAULT + : Region_map::State::READ_FAULT, 0); printf("\nstack pointer 0x%lx, qualifiers 0x%lx %s%s%s%s%s\n", pf_sp, pf_type, diff --git a/repos/base-nova/src/core/rm_session_support.cc b/repos/base-nova/src/core/region_map_support.cc similarity index 94% rename from repos/base-nova/src/core/rm_session_support.cc rename to repos/base-nova/src/core/region_map_support.cc index b422106c8a..5cfa91bc89 100644 --- a/repos/base-nova/src/core/rm_session_support.cc +++ b/repos/base-nova/src/core/region_map_support.cc @@ -1,5 +1,5 @@ /* - * \brief RM-session implementation + * \brief Region map implementation * \author Norman Feske * \author Sebastian Sumpf * \date 2009-10-02 diff --git a/repos/base-nova/src/core/target.inc b/repos/base-nova/src/core/target.inc index 8d06bb0ec9..c92a1a0b59 100644 --- a/repos/base-nova/src/core/target.inc +++ b/repos/base-nova/src/core/target.inc @@ -6,7 +6,7 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core SRC_CC = stack_area.cc \ core_mem_alloc.cc \ core_printf.cc \ - core_rm_session.cc \ + core_region_map.cc \ core_rpc_cap_alloc.cc \ cpu_session_component.cc \ cpu_session_extension.cc \ @@ -32,8 +32,8 @@ SRC_CC = stack_area.cc \ platform_thread.cc \ ram_session_component.cc \ ram_session_support.cc \ - rm_session_component.cc \ - rm_session_support.cc \ + region_map_component.cc \ + region_map_support.cc \ rom_session_component.cc \ thread_start.cc \ bios_data_area.cc \ @@ -53,7 +53,7 @@ vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) -vpath rm_session_component.cc $(GEN_CORE_DIR) +vpath region_map_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath io_port_session_component.cc $(GEN_CORE_DIR)/spec/x86 vpath io_mem_session_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-nova/src/test/platform/main.cc b/repos/base-nova/src/test/platform/main.cc index 4901435136..0df899c3ff 100644 --- a/repos/base-nova/src/test/platform/main.cc +++ b/repos/base-nova/src/test/platform/main.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -53,7 +54,8 @@ void test_pat() Test::Capability session_cap = ep.manage(&component); Test::Client client(session_cap); - Genode::Rm_connection rm_free_area(0, 1 << (DS_ORDER + PAGE_4K)); + Genode::Rm_connection rm; + Genode::Region_map_client rm_free_area(rm.create(1 << (DS_ORDER + PAGE_4K))); addr_t remap_addr = Genode::env()->rm_session()->attach(rm_free_area.dataspace()); /* trigger mapping of whole area */ @@ -193,12 +195,14 @@ class Greedy : public Thread<4096> { Thread<0x1000>("greedy") { } - void entry() { + void entry() + { PINF("starting"); enum { SUB_RM_SIZE = 2UL * 1024 * 1024 * 1024 }; - Genode::Rm_connection sub_rm(0, SUB_RM_SIZE); + Genode::Rm_connection rm; + Genode::Region_map_client sub_rm(rm.create(SUB_RM_SIZE)); addr_t const mem = env()->rm_session()->attach(sub_rm.dataspace()); Nova::Utcb * nova_utcb = reinterpret_cast(utcb()); diff --git a/repos/base-okl4/lib/mk/base-common.mk b/repos/base-okl4/lib/mk/base-common.mk index 2920278b0e..a0a4c7daa8 100644 --- a/repos/base-okl4/lib/mk/base-common.mk +++ b/repos/base-okl4/lib/mk/base-common.mk @@ -23,6 +23,7 @@ SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc SRC_CC += thread/myself.cc SRC_CC += thread/stack_allocator.cc SRC_CC += sleep.cc +SRC_CC += region_map_client.cc SRC_CC += rm_session_client.cc SRC_CC += entrypoint/entrypoint.cc SRC_CC += component/component.cc diff --git a/repos/base-okl4/src/core/core_rm_session.cc b/repos/base-okl4/src/core/core_region_map.cc similarity index 85% rename from repos/base-okl4/src/core/core_rm_session.cc rename to repos/base-okl4/src/core/core_region_map.cc index 4bc93e0818..509d012d8a 100644 --- a/repos/base-okl4/src/core/core_rm_session.cc +++ b/repos/base-okl4/src/core/core_region_map.cc @@ -1,5 +1,5 @@ /* - * \brief OKL4-specific implementation of core-local RM session + * \brief OKL4-specific implementation of core-local region map * \author Norman Feske * \date 2009-04-02 */ @@ -13,16 +13,16 @@ /* core includes */ #include -#include +#include #include using namespace Genode; -Rm_session::Local_addr -Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, +Region_map::Local_addr +Core_region_map::attach(Dataspace_capability ds_cap, size_t size, off_t offset, bool use_local_addr, - Rm_session::Local_addr, bool executable) + Region_map::Local_addr, bool executable) { using namespace Okl4; diff --git a/repos/base-okl4/src/core/include/core_region_map.h b/repos/base-okl4/src/core/include/core_region_map.h new file mode 100644 index 0000000000..1343c2225c --- /dev/null +++ b/repos/base-okl4/src/core/include/core_region_map.h @@ -0,0 +1,56 @@ +/* + * \brief OKL4-specific core-local region map + * \author Norman Feske + * \date 2009-04-02 + */ + +/* + * Copyright (C) 2009-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _CORE__INCLUDE__CORE_REGION_MAP_H_ +#define _CORE__INCLUDE__CORE_REGION_MAP_H_ + +/* Genode includes */ +#include +#include + +/* core includes */ +#include + +namespace Genode { class Core_region_map; } + + +class Genode::Core_region_map : public Region_map +{ + private: + + Rpc_entrypoint *_ds_ep; + + public: + + Core_region_map(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } + + Local_addr attach(Dataspace_capability ds_cap, size_t size=0, + off_t offset=0, bool use_local_addr = false, + Local_addr local_addr = 0, + bool executable = false); + + void detach(Local_addr) { } + + Pager_capability add_client(Thread_capability thread) { + return Pager_capability(); } + + void remove_client(Pager_capability) { } + + void fault_handler(Signal_context_capability handler) { } + + State state() { return State(); } + + Dataspace_capability dataspace() { return Dataspace_capability(); } +}; + +#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */ diff --git a/repos/base-okl4/src/core/include/core_rm_session.h b/repos/base-okl4/src/core/include/core_rm_session.h deleted file mode 100644 index f89eda67a4..0000000000 --- a/repos/base-okl4/src/core/include/core_rm_session.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * \brief OKL4-specific core-local region manager session - * \author Norman Feske - * \date 2009-04-02 - */ - -/* - * Copyright (C) 2009-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__CORE_RM_SESSION_H_ -#define _CORE__INCLUDE__CORE_RM_SESSION_H_ - -/* Genode includes */ -#include -#include - -/* core includes */ -#include - -namespace Genode { - - /** - * Region manager that uses the physical dataspace - * addresses directly as virtual addresses. - */ - class Core_rm_session : public Rm_session - { - private: - - Rpc_entrypoint *_ds_ep; - - public: - - Core_rm_session(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } - - Local_addr attach(Dataspace_capability ds_cap, size_t size=0, - off_t offset=0, bool use_local_addr = false, - Local_addr local_addr = 0, - bool executable = false); - - void detach(Local_addr) { } - - Pager_capability add_client(Thread_capability thread) { - return Pager_capability(); } - - void remove_client(Pager_capability) { } - - void fault_handler(Signal_context_capability handler) { } - - State state() { return State(); } - - Dataspace_capability dataspace() { return Dataspace_capability(); } - }; -} - -#endif /* _CORE__INCLUDE__CORE_RM_SESSION_H_ */ diff --git a/repos/base-okl4/src/core/include/platform.h b/repos/base-okl4/src/core/include/platform.h index df33f06218..c35be27bf5 100644 --- a/repos/base-okl4/src/core/include/platform.h +++ b/repos/base-okl4/src/core/include/platform.h @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include /* OKL4 includes */ diff --git a/repos/base-okl4/src/core/include/util.h b/repos/base-okl4/src/core/include/util.h index cd61c97120..e30fb51c01 100644 --- a/repos/base-okl4/src/core/include/util.h +++ b/repos/base-okl4/src/core/include/util.h @@ -114,11 +114,11 @@ namespace Genode { } inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, - Rm_session::Fault_type pf_type, + Region_map::State::Fault_type pf_type, unsigned long faulter_badge) { printf("%s (%s pf_addr=%p pf_ip=%p from %02lx)\n", msg, - pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", + pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ", (void *)pf_addr, (void *)pf_ip, faulter_badge); } diff --git a/repos/base-okl4/src/core/rm_session_support.cc b/repos/base-okl4/src/core/region_map_support.cc similarity index 85% rename from repos/base-okl4/src/core/rm_session_support.cc rename to repos/base-okl4/src/core/region_map_support.cc index 49fddeb1a9..94710d37ef 100644 --- a/repos/base-okl4/src/core/rm_session_support.cc +++ b/repos/base-okl4/src/core/region_map_support.cc @@ -1,5 +1,5 @@ /* - * \brief OKL4-specific part of RM-session implementation + * \brief OKL4-specific part of region-map implementation * \author Norman Feske * \date 2009-04-10 */ @@ -15,7 +15,7 @@ #include /* core includes */ -#include +#include using namespace Genode; diff --git a/repos/base-okl4/src/core/target.inc b/repos/base-okl4/src/core/target.inc index 014c44bda8..ecc1f49716 100644 --- a/repos/base-okl4/src/core/target.inc +++ b/repos/base-okl4/src/core/target.inc @@ -7,7 +7,7 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core SRC_CC += stack_area.cc \ core_mem_alloc.cc \ core_printf.cc \ - core_rm_session.cc \ + core_region_map.cc \ core_rpc_cap_alloc.cc \ cpu_session_component.cc \ cpu_session_support.cc \ @@ -30,8 +30,8 @@ SRC_CC += stack_area.cc \ platform_thread.cc \ ram_session_component.cc \ ram_session_support.cc \ - rm_session_component.cc \ - rm_session_support.cc \ + region_map_component.cc \ + region_map_support.cc \ rom_session_component.cc \ signal_source_component.cc \ thread_start.cc \ @@ -51,7 +51,7 @@ vpath pd_session_component.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath rpc_cap_factory.cc $(GEN_CORE_DIR) -vpath rm_session_component.cc $(GEN_CORE_DIR) +vpath region_map_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-pistachio/lib/mk/base-common.mk b/repos/base-pistachio/lib/mk/base-common.mk index 7717bb8135..93b7ee7973 100644 --- a/repos/base-pistachio/lib/mk/base-common.mk +++ b/repos/base-pistachio/lib/mk/base-common.mk @@ -23,6 +23,7 @@ SRC_CC += thread/thread.cc thread/trace.cc thread/thread_bootstrap.cc SRC_CC += thread/myself.cc SRC_CC += thread/stack_allocator.cc SRC_CC += sleep.cc +SRC_CC += region_map_client.cc SRC_CC += rm_session_client.cc SRC_CC += entrypoint/entrypoint.cc SRC_CC += component/component.cc diff --git a/repos/base-pistachio/src/core/include/platform_pd.h b/repos/base-pistachio/src/core/include/platform_pd.h index c5cb994f91..2f4500a661 100644 --- a/repos/base-pistachio/src/core/include/platform_pd.h +++ b/repos/base-pistachio/src/core/include/platform_pd.h @@ -230,7 +230,7 @@ namespace Genode { /* * On Pistachio, we don't use directed unmap but rely on the - * in-kernel mapping database. See 'rm_session_support.cc'. + * in-kernel mapping database. See 'region_map_support.cc'. */ void flush(addr_t, size_t) { PDBG("not implemented"); } }; diff --git a/repos/base-pistachio/src/core/include/platform_thread.h b/repos/base-pistachio/src/core/include/platform_thread.h index a7e622d995..220a5863b8 100644 --- a/repos/base-pistachio/src/core/include/platform_thread.h +++ b/repos/base-pistachio/src/core/include/platform_thread.h @@ -120,6 +120,15 @@ namespace Genode { */ void unbind(); + /** + * Return pointer to the thread's PD + * + * Used to validate the success of the bind operation. + * + * XXX to be removed + */ + Platform_pd *pd() { return _platform_pd; } + /** * Override thread state with 's' * diff --git a/repos/base-pistachio/src/core/include/util.h b/repos/base-pistachio/src/core/include/util.h index a18d392822..e5f601b138 100644 --- a/repos/base-pistachio/src/core/include/util.h +++ b/repos/base-pistachio/src/core/include/util.h @@ -107,13 +107,13 @@ namespace Genode { } inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, - Rm_session::Fault_type pf_type, + Region_map::State::Fault_type pf_type, unsigned long badge) { Pistachio::L4_ThreadId_t tid; tid.raw = badge; printf("%s (%s pf_addr=%p pf_ip=%p from %02lx (raw %08lx))\n", msg, - pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", + pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ", (void *)pf_addr, (void *)pf_ip, Pistachio::L4_GlobalId(tid).global.X.thread_no, tid.raw); } diff --git a/repos/base-pistachio/src/core/rm_session_support.cc b/repos/base-pistachio/src/core/region_map_support.cc similarity index 95% rename from repos/base-pistachio/src/core/rm_session_support.cc rename to repos/base-pistachio/src/core/region_map_support.cc index 8130d0bfff..ab15abac16 100644 --- a/repos/base-pistachio/src/core/rm_session_support.cc +++ b/repos/base-pistachio/src/core/region_map_support.cc @@ -1,5 +1,5 @@ /* - * \brief Pistachio-specific part of RM-session implementation + * \brief Pistachio-specific part of region-map implementation * \author Norman Feske * \date 2009-04-10 */ diff --git a/repos/base-pistachio/src/core/target.inc b/repos/base-pistachio/src/core/target.inc index ef57fe5b6b..a55d4c80b8 100644 --- a/repos/base-pistachio/src/core/target.inc +++ b/repos/base-pistachio/src/core/target.inc @@ -30,8 +30,8 @@ SRC_CC = stack_area.cc \ platform_thread.cc \ ram_session_component.cc \ ram_session_support.cc \ - rm_session_component.cc \ - rm_session_support.cc \ + region_map_component.cc \ + region_map_support.cc \ rom_session_component.cc \ signal_source_component.cc \ thread_start.cc \ @@ -51,7 +51,7 @@ vpath pd_session_component.cc $(GEN_CORE_DIR) vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) -vpath rm_session_component.cc $(GEN_CORE_DIR) +vpath region_map_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-sel4/include/pd_session/connection.h b/repos/base-sel4/include/pd_session/connection.h deleted file mode 100644 index ff88ee8dbd..0000000000 --- a/repos/base-sel4/include/pd_session/connection.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * \brief Connection to PD service - * \author Norman Feske - * \date 2008-08-22 - */ - -/* - * Copyright (C) 2008-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _INCLUDE__PD_SESSION__CONNECTION_H_ -#define _INCLUDE__PD_SESSION__CONNECTION_H_ - -#include -#include - -namespace Genode { struct Pd_connection; } - - -struct Genode::Pd_connection : Connection, Pd_session_client -{ - enum { RAM_QUOTA = 64*1024 }; - - /** - * Constructor - * - * \param label session label - */ - Pd_connection(char const *label = "") - : Connection(session("ram_quota=%u, label=\"%s\"", - RAM_QUOTA, label)), - Pd_session_client(cap()) - { } -}; - -#endif /* _INCLUDE__PD_SESSION__CONNECTION_H_ */ diff --git a/repos/base-sel4/lib/mk/base-common.inc b/repos/base-sel4/lib/mk/base-common.inc index 9c6cd6ae05..1db231895a 100644 --- a/repos/base-sel4/lib/mk/base-common.inc +++ b/repos/base-sel4/lib/mk/base-common.inc @@ -25,6 +25,7 @@ SRC_CC += thread/stack_allocator.cc SRC_CC += thread/thread_bootstrap.cc SRC_CC += env/capability.cc SRC_CC += sleep.cc +SRC_CC += region_map_client.cc SRC_CC += rm_session_client.cc SRC_CC += entrypoint/entrypoint.cc SRC_CC += component/component.cc diff --git a/repos/base-sel4/lib/mk/core.mk b/repos/base-sel4/lib/mk/core.mk index 004b095e33..5e9d1e5ba2 100644 --- a/repos/base-sel4/lib/mk/core.mk +++ b/repos/base-sel4/lib/mk/core.mk @@ -21,12 +21,12 @@ SRC_CC += \ platform_services.cc \ platform.cc \ dataspace_component.cc \ - rm_session_component.cc \ - rm_session_support.cc \ + region_map_component.cc \ + region_map_support.cc \ irq_session_component.cc \ signal_source_component.cc \ trace_session_component.cc \ - core_rm_session.cc \ + core_region_map.cc \ core_mem_alloc.cc \ core_rpc_cap_alloc.cc \ dump_alloc.cc \ @@ -50,7 +50,7 @@ vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) -vpath rm_session_component.cc $(GEN_CORE_DIR) +vpath region_map_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath platform_services.cc $(GEN_CORE_DIR) diff --git a/repos/base-sel4/src/core/core_rm_session.cc b/repos/base-sel4/src/core/core_region_map.cc similarity index 87% rename from repos/base-sel4/src/core/core_rm_session.cc rename to repos/base-sel4/src/core/core_region_map.cc index 428522e3a3..75415a33c9 100644 --- a/repos/base-sel4/src/core/core_rm_session.cc +++ b/repos/base-sel4/src/core/core_region_map.cc @@ -1,5 +1,5 @@ /* - * \brief Core-local RM session + * \brief Core-local region map * \author Norman Feske * \date 2015-05-01 */ @@ -15,17 +15,17 @@ #include /* core includes */ -#include +#include #include #include using namespace Genode; -Rm_session::Local_addr -Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, +Region_map::Local_addr +Core_region_map::attach(Dataspace_capability ds_cap, size_t size, off_t offset, bool use_local_addr, - Rm_session::Local_addr local_addr, + Region_map::Local_addr local_addr, bool executable) { auto lambda = [&] (Dataspace_component *ds) -> Local_addr { diff --git a/repos/base-sel4/src/core/include/core_rm_session.h b/repos/base-sel4/src/core/include/core_region_map.h similarity index 83% rename from repos/base-sel4/src/core/include/core_rm_session.h rename to repos/base-sel4/src/core/include/core_region_map.h index 3507c5c488..a58d16d096 100644 --- a/repos/base-sel4/src/core/include/core_rm_session.h +++ b/repos/base-sel4/src/core/include/core_region_map.h @@ -1,5 +1,5 @@ /* - * \brief Core-local RM session + * \brief Core-local region map * \author Norman Feske * \date 2015-05-01 */ @@ -16,15 +16,15 @@ /* Genode includes */ #include -#include +#include /* core includes */ #include -namespace Genode { class Core_rm_session; } +namespace Genode { class Core_region_map; } -class Genode::Core_rm_session : public Rm_session +class Genode::Core_region_map : public Region_map { private: @@ -32,7 +32,7 @@ class Genode::Core_rm_session : public Rm_session public: - Core_rm_session(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } + Core_region_map(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } Local_addr attach(Dataspace_capability ds_cap, size_t size = 0, off_t offset = 0, bool use_local_addr = false, diff --git a/repos/base-sel4/src/core/include/platform_thread.h b/repos/base-sel4/src/core/include/platform_thread.h index ee62c294e4..1f5b6cb7c7 100644 --- a/repos/base-sel4/src/core/include/platform_thread.h +++ b/repos/base-sel4/src/core/include/platform_thread.h @@ -173,6 +173,15 @@ class Genode::Platform_thread : public List::Element */ const char *name() const { return "noname"; } + /** + * Return pointer to the thread's PD + * + * Used to validate the success of the bind operation. + * + * XXX to be removed + */ + Platform_pd *pd() { return _pd; } + /***************************** ** seL4-specific interface ** diff --git a/repos/base-sel4/src/core/include/util.h b/repos/base-sel4/src/core/include/util.h index 9c7f52a305..6607845def 100644 --- a/repos/base-sel4/src/core/include/util.h +++ b/repos/base-sel4/src/core/include/util.h @@ -35,11 +35,11 @@ namespace Genode { inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, - Rm_session::Fault_type pf_type, + Region_map::State::Fault_type pf_type, unsigned long faulter_badge) { printf("%s (%s pf_addr=%p pf_ip=%p from %02lx)\n", msg, - pf_type == Rm_session::WRITE_FAULT ? "WRITE" : "READ", + pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ", (void *)pf_addr, (void *)pf_ip, faulter_badge); } diff --git a/repos/base-sel4/src/core/rm_session_support.cc b/repos/base-sel4/src/core/region_map_support.cc similarity index 88% rename from repos/base-sel4/src/core/rm_session_support.cc rename to repos/base-sel4/src/core/region_map_support.cc index e1ecd12b2a..ae88da3a5f 100644 --- a/repos/base-sel4/src/core/rm_session_support.cc +++ b/repos/base-sel4/src/core/region_map_support.cc @@ -1,5 +1,5 @@ /* - * \brief Kernel-specific supplements of the RM service + * \brief Kernel-specific supplements of the region-map implementation * \author Norman Feske * \date 2015-05-01 */ diff --git a/repos/base-sel4/src/core/stack_area.cc b/repos/base-sel4/src/core/stack_area.cc index de5ce48ac9..6d455c78e1 100644 --- a/repos/base-sel4/src/core/stack_area.cc +++ b/repos/base-sel4/src/core/stack_area.cc @@ -13,7 +13,7 @@ */ /* Genode includes */ -#include +#include #include #include #include @@ -27,6 +27,7 @@ /* base-internal includes */ #include +#include using namespace Genode; @@ -42,7 +43,7 @@ using namespace Genode; * place, the allocation of a dataspace has no effect, but the attachment of * the thereby "empty" dataspace is doing both: allocation and attachment. */ -class Stack_area_rm_session : public Rm_session +class Stack_area_region_map : public Region_map { private: @@ -135,13 +136,13 @@ class Stack_area_ram_session : public Ram_session namespace Genode { - Rm_session *env_stack_area_rm_session; + Region_map *env_stack_area_region_map; Ram_session *env_stack_area_ram_session; void init_stack_area() { - static Stack_area_rm_session rm_inst; - env_stack_area_rm_session = &rm_inst; + static Stack_area_region_map rm_inst; + env_stack_area_region_map = &rm_inst; static Stack_area_ram_session ram_inst; env_stack_area_ram_session = &ram_inst; diff --git a/repos/base/include/base/child.h b/repos/base/include/base/child.h index 4965620959..e79a78b2f6 100644 --- a/repos/base/include/base/child.h +++ b/repos/base/include/base/child.h @@ -165,14 +165,10 @@ class Genode::Child : protected Rpc_object /* CPU session that contains the quota of the child */ Cpu_session_capability _cpu; - /* RM session representing the address space of the child */ - Rm_session_capability _rm; - - /* Services where the PD, RAM, CPU, and RM resources come from */ + /* services where the PD, RAM, and CPU resources come from */ Service &_pd_service; Service &_ram_service; Service &_cpu_service; - Service &_rm_service; /* heap for child-specific allocations using the child's quota */ Heap _heap; @@ -238,14 +234,11 @@ class Genode::Child : protected Rpc_object * \param pd PD session representing the protection domain * \param ram RAM session with the child's quota * \param cpu CPU session with the child's quota - * \param rm RM session representing the address space - * of the child * \param entrypoint server entrypoint to serve the parent interface * \param policy child policy * \param pd_service provider of the 'pd' session * \param ram_service provider of the 'ram' session * \param cpu_service provider of the 'cpu' session - * \param rm_service provider of the 'rm' session * * If assigning a separate entry point to each child, the host of * multiple children is able to handle a blocking invocation of @@ -253,7 +246,7 @@ class Genode::Child : protected Rpc_object * service to other children, each having an independent entry * point. * - * The 'ram_service', 'cpu_service', and 'rm_service' arguments are + * The 'ram_service', 'cpu_service', and 'pd_service' arguments are * needed to direct quota upgrades referring to the resources of * the child environment. By default, we expect that these * resources are provided by the parent. @@ -262,13 +255,11 @@ class Genode::Child : protected Rpc_object Pd_session_capability pd, Ram_session_capability ram, Cpu_session_capability cpu, - Rm_session_capability rm, Rpc_entrypoint *entrypoint, Child_policy *policy, Service &pd_service = *_parent_service(), Service &ram_service = *_parent_service(), - Service &cpu_service = *_parent_service(), - Service &rm_service = *_parent_service()); + Service &cpu_service = *_parent_service()); /** * Destructor @@ -286,7 +277,6 @@ class Genode::Child : protected Rpc_object Pd_session_capability pd_session_cap() const { return _pd; } Ram_session_capability ram_session_cap() const { return _ram; } Cpu_session_capability cpu_session_cap() const { return _cpu; } - Rm_session_capability rm_session_cap() const { return _rm; } Parent_capability parent_cap() const { return cap(); } /** diff --git a/repos/base/include/base/component.h b/repos/base/include/base/component.h index 030b503366..a7e2f8491b 100644 --- a/repos/base/include/base/component.h +++ b/repos/base/include/base/component.h @@ -57,9 +57,9 @@ struct Genode::Environment virtual Cpu_session &cpu() = 0; /** - * Region-manager session of the component as created by the parent + * Region map of the component's address space */ - virtual Rm_session &rm() = 0; + virtual Region_map &rm() = 0; /** * PD session of the component as created by the parent diff --git a/repos/base/include/base/env.h b/repos/base/include/base/env.h index b6920c184c..be18e1e7e3 100644 --- a/repos/base/include/base/env.h +++ b/repos/base/include/base/env.h @@ -16,8 +16,8 @@ #include #include -#include -#include +#include +#include /* deprecated, kept for API compatibility only */ #include #include #include @@ -73,8 +73,12 @@ struct Genode::Env /** * Region-manager session of the component as created by the parent + * + * \deprecated This function exists for API compatibility only. + * The functionality of the former RM service is now + * provided by the 'Region_map' interface. */ - virtual Rm_session *rm_session() = 0; + virtual Region_map *rm_session() = 0; /** * PD session of the component as created by the parent @@ -113,7 +117,7 @@ struct Genode::Env * * \noapi */ - virtual void reinit_main_thread(Rm_session_capability &stack_area_rm) = 0; + virtual void reinit_main_thread(Capability &stack_area_rm) = 0; }; diff --git a/repos/base/include/base/heap.h b/repos/base/include/base/heap.h index 982f6f2970..4b92131b22 100644 --- a/repos/base/include/base/heap.h +++ b/repos/base/include/base/heap.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -74,15 +74,15 @@ class Genode::Heap : public Allocator struct Dataspace_pool : public List { Ram_session *ram_session; /* RAM session for backing store */ - Rm_session *rm_session; + Region_map *region_map; - Dataspace_pool(Ram_session *ram, Rm_session *rm) - : ram_session(ram), rm_session(rm) { } + Dataspace_pool(Ram_session *ram, Region_map *rm) + : ram_session(ram), region_map(rm) { } ~Dataspace_pool(); - void reassign_resources(Ram_session *ram, Rm_session *rm) { - ram_session = ram, rm_session = rm; } + void reassign_resources(Ram_session *ram, Region_map *rm) { + ram_session = ram, region_map = rm; } }; Lock _lock; @@ -98,8 +98,8 @@ class Genode::Heap : public Allocator * \param size number of bytes to allocate * \param enforce_separate_metadata if true, the new dataspace * will not contain any meta data - * \throw Rm_session::Invalid_dataspace, - * Rm_session::Region_conflict + * \throw Region_map::Invalid_dataspace, + * Region_map::Region_conflict * \return 0 on success or negative error code */ Heap::Dataspace *_allocate_dataspace(size_t size, bool enforce_separate_metadata); @@ -124,13 +124,13 @@ class Genode::Heap : public Allocator enum { UNLIMITED = ~0 }; Heap(Ram_session *ram_session, - Rm_session *rm_session, + Region_map *region_map, size_t quota_limit = UNLIMITED, void *static_addr = 0, size_t static_size = 0) : _alloc(nullptr), - _ds_pool(ram_session, rm_session), + _ds_pool(ram_session, region_map), _quota_limit(quota_limit), _quota_used(0), _chunk_size(MIN_CHUNK_SIZE) { @@ -151,7 +151,7 @@ class Genode::Heap : public Allocator /** * Re-assign RAM and RM sessions */ - void reassign_resources(Ram_session *ram, Rm_session *rm) { + void reassign_resources(Ram_session *ram, Region_map *rm) { _ds_pool.reassign_resources(ram, rm); } @@ -176,18 +176,18 @@ class Genode::Sliced_heap : public Allocator class Block; - Ram_session *_ram_session; /* RAM session for backing store */ - Rm_session *_rm_session; /* region manager */ - size_t _consumed; /* number of allocated bytes */ - List _block_list; /* list of allocated blocks */ - Lock _lock; /* serialize allocations */ + Ram_session *_ram_session; /* RAM session for backing store */ + Region_map *_region_map; /* region map of the address space */ + size_t _consumed; /* number of allocated bytes */ + List _block_list; /* list of allocated blocks */ + Lock _lock; /* serialize allocations */ public: /** * Constructor */ - Sliced_heap(Ram_session *ram_session, Rm_session *rm_session); + Sliced_heap(Ram_session *ram_session, Region_map *region_map); /** * Destructor diff --git a/repos/base/include/base/process.h b/repos/base/include/base/process.h index 700f8eb60e..cc972a8ee3 100644 --- a/repos/base/include/base/process.h +++ b/repos/base/include/base/process.h @@ -15,7 +15,7 @@ #define _INCLUDE__BASE__PROCESS_H_ #include -#include +#include #include #include #include @@ -30,7 +30,6 @@ class Genode::Process Pd_session_client _pd_session_client; Thread_capability _thread0_cap; Cpu_session_client _cpu_session_client; - Rm_session_client _rm_session_client; static Dataspace_capability _dynamic_linker_cap; @@ -44,7 +43,6 @@ class Genode::Process * \param ram_session RAM session providing the BSS for the * new protection domain * \param cpu_session CPU session for the new protection domain - * \param rm_session RM session for the new protection domain * \param parent parent of the new protection domain * \param name name of protection domain (can be used * for debugging) @@ -58,7 +56,6 @@ class Genode::Process Pd_session_capability pd_session, Ram_session_capability ram_session, Cpu_session_capability cpu_session, - Rm_session_capability rm_session, Parent_capability parent, char const *name); diff --git a/repos/base/include/pager/capability.h b/repos/base/include/pager/capability.h index 7c57614f1c..cec4dff619 100644 --- a/repos/base/include/pager/capability.h +++ b/repos/base/include/pager/capability.h @@ -19,7 +19,7 @@ namespace Genode { /* - * The 'Pager_capability' type is returned by 'Rm_session::add_client' and + * The 'Pager_capability' type is returned by 'Region_map::add_client' and * passed as argument to 'Cpu_session::set_pager'. It is never invoked or * otherwise used. */ diff --git a/repos/base/include/pd_session/client.h b/repos/base/include/pd_session/client.h index d8971849f4..ab42423d7b 100644 --- a/repos/base/include/pd_session/client.h +++ b/repos/base/include/pd_session/client.h @@ -56,6 +56,15 @@ struct Genode::Pd_session_client : Rpc_client void free_rpc_cap(Native_capability cap) override { call(cap); } + Capability address_space() override { + return call(); } + + Capability stack_area() override { + return call(); } + + Capability linker_area() override { + return call(); } + Capability native_pd() override { return call(); } }; diff --git a/repos/base/include/pd_session/connection.h b/repos/base/include/pd_session/connection.h index 9280547a05..6eee00fe2b 100644 --- a/repos/base/include/pd_session/connection.h +++ b/repos/base/include/pd_session/connection.h @@ -22,7 +22,7 @@ namespace Genode { struct Pd_connection; } struct Genode::Pd_connection : Connection, Pd_session_client { - enum { RAM_QUOTA = 4*1024*sizeof(long) }; + enum { RAM_QUOTA = 20*1024*sizeof(long) }; /** * Constructor diff --git a/repos/base/include/pd_session/pd_session.h b/repos/base/include/pd_session/pd_session.h index b819d834d9..c2974c65c0 100644 --- a/repos/base/include/pd_session/pd_session.h +++ b/repos/base/include/pd_session/pd_session.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace Genode { @@ -155,6 +156,28 @@ struct Genode::Pd_session : Session virtual void free_rpc_cap(Native_capability cap) = 0; + /************************************** + ** Virtual address-space management ** + **************************************/ + + enum { LINKER_AREA_SIZE = 160*1024*1024UL }; + + /** + * Return region map of the PD's virtual address space + */ + virtual Capability address_space() = 0; + + /** + * Return region map of the PD's stack area + */ + virtual Capability stack_area() = 0; + + /** + * Return region map of the PD's linker area + */ + virtual Capability linker_area() = 0; + + /***************************************** ** Access to kernel-specific interface ** *****************************************/ @@ -180,23 +203,22 @@ struct Genode::Pd_session : Session GENODE_RPC_THROW(Rpc_alloc_signal_source, Signal_source_capability, alloc_signal_source, GENODE_TYPE_LIST(Out_of_metadata)); - GENODE_RPC(Rpc_free_signal_source, void, free_signal_source, Signal_source_capability); - GENODE_RPC_THROW(Rpc_alloc_context, Capability, alloc_context, GENODE_TYPE_LIST(Out_of_metadata, Invalid_signal_source), Signal_source_capability, unsigned long); - GENODE_RPC(Rpc_free_context, void, free_context, Capability); - GENODE_RPC(Rpc_submit, void, submit, Capability, unsigned); GENODE_RPC_THROW(Rpc_alloc_rpc_cap, Native_capability, alloc_rpc_cap, GENODE_TYPE_LIST(Out_of_metadata), Native_capability); - GENODE_RPC(Rpc_free_rpc_cap, void, free_rpc_cap, Native_capability); + GENODE_RPC(Rpc_address_space, Capability, address_space); + GENODE_RPC(Rpc_stack_area, Capability, stack_area); + GENODE_RPC(Rpc_linker_area, Capability, linker_area); + GENODE_RPC(Rpc_native_pd, Capability, native_pd); /* @@ -212,9 +234,12 @@ struct Genode::Pd_session : Session Meta::Type_tuple - > > > > > > > > > > Rpc_functions; + > > > > > > > > > > > > > Rpc_functions; }; #endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */ diff --git a/repos/base/include/ram_session/connection.h b/repos/base/include/ram_session/connection.h index 60089aabb0..bd79e8a273 100644 --- a/repos/base/include/ram_session/connection.h +++ b/repos/base/include/ram_session/connection.h @@ -22,7 +22,8 @@ namespace Genode { struct Ram_connection; } struct Genode::Ram_connection : Connection, Ram_session_client { - enum { RAM_QUOTA = 64*1024 }; + enum { RAM_QUOTA = 4*1024*sizeof(long) }; + /** * Constructor * diff --git a/repos/base/include/region_map/client.h b/repos/base/include/region_map/client.h new file mode 100644 index 0000000000..48e790b0f1 --- /dev/null +++ b/repos/base/include/region_map/client.h @@ -0,0 +1,57 @@ +/* + * \brief Client-side stub for region map + * \author Christian Helmuth + * \author Norman Feske + * \date 2006-07-11 + */ + +/* + * Copyright (C) 2006-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__REGION_MAP__CLIENT_H_ +#define _INCLUDE__REGION_MAP__CLIENT_H_ + +#include +#include + +namespace Genode { class Region_map_client; } + + +class Genode::Region_map_client : public Rpc_client +{ + private: + + /* + * Multiple calls to get the dataspace capability on NOVA lead to the + * situation that the caller gets each time a new mapping of the same + * capability at different indices. But the client/caller assumes to + * get every time the very same index, e.g., in Noux the index is used + * to look up data structures attached to the capability. Therefore, we + * cache the dataspace capability on the first request. + * + * On all other base platforms, this member variable remains unused. + */ + Dataspace_capability _rm_ds_cap; + + public: + + explicit Region_map_client(Capability); + + Local_addr attach(Dataspace_capability ds, size_t size = 0, + off_t offset = 0, bool use_local_addr = false, + Local_addr local_addr = (void *)0, + bool executable = false) override; + + void detach(Local_addr) override; + Pager_capability add_client(Thread_capability) override; + void remove_client(Pager_capability) override; + void fault_handler(Signal_context_capability) override; + State state() override; + Dataspace_capability dataspace() override; +}; + +#endif /* _INCLUDE__REGION_MAP__CLIENT_H_ */ diff --git a/repos/base/include/region_map/region_map.h b/repos/base/include/region_map/region_map.h new file mode 100644 index 0000000000..d1987a5776 --- /dev/null +++ b/repos/base/include/region_map/region_map.h @@ -0,0 +1,210 @@ +/* + * \brief Region map interface + * \author Norman Feske + * \date 2006-05-15 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__REGION_MAP__REGION_MAP_H_ +#define _INCLUDE__REGION_MAP__REGION_MAP_H_ + +#include +#include +#include +#include +#include +#include + +namespace Genode { struct Region_map; } + + +struct Genode::Region_map +{ + /** + * State of region map + * + * If a thread accesses a location outside the regions attached to its + * address space, a fault occurs and gets signalled to the registered fault + * handler. The fault handler, in turn needs the information about the + * fault address and fault type to resolve the fault. This information is + * represented by this structure. + */ + struct State + { + enum Fault_type { READY, READ_FAULT, WRITE_FAULT, EXEC_FAULT }; + + /** + * Type of occurred fault + */ + Fault_type type = READY; + + /** + * Fault address + */ + addr_t addr = 0; + + /** + * Default constructor + */ + State() { } + + /** + * Constructor + */ + State(Fault_type fault_type, addr_t fault_addr) + : type(fault_type), addr(fault_addr) { } + }; + + + /** + * Helper for tranferring the bit representation of a pointer as RPC + * argument. + */ + class Local_addr + { + private: + + void *_ptr = nullptr; + + public: + + template + Local_addr(T ptr) : _ptr((void *)ptr) { } + + Local_addr() { } + + template + operator T () { return (T)_ptr; } + }; + + + /********************* + ** Exception types ** + *********************/ + + class Attach_failed : public Exception { }; + class Invalid_args : public Attach_failed { }; + class Invalid_dataspace : public Attach_failed { }; + class Region_conflict : public Attach_failed { }; + class Out_of_metadata : public Attach_failed { }; + + class Invalid_thread : public Exception { }; + class Unbound_thread : public Exception { }; + + + /** + * Map dataspace into local address space + * + * \param ds capability of dataspace to map + * \param size size of the locally mapped region + * default (0) is the whole dataspace + * \param offset start at offset in dataspace (page-aligned) + * \param use_local_addr if set to true, attach the dataspace at + * the specified 'local_addr' + * \param local_addr local destination address + * \param executable if the mapping should be executable + * + * \throw Attach_failed if dataspace or offset is invalid, + * or on region conflict + * \throw Out_of_metadata if meta-data backing store is exhausted + * + * \return local address of mapped dataspace + * + */ + virtual Local_addr attach(Dataspace_capability ds, + size_t size = 0, off_t offset = 0, + bool use_local_addr = false, + Local_addr local_addr = (void *)0, + bool executable = false) = 0; + + /** + * Shortcut for attaching a dataspace at a predefined local address + */ + Local_addr attach_at(Dataspace_capability ds, addr_t local_addr, + size_t size = 0, off_t offset = 0) { + return attach(ds, size, offset, true, local_addr); } + + /** + * Shortcut for attaching a dataspace executable at a predefined local address + */ + Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr, + size_t size = 0, off_t offset = 0) { + return attach(ds, size, offset, true, local_addr, true); } + + /** + * Remove region from local address space + */ + virtual void detach(Local_addr local_addr) = 0; + + /** + * Add client to pager + * + * \param thread thread that will be paged + * \throw Invalid_thread + * \throw Out_of_metadata + * \throw Unbound_thread + * \return capability to be used for handling page faults + * + * This method must be called at least once to establish a valid + * communication channel between the pager part of the region manager + * and the client thread. + */ + virtual Pager_capability add_client(Thread_capability thread) = 0; + + /** + * Remove client from pager + * + * \param pager pager capability of client to be removed + */ + virtual void remove_client(Pager_capability) = 0; + + /** + * Register signal handler for region-manager faults + * + * On Linux, this signal is never delivered because page-fault handling + * is performed by the Linux kernel. On microkernel platforms, + * unresolvable page faults (traditionally called segmentation fault) + * will result in the delivery of the signal. + */ + virtual void fault_handler(Signal_context_capability handler) = 0; + + /** + * Request current state of region map + */ + virtual State state() = 0; + + /** + * Return dataspace representation of region map + */ + virtual Dataspace_capability dataspace() = 0; + + + /********************* + ** RPC declaration ** + *********************/ + + GENODE_RPC_THROW(Rpc_attach, Local_addr, attach, + GENODE_TYPE_LIST(Invalid_dataspace, Region_conflict, + Out_of_metadata, Invalid_args), + Dataspace_capability, size_t, off_t, bool, Local_addr, bool); + GENODE_RPC(Rpc_detach, void, detach, Local_addr); + GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client, + GENODE_TYPE_LIST(Unbound_thread, Invalid_thread, Out_of_metadata), + Thread_capability); + GENODE_RPC(Rpc_remove_client, void, remove_client, Pager_capability); + GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability); + GENODE_RPC(Rpc_state, State, state); + GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace); + + GENODE_RPC_INTERFACE(Rpc_attach, Rpc_detach, Rpc_add_client, + Rpc_remove_client, Rpc_fault_handler, Rpc_state, + Rpc_dataspace); +}; + +#endif /* _INCLUDE__REGION_MAP__REGION_MAP_H_ */ diff --git a/repos/base/include/rm_session/client.h b/repos/base/include/rm_session/client.h index 6065ae3241..aa5ee57d0f 100644 --- a/repos/base/include/rm_session/client.h +++ b/repos/base/include/rm_session/client.h @@ -1,12 +1,11 @@ /* * \brief Client-side region manager session interface - * \author Christian Helmuth * \author Norman Feske - * \date 2006-07-11 + * \date 2016-04-15 */ /* - * Copyright (C) 2006-2016 Genode Labs GmbH + * Copyright (C) 2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -18,40 +17,15 @@ #include #include -namespace Genode { class Rm_session_client; } +namespace Genode { struct Rm_session_client; } -class Genode::Rm_session_client : public Rpc_client +struct Genode::Rm_session_client : Rpc_client { - private: + explicit Rm_session_client(Rm_session_capability); - /* - * Multiple calls to get the dataspace capability on NOVA lead to the - * situation that the caller gets each time a new mapping of the same - * capability at different indices. But the client/caller assumes to - * get every time the very same index, e.g., in Noux the index is used - * to look up data structures attached to the capability. Therefore, we - * cache the dataspace capability on the first request. - * - * On all other base platforms, this member variable remains unused. - */ - Dataspace_capability _rm_ds_cap; - - public: - - explicit Rm_session_client(Rm_session_capability session); - - Local_addr attach(Dataspace_capability ds, size_t size = 0, - off_t offset = 0, bool use_local_addr = false, - Local_addr local_addr = (void *)0, - bool executable = false) override; - - void detach(Local_addr) override; - Pager_capability add_client(Thread_capability) override; - void remove_client(Pager_capability) override; - void fault_handler(Signal_context_capability) override; - State state() override; - Dataspace_capability dataspace() override; + Capability create(size_t) override; + void destroy(Capability) override; }; #endif /* _INCLUDE__RM_SESSION__CLIENT_H_ */ diff --git a/repos/base/include/rm_session/connection.h b/repos/base/include/rm_session/connection.h index 88afd1173a..9fc2f0b22a 100644 --- a/repos/base/include/rm_session/connection.h +++ b/repos/base/include/rm_session/connection.h @@ -24,16 +24,8 @@ struct Genode::Rm_connection : Connection, Rm_session_client { enum { RAM_QUOTA = 64*1024 }; - /** - * Constructor - * - * \param start start of the managed VM-region - * \param size size of the VM-region to manage - */ - Rm_connection(addr_t start = ~0UL, size_t size = 0) : - Connection( - session("ram_quota=%u, start=0x%p, size=0x%zx", - RAM_QUOTA, start, size)), + Rm_connection() : + Connection(session("ram_quota=%u", RAM_QUOTA)), Rm_session_client(cap()) { } }; diff --git a/repos/base/include/rm_session/rm_session.h b/repos/base/include/rm_session/rm_session.h index baa139a121..e932668057 100644 --- a/repos/base/include/rm_session/rm_session.h +++ b/repos/base/include/rm_session/rm_session.h @@ -1,11 +1,11 @@ /* - * \brief Region manager session interface + * \brief Region-map session interface * \author Norman Feske - * \date 2006-05-15 + * \date 2016-04-15 */ /* - * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -14,12 +14,7 @@ #ifndef _INCLUDE__RM_SESSION__RM_SESSION_H_ #define _INCLUDE__RM_SESSION__RM_SESSION_H_ -#include -#include -#include -#include -#include -#include +#include #include namespace Genode { struct Rm_session; } @@ -27,194 +22,42 @@ namespace Genode { struct Rm_session; } struct Genode::Rm_session : Session { - enum Fault_type { - READY = 0, READ_FAULT = 1, WRITE_FAULT = 2, EXEC_FAULT = 3 }; - - /** - * State of region-manager session - * - * If a client accesses a location outside the regions attached to - * the region-manager session, a fault occurs and gets signalled to - * the registered fault handler. The fault handler, in turn needs - * the information about the fault address and fault type to - * resolve the fault. This information is represented by this - * structure. - */ - struct State - { - /** - * Type of occurred fault - */ - Fault_type type; - - /** - * Fault address - */ - addr_t addr; - - /** - * Default constructor - */ - State() : type(READY), addr(0) { } - - /** - * Constructor - */ - State(Fault_type fault_type, addr_t fault_addr) : - type(fault_type), addr(fault_addr) { } - }; - - - /** - * Helper for tranferring the bit representation of a pointer as RPC - * argument. - */ - class Local_addr - { - private: - - void *_ptr; - - public: - - template - Local_addr(T ptr) : _ptr((void *)ptr) { } - - Local_addr() : _ptr(0) { } - - template - operator T () { return (T)_ptr; } - }; - - static const char *service_name() { return "RM"; } - - /********************* - ** Exception types ** - *********************/ - - class Attach_failed : public Exception { }; - class Invalid_args : public Attach_failed { }; - class Invalid_dataspace : public Attach_failed { }; - class Region_conflict : public Attach_failed { }; - class Out_of_metadata : public Attach_failed { }; - - class Invalid_thread : public Exception { }; - class Unbound_thread : public Exception { }; - /** - * Destructor - */ - virtual ~Rm_session() { } - - /** - * Map dataspace into local address space + * Exception types * - * \param ds capability of dataspace to map - * \param size size of the locally mapped region - * default (0) is the whole dataspace - * \param offset start at offset in dataspace (page-aligned) - * \param use_local_addr if set to true, attach the dataspace at - * the specified 'local_addr' - * \param local_addr local destination address - * \param executable if the mapping should be executable - * - * \throw Attach_failed if dataspace or offset is invalid, - * or on region conflict - * \throw Out_of_metadata if meta-data backing store is exhausted - * - * \return local address of mapped dataspace + * \deprecated The following type definitions will be removed after the + * transition to the 'Region_map' API is completed. + */ + typedef Region_map::Attach_failed Attach_failed; + typedef Region_map::Out_of_metadata Out_of_metadata; + typedef Region_map::Region_conflict Region_conflict; + + /** + * Create region map * + * \param size upper bound of region map + * \return region-map capability + * \throw Out_of_metadata */ - virtual Local_addr attach(Dataspace_capability ds, - size_t size = 0, off_t offset = 0, - bool use_local_addr = false, - Local_addr local_addr = (void *)0, - bool executable = false) = 0; + virtual Capability create(size_t size) = 0; /** - * Shortcut for attaching a dataspace at a predefined local address + * Destroy region map */ - Local_addr attach_at(Dataspace_capability ds, addr_t local_addr, - size_t size = 0, off_t offset = 0) { - return attach(ds, size, offset, true, local_addr); } - - /** - * Shortcut for attaching a dataspace executable at a predefined local address - */ - Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr, - size_t size = 0, off_t offset = 0) { - return attach(ds, size, offset, true, local_addr, true); } - - /** - * Remove region from local address space - */ - virtual void detach(Local_addr local_addr) = 0; - - /** - * Add client to pager - * - * \param thread thread that will be paged - * \throw Invalid_thread - * \throw Out_of_metadata - * \throw Unbound_thread - * \return capability to be used for handling page faults - * - * This method must be called at least once to establish a valid - * communication channel between the pager part of the region manager - * and the client thread. - */ - virtual Pager_capability add_client(Thread_capability thread) = 0; - - /** - * Remove client from pager - * - * \param pager pager capability of client to be removed - */ - virtual void remove_client(Pager_capability) = 0; - - /** - * Register signal handler for region-manager faults - * - * On Linux, this signal is never delivered because page-fault handling - * is performed by the Linux kernel. On microkernel platforms, - * unresolvable page faults (traditionally called segmentation fault) - * will result in the delivery of the signal. - */ - virtual void fault_handler(Signal_context_capability handler) = 0; - - /** - * Request current state of RM session - */ - virtual State state() = 0; - - /** - * Return dataspace representation of region-manager session - */ - virtual Dataspace_capability dataspace() = 0; + virtual void destroy(Capability) = 0; /********************* ** RPC declaration ** *********************/ - GENODE_RPC_THROW(Rpc_attach, Local_addr, attach, - GENODE_TYPE_LIST(Invalid_dataspace, Region_conflict, - Out_of_metadata, Invalid_args), - Dataspace_capability, size_t, off_t, bool, Local_addr, bool); - GENODE_RPC(Rpc_detach, void, detach, Local_addr); - GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client, - GENODE_TYPE_LIST(Unbound_thread, Invalid_thread, Out_of_metadata), - Thread_capability); - GENODE_RPC(Rpc_remove_client, void, remove_client, Pager_capability); - GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability); - GENODE_RPC(Rpc_state, State, state); - GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace); + GENODE_RPC_THROW(Rpc_create, Capability, create, + GENODE_TYPE_LIST(Out_of_metadata), size_t); + GENODE_RPC(Rpc_destroy, void, destroy, Capability); - GENODE_RPC_INTERFACE(Rpc_attach, Rpc_detach, Rpc_add_client, - Rpc_remove_client, Rpc_fault_handler, Rpc_state, - Rpc_dataspace); + GENODE_RPC_INTERFACE(Rpc_create, Rpc_destroy); }; #endif /* _INCLUDE__RM_SESSION__RM_SESSION_H_ */ diff --git a/repos/base/run/mp_server.run b/repos/base/run/mp_server.run index ad143eb475..91f34725fc 100644 --- a/repos/base/run/mp_server.run +++ b/repos/base/run/mp_server.run @@ -63,7 +63,7 @@ if {[have_include "power_on/qemu"]} { grep_output {^\[init } # remove upgrade messages from init -unify_output {\[init \-\> test\-server\-mp\] upgrading quota donation for Env\:\:CPU \([0-9]+ bytes\)} "" +unify_output {\[init \-\> test\-server\-mp\] upgrading quota donation for .* \([0-9]+ bytes\)} "" trim_lines unify_output {transfer cap [a-f0-9]+} "transfer cap UNIFIED" diff --git a/repos/base/run/rm_nested.run b/repos/base/run/rm_nested.run new file mode 100644 index 0000000000..0c23669da1 --- /dev/null +++ b/repos/base/run/rm_nested.run @@ -0,0 +1,33 @@ +if {[have_spec linux]} { + puts "Platform does not support managed dataspaces"; exit } + +build "core init test/rm_nested" + +create_boot_directory + +install_config { + + + + + + + + + + + + + + + + + + +} + +build_boot_image "core init test-rm_nested" + +append qemu_args "-nographic -m 64" + +run_genode_until {child "test-rm_nested" exited with exit value 0.*} 300 diff --git a/repos/base/run/thread.run b/repos/base/run/thread.run index 71fd4f61aa..0dc3eb6979 100644 --- a/repos/base/run/thread.run +++ b/repos/base/run/thread.run @@ -22,7 +22,7 @@ build_boot_image "core init test-thread" append qemu_args "-nographic -m 64" -run_genode_until {child "test-thread" exited with exit value .*\n} 40 +run_genode_until {child "test-thread" exited with exit value .*\n} 60 # determine error code of child exit set exit_code [regexp -inline {child "test-thread" exited with exit value .*\n} $output] diff --git a/repos/base/src/base/child/child.cc b/repos/base/src/base/child/child.cc index 5ad4ae075e..2469dea6bb 100644 --- a/repos/base/src/base/child/child.cc +++ b/repos/base/src/base/child/child.cc @@ -316,7 +316,6 @@ Session_capability Child::session(Parent::Service_name const &name, /* return sessions that we created for the child */ if (!strcmp("Env::ram_session", name.string())) return _ram; if (!strcmp("Env::cpu_session", name.string())) return _cpu; - if (!strcmp("Env::rm_session", name.string())) return _rm; if (!strcmp("Env::pd_session", name.string())) return _pd; /* filter session arguments according to the child policy */ @@ -369,8 +368,6 @@ void Child::upgrade(Session_capability to_session, Parent::Upgrade_args const &a targeted_service = &_ram_service; if (to_session.local_name() == _cpu.local_name()) targeted_service = &_cpu_service; - if (to_session.local_name() == _rm.local_name()) - targeted_service = &_rm_service; if (to_session.local_name() == _pd.local_name()) targeted_service = &_pd_service; @@ -419,7 +416,6 @@ void Child::close(Session_capability session_cap) /* refuse to close the child's initial sessions */ if (session_cap.local_name() == _ram.local_name() || session_cap.local_name() == _cpu.local_name() - || session_cap.local_name() == _rm.local_name() || session_cap.local_name() == _pd.local_name()) return; @@ -483,24 +479,21 @@ Child::Child(Dataspace_capability elf_ds, Pd_session_capability pd, Ram_session_capability ram, Cpu_session_capability cpu, - Rm_session_capability rm, Rpc_entrypoint *entrypoint, Child_policy *policy, Service &pd_service, Service &ram_service, - Service &cpu_service, - Service &rm_service) + Service &cpu_service) : _pd(pd), _pd_session_client(pd), _ram(ram), _ram_session_client(ram), - _cpu(cpu), _rm(rm), _pd_service(pd_service), + _cpu(cpu), _pd_service(pd_service), _ram_service(ram_service), _cpu_service(cpu_service), - _rm_service(rm_service), _heap(&_ram_session_client, env()->rm_session()), _entrypoint(entrypoint), _parent_cap(_entrypoint->manage(this)), _policy(policy), _server(ram), - _process(elf_ds, pd, ram, cpu, rm, _parent_cap, policy->name()) + _process(elf_ds, pd, ram, cpu, _parent_cap, policy->name()) { } diff --git a/repos/base/src/base/component/component.cc b/repos/base/src/base/component/component.cc index 5cd12f21b6..4a224685fd 100644 --- a/repos/base/src/base/component/component.cc +++ b/repos/base/src/base/component/component.cc @@ -28,7 +28,7 @@ namespace { Genode::Parent &parent() override { return *Genode::env()->parent(); } Genode::Ram_session &ram() override { return *Genode::env()->ram_session(); } Genode::Cpu_session &cpu() override { return *Genode::env()->cpu_session(); } - Genode::Rm_session &rm() override { return *Genode::env()->rm_session(); } + Genode::Region_map &rm() override { return *Genode::env()->rm_session(); } Genode::Pd_session &pd() override { return *Genode::env()->pd_session(); } Genode::Entrypoint &ep() override { return _ep; } diff --git a/repos/base/src/base/env/reinitialize.cc b/repos/base/src/base/env/reinitialize.cc index e0b7b09811..7bca94e849 100644 --- a/repos/base/src/base/env/reinitialize.cc +++ b/repos/base/src/base/env/reinitialize.cc @@ -78,12 +78,12 @@ void Genode::Platform_env::reinit(Native_capability::Dst dst, void Genode::Platform_env:: -reinit_main_thread(Rm_session_capability & stack_area_rm) +reinit_main_thread(Capability &stack_area_rm) { /* reinitialize stack area RM session */ - Rm_session * const rms = env_stack_area_rm_session; - Rm_session_client * const rmc = dynamic_cast(rms); - construct_at(rmc, stack_area_rm); + Region_map * const rms = env_stack_area_region_map; + Region_map_client * const rmc = dynamic_cast(rms); + construct_at(rmc, stack_area_rm); /* reinitialize main-thread object */ ::reinit_main_thread(); diff --git a/repos/base/src/base/env/stack_area.cc b/repos/base/src/base/env/stack_area.cc index 34c6b40d09..416cf7e612 100644 --- a/repos/base/src/base/env/stack_area.cc +++ b/repos/base/src/base/env/stack_area.cc @@ -16,7 +16,7 @@ #include namespace Genode { - Rm_session *env_stack_area_rm_session; + Region_map *env_stack_area_region_map; Ram_session *env_stack_area_ram_session; } diff --git a/repos/base/src/base/heap/heap.cc b/repos/base/src/base/heap/heap.cc index 49b0f73f52..0288b4410a 100644 --- a/repos/base/src/base/heap/heap.cc +++ b/repos/base/src/base/heap/heap.cc @@ -44,7 +44,7 @@ Heap::Dataspace_pool::~Dataspace_pool() */ ds->~Dataspace(); - rm_session->detach(ds_local_addr); + region_map->detach(ds_local_addr); ram_session->free(ds_cap); } } @@ -68,11 +68,11 @@ Heap::Dataspace *Heap::_allocate_dataspace(size_t size, bool enforce_separate_me /* make new ram dataspace available at our local address space */ try { new_ds_cap = _ds_pool.ram_session->alloc(size); - ds_addr = _ds_pool.rm_session->attach(new_ds_cap); + ds_addr = _ds_pool.region_map->attach(new_ds_cap); } catch (Ram_session::Alloc_failed) { PWRN("could not allocate new dataspace of size %zu", size); return 0; - } catch (Rm_session::Attach_failed) { + } catch (Region_map::Attach_failed) { PWRN("could not attach dataspace"); _ds_pool.ram_session->free(new_ds_cap); return 0; @@ -215,7 +215,7 @@ void Heap::free(void *addr, size_t size) break; _ds_pool.remove(ds); - _ds_pool.rm_session->detach(ds->local_addr); + _ds_pool.region_map->detach(ds->local_addr); _ds_pool.ram_session->free(ds->cap); _quota_used -= ds->size; diff --git a/repos/base/src/base/heap/sliced_heap.cc b/repos/base/src/base/heap/sliced_heap.cc index 44264f7e9e..7d7f88a5c8 100644 --- a/repos/base/src/base/heap/sliced_heap.cc +++ b/repos/base/src/base/heap/sliced_heap.cc @@ -57,8 +57,8 @@ namespace Genode { using namespace Genode; -Sliced_heap::Sliced_heap(Ram_session *ram_session, Rm_session *rm_session): - _ram_session(ram_session), _rm_session(rm_session), +Sliced_heap::Sliced_heap(Ram_session *ram_session, Region_map *region_map): + _ram_session(ram_session), _region_map(region_map), _consumed(0) { } @@ -78,8 +78,8 @@ bool Sliced_heap::alloc(size_t size, void **out_addr) try { ds_cap = _ram_session->alloc(size); - local_addr = _rm_session->attach(ds_cap); - } catch (Rm_session::Attach_failed) { + local_addr = _region_map->attach(ds_cap); + } catch (Region_map::Attach_failed) { PERR("Could not attach dataspace to local address space"); _ram_session->free(ds_cap); return false; @@ -115,7 +115,7 @@ void Sliced_heap::free(void *addr, size_t size) delete b; } - _rm_session->detach(local_addr); + _region_map->detach(local_addr); _ram_session->free(ds_cap); } diff --git a/repos/base/src/base/process/process.cc b/repos/base/src/base/process/process.cc index 6a83dbf31c..7d5d37225f 100644 --- a/repos/base/src/base/process/process.cc +++ b/repos/base/src/base/process/process.cc @@ -37,7 +37,7 @@ static bool _check_dynamic_elf(Dataspace_capability elf_ds_cap) /* attach ELF locally */ addr_t elf_addr; try { elf_addr = env()->rm_session()->attach(elf_ds_cap); } - catch (Rm_session::Attach_failed) { return false; } + catch (Region_map::Attach_failed) { return false; } /* read program header */ Elf_binary elf((addr_t)elf_addr); @@ -52,16 +52,16 @@ static bool _check_dynamic_elf(Dataspace_capability elf_ds_cap) * \param parent_cap parent capability for child (i.e. myself) * \param elf_ds_cap dataspace containing the ELF binary * \param ram RAM session of the new protection domain - * \param rm region manager session of the new protection domain + * \param rm region map of the new protection domain */ static addr_t _setup_elf(Parent_capability parent_cap, Dataspace_capability elf_ds_cap, - Ram_session &ram, Rm_session &rm) + Ram_session &ram, Region_map &rm) { /* attach ELF locally */ addr_t elf_addr; try { elf_addr = env()->rm_session()->attach(elf_ds_cap); } - catch (Rm_session::Attach_failed) { return 0; } + catch (Region_map::Attach_failed) { return 0; } /* setup ELF object and read program entry pointer */ Elf_binary elf((addr_t)elf_addr); @@ -108,7 +108,7 @@ static addr_t _setup_elf(Parent_capability parent_cap, /* attach dataspace */ void *base; try { base = env()->rm_session()->attach(ds_cap); } - catch (Rm_session::Attach_failed) { + catch (Region_map::Attach_failed) { PERR("env()->rm_session()->attach() failed"); entry = 0; break; @@ -140,7 +140,7 @@ static addr_t _setup_elf(Parent_capability parent_cap, env()->rm_session()->detach(base); try { out_ptr = rm.attach_at(ds_cap, addr, size, offset); } - catch (Rm_session::Attach_failed) { } + catch (Region_map::Attach_failed) { } } else { @@ -154,10 +154,10 @@ static addr_t _setup_elf(Parent_capability parent_cap, if (exec) try { out_ptr = rm.attach_executable(ds_cap, addr, size, offset); } - catch (Rm_session::Attach_failed) { } + catch (Region_map::Attach_failed) { } else try { out_ptr = rm.attach_at(ds_cap, addr, size, offset); } - catch (Rm_session::Attach_failed) { } + catch (Region_map::Attach_failed) { } } if ((addr_t)out_ptr != addr) @@ -176,16 +176,17 @@ Process::Process(Dataspace_capability elf_ds_cap, Pd_session_capability pd_session_cap, Ram_session_capability ram_session_cap, Cpu_session_capability cpu_session_cap, - Rm_session_capability rm_session_cap, Parent_capability parent_cap, char const *name) : _pd_session_client(pd_session_cap), - _cpu_session_client(cpu_session_cap), - _rm_session_client(rm_session_cap) + _cpu_session_client(cpu_session_cap) { if (!pd_session_cap.valid()) return; + /* region map of the new protection domain */ + Region_map_client rm(Pd_session_client(pd_session_cap).address_space()); + enum Local_exception { THREAD_FAIL, ELF_FAIL, THREAD_ADD_FAIL, @@ -232,7 +233,7 @@ Process::Process(Dataspace_capability elf_ds_cap, /* parse ELF binary and setup segment dataspaces */ addr_t entry = 0; if (elf_ds_cap.valid()) { - entry = _setup_elf(parent_cap, elf_ds_cap, ram, _rm_session_client); + entry = _setup_elf(parent_cap, elf_ds_cap, ram, rm); if (!entry) { PERR("Setup ELF failed"); throw ELF_FAIL; @@ -248,7 +249,7 @@ Process::Process(Dataspace_capability elf_ds_cap, /* register thread0 at region manager session */ Pager_capability pager; try { - pager = _rm_session_client.add_client(_thread0_cap); + pager = rm.add_client(_thread0_cap); } catch (...) { PERR("Pager setup failed"); throw THREAD_ADD_FAIL; diff --git a/repos/base/src/base/region_map_client.cc b/repos/base/src/base/region_map_client.cc new file mode 100644 index 0000000000..181cf13cfa --- /dev/null +++ b/repos/base/src/base/region_map_client.cc @@ -0,0 +1,54 @@ +/* + * \brief Client-side stub for region map + * \author Norman Feske + * \date 2016-01-22 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + +using namespace Genode; + + +Region_map_client::Region_map_client(Capability cap) +: Rpc_client(cap) { } + + +Region_map::Local_addr +Region_map_client::attach(Dataspace_capability ds, size_t size, off_t offset, + bool use_local_addr, Local_addr local_addr, + bool executable) +{ + return call(ds, size, offset, use_local_addr, local_addr, + executable); +} + + +void Region_map_client::detach(Local_addr local_addr) { + call(local_addr); } + + +Pager_capability Region_map_client::add_client(Thread_capability thread) +{ + return call(thread); +} + + +void Region_map_client::remove_client(Pager_capability pager) { + call(pager); } + + +void Region_map_client::fault_handler(Signal_context_capability cap) { + call(cap); } + + +Region_map::State Region_map_client::state() { return call(); } + + +Dataspace_capability Region_map_client::dataspace() { return call(); } diff --git a/repos/base/src/base/rm_session_client.cc b/repos/base/src/base/rm_session_client.cc index b5a19694c6..ce7ff7e0d1 100644 --- a/repos/base/src/base/rm_session_client.cc +++ b/repos/base/src/base/rm_session_client.cc @@ -1,11 +1,11 @@ /* - * \brief Client-side region manager session interface + * \brief Client-side stub for RM session * \author Norman Feske - * \date 2016-01-22 + * \date 2016-04-19 */ /* - * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -15,32 +15,15 @@ using namespace Genode; -Rm_session_client::Rm_session_client(Rm_session_capability session) -: Rpc_client(session) { } -Rm_session::Local_addr -Rm_session_client::attach(Dataspace_capability ds, size_t size, off_t offset, - bool use_local_addr, Local_addr local_addr, - bool executable) -{ - return call(ds, size, offset, use_local_addr, local_addr, - executable); -} +Rm_session_client::Rm_session_client(Capability cap) +: Rpc_client(cap) { } -void Rm_session_client::detach(Local_addr local_addr) { - call(local_addr); } -Pager_capability Rm_session_client::add_client(Thread_capability thread) -{ - return call(thread); -} +Capability Rm_session_client::create(size_t size) { + return call(size); } -void Rm_session_client::remove_client(Pager_capability pager) { - call(pager); } -void Rm_session_client::fault_handler(Signal_context_capability cap) { - call(cap); } +void Rm_session_client::destroy(Capability cap) { + call(cap); } - Rm_session::State Rm_session_client::state() { return call(); } - -Dataspace_capability Rm_session_client::dataspace() { return call(); } diff --git a/repos/base/src/base/thread/thread.cc b/repos/base/src/base/thread/thread.cc index f07548aedf..62245deb14 100644 --- a/repos/base/src/base/thread/thread.cc +++ b/repos/base/src/base/thread/thread.cc @@ -33,7 +33,7 @@ using namespace Genode; */ namespace Genode { - extern Rm_session * const env_stack_area_rm_session; + extern Region_map * const env_stack_area_region_map; extern Ram_session * const env_stack_area_ram_session; } @@ -60,7 +60,7 @@ void Stack::size(size_t const size) try { Ram_session * const ram = env_stack_area_ram_session; Ram_dataspace_capability const ds_cap = ram->alloc(ds_size); - Rm_session * const rm = env_stack_area_rm_session; + Region_map * const rm = env_stack_area_region_map; void * const attach_addr = rm->attach_at(ds_cap, ds_addr, ds_size); if (ds_addr != (addr_t)attach_addr) @@ -116,7 +116,7 @@ Thread_base::_alloc_stack(size_t stack_size, char const *name, bool main_thread) try { ds_cap = env_stack_area_ram_session->alloc(ds_size); addr_t attach_addr = ds_addr - stack_area_virtual_base(); - if (attach_addr != (addr_t)env_stack_area_rm_session->attach_at(ds_cap, attach_addr, ds_size)) + if (attach_addr != (addr_t)env_stack_area_region_map->attach_at(ds_cap, attach_addr, ds_size)) throw Stack_alloc_failed(); } catch (Ram_session::Alloc_failed) { throw Stack_alloc_failed(); } @@ -143,7 +143,7 @@ void Thread_base::_free_stack(Stack *stack) /* call de-constructor explicitly before memory gets detached */ stack->~Stack(); - Genode::env_stack_area_rm_session->detach((void *)ds_addr); + Genode::env_stack_area_region_map->detach((void *)ds_addr); Genode::env_stack_area_ram_session->free(ds_cap); /* stack ready for reuse */ diff --git a/repos/base/src/base/thread/thread_start.cc b/repos/base/src/base/thread/thread_start.cc index b0b9a5c05d..6548ab7756 100644 --- a/repos/base/src/base/thread/thread_start.cc +++ b/repos/base/src/base/thread/thread_start.cc @@ -67,7 +67,11 @@ void Thread_base::start() env()->pd_session()->bind_thread(_thread_cap); /* create new pager object and assign it to the new thread */ - Pager_capability pager_cap = env()->rm_session()->add_client(_thread_cap); + Pager_capability pager_cap; + try { + pager_cap = env()->rm_session()->add_client(_thread_cap); + } catch (Region_map::Unbound_thread) { } + if (!pager_cap.valid()) throw Cpu_session::Thread_creation_failed(); diff --git a/repos/base/src/core/dataspace_component.cc b/repos/base/src/core/dataspace_component.cc index 1567ac1a5d..21e3dee3f5 100644 --- a/repos/base/src/core/dataspace_component.cc +++ b/repos/base/src/core/dataspace_component.cc @@ -13,7 +13,7 @@ /* core includes */ #include -#include +#include using namespace Genode; @@ -43,7 +43,7 @@ void Dataspace_component::detach_from_rm_sessions() * and thereby removes the current region from the '_regions' list. */ _lock.unlock(); - r->session()->detach((void *)r->base()); + r->rm()->detach((void *)r->base()); _lock.lock(); } diff --git a/repos/base/src/core/include/core_env.h b/repos/base/src/core/include/core_env.h index 20d109fc6f..fdc0e5ed32 100644 --- a/repos/base/src/core/include/core_env.h +++ b/repos/base/src/core/include/core_env.h @@ -28,7 +28,7 @@ /* core includes */ #include #include -#include +#include #include #include @@ -128,7 +128,7 @@ namespace Genode { bool _stack_area_initialized = _init_stack_area(); Rpc_entrypoint _entrypoint; - Core_rm_session _rm_session; + Core_region_map _region_map; Core_ram_session _ram_session; Ram_session_capability const _ram_session_cap; @@ -152,14 +152,14 @@ namespace Genode { Core_env() : _entrypoint(nullptr, ENTRYPOINT_STACK_SIZE, "entrypoint"), - _rm_session(&_entrypoint), + _region_map(&_entrypoint), _ram_session(&_entrypoint, &_entrypoint, platform()->ram_alloc(), platform()->core_mem_alloc(), "ram_quota=4M", platform()->ram_alloc()->avail()), _ram_session_cap(_entrypoint.manage(&_ram_session)), _pd_session_component(_entrypoint /* XXX use a different entrypoint */), _pd_session_client(_entrypoint.manage(&_pd_session_component)), - _heap(&_ram_session, &_rm_session) + _heap(&_ram_session, &_region_map) { } /** @@ -177,7 +177,7 @@ namespace Genode { Parent *parent() override { return &_core_parent; } Ram_session *ram_session() override { return &_ram_session; } Ram_session_capability ram_session_cap() override { return _ram_session_cap; } - Rm_session *rm_session() override { return &_rm_session; } + Region_map *rm_session() override { return &_region_map; } Pd_session *pd_session() override { return &_pd_session_client; } Allocator *heap() override { return &_heap; } @@ -201,7 +201,7 @@ namespace Genode { void reinit(Capability::Dst, long) override { } - void reinit_main_thread(Rm_session_capability &) override { } + void reinit_main_thread(Capability &) override { } }; diff --git a/repos/base/src/core/include/core_pd_session.h b/repos/base/src/core/include/core_pd_session.h index 26b4ba8bcf..37abd8428a 100644 --- a/repos/base/src/core/include/core_pd_session.h +++ b/repos/base/src/core/include/core_pd_session.h @@ -108,6 +108,12 @@ class Genode::Core_pd_session_component : public Rpc_object ASSERT_NEVER_CALLED; } + Capability address_space() { ASSERT_NEVER_CALLED; } + + Capability stack_area() { ASSERT_NEVER_CALLED; } + + Capability linker_area() { ASSERT_NEVER_CALLED; } + Capability native_pd() override { ASSERT_NEVER_CALLED; } }; diff --git a/repos/base/src/core/include/core_region_map.h b/repos/base/src/core/include/core_region_map.h new file mode 100644 index 0000000000..dc52bdd0ff --- /dev/null +++ b/repos/base/src/core/include/core_region_map.h @@ -0,0 +1,65 @@ +/* + * \brief Core-specific region map + * \author Norman Feske + * \date 2006-07-12 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _CORE__INCLUDE__CORE_REGION_MAP_H_ +#define _CORE__INCLUDE__CORE_REGION_MAP_H_ + +/* Genode includes */ +#include +#include + +/* core includes */ +#include + +namespace Genode { class Core_region_map; } + + +class Genode::Core_region_map : public Region_map +{ + private: + + Rpc_entrypoint *_ds_ep; + + public: + + Core_region_map(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } + + Local_addr attach(Dataspace_capability ds_cap, size_t size=0, + off_t offset=0, bool use_local_addr = false, + Local_addr local_addr = 0, + bool executable = false) override + { + auto lambda = [] (Dataspace_component *ds) { + if (!ds) + throw Invalid_dataspace(); + + return (void *)ds->phys_addr(); + }; + return _ds_ep->apply(ds_cap, lambda); + } + + void detach(Local_addr) override { } + + Pager_capability add_client(Thread_capability) override { + return Pager_capability(); } + + void remove_client(Pager_capability) override { } + + void fault_handler(Signal_context_capability) override { } + + State state() override { return State(); } + + Dataspace_capability dataspace() override { return Dataspace_capability(); } +}; + +#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */ diff --git a/repos/base/src/core/include/core_rm_session.h b/repos/base/src/core/include/core_rm_session.h deleted file mode 100644 index 7cafff5a5e..0000000000 --- a/repos/base/src/core/include/core_rm_session.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * \brief Core-specific region manager session - * \author Norman Feske - * \date 2006-07-12 - */ - -/* - * Copyright (C) 2006-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__CORE_RM_SESSION_H_ -#define _CORE__INCLUDE__CORE_RM_SESSION_H_ - -/* Genode includes */ -#include - -/* core includes */ -#include - -namespace Genode { - - /** - * Region manager that uses the physical dataspace - * addresses directly as virtual addresses. - */ - class Core_rm_session : public Rm_session - { - private: - - Rpc_entrypoint *_ds_ep; - - public: - - Core_rm_session(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } - - Local_addr attach(Dataspace_capability ds_cap, size_t size=0, - off_t offset=0, bool use_local_addr = false, - Local_addr local_addr = 0, - bool executable = false) - { - auto lambda = [] (Dataspace_component *ds) { - if (!ds) - throw Invalid_dataspace(); - - return (void *)ds->phys_addr(); - }; - return _ds_ep->apply(ds_cap, lambda); - } - - void detach(Local_addr local_addr) { } - - Pager_capability add_client(Thread_capability thread) { - return Pager_capability(); } - - void remove_client(Pager_capability) { } - - void fault_handler(Signal_context_capability handler) { } - - State state() { return State(); } - - Dataspace_capability dataspace() { return Dataspace_capability(); } - }; -} - -#endif /* _CORE__INCLUDE__CORE_RM_SESSION_H_ */ diff --git a/repos/base/src/core/include/dataspace_component.h b/repos/base/src/core/include/dataspace_component.h index 5a9a14fd21..e112da4f9f 100644 --- a/repos/base/src/core/include/dataspace_component.h +++ b/repos/base/src/core/include/dataspace_component.h @@ -114,11 +114,11 @@ namespace Genode { ~Dataspace_component(); /** - * Return region-manager session corresponding to nested dataspace + * Return region map corresponding to nested dataspace * * \retval invalid capability if dataspace is not a nested one */ - virtual Native_capability sub_rm_session() { return Dataspace_capability(); } + virtual Native_capability sub_rm() { return Dataspace_capability(); } addr_t core_local_addr() const { return _core_local_addr; } bool is_io_mem() const { return _is_io_mem; } diff --git a/repos/base/src/core/include/pd_root.h b/repos/base/src/core/include/pd_root.h index 6c0d9c572e..185aeb95be 100644 --- a/repos/base/src/core/include/pd_root.h +++ b/repos/base/src/core/include/pd_root.h @@ -29,8 +29,9 @@ class Genode::Pd_root : public Genode::Root_component(session_ep, md_alloc), - _thread_ep(*thread_ep), _md_alloc(*md_alloc) { } + _thread_ep(*thread_ep), _pager_ep(pager_ep), _md_alloc(*md_alloc) { } }; #endif /* _CORE__INCLUDE__PD_ROOT_H_ */ diff --git a/repos/base/src/core/include/pd_session_component.h b/repos/base/src/core/include/pd_session_component.h index 61a6fd2058..2feb7f6a4e 100644 --- a/repos/base/src/core/include/pd_session_component.h +++ b/repos/base/src/core/include/pd_session_component.h @@ -27,6 +27,11 @@ #include #include #include +#include +#include + +/* base-internal includes */ +#include namespace Genode { class Pd_session_component; } @@ -58,6 +63,10 @@ class Genode::Pd_session_component : public Rpc_object Rpc_cap_factory _rpc_cap_factory; Native_pd_component _native_pd; + Region_map_component _address_space; + Region_map_component _stack_area; + Region_map_component _linker_area; + size_t _ram_quota(char const * args) { return Arg_string::find_arg(args, "ram_quota").long_value(0); } @@ -80,12 +89,12 @@ class Genode::Pd_session_component : public Rpc_object * to map signal-context capabilities to 'Signal_context_component' * objects and as capability allocator for such objects. */ - - Pd_session_component(Rpc_entrypoint &thread_ep, - Rpc_entrypoint &receiver_ep, - Rpc_entrypoint &context_ep, - Allocator &md_alloc, - char const *args) + Pd_session_component(Rpc_entrypoint &thread_ep, + Rpc_entrypoint &receiver_ep, + Rpc_entrypoint &context_ep, + Allocator &md_alloc, + Pager_entrypoint &pager_ep, + char const *args) : _label(args), _md_alloc(&md_alloc, _ram_quota(args)), @@ -93,7 +102,11 @@ class Genode::Pd_session_component : public Rpc_object _thread_ep(thread_ep), _signal_broker(_md_alloc, receiver_ep, context_ep), _rpc_cap_factory(_md_alloc), - _native_pd(*this, args) + _native_pd(*this, args), + _address_space(thread_ep, _md_alloc, pager_ep, + platform()->vm_start(), platform()->vm_size()), + _stack_area(thread_ep, _md_alloc, pager_ep, 0, stack_area_virtual_size()), + _linker_area(thread_ep, _md_alloc, pager_ep, 0, LINKER_AREA_SIZE) { } /** @@ -149,6 +162,15 @@ class Genode::Pd_session_component : public Rpc_object void free_rpc_cap(Native_capability cap) override { _rpc_cap_factory.free(cap); } + Capability address_space() { + return _address_space.cap(); } + + Capability stack_area() { + return _stack_area.cap(); } + + Capability linker_area() { + return _linker_area.cap(); } + Capability native_pd() { return _native_pd.cap(); } }; diff --git a/repos/base/src/core/include/region_map_component.h b/repos/base/src/core/include/region_map_component.h new file mode 100644 index 0000000000..298c8899d0 --- /dev/null +++ b/repos/base/src/core/include/region_map_component.h @@ -0,0 +1,401 @@ +/* + * \brief Region map interface + * \author Christian Helmuth + * \author Norman Feske + * \date 2006-07-17 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _CORE__INCLUDE__REGION_MAP_COMPONENT_H_ +#define _CORE__INCLUDE__REGION_MAP_COMPONENT_H_ + +/* Genode includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* core includes */ +#include +#include +#include +#include + +/* base-internal includes */ +#include + +namespace Genode { + + class Dataspace_component; + class Region_map_component; + class Rm_client; + class Rm_region; + class Rm_faulter; +} + + +/** + * Representation of a single entry of a region map + * + * Each 'Rm_region' is associated with one dataspace and makes a portion + * of this dataspace visible in a address space of a region map. + * All 'Rm_regions' to which one and the same dataspace is attached to, are + * organized in a linked list. The head of the list is a member of the + * 'Dataspace_component'. + */ +class Genode::Rm_region : public List::Element +{ + private: + + addr_t _base = 0; + size_t _size = 0; + bool _write = false; + + Dataspace_component *_dsc = nullptr; + off_t _off = 0; + + Region_map_component *_rm = nullptr; + + public: + + /** + * Default constructor - invalid region + */ + Rm_region() { } + + Rm_region(addr_t base, size_t size, bool write, + Dataspace_component *dsc, off_t offset, + Region_map_component *rm) + : _base(base), _size(size), _write(write), + _dsc(dsc), _off(offset), _rm(rm) { } + + + /*************** + ** Accessors ** + ***************/ + + addr_t base() const { return _base; } + size_t size() const { return _size; } + bool write() const { return _write; } + Dataspace_component* dataspace() const { return _dsc; } + off_t offset() const { return _off; } + Region_map_component* rm() const { return _rm; } +}; + + +/** + * Member of faulter list + * + * Each 'Rm_client' can fault not only at the region map that it is member + * of but also on any other region map used as a nested dataspace. If a + * 'Rm_client' faults, it gets enqueued at the leaf region map that + * detected the fault and waits for this region map to resolve the fault. + * For example, the dataspace manager that resolves the faults for the + * nested dataspace exported to its client. Because each region map must + * be able to handle faults by arbitrary clients (not only its own + * clients), it maintains the list head of faulters. + */ +class Genode::Rm_faulter : public Fifo::Element +{ + private: + + Pager_object *_pager_object; + Lock _lock; + Region_map_component *_faulting_region_map; + Region_map::State _fault_state; + + public: + + /** + * Constructor + * + * \param Pager_object pager object that corresponds to the faulter + * + * Currently, there is only one pager in core. + */ + Rm_faulter(Pager_object *pager_object) : + _pager_object(pager_object), _faulting_region_map(0) { } + + /** + * Assign fault state + */ + void fault(Region_map_component *faulting_region_map, + Region_map::State fault_state); + + /** + * Disassociate faulter from the faulted region map + * + * This function must be called when destructing region maps + * to prevent dangling pointers in '_faulters' lists. + */ + void dissolve_from_faulting_region_map(Region_map_component *); + + /** + * Return true if page fault occurred in specified address range + */ + bool fault_in_addr_range(addr_t addr, size_t size) { + return (_fault_state.addr >= addr) && (_fault_state.addr <= addr + size - 1); } + + /** + * Return fault state as exported via the region-map interface + */ + Region_map::State fault_state() { return _fault_state; } + + /** + * Wake up faulter by answering the pending page fault + */ + void continue_after_resolved_fault(); +}; + + +/** + * Member role of region map + * + * A region map can be used as address space for any number of threads. This + * class represents the thread's role as member of this address space. + */ +class Genode::Rm_client : public Pager_object, public Rm_faulter, + public List::Element +{ + private: + + Region_map_component *_region_map; + Weak_ptr _address_space; + + public: + + /** + * Constructor + * + * \param rm region map to which the client belongs + * \param badge pager-object badge used of identifying the client + * when a page-fault occurs + * \param location affinity to physical CPU + */ + Rm_client(Region_map_component *rm, unsigned long badge, + Weak_ptr &address_space, + Affinity::Location location) + : + Pager_object(badge, location), Rm_faulter(this), + _region_map(rm), _address_space(address_space) + { } + + int pager(Ipc_pager &pager); + + /** + * Flush memory mappings for the specified virtual address range + */ + void unmap(addr_t core_local_base, addr_t virt_base, size_t size); + + bool has_same_address_space(Rm_client const &other) + { + return other._address_space == _address_space; + } + + /** + * Return region map that the RM client is member of + */ + Region_map_component *member_rm() { return _region_map; } +}; + + +class Genode::Region_map_component : public Rpc_object, + public List::Element +{ + private: + + Rpc_entrypoint *_ds_ep; + Rpc_entrypoint *_thread_ep; + Rpc_entrypoint *_session_ep; + + Allocator &_md_alloc; + + Signal_transmitter _fault_notifier; /* notification mechanism for + region-manager faults */ + + /********************* + ** Paging facility ** + *********************/ + + class Rm_region_ref : public List::Element + { + private: + + Rm_region *_region; + + public: + + Rm_region_ref(Rm_region *region) : _region(region) { } + + Rm_region* region() const { return _region; } + }; + + + class Rm_dataspace_component : public Dataspace_component + { + private: + + Native_capability _rm_cap; + + public: + + /** + * Constructor + */ + Rm_dataspace_component(size_t size) + : + Dataspace_component(size, 0, CACHED, false, 0) + { + _managed = true; + } + + + /*********************************** + ** Dataspace component interface ** + ***********************************/ + + Native_capability sub_rm() override { return _rm_cap; } + void sub_rm(Native_capability cap) { _rm_cap = cap; } + }; + + + typedef Synced_allocator > Client_slab_alloc; + Client_slab_alloc _client_slab; /* backing store for + client structures, synchronized */ + Tslab _ref_slab; /* backing store for + region list */ + Allocator_avl_tpl _map; /* region map for attach, + detach, pagefaults */ + List _regions; /* region list for destruction */ + + Fifo _faulters; /* list of threads that faulted at + the region map and wait + for fault resolution */ + List _clients; /* list of RM clients using this region map */ + Lock _lock; /* lock for map and list */ + Pager_entrypoint *_pager_ep; + Rm_dataspace_component _ds; /* dataspace representation of region map */ + Dataspace_capability _ds_cap; + + template + auto _apply_to_dataspace(addr_t addr, F f, addr_t offset, unsigned level) + -> typename Trait::Functor::Return_type + { + using Functor = Trait::Functor; + using Return_type = typename Functor::Return_type; + + Lock::Guard lock_guard(_lock); + + /* skip further lookup when reaching the recursion limit */ + if (!level) return f(this, nullptr, 0, 0); + + /* lookup region and dataspace */ + Rm_region *region = _map.metadata((void*)addr); + Dataspace_component *dsc = region ? region->dataspace() + : nullptr; + + /* calculate offset in dataspace */ + addr_t ds_offset = region ? (addr - region->base() + + region->offset()) : 0; + + /* check for nested dataspace */ + Native_capability cap = dsc ? dsc->sub_rm() + : Native_capability(); + + if (!cap.valid()) return f(this, region, ds_offset, offset); + + /* in case of a nested dataspace perform a recursive lookup */ + auto lambda = [&] (Region_map_component *rmc) -> Return_type + { + return (!rmc) ? f(nullptr, nullptr, ds_offset, offset) + : rmc->_apply_to_dataspace(ds_offset, f, + offset+region->base(), + --level); + }; + return _session_ep->apply(cap, lambda); + } + + public: + + /** + * Constructor + * + * The object calls 'ep.manage' for itself on construction. + */ + Region_map_component(Rpc_entrypoint &ep, + Allocator &md_alloc, + Pager_entrypoint &pager_ep, + addr_t vm_start, + size_t vm_size); + + ~Region_map_component(); + + class Fault_area; + + /** + * Register fault + * + * This function is called by the pager to schedule a page fault + * for resolution. + * + * \param faulter faulting region-manager client + * \param pf_addr page-fault address + * \param pf_type type of page fault (read/write/execute) + */ + void fault(Rm_faulter *faulter, addr_t pf_addr, + Region_map::State::Fault_type pf_type); + + /** + * Dissolve faulter from region map + */ + void discard_faulter(Rm_faulter *faulter, bool do_lock); + + List *clients() { return &_clients; } + + /** + * Return the dataspace representation of this region map + */ + Rm_dataspace_component *dataspace_component() { return &_ds; } + + /** + * Apply a function to dataspace attached at a given address + * + * /param addr address where the dataspace is attached + * /param f functor or lambda to apply + */ + template + auto apply_to_dataspace(addr_t addr, F f) + -> typename Trait::Functor::Return_type + { + enum { RECURSION_LIMIT = 5 }; + + return _apply_to_dataspace(addr, f, 0, RECURSION_LIMIT); + } + + /************************** + ** Region map interface ** + **************************/ + + Local_addr attach (Dataspace_capability, size_t, off_t, bool, Local_addr, bool) override; + void detach (Local_addr) override; + Pager_capability add_client (Thread_capability) override; + void remove_client (Pager_capability) override; + void fault_handler (Signal_context_capability handler) override; + State state () override; + + Dataspace_capability dataspace () override { return _ds_cap; } +}; + +#endif /* _CORE__INCLUDE__REGION_MAP_COMPONENT_H_ */ diff --git a/repos/base/src/core/include/rm_root.h b/repos/base/src/core/include/rm_root.h index 4e5affa5a9..850a8c5b71 100644 --- a/repos/base/src/core/include/rm_root.h +++ b/repos/base/src/core/include/rm_root.h @@ -1,11 +1,11 @@ -/** +/* * \brief RM root interface - * \author Christian Helmuth - * \date 2006-07-17 + * \author Norman Feske + * \date 2016-04-17 */ /* - * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -14,103 +14,54 @@ #ifndef _CORE__INCLUDE__RM_ROOT_H_ #define _CORE__INCLUDE__RM_ROOT_H_ -/* Genode */ +/* Genode includes */ #include /* core-local includes */ #include #include -namespace Genode { +namespace Genode { class Rm_root; } - class Rm_root : public Root_component - { - private: - Rpc_entrypoint *_ds_ep; - Rpc_entrypoint *_thread_ep; - Allocator *_md_alloc; - Pager_entrypoint _pager_ep; - addr_t _vm_start; - size_t _vm_size; +class Genode::Rm_root : public Root_component +{ + private: - protected: + Pager_entrypoint &_pager_ep; - Rm_session_component *_create_session(const char *args) - { - addr_t start = Arg_string::find_arg(args, "start").ulong_value(~0UL); - size_t size = Arg_string::find_arg(args, "size").ulong_value(0); - size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); + protected: - return new (md_alloc()) - Rm_session_component(_ds_ep, - _thread_ep, - this->ep(), - _md_alloc, ram_quota, - &_pager_ep, - start == ~0UL ? _vm_start : start, - size == 0 ? _vm_size : size); - } + Rm_session_component *_create_session(const char *args) + { + size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - Session_capability session(Root::Session_args const &args, Affinity const &affinity) - { - Session_capability cap = Root_component::session(args, affinity); + return new (md_alloc()) + Rm_session_component(*this->ep(), *md_alloc(), _pager_ep, ram_quota); + } - /* lookup rm_session_component object */ - auto lambda = [] (Rm_session_component *rm_session) { - if (!rm_session) - /* should never happen */ - return; + void _upgrade_session(Rm_session_component *rm, const char *args) + { + size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); + rm->upgrade_ram_quota(ram_quota); + } - /** - * Assign rm_session capability to dataspace component. It can - * not be done beforehand because the dataspace_component is - * constructed before the rm_session - */ - if (rm_session->dataspace_component()) - rm_session->dataspace_component()->sub_rm_session(rm_session->cap()); - }; - ep()->apply(cap, lambda); - return cap; - } + public: - void _upgrade_session(Rm_session_component *rm, const char *args) - { - size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - rm->upgrade_ram_quota(ram_quota); - } - - public: - - /** - * Constructor - * - * \param session_ep entry point for managing RM session objects - * \param ds_ep entry point for managing dataspaces - * \param thread_ep entry point for managing threads - * \param md_alloc meta data allocator to be used by root component - * \param cap_factory for allocating pager-object capabilities - * \param vm_start begin of virtual memory (default value) - * \param vm_size size of virtual memory (default value) - */ - Rm_root(Rpc_entrypoint *session_ep, - Rpc_entrypoint *ds_ep, - Rpc_entrypoint *thread_ep, - Allocator *md_alloc, - Rpc_cap_factory &cap_factory, - addr_t vm_start, - size_t vm_size) - : - Root_component(session_ep, md_alloc), - _ds_ep(ds_ep), _thread_ep(thread_ep), _md_alloc(md_alloc), - _pager_ep(cap_factory), _vm_start(vm_start), _vm_size(vm_size) - { } - - /** - * Return pager entrypoint - */ - Pager_entrypoint *pager_ep() { return &_pager_ep; } - }; -} + /** + * Constructor + * + * \param session_ep entry point for managing RM session objects + * \param md_alloc meta data allocator to be used by root component + * \param pager_ep pager entrypoint + */ + Rm_root(Rpc_entrypoint *session_ep, + Allocator *md_alloc, + Pager_entrypoint &pager_ep) + : + Root_component(session_ep, md_alloc), + _pager_ep(pager_ep) + { } +}; #endif /* _CORE__INCLUDE__RM_ROOT_H_ */ diff --git a/repos/base/src/core/include/rm_session_component.h b/repos/base/src/core/include/rm_session_component.h index 3c919127f4..df16fe97a1 100644 --- a/repos/base/src/core/include/rm_session_component.h +++ b/repos/base/src/core/include/rm_session_component.h @@ -1,12 +1,11 @@ /* * \brief RM session interface - * \author Christian Helmuth * \author Norman Feske - * \date 2006-07-17 + * \date 2016-04-15 */ /* - * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -16,384 +15,90 @@ #define _CORE__INCLUDE__RM_SESSION_COMPONENT_H_ /* Genode includes */ -#include -#include -#include -#include -#include #include -#include -#include #include -#include -#include +#include /* core includes */ -#include -#include -#include -#include +#include -namespace Genode { +namespace Genode { class Rm_session_component; } - class Dataspace_component; - class Rm_session_component; - class Rm_client; - /** - * Representation of a single entry of a region-manager session - * - * Each 'Rm_region' is associated with one dataspace and makes a portion - * of this dataspace visible in a address space of a region-manager session. - * All 'Rm_regions' to which one and the same dataspace is attached to, are - * organized in a linked list. The head of the list is a member of the - * 'Dataspace_component'. - */ - class Rm_region : public List::Element - { - private: +class Genode::Rm_session_component : public Rpc_object +{ + private: - addr_t _base; - size_t _size; - bool _write; + Rpc_entrypoint &_ep; + Allocator_guard _md_alloc; + Pager_entrypoint &_pager_ep; - Dataspace_component *_dsc; - off_t _off; + Lock _region_maps_lock; + List _region_maps; - Rm_session_component *_session; /* corresponding region manager - session */ + void _destroy(Region_map_component &rmc) + { + _region_maps.remove(&rmc); + Genode::destroy(_md_alloc, &rmc); + } - public: + public: - /** - * Default constructor - invalid region - */ - Rm_region() { } + /** + * Constructor + */ + Rm_session_component(Rpc_entrypoint &ep, + Allocator &md_alloc, + Pager_entrypoint &pager_ep, + size_t ram_quota) + : + _ep(ep), _md_alloc(&md_alloc, ram_quota), _pager_ep(pager_ep) + { } - Rm_region(addr_t base, size_t size, bool write, - Dataspace_component *dsc, off_t offset, - Rm_session_component *session) - : _base(base), _size(size), _write(write), - _dsc(dsc), _off(offset), _session(session) { } + ~Rm_session_component() + { + Lock::Guard guard(_region_maps_lock); + while (Region_map_component *rmc = _region_maps.first()) + _destroy(*rmc); + } - /*************** - ** Accessors ** - ***************/ + /** + * Register quota donation at allocator guard + */ + void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); } - addr_t base() const { return _base; } - size_t size() const { return _size; } - bool write() const { return _write; } - Dataspace_component* dataspace() const { return _dsc; } - off_t offset() const { return _off; } - Rm_session_component* session() const { return _session; } - }; + /************************** + ** Rm_session interface ** + **************************/ - /** - * Member of faulter list - * - * Each 'Rm_client' can fault not only at the RM session that it is member - * of but also on any other RM session used as a nested dataspace. If a - * 'Rm_client' faults, it gets enqueued at the leaf RM session that - * detected the fault and waits for this RM session to resolve the fault. - * For example, the dataspace manager that resolves the faults for the - * nested dataspace exported to its client. Because each RM session must - * be able to handle faults by arbitrary clients (not only its own - * clients), it maintains the list head of faulters. - */ - class Rm_faulter : public Fifo::Element - { - private: + Capability create(size_t size) override + { + Lock::Guard guard(_region_maps_lock); - Pager_object *_pager_object; - Lock _lock; - Rm_session_component *_faulting_rm_session; - Rm_session::State _fault_state; + Region_map_component *rm = + new (_md_alloc) + Region_map_component(_ep, _md_alloc, _pager_ep, 0, size); - public: + _region_maps.insert(rm); - /** - * Constructor - * - * \param Pager_object pager object that corresponds to the faulter - * - * Currently, there is only one pager in core. - */ - Rm_faulter(Pager_object *pager_object) : - _pager_object(pager_object), _faulting_rm_session(0) { } + return rm->cap(); + } - /** - * Assign fault state - */ - void fault(Rm_session_component *faulting_rm_session, - Rm_session::State fault_state); + void destroy(Capability rm) override + { + Lock::Guard guard(_region_maps_lock); - /** - * Disassociate faulter from the faulted region-manager session - * - * This function must be called when destructing region-manager - * sessions to prevent dangling pointers in '_faulters' lists. - */ - void dissolve_from_faulting_rm_session(Rm_session_component *); + _ep.apply(rm, [&] (Region_map_component *rmc) { + if (!rmc) { + PWRN("could not look up region map to destruct"); + return; + } - /** - * Return true if page fault occurred in specified address range - */ - bool fault_in_addr_range(addr_t addr, size_t size) { - return (_fault_state.addr >= addr) && (_fault_state.addr <= addr + size - 1); } - - /** - * Return fault state as exported via the rm-session interface - */ - Rm_session::State fault_state() { return _fault_state; } - - /** - * Wake up faulter by answering the pending page fault - */ - void continue_after_resolved_fault(); - }; - - - /** - * Member role of region manager session - * - * A region-manager session can be used as address space for any number - * of threads (region-manager clients). This class represents the client's - * role as member of this address space. - */ - class Rm_client : public Pager_object, public Rm_faulter, - public List::Element - { - private: - - Rm_session_component *_rm_session; - Weak_ptr _address_space; - - public: - - /** - * Constructor - * - * \param session RM session to which the client belongs - * \param badge pager-object badge used of identifying the client - * when a page-fault occurs - * \param location affinity to physical CPU - */ - Rm_client(Rm_session_component *session, unsigned long badge, - Weak_ptr &address_space, - Affinity::Location location) - : - Pager_object(badge, location), Rm_faulter(this), - _rm_session(session), _address_space(address_space) - { } - - int pager(Ipc_pager &pager); - - /** - * Flush memory mappings for the specified virtual address range - */ - void unmap(addr_t core_local_base, addr_t virt_base, size_t size); - - bool has_same_address_space(Rm_client const &other) - { - return other._address_space == _address_space; - } - - /** - * Return region-manager session that the RM client is member of - */ - Rm_session_component *member_rm_session() { return _rm_session; } - }; - - - class Rm_session_component : public Rpc_object - { - private: - - Rpc_entrypoint *_ds_ep; - Rpc_entrypoint *_thread_ep; - Rpc_entrypoint *_session_ep; - - Allocator_guard _md_alloc; - Signal_transmitter _fault_notifier; /* notification mechanism for - region-manager faults */ - - /********************* - ** Paging facility ** - *********************/ - - class Rm_region_ref : public List::Element - { - private: - - Rm_region *_region; - - public: - - Rm_region_ref(Rm_region *region) : _region(region) { } - - Rm_region* region() const { return _region; } - }; - - - class Rm_dataspace_component : public Dataspace_component - { - private: - - Native_capability _rm_session_cap; - - public: - - /** - * Constructor - */ - Rm_dataspace_component(size_t size) - : - Dataspace_component(size, 0, CACHED, false, 0) - { _managed = true; } - - - /*********************************** - ** Dataspace component interface ** - ***********************************/ - - Native_capability sub_rm_session() { return _rm_session_cap; } - void sub_rm_session(Native_capability _cap) { _rm_session_cap = _cap; } - }; - - - typedef Synced_allocator > Client_slab_alloc; - Client_slab_alloc _client_slab; /* backing store for - client structures, synchronized */ - Tslab _ref_slab; /* backing store for - region list */ - Allocator_avl_tpl _map; /* region map for attach, - detach, pagefaults */ - List _regions; /* region list for destruction */ - - Fifo _faulters; /* list of threads that faulted at - the region-manager session and wait - for fault resolution */ - List _clients; /* list of RM clients using this RM - session */ - Lock _lock; /* lock for map and list */ - Pager_entrypoint *_pager_ep; - Rm_dataspace_component _ds; /* dataspace representation of region map */ - Dataspace_capability _ds_cap; - - template - auto _apply_to_dataspace(addr_t addr, F f, addr_t offset, unsigned level) - -> typename Trait::Functor::Return_type - { - using Functor = Trait::Functor; - using Return_type = typename Functor::Return_type; - - Lock::Guard lock_guard(_lock); - - /* skip further lookup when reaching the recursion limit */ - if (!level) return f(this, nullptr, 0, 0); - - /* lookup region and dataspace */ - Rm_region *region = _map.metadata((void*)addr); - Dataspace_component *dsc = region ? region->dataspace() - : nullptr; - - /* calculate offset in dataspace */ - addr_t ds_offset = region ? (addr - region->base() - + region->offset()) : 0; - - /* check for nested dataspace */ - Native_capability cap = dsc ? dsc->sub_rm_session() - : Native_capability(); - if (!cap.valid()) return f(this, region, ds_offset, offset); - - /* in case of a nested dataspace perform a recursive lookup */ - auto lambda = [&] (Rm_session_component *rsc) -> Return_type - { - return (!rsc) ? f(nullptr, nullptr, ds_offset, offset) - : rsc->_apply_to_dataspace(ds_offset, f, - offset+region->base(), - --level); - }; - return _session_ep->apply(cap, lambda); - } - - public: - - /** - * Constructor - */ - Rm_session_component(Rpc_entrypoint *ds_ep, - Rpc_entrypoint *thread_ep, - Rpc_entrypoint *session_ep, - Allocator *md_alloc, - size_t ram_quota, - Pager_entrypoint *pager_ep, - addr_t vm_start, - size_t vm_size); - - ~Rm_session_component(); - - class Fault_area; - - /** - * Register fault - * - * This function is called by the pager to schedule a page fault - * for resolution. - * - * \param faulter faulting region-manager client - * \param pf_addr page-fault address - * \param pf_type type of page fault (read/write/execute) - */ - void fault(Rm_faulter *faulter, addr_t pf_addr, - Rm_session::Fault_type pf_type); - - /** - * Dissolve faulter from region-manager session - */ - void discard_faulter(Rm_faulter *faulter, bool do_lock); - - List *clients() { return &_clients; } - - /** - * Return the dataspace representation of this session - */ - Rm_dataspace_component *dataspace_component() { return &_ds; } - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); } - - /** - * Apply a function to dataspace attached at a given address - * - * /param addr address where the dataspace is attached - * /param f functor or lambda to apply - */ - template - auto apply_to_dataspace(addr_t addr, F f) - -> typename Trait::Functor::Return_type - { - enum { RECURSION_LIMIT = 5 }; - - return _apply_to_dataspace(addr, f, 0, RECURSION_LIMIT); - } - - /************************************** - ** Region manager session interface ** - **************************************/ - - Local_addr attach (Dataspace_capability, size_t, off_t, bool, Local_addr, bool); - void detach (Local_addr); - Pager_capability add_client (Thread_capability); - void remove_client (Pager_capability); - void fault_handler (Signal_context_capability handler); - State state (); - Dataspace_capability dataspace () { return _ds_cap; } - }; -} + _destroy(*rmc); + }); + } +}; #endif /* _CORE__INCLUDE__RM_SESSION_COMPONENT_H_ */ diff --git a/repos/base/src/core/main.cc b/repos/base/src/core/main.cc index 70b5eecbb8..0135038ac5 100644 --- a/repos/base/src/core/main.cc +++ b/repos/base/src/core/main.cc @@ -120,16 +120,16 @@ class Core_child : public Child_policy */ Core_child(Dataspace_capability elf_ds, Pd_session_capability pd, Ram_session_capability ram, - Cpu_session_capability cpu, Rm_session_capability rm, + Cpu_session_capability cpu, Service_registry &services) : _entrypoint(nullptr, STACK_SIZE, "init", false), _local_services(services), - _child(elf_ds, pd, ram, cpu, rm, &_entrypoint, this, + _child(elf_ds, pd, ram, cpu, + &_entrypoint, this, *_local_services.find(Pd_session::service_name()), *_local_services.find(Ram_session::service_name()), - *_local_services.find(Cpu_session::service_name()), - *_local_services.find(Rm_session::service_name())) + *_local_services.find(Cpu_session::service_name())) { _entrypoint.activate(); } @@ -233,13 +233,14 @@ int main() */ static Rpc_cap_factory rpc_cap_factory(sliced_heap); + static Pager_entrypoint pager_ep(rpc_cap_factory); + static Ram_root ram_root (e, e, platform()->ram_alloc(), &sliced_heap); static Rom_root rom_root (e, e, platform()->rom_fs(), &sliced_heap); - static Rm_root rm_root (e, e, e, &sliced_heap, rpc_cap_factory, - platform()->vm_start(), platform()->vm_size()); - static Cpu_root cpu_root (e, e, rm_root.pager_ep(), &sliced_heap, + static Rm_root rm_root (e, &sliced_heap, pager_ep); + static Cpu_root cpu_root (e, e, &pager_ep, &sliced_heap, Trace::sources()); - static Pd_root pd_root (e, e, &sliced_heap); + static Pd_root pd_root (e, e, pager_ep, &sliced_heap); static Log_root log_root (e, &sliced_heap); static Io_mem_root io_mem_root (e, e, platform()->io_mem_alloc(), platform()->ram_alloc(), &sliced_heap); @@ -287,15 +288,13 @@ int main() /* create CPU session for init and transfer all of the CPU quota to it */ static Cpu_session_component - cpu(e, e, rm_root.pager_ep(), &sliced_heap, Trace::sources(), + cpu(e, e, &pager_ep, &sliced_heap, Trace::sources(), "label=\"core\"", Affinity(), Cpu_session::QUOTA_LIMIT); Cpu_session_capability cpu_cap = core_env()->entrypoint()->manage(&cpu); Cpu_connection init_cpu("init"); init_cpu.ref_account(cpu_cap); cpu.transfer_quota(init_cpu, Cpu_session::quota_lim_upscale(100, 100)); - Rm_connection init_rm; - /* transfer all left memory to init, but leave some memory left for core */ /* NOTE: exception objects thrown in core components are currently allocated on core's heap and not accounted by the component's meta data allocator */ @@ -306,7 +305,7 @@ int main() Pd_connection init_pd("init"); Core_child *init = new (env()->heap()) Core_child(Rom_session_client(init_rom_session_cap).dataspace(), - init_pd, init_ram_session_cap, init_cpu.cap(), init_rm.cap(), + init_pd, init_ram_session_cap, init_cpu.cap(), local_services); PDBG("--- init created, waiting for exit condition ---"); diff --git a/repos/base/src/core/pd_session_component.cc b/repos/base/src/core/pd_session_component.cc index efdd301775..548800ea3a 100644 --- a/repos/base/src/core/pd_session_component.cc +++ b/repos/base/src/core/pd_session_component.cc @@ -38,7 +38,8 @@ void Pd_session_component::bind_thread(Thread_capability thread) _pd.bind_thread(p_thread); - cpu_thread->bound(true); + if (p_thread->pd()) + cpu_thread->bound(true); }); } diff --git a/repos/base/src/core/rm_session_component.cc b/repos/base/src/core/region_map_component.cc similarity index 68% rename from repos/base/src/core/rm_session_component.cc rename to repos/base/src/core/region_map_component.cc index 433b30873f..9dc3c005b0 100644 --- a/repos/base/src/core/rm_session_component.cc +++ b/repos/base/src/core/region_map_component.cc @@ -1,11 +1,9 @@ /* - * \brief Implementation of the RM session interface + * \brief Implementation of the region map * \author Christian Helmuth * \author Norman Feske * \author Alexander Boettcher * \date 2006-07-17 - * - * FIXME arg_string and quota missing */ /* @@ -24,140 +22,137 @@ /* core includes */ #include #include -#include +#include #include -using namespace Genode; - - static const bool verbose = false; static const bool verbose_page_faults = false; -namespace Genode { +struct Genode::Region_map_component::Fault_area +{ + addr_t _fault_addr; + addr_t _base; + size_t _size_log2; - struct Rm_session_component::Fault_area + addr_t _upper_bound() const { + return (_size_log2 == ~0UL) ? ~0 : (_base + (1 << _size_log2) - 1); } + + /** + * Default constructor, constructs invalid fault area + */ + Fault_area() : _size_log2(0) { } + + /** + * Constructor, fault area spans the maximum address-space size + */ + Fault_area(addr_t fault_addr) : + _fault_addr(fault_addr), _base(0), _size_log2(~0) { } + + /** + * Constrain fault area to specified region + */ + void constrain(addr_t region_base, size_t region_size) { - addr_t _fault_addr; - addr_t _base; - size_t _size_log2; - - addr_t _upper_bound() const { - return (_size_log2 == ~0UL) ? ~0 : (_base + (1 << _size_log2) - 1); } - - /** - * Default constructor, constructs invalid fault area + /* + * Find flexpage around _fault_addr that lies within the + * specified region. + * + * Start with a 'size_log2' of one less than the minimal + * page size. If the specified constraint conflicts with + * the existing fault area, the loop breaks at the first + * iteration and we can check for this condition after the + * loop. */ - Fault_area() : _size_log2(0) { } + size_t size_log2 = get_page_size_log2() - 1; + addr_t base = 0; + for (size_t try_size_log2 = get_page_size_log2(); + try_size_log2 < sizeof(addr_t)*8 ; try_size_log2++) { + addr_t fpage_mask = ~((1UL << try_size_log2) - 1); + addr_t try_base = _fault_addr & fpage_mask; - /** - * Constructor, fault area spans the maximum address-space size - */ - Fault_area(addr_t fault_addr) : - _fault_addr(fault_addr), _base(0), _size_log2(~0) { } + /* check lower bound of existing fault area */ + if (try_base < _base) + break; - /** - * Constrain fault area to specified region - */ - void constrain(addr_t region_base, size_t region_size) - { - /* - * Find flexpage around _fault_addr that lies within the - * specified region. - * - * Start with a 'size_log2' of one less than the minimal - * page size. If the specified constraint conflicts with - * the existing fault area, the loop breaks at the first - * iteration and we can check for this condition after the - * loop. - */ - size_t size_log2 = get_page_size_log2() - 1; - addr_t base = 0; - for (size_t try_size_log2 = get_page_size_log2(); - try_size_log2 < sizeof(addr_t)*8 ; try_size_log2++) { - addr_t fpage_mask = ~((1UL << try_size_log2) - 1); - addr_t try_base = _fault_addr & fpage_mask; + /* check against upper bound of existing fault area */ + if (try_base + (1UL << try_size_log2) - 1 > _upper_bound()) + break; - /* check lower bound of existing fault area */ - if (try_base < _base) - break; + /* check against lower bound of region */ + if (try_base < region_base) + break; - /* check against upper bound of existing fault area */ - if (try_base + (1UL << try_size_log2) - 1 > _upper_bound()) - break; + /* check against upper bound of region */ + if (try_base + (1 << try_size_log2) - 1 > region_base + region_size - 1) + break; - /* check against lower bound of region */ - if (try_base < region_base) - break; - - /* check against upper bound of region */ - if (try_base + (1 << try_size_log2) - 1 > region_base + region_size - 1) - break; - - /* flexpage is compatible with fault area, use it */ - size_log2 = try_size_log2; - base = try_base; - } - - /* if constraint is compatible with the fault area, invalidate */ - if (size_log2 < get_page_size_log2()) { - _size_log2 = 0; - _base = 0; - } else { - _size_log2 = size_log2; - _base = base; - } + /* flexpage is compatible with fault area, use it */ + size_log2 = try_size_log2; + base = try_base; } - /** - * Constrain fault area to specified flexpage size - */ - void constrain(size_t size_log2) - { - if (size_log2 >= _size_log2) - return; - - _base = _fault_addr & ~((1 << size_log2) - 1); + /* if constraint is compatible with the fault area, invalidate */ + if (size_log2 < get_page_size_log2()) { + _size_log2 = 0; + _base = 0; + } else { _size_log2 = size_log2; + _base = base; } + } - /** - * Determine common flexpage size compatible with specified fault areas + /** + * Constrain fault area to specified flexpage size + */ + void constrain(size_t size_log2) + { + if (size_log2 >= _size_log2) + return; + + _base = _fault_addr & ~((1 << size_log2) - 1); + _size_log2 = size_log2; + } + + /** + * Determine common flexpage size compatible with specified fault areas + */ + static size_t common_size_log2(Fault_area const &a1, Fault_area const &a2) + { + /* + * We have to make sure that the offset of page-fault address + * relative to the flexpage base is the same for both fault areas. + * This condition is met by the flexpage size equal to the number + * of common least-significant bits of both offsets. */ - static size_t common_size_log2(Fault_area const &a1, Fault_area const &a2) - { - /* - * We have to make sure that the offset of page-fault address - * relative to the flexpage base is the same for both fault areas. - * This condition is met by the flexpage size equal to the number - * of common least-significant bits of both offsets. - */ - size_t const diff = (a1.fault_addr() - a1.base()) - ^ (a2.fault_addr() - a2.base()); + size_t const diff = (a1.fault_addr() - a1.base()) + ^ (a2.fault_addr() - a2.base()); - /* - * Find highest clear bit in 'diff', starting from the least - * significant candidate. We can skip all bits lower then - * 'get_page_size_log2()' because they are not relevant as - * flexpage size (and are always zero). - */ - size_t n = get_page_size_log2(); - size_t const min_size_log2 = min(a1._size_log2, a2._size_log2); - for (; n < min_size_log2 && !(diff & (1 << n)); n++); + /* + * Find highest clear bit in 'diff', starting from the least + * significant candidate. We can skip all bits lower then + * 'get_page_size_log2()' because they are not relevant as + * flexpage size (and are always zero). + */ + size_t n = get_page_size_log2(); + size_t const min_size_log2 = min(a1._size_log2, a2._size_log2); + for (; n < min_size_log2 && !(diff & (1 << n)); n++); - return n; - } + return n; + } - addr_t fault_addr() const { return _fault_addr; } - addr_t base() const { return _base; } - bool valid() const { return _size_log2 > 0; } - }; -} + addr_t fault_addr() const { return _fault_addr; } + addr_t base() const { return _base; } + bool valid() const { return _size_log2 > 0; } +}; -/*************************** - ** Region-manager client ** - ***************************/ +using namespace Genode; + + +/*********************** + ** Region-map client ** + ***********************/ /* * This code is executed by the page-fault handler thread. @@ -165,17 +160,17 @@ namespace Genode { int Rm_client::pager(Ipc_pager &pager) { - using Fault_area = Rm_session_component::Fault_area; + using Fault_area = Region_map_component::Fault_area; - Rm_session::Fault_type pf_type = pager.is_write_fault() ? Rm_session::WRITE_FAULT - : Rm_session::READ_FAULT; + Region_map::State::Fault_type pf_type = pager.is_write_fault() ? Region_map::State::WRITE_FAULT + : Region_map::State::READ_FAULT; addr_t pf_addr = pager.fault_addr(); addr_t pf_ip = pager.fault_ip(); if (verbose_page_faults) print_page_fault("page fault", pf_addr, pf_ip, pf_type, badge()); - auto lambda = [&] (Rm_session_component *rm_session, + auto lambda = [&] (Region_map_component *region_map, Rm_region *region, addr_t ds_offset, addr_t region_offset) -> int @@ -186,18 +181,17 @@ int Rm_client::pager(Ipc_pager &pager) /* * We found no attachment at the page-fault address and therefore have * to reflect the page fault as region-manager fault. The signal - * handler is then expected to request the state of the region-manager - * session. + * handler is then expected to request the state of the region map. */ /* print a warning if it's no managed-dataspace */ - if (rm_session == member_rm_session()) + if (region_map == member_rm()) print_page_fault("no RM attachment", pf_addr, pf_ip, pf_type, badge()); - /* register fault at responsible region-manager session */ - if (rm_session) - rm_session->fault(this, pf_addr - region_offset, pf_type); + /* register fault at responsible region map */ + if (region_map) + region_map->fault(this, pf_addr - region_offset, pf_type); /* there is no attachment return an error condition */ return 1; @@ -225,14 +219,14 @@ int Rm_client::pager(Ipc_pager &pager) /* * Check if dataspace is compatible with page-fault type */ - if (pf_type == Rm_session::WRITE_FAULT && !dsc->writable()) { + if (pf_type == Region_map::State::WRITE_FAULT && !dsc->writable()) { /* attempted there is no attachment return an error condition */ print_page_fault("attempted write at read-only memory", pf_addr, pf_ip, pf_type, badge()); - /* register fault at responsible region-manager session */ - rm_session->fault(this, src_fault_area.fault_addr(), pf_type); + /* register fault at responsible region map */ + region_map->fault(this, src_fault_area.fault_addr(), pf_type); return 2; } @@ -255,7 +249,7 @@ int Rm_client::pager(Ipc_pager &pager) pager.set_reply_mapping(mapping); return 0; }; - return member_rm_session()->apply_to_dataspace(pf_addr, lambda); + return member_rm()->apply_to_dataspace(pf_addr, lambda); } @@ -263,27 +257,27 @@ int Rm_client::pager(Ipc_pager &pager) ** Faulter ** *************/ -void Rm_faulter::fault(Rm_session_component *faulting_rm_session, - Rm_session::State fault_state) +void Rm_faulter::fault(Region_map_component *faulting_region_map, + Region_map::State fault_state) { Lock::Guard lock_guard(_lock); - _faulting_rm_session = faulting_rm_session; + _faulting_region_map = faulting_region_map; _fault_state = fault_state; _pager_object->unresolved_page_fault_occurred(); } -void Rm_faulter::dissolve_from_faulting_rm_session(Rm_session_component * caller) +void Rm_faulter::dissolve_from_faulting_region_map(Region_map_component * caller) { /* serialize access */ Lock::Guard lock_guard(_lock); - if (_faulting_rm_session) - _faulting_rm_session->discard_faulter(this, _faulting_rm_session != caller); + if (_faulting_region_map) + _faulting_region_map->discard_faulter(this, _faulting_region_map != caller); - _faulting_rm_session = 0; + _faulting_region_map = 0; } @@ -292,19 +286,19 @@ void Rm_faulter::continue_after_resolved_fault() Lock::Guard lock_guard(_lock); _pager_object->wake_up(); - _faulting_rm_session = 0; - _fault_state = Rm_session::State(); + _faulting_region_map = 0; + _fault_state = Region_map::State(); } -/************************************** - ** Region-manager-session component ** - **************************************/ +/************************** + ** Region-map component ** + **************************/ -Rm_session::Local_addr -Rm_session_component::attach(Dataspace_capability ds_cap, size_t size, +Region_map::Local_addr +Region_map_component::attach(Dataspace_capability ds_cap, size_t size, off_t offset, bool use_local_addr, - Rm_session::Local_addr local_addr, + Region_map::Local_addr local_addr, bool executable) { /* serialize access */ @@ -422,25 +416,25 @@ Rm_session_component::attach(Dataspace_capability ds_cap, size_t size, } -static void unmap_managed(Rm_session_component *session, Rm_region *region, int level) +static void unmap_managed(Region_map_component *rm, Rm_region *region, int level) { - for (Rm_region *managed = session->dataspace_component()->regions()->first(); + for (Rm_region *managed = rm->dataspace_component()->regions()->first(); managed; managed = managed->List::Element::next()) { if (verbose) PDBG("(%d: %p) a=%lx,s=%lx,off=%lx ra=%lx,s=%lx,off=%lx sub-session %p", - level, session, managed->base(), (long)managed->size(), managed->offset(), - region->base(), (long)region->size(), region->offset(), managed->session()); + level, rm, managed->base(), (long)managed->size(), managed->offset(), + region->base(), (long)region->size(), region->offset(), managed->rm()); if (managed->base() - managed->offset() >= region->base() - region->offset() && managed->base() - managed->offset() + managed->size() <= region->base() - region->offset() + region->size()) - unmap_managed(managed->session(), managed, level + 1); + unmap_managed(managed->rm(), managed, level + 1); - /* Found a leaf node (here a leaf is an Rm_session whose dataspace has no regions) */ - if (!managed->session()->dataspace_component()->regions()->first()) - for (Rm_client *rc = managed->session()->clients()->first(); + /* found a leaf node (here a leaf is an Region_map whose dataspace has no regions) */ + if (!managed->rm()->dataspace_component()->regions()->first()) + for (Rm_client *rc = managed->rm()->clients()->first(); rc; rc = rc->List::Element::next()) rc->unmap(region->dataspace()->core_local_addr() + region->offset(), managed->base() + region->base() - managed->offset(), region->size()); @@ -448,7 +442,7 @@ static void unmap_managed(Rm_session_component *session, Rm_region *region, int } -void Rm_session_component::detach(Local_addr local_addr) +void Region_map_component::detach(Local_addr local_addr) { /* serialize access */ Lock::Guard lock_guard(_lock); @@ -496,12 +490,12 @@ void Rm_session_component::detach(Local_addr local_addr) /* * This function gets called from the destructor of 'Dataspace_component', * which iterates through all regions the dataspace is attached to. One - * particular case is the destruction of an 'Rm_session_component' and its + * particular case is the destruction of an 'Region_map_component' and its * contained managed dataspace ('_ds') member. The type of this member is - * derived from 'Dataspace_component' and provides the 'sub_rm_session' + * derived from 'Dataspace_component' and provides the 'sub_region_map' * function, which can normally be used to distinguish managed dataspaces * from leaf dataspaces. However, at destruction time of the '_dsc' base - * class, the vtable entry of 'sub_rm_session' already points to the + * class, the vtable entry of 'sub_region_map' already points to the * base-class's function. Hence, we cannot check the return value of this * function to determine if the dataspace is a managed dataspace. Instead, * we introduced a dataspace member '_managed' with the non-virtual accessor @@ -509,7 +503,7 @@ void Rm_session_component::detach(Local_addr local_addr) */ /* - * Go through all RM clients using the RM session. For each RM client, we + * Go through all RM clients using the region map. For each RM client, we * need to unmap the referred region from its virtual address space. */ Rm_client *prev_rc = 0; @@ -554,8 +548,8 @@ void Rm_session_component::detach(Local_addr local_addr) } /* - * If RM session is used as nested dataspace, unmap this - * dataspace from all RM sessions. + * If region map is used as nested dataspace, unmap this dataspace from all + * region maps. */ unmap_managed(this, ®ion, 1); @@ -571,7 +565,7 @@ void Rm_session_component::detach(Local_addr local_addr) } -Pager_capability Rm_session_component::add_client(Thread_capability thread) +Pager_capability Region_map_component::add_client(Thread_capability thread) { unsigned long badge; Affinity::Location location; @@ -582,6 +576,11 @@ Pager_capability Rm_session_component::add_client(Thread_capability thread) auto lambda = [&] (Cpu_thread_component *cpu_thread) { if (!cpu_thread) throw Invalid_thread(); + if (!cpu_thread->bound()) { + PERR("attempt to create pager for unbound thread"); + throw Region_map::Unbound_thread(); + } + /* determine identification of client when faulting */ badge = cpu_thread->platform_thread()->pager_object_badge(); @@ -610,7 +609,7 @@ Pager_capability Rm_session_component::add_client(Thread_capability thread) } -void Rm_session_component::remove_client(Pager_capability pager_cap) +void Region_map_component::remove_client(Pager_capability pager_cap) { Rm_client *client; @@ -622,12 +621,12 @@ void Rm_session_component::remove_client(Pager_capability pager_cap) /* * Rm_client is derived from Pager_object. If the Pager_object is also * derived from Thread_base then the Rm_client object must be - * destructed without holding the rm_session_object lock. The native + * destructed without holding the region_map lock. The native * platform specific Thread_base implementation has to take care that * all in-flight page handling requests are finished before * destruction. (Either by waiting until the end of or by * cancellation of the last in-flight request. - * This operation can also require taking the rm_session_object lock. + * This operation can also require taking the region_map lock. */ { Lock::Guard lock_guard(_lock); @@ -639,7 +638,7 @@ void Rm_session_component::remove_client(Pager_capability pager_cap) { Lock::Guard lock_guard(_lock); - client->dissolve_from_faulting_rm_session(this); + client->dissolve_from_faulting_region_map(this); } }; _pager_ep->apply(pager_cap, lambda); @@ -648,11 +647,11 @@ void Rm_session_component::remove_client(Pager_capability pager_cap) } -void Rm_session_component::fault(Rm_faulter *faulter, addr_t pf_addr, - Rm_session::Fault_type pf_type) +void Region_map_component::fault(Rm_faulter *faulter, addr_t pf_addr, + Region_map::State::Fault_type pf_type) { /* remember fault state in faulting thread */ - faulter->fault(this, Rm_session::State(pf_type, pf_addr)); + faulter->fault(this, Region_map::State(pf_type, pf_addr)); /* enqueue faulter */ _faulters.enqueue(faulter); @@ -662,7 +661,7 @@ void Rm_session_component::fault(Rm_faulter *faulter, addr_t pf_addr, } -void Rm_session_component::discard_faulter(Rm_faulter *faulter, bool do_lock) +void Region_map_component::discard_faulter(Rm_faulter *faulter, bool do_lock) { if (do_lock) { Lock::Guard lock_guard(_lock); @@ -672,13 +671,13 @@ void Rm_session_component::discard_faulter(Rm_faulter *faulter, bool do_lock) } -void Rm_session_component::fault_handler(Signal_context_capability handler) +void Region_map_component::fault_handler(Signal_context_capability handler) { _fault_notifier.context(handler); } -Rm_session::State Rm_session_component::state() +Region_map::State Region_map_component::state() { /* serialize access */ Lock::Guard lock_guard(_lock); @@ -688,7 +687,7 @@ Rm_session::State Rm_session_component::state() /* return ready state if there are not current faulters */ if (!faulter) - return Rm_session::State(); + return Region_map::State(); /* return fault information regarding the first faulter of the list */ return faulter->fault_state(); @@ -698,29 +697,31 @@ static Dataspace_capability _type_deduction_helper(Dataspace_capability cap) { return cap; } -Rm_session_component::Rm_session_component(Rpc_entrypoint *ds_ep, - Rpc_entrypoint *thread_ep, - Rpc_entrypoint *session_ep, - Allocator *md_alloc, - size_t ram_quota, - Pager_entrypoint *pager_ep, +Region_map_component::Region_map_component(Rpc_entrypoint &ep, + Allocator &md_alloc, + Pager_entrypoint &pager_ep, addr_t vm_start, size_t vm_size) : - _ds_ep(ds_ep), _thread_ep(thread_ep), _session_ep(session_ep), - _md_alloc(md_alloc, ram_quota), + _ds_ep(&ep), _thread_ep(&ep), _session_ep(&ep), + _md_alloc(md_alloc), _client_slab(&_md_alloc), _ref_slab(&_md_alloc), - _map(&_md_alloc), _pager_ep(pager_ep), + _map(&_md_alloc), _pager_ep(&pager_ep), _ds(align_addr(vm_size, get_page_size_log2())), - _ds_cap(_type_deduction_helper(ds_ep->manage(&_ds))) + _ds_cap(_type_deduction_helper(_ds_ep->manage(&_ds))) { /* configure managed VM area */ _map.add_range(vm_start, align_addr(vm_size, get_page_size_log2())); + + Capability cap = ep.manage(this); + _ds.sub_rm(cap); } -Rm_session_component::~Rm_session_component() +Region_map_component::~Region_map_component() { + _ds_ep->dissolve(this); + /* dissolve all clients from pager entrypoint */ Rm_client *cl; do { @@ -755,13 +756,13 @@ Rm_session_component::~Rm_session_component() /* serialize access */ _lock.lock(); - /* remove all faulters with pending page faults at this rm session */ + /* remove all faulters with pending page faults at this region map */ while (Rm_faulter *faulter = _faulters.head()) - faulter->dissolve_from_faulting_rm_session(this); + faulter->dissolve_from_faulting_region_map(this); /* remove all clients, invalidate rm_client pointers in cpu_thread objects */ while (Rm_client *cl = _client_slab()->first_object()) { - cl->dissolve_from_faulting_rm_session(this); + cl->dissolve_from_faulting_region_map(this); Thread_capability thread_cap = cl->thread_cap(); if (thread_cap.valid()) diff --git a/repos/base/src/core/stack_area.cc b/repos/base/src/core/stack_area.cc index c3960cc109..b264d59ae7 100644 --- a/repos/base/src/core/stack_area.cc +++ b/repos/base/src/core/stack_area.cc @@ -13,7 +13,7 @@ */ /* Genode includes */ -#include +#include #include #include #include @@ -30,7 +30,7 @@ namespace Genode { - Rm_session *env_stack_area_rm_session; + Region_map *env_stack_area_region_map; Ram_session *env_stack_area_ram_session; void init_stack_area(); @@ -52,7 +52,7 @@ using namespace Genode; * of a dataspace has no effect, but the attachment of the thereby "empty" * dataspace is doing both: allocation and attachment. */ -class Stack_area_rm_session : public Rm_session +class Stack_area_region_map : public Region_map { private: @@ -161,8 +161,8 @@ class Stack_area_ram_session : public Ram_session void Genode::init_stack_area() { - static Stack_area_rm_session rm; - env_stack_area_rm_session = &rm; + static Stack_area_region_map rm; + env_stack_area_region_map = &rm; static Stack_area_ram_session ram; env_stack_area_ram_session = &ram; diff --git a/repos/base/src/include/base/internal/platform_env.h b/repos/base/src/include/base/internal/platform_env.h index 72cb5141c4..24b140abd8 100644 --- a/repos/base/src/include/base/internal/platform_env.h +++ b/repos/base/src/include/base/internal/platform_env.h @@ -75,15 +75,15 @@ class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve Expanding_ram_session_client ram; Expanding_cpu_session_client cpu; - Expanding_rm_session_client rm; Pd_session_client pd; + Expanding_region_map_client rm; Resources(Parent &parent) : ram(request(parent, "Env::ram_session")), cpu(request(parent, "Env::cpu_session")), - rm (request (parent, "Env::rm_session")), - pd (request (parent, "Env::pd_session")) + pd (request (parent, "Env::pd_session")), + rm (pd, pd.address_space()) { } }; @@ -96,7 +96,7 @@ class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve * because the 'Local_parent' performs a dynamic memory allocation * due to the creation of the stack area's sub-RM session. */ - Attached_stack_area _stack_area { _parent_client, _resources.rm }; + Attached_stack_area _stack_area { _parent_client, _resources.pd }; char _initial_heap_chunk[sizeof(addr_t) * 4096]; @@ -105,7 +105,7 @@ class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve * * See the comment of '_fallback_sig_cap()' in 'env/env.cc'. */ - constexpr static size_t _emergency_ram_size() { return 8*1024; } + constexpr static size_t _emergency_ram_size() { return 16*1024; } Ram_dataspace_capability _emergency_ram_ds; public: @@ -122,14 +122,14 @@ class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve _emergency_ram_ds(_resources.ram.alloc(_emergency_ram_size())) { env_stack_area_ram_session = &_resources.ram; - env_stack_area_rm_session = &_stack_area; + env_stack_area_region_map = &_stack_area; } /* * Support functions for implementing fork on Noux. */ void reinit(Native_capability::Dst, long) override; - void reinit_main_thread(Rm_session_capability &) override; + void reinit_main_thread(Capability &) override; /************************************* @@ -153,7 +153,7 @@ class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve Ram_session_capability ram_session_cap() override { return _resources.ram; } Cpu_session *cpu_session() override { return &_resources.cpu; } Cpu_session_capability cpu_session_cap() override { return _resources.cpu; } - Rm_session *rm_session() override { return &_resources.rm; } + Region_map *rm_session() override { return &_resources.rm; } Pd_session *pd_session() override { return &_resources.pd; } Pd_session_capability pd_session_cap() override { return _resources.pd; } Allocator *heap() override { return &_heap; } diff --git a/repos/base/src/include/base/internal/platform_env_common.h b/repos/base/src/include/base/internal/platform_env_common.h index 1db60c4a6e..a8913e434b 100644 --- a/repos/base/src/include/base/internal/platform_env_common.h +++ b/repos/base/src/include/base/internal/platform_env_common.h @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include @@ -30,7 +30,7 @@ namespace Genode { - class Expanding_rm_session_client; + class Expanding_region_map_client; class Expanding_ram_session_client; class Expanding_cpu_session_client; class Expanding_parent_client; @@ -39,7 +39,7 @@ namespace Genode { Parent_capability parent_cap(); - extern Rm_session *env_stack_area_rm_session; + extern Region_map *env_stack_area_region_map; extern Ram_session *env_stack_area_ram_session; void init_signal_thread(); @@ -71,31 +71,31 @@ struct Upgradeable_client : CLIENT }; -struct Genode::Expanding_rm_session_client -: - Upgradeable_client +struct Genode::Expanding_region_map_client : Region_map_client { - Expanding_rm_session_client(Rm_session_capability cap) - : Upgradeable_client(cap) { } + Upgradeable_client _pd_client; + + Expanding_region_map_client(Pd_session_capability pd, Capability rm) + : Region_map_client(rm), _pd_client(pd) { } Local_addr attach(Dataspace_capability ds, size_t size, off_t offset, bool use_local_addr, Local_addr local_addr, bool executable) { - return retry( + return retry( [&] () { - return Rm_session_client::attach(ds, size, offset, + return Region_map_client::attach(ds, size, offset, use_local_addr, local_addr, executable); }, - [&] () { upgrade_ram(8*1024); }); + [&] () { _pd_client.upgrade_ram(8*1024); }); } Pager_capability add_client(Thread_capability thread) { - return retry( - [&] () { return Rm_session_client::add_client(thread); }, - [&] () { upgrade_ram(8*1024); }); + return retry( + [&] () { return Region_map_client::add_client(thread); }, + [&] () { _pd_client.upgrade_ram(8*1024); }); } }; @@ -336,30 +336,18 @@ class Genode::Expanding_parent_client : public Parent_client }; -struct Genode::Attached_stack_area : Genode::Expanding_rm_session_client +struct Genode::Attached_stack_area : Genode::Expanding_region_map_client { - /** - * Helper for requesting the sub RM session of the stack area - */ - Rm_session_capability _session(Parent &parent) - { - char buf[256]; - snprintf(buf, sizeof(buf), "ram_quota=64K, start=0x0, size=0x%zx", - (size_t)stack_area_virtual_size()); - - return static_cap_cast(parent.session(Rm_session::service_name(), - buf, Affinity())); - } - - Attached_stack_area(Parent &parent, Rm_session &env_rm) + Attached_stack_area(Parent &parent, Pd_session_capability pd) : - Expanding_rm_session_client(_session(parent)) + Expanding_region_map_client(pd, Pd_session_client(pd).stack_area()) { - env_rm.attach_at(Expanding_rm_session_client::dataspace(), - stack_area_virtual_base(), - stack_area_virtual_size()); + Region_map_client address_space(Pd_session_client(pd).address_space()); + + address_space.attach_at(Expanding_region_map_client::dataspace(), + stack_area_virtual_base(), + stack_area_virtual_size()); } }; - #endif /* _INCLUDE__BASE__INTERNAL__PLATFORM_ENV_COMMON_H_ */ diff --git a/repos/base/src/lib/ldso/file.cc b/repos/base/src/lib/ldso/file.cc index 3c42844e25..6df2c54c22 100644 --- a/repos/base/src/lib/ldso/file.cc +++ b/repos/base/src/lib/ldso/file.cc @@ -11,13 +11,17 @@ * under the terms of the GNU General Public License version 2. */ +/* local includes */ #include #include -#include -#include -#include +/* Genode includes */ #include +#include +#include +#include +#include +#include char const *Linker::ELFMAG = "\177ELF"; @@ -33,12 +37,16 @@ namespace Linker /** * Managed dataspace for ELF files (singelton) */ -class Linker::Rm_area : public Rm_connection +class Linker::Rm_area { + public: + + typedef Region_map_client::Local_addr Local_addr; + typedef Region_map_client::Region_conflict Region_conflict; + private: - /* size of dataspace */ - enum { RESERVATION = 160 * 1024 * 1024 }; + Region_map_client _rm; addr_t _base; /* base address of dataspace */ Allocator_avl _range; /* VM range allocator */ @@ -46,12 +54,10 @@ class Linker::Rm_area : public Rm_connection protected: Rm_area(addr_t base) - : Rm_connection(0, RESERVATION), _range(env()->heap()) + : _rm(env()->pd_session()->linker_area()), _range(env()->heap()) { - on_destruction(KEEP_OPEN); - - _base = (addr_t) env()->rm_session()->attach_at(dataspace(), base); - _range.add_range(base, RESERVATION); + _base = (addr_t) env()->rm_session()->attach_at(_rm.dataspace(), base); + _range.add_range(base, Pd_session::LINKER_AREA_SIZE); } public: @@ -96,21 +102,32 @@ class Linker::Rm_area : public Rm_connection void free_region(addr_t vaddr) { _range.free((void *)vaddr); } /** - * Overwritten from 'Rm_connection' + * Overwritten from 'Region_map_client' */ Local_addr attach_at(Dataspace_capability ds, addr_t local_addr, - size_t size = 0, off_t offset = 0) { - return Rm_connection::attach_at(ds, local_addr - _base, size, offset); } + size_t size = 0, off_t offset = 0) + { + return retry( + [&] () { + return _rm.attach_at(ds, local_addr - _base, size, offset); + }, + [&] () { env()->parent()->upgrade(env()->pd_session_cap(), "ram_quota=8K"); }); + } /** - * Overwritten from 'Rm_connection' + * Overwritten from 'Region_map_client' */ Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr, - size_t size = 0, off_t offset = 0) { - return Rm_connection::attach_executable(ds, local_addr - _base, size, offset); } + size_t size = 0, off_t offset = 0) + { + return retry( + [&] () { + return _rm.attach_executable(ds, local_addr - _base, size, offset); + }, + [&] () { env()->parent()->upgrade(env()->pd_session_cap(), "ram_quota=8K"); }); + } - void detach(Local_addr local_addr) { - Rm_connection::detach((addr_t)local_addr - _base); } + void detach(Local_addr local_addr) { _rm.detach((addr_t)local_addr - _base); } }; @@ -306,7 +323,7 @@ File const *Linker::load(char const *path, bool load) if (verbose_loading) PDBG("loading: %s (PHDRS only: %s)", path, load ? "no" : "yes"); - Elf_file *file = new(env()->heap()) Elf_file(Linker::file(path), load); + Elf_file *file = new (env()->heap()) Elf_file(Linker::file(path), load); return file; } diff --git a/repos/base/src/lib/startup/init_main_thread.cc b/repos/base/src/lib/startup/init_main_thread.cc index b28a93be28..bd3118870f 100644 --- a/repos/base/src/lib/startup/init_main_thread.cc +++ b/repos/base/src/lib/startup/init_main_thread.cc @@ -25,7 +25,7 @@ addr_t init_main_thread_result; extern void init_exception_handling(); -namespace Genode { extern Rm_session * const env_stack_area_rm_session; } +namespace Genode { extern Region_map * const env_stack_area_region_map; } void prepare_init_main_thread(); diff --git a/repos/base/src/test/rm_fault/main.cc b/repos/base/src/test/rm_fault/main.cc index 4be95adff1..59fca09bdb 100644 --- a/repos/base/src/test/rm_fault/main.cc +++ b/repos/base/src/test/rm_fault/main.cc @@ -82,7 +82,6 @@ class Test_child : public Child_policy Child _child; Parent_service _log_service; - Parent_service _rm_service; public: @@ -93,19 +92,16 @@ class Test_child : public Child_policy Genode::Pd_session_capability pd, Genode::Ram_session_capability ram, Genode::Cpu_session_capability cpu, - Genode::Rm_session_capability rm, Genode::Cap_session *cap) : _entrypoint(cap, STACK_SIZE, "child", false), - _child(elf_ds, pd, ram, cpu, rm, &_entrypoint, this), - _log_service("LOG"), _rm_service("RM") + _child(elf_ds, pd, ram, cpu, &_entrypoint, this), + _log_service("LOG") { /* start execution of the new child */ _entrypoint.activate(); } - Rm_session_capability rm_session_cap() { return _child.rm_session_cap(); } - /**************************** ** Child-policy interface ** @@ -116,9 +112,7 @@ class Test_child : public Child_policy Service *resolve_session_request(const char *service, const char *) { /* forward white-listed session requests to our parent */ - return !strcmp(service, "LOG") ? &_log_service - : !strcmp(service, "RM") ? &_rm_service - : 0; + return !strcmp(service, "LOG") ? &_log_service : 0; } void filter_session_args(const char *service, @@ -138,7 +132,6 @@ void main_parent(Dataspace_capability elf_ds) static Pd_connection pd; static Ram_connection ram; static Cpu_connection cpu; - static Rm_connection rm; static Cap_connection cap; /* transfer some of our own ram quota to the new child */ @@ -148,13 +141,13 @@ void main_parent(Dataspace_capability elf_ds) static Signal_receiver fault_handler; - /* register fault handler */ + /* register fault handler at the child's address space */ static Signal_context signal_context; - rm.fault_handler(fault_handler.manage(&signal_context)); + Region_map_client address_space(pd.address_space()); + address_space.fault_handler(fault_handler.manage(&signal_context)); /* create child */ - static Test_child child(elf_ds, pd.cap(), ram.cap(), cpu.cap(), - rm.cap(), &cap); + static Test_child child(elf_ds, pd.cap(), ram.cap(), cpu.cap(), &cap); /* allocate dataspace used for creating shared memory between parent and child */ Dataspace_capability ds = env()->ram_session()->alloc(4096); @@ -166,16 +159,16 @@ void main_parent(Dataspace_capability elf_ds) fault_handler.wait_for_signal(); printf("received region-manager fault signal, request fault state\n"); - Rm_session::State state = rm.state(); + Region_map::State state = address_space.state(); printf("rm session state is %s, pf_addr=0x%p\n", - state.type == Rm_session::READ_FAULT ? "READ_FAULT" : - state.type == Rm_session::WRITE_FAULT ? "WRITE_FAULT" : - state.type == Rm_session::EXEC_FAULT ? "EXEC_FAULT" : "READY", + state.type == Region_map::State::READ_FAULT ? "READ_FAULT" : + state.type == Region_map::State::WRITE_FAULT ? "WRITE_FAULT" : + state.type == Region_map::State::EXEC_FAULT ? "EXEC_FAULT" : "READY", (void *)state.addr); /* ignore spuriuous fault signal */ - if (state.type == Rm_session::READY) { + if (state.type == Region_map::State::READY) { PINF("ignoring spurious fault signal"); continue; } @@ -186,7 +179,7 @@ void main_parent(Dataspace_capability elf_ds) printf("attach dataspace to the child at 0x%p\n", (void *)child_virt_addr); *local_addr = 0x1234; - rm.attach_at(ds, child_virt_addr); + address_space.attach_at(ds, child_virt_addr); /* wait until our child modifies the dataspace content */ while (*local_addr == 0x1234); @@ -194,7 +187,7 @@ void main_parent(Dataspace_capability elf_ds) printf("child modified dataspace content, new value is %x\n", *local_addr); printf("revoke dataspace from child\n"); - rm.detach((void *)child_virt_addr); + address_space.detach((void *)child_virt_addr); } fault_handler.dissolve(&signal_context); diff --git a/repos/base/src/test/rm_nested/main.cc b/repos/base/src/test/rm_nested/main.cc index 525f2c9cad..dff4b6a450 100644 --- a/repos/base/src/test/rm_nested/main.cc +++ b/repos/base/src/test/rm_nested/main.cc @@ -1,15 +1,14 @@ /* - * \brief Testing nested region-manager sessions + * \brief Testing nested region maps * \author Norman Feske * \date 2008-09-27 * * The program uses two threads. A local fault-handler thread waits for fault - * signals regarding a sub-region-manager session that is mapped into the local + * signals regarding a sub-region maps that is mapped into the local * address space as a dataspace. If a fault occurs, this thread allocates a new * dataspace and attaches it to the faulting address to resolve the fault. The * main thread performs memory accesses at the local address range that is - * backed by the sub-region-manager session. Thereby, it triggers - * region-manager faults. + * backed by the region map. Thereby, it triggers region-map faults. */ /* @@ -25,6 +24,7 @@ #include #include #include +#include #include using namespace Genode; @@ -43,30 +43,30 @@ class Local_fault_handler : public Thread<4096> { private: - Rm_session *_rm_session; - Signal_receiver *_receiver; + Region_map &_region_map; + Signal_receiver &_receiver; public: - Local_fault_handler(Rm_session *rm_session, Signal_receiver *receiver) + Local_fault_handler(Region_map ®ion_map, Signal_receiver &receiver) : Thread("local_fault_handler"), - _rm_session(rm_session), _receiver(receiver) + _region_map(region_map), _receiver(receiver) { } void handle_fault() { - Rm_session::State state = _rm_session->state(); + Region_map::State state = _region_map.state(); - printf("rm session state is %s, pf_addr=0x%lx\n", - state.type == Rm_session::READ_FAULT ? "READ_FAULT" : - state.type == Rm_session::WRITE_FAULT ? "WRITE_FAULT" : - state.type == Rm_session::EXEC_FAULT ? "EXEC_FAULT" : "READY", + printf("region-map state is %s, pf_addr=0x%lx\n", + state.type == Region_map::State::READ_FAULT ? "READ_FAULT" : + state.type == Region_map::State::WRITE_FAULT ? "WRITE_FAULT" : + state.type == Region_map::State::EXEC_FAULT ? "EXEC_FAULT" : "READY", state.addr); - printf("allocate dataspace and attach it to sub rm session\n"); + printf("allocate dataspace and attach it to sub region map\n"); Dataspace_capability ds = env()->ram_session()->alloc(PAGE_SIZE); - _rm_session->attach_at(ds, state.addr & ~(PAGE_SIZE - 1)); + _region_map.attach_at(ds, state.addr & ~(PAGE_SIZE - 1)); printf("returning from handle_fault\n"); } @@ -75,7 +75,7 @@ class Local_fault_handler : public Thread<4096> { while (true) { printf("fault handler: waiting for fault signal\n"); - Signal signal = _receiver->wait_for_signal(); + Signal signal = _receiver.wait_for_signal(); printf("received %u fault signals\n", signal.num()); for (unsigned i = 0; i < signal.num(); i++) handle_fault(); @@ -86,32 +86,31 @@ class Local_fault_handler : public Thread<4096> int main(int argc, char **argv) { - printf("--- nested region-manager test ---\n"); + printf("--- nested region map test ---\n"); /* - * Initialize sub-region-manager session and set up a local fault handler - * for it. + * Initialize sub region map and set up a local fault handler for it. */ - static Rm_connection sub_rm(0, MANAGED_SIZE); + static Rm_connection rm; + static Region_map_client region_map(rm.create(MANAGED_SIZE)); static Cap_connection cap; static Signal_receiver receiver; static Signal_context context; - sub_rm.fault_handler(receiver.manage(&context)); - static Local_fault_handler fault_handler(&sub_rm, &receiver); + region_map.fault_handler(receiver.manage(&context)); + static Local_fault_handler fault_handler(region_map, receiver); fault_handler.start(); /* - * Attach sub-region-manager session as dataspace to the local address - * space. + * Attach region map as dataspace to the local address space. */ - void *addr = env()->rm_session()->attach(sub_rm.dataspace()); + void *addr = env()->rm_session()->attach(region_map.dataspace()); printf("attached sub dataspace at local address 0x%p\n", addr); - Dataspace_client client(sub_rm.dataspace()); - printf("sub dataspace size is %u should be %u\n", client.size(), MANAGED_SIZE); + Dataspace_client client(region_map.dataspace()); + printf("sub dataspace size is %zu should be %u\n", client.size(), MANAGED_SIZE); /* - * Walk through the address range belonging to the sub-region-manager session + * Walk through the address range belonging to the region map */ char *managed = (char *)addr; for (int i = 0; i < MANAGED_SIZE; i += PAGE_SIZE/16) { @@ -119,6 +118,8 @@ int main(int argc, char **argv) managed[i] = 13; } - printf("--- finished nested region-manager test ---\n"); + receiver.dissolve(&context); + + printf("--- finished nested region map test ---\n"); return 0; } diff --git a/repos/base/src/test/rm_nested/target.mk b/repos/base/src/test/rm_nested/target.mk index 4d5f2a156a..3ba1b099e0 100644 --- a/repos/base/src/test/rm_nested/target.mk +++ b/repos/base/src/test/rm_nested/target.mk @@ -1,4 +1,3 @@ -TARGET = test-rm_nested -REQUIRES = experimental -SRC_CC = main.cc -LIBS = base +TARGET = test-rm_nested +SRC_CC = main.cc +LIBS = base diff --git a/repos/base/src/test/sub_rm/main.cc b/repos/base/src/test/sub_rm/main.cc index 808c52e15f..d65d75f15f 100644 --- a/repos/base/src/test/sub_rm/main.cc +++ b/repos/base/src/test/sub_rm/main.cc @@ -16,6 +16,7 @@ #include #include #include +#include /* platform-specific test policy */ #include @@ -62,7 +63,9 @@ int main(int, char **) printf("create RM connection\n"); enum { SUB_RM_SIZE = 1024*1024 }; - Rm_connection sub_rm(0, SUB_RM_SIZE); + Rm_connection rm; + + Region_map_client sub_rm(rm.create(SUB_RM_SIZE)); enum { DS_SIZE = 4*4096 }; Ram_dataspace_capability ds = env()->ram_session()->alloc(DS_SIZE); @@ -79,7 +82,7 @@ int main(int, char **) sub_rm.attach(ds, 0, 0, false, (addr_t)0); fail("sub rm attach_any unexpectedly did not fail"); } - catch (Rm_session::Out_of_metadata) { + catch (Region_map::Out_of_metadata) { printf("attach failed as expected\n"); } } @@ -127,7 +130,7 @@ int main(int, char **) sub_rm.attach_at(ds, SUB_RM_SIZE - 4096, 0, 0); fail("undetected boundary conflict\n"); } - catch (Rm_session::Region_conflict) { + catch (Region_map::Region_conflict) { printf("attaching beyond sub RM boundary failed as expected\n"); } /* @@ -138,7 +141,7 @@ int main(int, char **) sub_rm.attach_at(ds, DS_SUB_OFFSET + 4096, 0, 0); fail("region conflict went undetected\n"); } - catch (Rm_session::Region_conflict) { + catch (Region_map::Region_conflict) { printf("attaching conflicting region failed as expected\n"); } if (attach_twice_forbidden) { @@ -150,7 +153,7 @@ int main(int, char **) env()->rm_session()->attach(sub_rm.dataspace()); fail("double attachment of sub RM session went undetected\n"); } - catch (Rm_session::Out_of_metadata) { + catch (Region_map::Out_of_metadata) { printf("doubly attaching sub RM session failed as expected\n"); } } diff --git a/repos/dde_bsd/src/lib/audio/mem.cc b/repos/dde_bsd/src/lib/audio/mem.cc index 29233c8f97..207474f17b 100644 --- a/repos/dde_bsd/src/lib/audio/mem.cc +++ b/repos/dde_bsd/src/lib/audio/mem.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include /* local includes */ @@ -42,7 +43,8 @@ namespace Bsd { * Back-end allocator for Genode's slab allocator */ class Bsd::Slab_backend_alloc : public Genode::Allocator, - public Genode::Rm_connection + public Genode::Rm_connection, + public Genode::Region_map_client { private: @@ -68,7 +70,7 @@ class Bsd::Slab_backend_alloc : public Genode::Allocator, try { _ds_cap[_index] = _ram.alloc(BLOCK_SIZE); - Rm_connection::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); + Region_map_client::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); } catch (...) { return false; } /* return base + offset in VM area */ @@ -83,7 +85,7 @@ class Bsd::Slab_backend_alloc : public Genode::Allocator, Slab_backend_alloc(Genode::Ram_session &ram) : - Rm_connection(0, VM_SIZE), + Region_map_client(Rm_connection::create(VM_SIZE)), _index(0), _range(Genode::env()->heap()), _ram(ram) { /* reserver attach us, anywere */ diff --git a/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc b/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc index 9e3a9adf74..b577ed269a 100644 --- a/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc +++ b/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -429,7 +430,8 @@ extern "C" void dde_outl(dde_addr_t port, dde_uint32_t data) { **********************/ struct Slab_backend_alloc : public Genode::Allocator, - public Genode::Rm_connection + public Genode::Rm_connection, + public Genode::Region_map_client { enum { VM_SIZE = 1024 * 1024, @@ -454,7 +456,7 @@ struct Slab_backend_alloc : public Genode::Allocator, try { _ds_cap[_index] = _ram.alloc(BLOCK_SIZE); - Rm_connection::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); + Region_map_client::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); } catch (...) { return false; } /* return base + offset in VM area */ @@ -467,7 +469,7 @@ struct Slab_backend_alloc : public Genode::Allocator, Slab_backend_alloc(Genode::Ram_session &ram) : - Rm_connection(0, VM_SIZE), + Region_map_client(Rm_connection::create(VM_SIZE)), _index(0), _range(Genode::env()->heap()), _ram(ram) { /* reserver attach us, anywere */ diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/mapped_io_mem_range.h b/repos/dde_linux/src/include/lx_emul/impl/internal/mapped_io_mem_range.h index ba5d4768c7..0b2dcbd330 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/internal/mapped_io_mem_range.h +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/mapped_io_mem_range.h @@ -17,6 +17,7 @@ /* Genode includes */ #include #include +#include /* Linux emulation environment includes */ #include @@ -42,6 +43,7 @@ class Lx::Mapped_io_mem_range : public Lx::List::Element Genode::size_t const _size; Genode::addr_t const _phys; Genode::Rm_connection _rm; + Genode::Region_map_client _region_map; Genode::Attached_dataspace _ds; Genode::addr_t const _virt; @@ -52,10 +54,10 @@ class Lx::Mapped_io_mem_range : public Lx::List::Element Genode::addr_t offset) : _size(size), _phys(phys), - _rm(0, size), - _ds(_rm.dataspace()), + _region_map(_rm.create(size)), + _ds(_region_map.dataspace()), _virt((Genode::addr_t)_ds.local_addr() | (phys &0xfffUL)) { - _rm.attach_at(ds_cap, 0, size, offset); } + _region_map.attach_at(ds_cap, 0, size, offset); } Genode::addr_t phys() const { return _phys; } Genode::addr_t virt() const { return _virt; } diff --git a/repos/dde_linux/src/include/lx_emul/impl/internal/slab_backend_alloc.h b/repos/dde_linux/src/include/lx_emul/impl/internal/slab_backend_alloc.h index e36ee91ae3..b4a5485788 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/internal/slab_backend_alloc.h +++ b/repos/dde_linux/src/include/lx_emul/impl/internal/slab_backend_alloc.h @@ -21,6 +21,7 @@ #include #include #include +#include #include namespace Lx { @@ -33,7 +34,8 @@ namespace Lx { } class Lx::Slab_backend_alloc : public Genode::Allocator, - public Genode::Rm_connection + public Genode::Rm_connection, + public Genode::Region_map_client { private: @@ -62,7 +64,7 @@ class Lx::Slab_backend_alloc : public Genode::Allocator, try { _ds_cap[_index] = Lx::backend_alloc(BLOCK_SIZE, _cached); /* attach at index * BLOCK_SIZE */ - Rm_connection::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); + Region_map_client::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); /* lookup phys. address */ _ds_phys[_index] = Genode::Dataspace_client(_ds_cap[_index]).phys_addr(); @@ -80,7 +82,7 @@ class Lx::Slab_backend_alloc : public Genode::Allocator, Slab_backend_alloc(Genode::Cache_attribute cached) : - Rm_connection(0, VM_SIZE), + Region_map_client(Rm_connection::create(VM_SIZE)), _cached(cached), _index(0), _range(Genode::env()->heap()) { /* reserver attach us, anywere */ diff --git a/repos/dde_linux/src/lib/lxip/lxcc_emul.cc b/repos/dde_linux/src/lib/lxip/lxcc_emul.cc index 7c0782c3fa..f7257a813e 100644 --- a/repos/dde_linux/src/lib/lxip/lxcc_emul.cc +++ b/repos/dde_linux/src/lib/lxip/lxcc_emul.cc @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -46,7 +47,8 @@ namespace Genode { */ template class Genode::Slab_backend_alloc : public Genode::Allocator, - public Genode::Rm_connection + public Genode::Rm_connection, + public Genode::Region_map_client { private: @@ -72,7 +74,7 @@ class Genode::Slab_backend_alloc : public Genode::Allocator, try { _ds_cap[_index] = Genode::env()->ram_session()->alloc(BLOCK_SIZE, _cached); /* attach at index * BLOCK_SIZE */ - Rm_connection::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); + Region_map_client::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); /* lookup phys. address */ _ds_phys[_index] = Dataspace_client(_ds_cap[_index]).phys_addr(); @@ -89,8 +91,9 @@ class Genode::Slab_backend_alloc : public Genode::Allocator, public: Slab_backend_alloc(Cache_attribute cached) - : Rm_connection(0, VM_SIZE), _cached(cached), _index(0), - _range(env()->heap()) + : + Region_map_client(Rm_connection::create(VM_SIZE)), + _cached(cached), _index(0), _range(env()->heap()) { /* reserver attach us, anywere */ _base = env()->rm_session()->attach(dataspace()); diff --git a/repos/dde_linux/src/lib/usb/lx_emul.cc b/repos/dde_linux/src/lib/usb/lx_emul.cc index 04cf17ebbd..5d5490d7ef 100644 --- a/repos/dde_linux/src/lib/usb/lx_emul.cc +++ b/repos/dde_linux/src/lib/usb/lx_emul.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,8 @@ namespace Genode { * Back-end allocator for Genode's slab allocator */ class Genode::Slab_backend_alloc : public Genode::Allocator, - public Genode::Rm_connection + public Genode::Rm_connection, + public Genode::Region_map_client { private: @@ -66,7 +68,7 @@ class Genode::Slab_backend_alloc : public Genode::Allocator, try { _ds_cap[_index] = Backend_memory::alloc(P_BLOCK_SIZE, _cached); /* attach at index * V_BLOCK_SIZE */ - Rm_connection::attach_at(_ds_cap[_index], _index * V_BLOCK_SIZE, P_BLOCK_SIZE, 0); + Region_map_client::attach_at(_ds_cap[_index], _index * V_BLOCK_SIZE, P_BLOCK_SIZE, 0); /* lookup phys. address */ _ds_phys[_index] = Dataspace_client(_ds_cap[_index]).phys_addr(); @@ -84,8 +86,9 @@ class Genode::Slab_backend_alloc : public Genode::Allocator, public: Slab_backend_alloc(Genode::Cache_attribute cached) - : Rm_connection(0, VM_SIZE), _cached(cached), _index(0), - _range(env()->heap()) + : + Region_map_client(Rm_connection::create(VM_SIZE)), + _cached(cached), _index(0), _range(env()->heap()) { /* reserver attach us, anywere */ _base = env()->rm_session()->attach(dataspace()); diff --git a/repos/dde_linux/src/lib/wifi/lxcc_emul.cc b/repos/dde_linux/src/lib/wifi/lxcc_emul.cc index 79f46c75df..2b5506bd33 100644 --- a/repos/dde_linux/src/lib/wifi/lxcc_emul.cc +++ b/repos/dde_linux/src/lib/wifi/lxcc_emul.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -48,7 +49,8 @@ namespace Lx { * Back-end allocator for Genode's slab allocator */ class Lx::Slab_backend_alloc : public Genode::Allocator, - public Genode::Rm_connection + public Genode::Rm_connection, + public Genode::Region_map_client { private: @@ -75,7 +77,7 @@ class Lx::Slab_backend_alloc : public Genode::Allocator, try { _ds_cap[_index] = Lx::backend_alloc(BLOCK_SIZE, _cached); /* attach at index * BLOCK_SIZE */ - Rm_connection::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); + Region_map_client::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); /* lookup phys. address */ _ds_phys[_index] = Genode::Dataspace_client(_ds_cap[_index]).phys_addr(); @@ -93,7 +95,7 @@ class Lx::Slab_backend_alloc : public Genode::Allocator, Slab_backend_alloc(Genode::Cache_attribute cached) : - Rm_connection(0, VM_SIZE), + Region_map_client(Rm_connection::create(VM_SIZE)), _cached(cached), _index(0), _range(Genode::env()->heap()) { /* reserver attach us, anywere */ diff --git a/repos/dde_rump/include/util/allocator_fap.h b/repos/dde_rump/include/util/allocator_fap.h index 8f6578e29d..9ad7a10a96 100644 --- a/repos/dde_rump/include/util/allocator_fap.h +++ b/repos/dde_rump/include/util/allocator_fap.h @@ -17,6 +17,7 @@ #include #include #include +#include namespace Allocator { @@ -48,7 +49,8 @@ namespace Allocator { */ template class Backend_alloc : public Genode::Allocator, - public Genode::Rm_connection + public Genode::Rm_connection, + public Genode::Region_map_client { private: @@ -84,14 +86,14 @@ namespace Allocator { try { _ds_cap[_index] = Genode::env()->ram_session()->alloc(BLOCK_SIZE, _cached); /* attach at index * BLOCK_SIZE */ - Rm_connection::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); + Region_map_client::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); /* lookup phys. address */ _ds_phys[_index] = Genode::Dataspace_client(_ds_cap[_index]).phys_addr(); } catch (Genode::Ram_session::Quota_exceeded) { PWRN("Backend allocator exhausted"); _quota_exceeded = true; return false; - } catch (Genode::Rm_session::Attach_failed) { + } catch (Genode::Region_map::Attach_failed) { PWRN("Backend VM region exhausted"); _quota_exceeded = true; return false; @@ -108,8 +110,10 @@ namespace Allocator { public: Backend_alloc(Cache_attribute cached) - : Rm_connection(0, VM_SIZE), _cached(cached), - _range(Genode::env()->heap()) + : + Region_map_client(Rm_connection::create(VM_SIZE)), + _cached(cached), + _range(Genode::env()->heap()) { /* reserver attach us, anywere */ _base = Genode::env()->rm_session()->attach(dataspace()); diff --git a/repos/demo/include/launchpad/launchpad.h b/repos/demo/include/launchpad/launchpad.h index 9aa0ed579e..06b1ce9485 100644 --- a/repos/demo/include/launchpad/launchpad.h +++ b/repos/demo/include/launchpad/launchpad.h @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -156,7 +157,6 @@ class Launchpad_child : public Genode::List::Element Genode::Rom_session_capability _rom; Genode::Ram_session_capability _ram; Genode::Cpu_session_capability _cpu; - Genode::Rm_session_capability _rm; Genode::Server _server; /* @@ -177,7 +177,6 @@ class Launchpad_child : public Genode::List::Element Genode::Pd_session_capability pd, Genode::Ram_session_capability ram, Genode::Cpu_session_capability cpu, - Genode::Rm_session_capability rm, Genode::Rom_session_capability rom, Genode::Cap_session *cap_session, Genode::Service_registry *parent_services, @@ -186,17 +185,16 @@ class Launchpad_child : public Genode::List::Element Launchpad *launchpad) : _launchpad(launchpad), - _rom(rom), _ram(ram), _cpu(cpu), _rm(rm), _server(_ram), + _rom(rom), _ram(ram), _cpu(cpu), _server(_ram), _entrypoint(cap_session, ENTRYPOINT_STACK_SIZE, name, false), _policy(name, &_server, parent_services, child_services, config_ds, elf_ds, &_entrypoint), - _child(elf_ds, pd, ram, cpu, rm, &_entrypoint, &_policy) { + _child(elf_ds, pd, ram, cpu, &_entrypoint, &_policy) { _entrypoint.activate(); } Genode::Rom_session_capability rom_session_cap() { return _rom; } Genode::Ram_session_capability ram_session_cap() { return _ram; } Genode::Cpu_session_capability cpu_session_cap() { return _cpu; } - Genode::Rm_session_capability rm_session_cap() { return _rm; } const char *name() const { return _policy.name(); } diff --git a/repos/demo/src/lib/launchpad/launchpad.cc b/repos/demo/src/lib/launchpad/launchpad.cc index d60ad5162a..4fc403511c 100644 --- a/repos/demo/src/lib/launchpad/launchpad.cc +++ b/repos/demo/src/lib/launchpad/launchpad.cc @@ -251,16 +251,6 @@ Launchpad_child *Launchpad::start_child(const char *filename, return 0; } - Rm_connection rm; - rm.on_destruction(Rm_connection::KEEP_OPEN); - if (!rm.cap().valid()) { - PWRN("Failed to create RM session"); - env()->parent()->close(ram.cap()); - env()->parent()->close(cpu.cap()); - env()->parent()->close(rom_cap); - return 0; - } - Pd_connection pd; pd.on_destruction(Pd_connection::KEEP_OPEN); if (!pd.cap().valid()) { @@ -268,14 +258,13 @@ Launchpad_child *Launchpad::start_child(const char *filename, env()->parent()->close(ram.cap()); env()->parent()->close(cpu.cap()); env()->parent()->close(rom_cap); - env()->parent()->close(rm.cap()); return 0; } try { Launchpad_child *c = new (&_sliced_heap) Launchpad_child(unique_name, file_cap, pd.cap(), ram.cap(), - cpu.cap(), rm.cap(), rom_cap, + cpu.cap(), rom_cap, &_cap_session, &_parent_services, &_child_services, config_ds, this); @@ -291,7 +280,6 @@ Launchpad_child *Launchpad::start_child(const char *filename, PWRN("Failed to create child - unknown reason"); } - env()->parent()->close(rm.cap()); env()->parent()->close(ram.cap()); env()->parent()->close(cpu.cap()); env()->parent()->close(rom_cap); @@ -453,7 +441,6 @@ void Launchpad::exit_child(Launchpad_child *child, Lock::Guard lock_guard(_children_lock); _children.remove(child); - Rm_session_capability rm_session_cap = child->rm_session_cap(); Ram_session_capability ram_session_cap = child->ram_session_cap(); Cpu_session_capability cpu_session_cap = child->cpu_session_cap(); Rom_session_capability rom_session_cap = child->rom_session_cap(); @@ -461,7 +448,6 @@ void Launchpad::exit_child(Launchpad_child *child, const Genode::Server *server = child->server(); destruct_child(&_sliced_heap, child, timer, session_close_timeout_ms); - env()->parent()->close(rm_session_cap); env()->parent()->close(cpu_session_cap); env()->parent()->close(rom_session_cap); env()->parent()->close(ram_session_cap); diff --git a/repos/libports/ports/qt5.hash b/repos/libports/ports/qt5.hash index 26e70c0d80..228779fba5 100644 --- a/repos/libports/ports/qt5.hash +++ b/repos/libports/ports/qt5.hash @@ -1 +1 @@ -4d7c2192509a580b54ac069e68f1e9ac4d9159bd +572aad892107d4e90dd4659c09cb075a25b0d613 diff --git a/repos/libports/run/ldso.run b/repos/libports/run/ldso.run index fc48912e61..fe9154816f 100644 --- a/repos/libports/run/ldso.run +++ b/repos/libports/run/ldso.run @@ -39,6 +39,8 @@ run_genode_until {child ".*" exited with exit value 123.*\n} 10 # pay only attention to the output of init and its children grep_output {^\[init } +unify_output {\[init \-\> test\-ldso\] upgrading quota donation for .* \([0-9]+ bytes\)} "" +trim_lines compare_output_to { [init -> test-ldso] Lib_2_global 11223343 diff --git a/repos/libports/src/lib/libc/libc_mem_alloc.cc b/repos/libports/src/lib/libc/libc_mem_alloc.cc index b211df91d4..6dd0b7d901 100644 --- a/repos/libports/src/lib/libc/libc_mem_alloc.cc +++ b/repos/libports/src/lib/libc/libc_mem_alloc.cc @@ -39,7 +39,7 @@ Libc::Mem_alloc_impl::Dataspace_pool::~Dataspace_pool() remove(ds); delete ds; - _rm_session->detach(ds->local_addr); + _region_map->detach(ds->local_addr); _ram_session->free(ds_cap); } } @@ -53,10 +53,10 @@ int Libc::Mem_alloc_impl::Dataspace_pool::expand(size_t size, Range_allocator *a /* make new ram dataspace available at our local address space */ try { new_ds_cap = _ram_session->alloc(size); - local_addr = _rm_session->attach(new_ds_cap); + local_addr = _region_map->attach(new_ds_cap); } catch (Ram_session::Alloc_failed) { return -2; - } catch (Rm_session::Attach_failed) { + } catch (Region_map::Attach_failed) { _ram_session->free(new_ds_cap); return -3; } diff --git a/repos/libports/src/lib/libc/libc_mem_alloc.h b/repos/libports/src/lib/libc/libc_mem_alloc.h index 5e9ad5480c..4f9e3122a5 100644 --- a/repos/libports/src/lib/libc/libc_mem_alloc.h +++ b/repos/libports/src/lib/libc/libc_mem_alloc.h @@ -59,15 +59,15 @@ namespace Libc { private: Genode::Ram_session *_ram_session; /* ram session for backing store */ - Genode::Rm_session *_rm_session; /* region manager */ + Genode::Region_map *_region_map; /* region map of address space */ public: /** * Constructor */ - Dataspace_pool(Genode::Ram_session *ram_session, Genode::Rm_session *rm_session): - _ram_session(ram_session), _rm_session(rm_session) { } + Dataspace_pool(Genode::Ram_session *ram, Genode::Region_map *rm): + _ram_session(ram), _region_map(rm) { } /** * Destructor @@ -81,18 +81,18 @@ namespace Libc { * \param md_alloc allocator to expand. This allocator is also * used for meta data allocation (only after * being successfully expanded). - * \throw Rm_session::Invalid_dataspace, - * Rm_session::Region_conflict + * \throw Region_map::Invalid_dataspace, + * Region_map::Region_conflict * \return 0 on success or negative error code */ int expand(Genode::size_t size, Genode::Range_allocator *alloc); - void reassign_resources(Genode::Ram_session *ram, Genode::Rm_session *rm) { - _ram_session = ram, _rm_session = rm; } + void reassign_resources(Genode::Ram_session *ram, Genode::Region_map *rm) { + _ram_session = ram, _region_map = rm; } }; Genode::Lock mutable _lock; - Dataspace_pool _ds_pool; /* list of dataspaces */ + Dataspace_pool _ds_pool; /* list of dataspaces */ Genode::Allocator_avl _alloc; /* local allocator */ Genode::size_t _chunk_size; @@ -108,7 +108,7 @@ namespace Libc { public: - Mem_alloc_impl(Genode::Rm_session * rm = Genode::env()->rm_session(), + Mem_alloc_impl(Genode::Region_map * rm = Genode::env()->rm_session(), Genode::Ram_session * ram = Genode::env()->ram_session()) : _ds_pool(ram, rm), @@ -122,6 +122,4 @@ namespace Libc { }; } - - #endif /* _LIBC_MEM_ALLOC_H_ */ diff --git a/repos/libports/src/lib/qt5/patches/qt5_qml.patch b/repos/libports/src/lib/qt5/patches/qt5_qml.patch index 9e02f63ac8..06cd7038d7 100644 --- a/repos/libports/src/lib/qt5/patches/qt5_qml.patch +++ b/repos/libports/src/lib/qt5/patches/qt5_qml.patch @@ -8,9 +8,9 @@ From: Christian Prochaska qtdeclarative/src/qml/qml/qqmlimport.cpp | 9 qtdeclarative/src/qml/qml/v8/qv8qobjectwrapper.cpp | 4 qtdeclarative/src/qml/types/qqmldelegatemodel_p.h | 2 - qtjsbackend/src/3rdparty/v8/src/platform-genode.cc | 701 ++++++++++++++++++++ + qtjsbackend/src/3rdparty/v8/src/platform-genode.cc | 706 ++++++++++++++++++++ qtjsbackend/src/v8/v8.pri | 2 - 6 files changed, 717 insertions(+), 3 deletions(-) + 6 files changed, 722 insertions(+), 3 deletions(-) create mode 100644 qtjsbackend/src/3rdparty/v8/src/platform-genode.cc diff --git a/qtdeclarative/src/qml/qml/qqmlaccessors_p.h b/qtdeclarative/src/qml/qml/qqmlaccessors_p.h @@ -90,10 +90,10 @@ index 5702c59..3d616b5 100644 QT_BEGIN_NAMESPACE diff --git a/qtjsbackend/src/3rdparty/v8/src/platform-genode.cc b/qtjsbackend/src/3rdparty/v8/src/platform-genode.cc new file mode 100644 -index 0000000..a2e5634 +index 0000000..de6f632 --- /dev/null +++ b/qtjsbackend/src/3rdparty/v8/src/platform-genode.cc -@@ -0,0 +1,701 @@ +@@ -0,0 +1,706 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are @@ -127,6 +127,7 @@ index 0000000..a2e5634 +// messages. + +#include ++#include +#include +#include + @@ -318,8 +319,10 @@ index 0000000..a2e5634 + +/* --- */ + -+class Attached_rm_connection : public Genode::Rm_connection, -+ public Genode::Avl_node ++class Attached_region_map : private Genode::Rm_connection, ++ public Genode::Region_map_client, ++ public Genode::Avl_node ++ +{ + + private: @@ -331,8 +334,10 @@ index 0000000..a2e5634 + + public: + -+ Attached_rm_connection(size_t size, size_t alignment = 0) -+ : Genode::Rm_connection(0, size), ++ typedef Region_map_client::Region_conflict Region_conflict; ++ ++ Attached_region_map(size_t size, size_t alignment = 0) ++ : Genode::Region_map_client(Rm_connection::create(size)), + _ds_cap(dataspace()), + _size(size) + { @@ -345,16 +350,16 @@ index 0000000..a2e5634 + try { + Genode::env()->rm_session()->attach_at(_ds_cap, _base_addr); + return; -+ } catch (Genode::Rm_connection::Region_conflict) { ++ } catch (Genode::Region_map::Region_conflict) { + if (verbose) + PDBG("could not attach at address 0x%lx", _base_addr); + } + } -+ throw Rm_connection::Region_conflict(); ++ throw Region_map::Region_conflict(); + } + } + -+ ~Attached_rm_connection() ++ ~Attached_region_map() + { + Genode::env()->rm_session()->detach(_base_addr); + } @@ -366,12 +371,12 @@ index 0000000..a2e5634 + void attach(Genode::Dataspace_capability ds_cap, Genode::addr_t addr, + bool executable) + { -+ Genode::Rm_connection::attach(ds_cap, 0, 0, true, ++ Genode::Region_map_client::attach(ds_cap, 0, 0, true, + (void*)(addr - _base_addr), + executable); + } + -+ Attached_rm_connection *find_by_addr(Genode::addr_t addr) ++ Attached_region_map *find_by_addr(Genode::addr_t addr) + { + if (verbose) + PDBG("addr = 0x%lx, _base_addr = 0x%lx, _end_addr = 0x%lx", @@ -379,33 +384,33 @@ index 0000000..a2e5634 + if ((addr >= _base_addr) && (addr < _base_addr + _size)) + return this; + -+ Attached_rm_connection *next = child(addr > _base_addr); ++ Attached_region_map *next = child(addr > _base_addr); + return next ? next->find_by_addr(addr) : 0; + } + + /** + * Avl_node interface + */ -+ bool higher(Attached_rm_connection *other) ++ bool higher(Attached_region_map *other) + { + return ((Genode::addr_t)other->base_addr() > _base_addr); + } +}; + + -+static Genode::Avl_tree &vm_registry() ++static Genode::Avl_tree &vm_registry() +{ -+ static Genode::Avl_tree _vm_registry; ++ static Genode::Avl_tree _vm_registry; + return _vm_registry; +} + + +static void *reserve_region(size_t size, size_t alignment = 0) +{ -+ Attached_rm_connection *rm; ++ Attached_region_map *rm; + try { -+ rm = new Attached_rm_connection(size, alignment); -+ } catch (Attached_rm_connection::Region_conflict) { ++ rm = new Attached_region_map(size, alignment); ++ } catch (Attached_region_map::Region_conflict) { + PDBG("could not reserve region"); + return 0; + } @@ -481,7 +486,7 @@ index 0000000..a2e5634 +bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { + if (verbose) + PDBG("base = 0x%p, size = 0x%zx", base, size); -+ Attached_rm_connection *rm = vm_registry().first(); ++ Attached_region_map *rm = vm_registry().first(); + rm = rm->find_by_addr((Genode::addr_t)base); + if (!rm) { + if (verbose) diff --git a/repos/libports/src/test/ldso/lib_1.cc b/repos/libports/src/test/ldso/lib_1.cc index 3ffd76ea8a..3846d6d1b4 100644 --- a/repos/libports/src/test/ldso/lib_1.cc +++ b/repos/libports/src/test/ldso/lib_1.cc @@ -115,7 +115,7 @@ static void lib_1_attr_destructor_2() { printf("%s %x\n", __func__, --lib_1_pod static void exception() { throw 666; } -void lib_1_exception() { throw Genode::Rm_session::Region_conflict(); } +void lib_1_exception() { throw Genode::Region_map::Region_conflict(); } void lib_1_good() { } diff --git a/repos/libports/src/test/ldso/main.cc b/repos/libports/src/test/ldso/main.cc index 1cf6e4a7fc..5ce4baa544 100644 --- a/repos/libports/src/test/ldso/main.cc +++ b/repos/libports/src/test/ldso/main.cc @@ -226,7 +226,7 @@ int main(int argc, char **argv) printf("exception in shared lib: "); try { lib_1_exception(); } - catch (Rm_session::Region_conflict) { printf("caught\n"); } + catch (Region_map::Region_conflict) { printf("caught\n"); } printf("exception in dynamic linker: "); try { __ldso_raise_exception(); } diff --git a/repos/os/include/cli_monitor/child.h b/repos/os/include/cli_monitor/child.h index bd9bec5414..e1afd24c9f 100644 --- a/repos/os/include/cli_monitor/child.h +++ b/repos/os/include/cli_monitor/child.h @@ -20,7 +20,6 @@ #include #include #include -#include #include /* CLI-monitor includes */ @@ -54,7 +53,6 @@ class Child_base : public Genode::Child_policy Genode::Pd_connection pd; Genode::Ram_connection ram; Genode::Cpu_connection cpu; - Genode::Rm_connection rm; Resources(const char *label, Genode::size_t ram_quota) : pd(label), ram(label), cpu(label) @@ -123,7 +121,7 @@ class Child_base : public Genode::Child_policy _config_policy("config", _entrypoint, &_resources.ram), _child(_binary_rom.dataspace(), _resources.pd.cap(), _resources.ram.cap(), _resources.cpu.cap(), - _resources.rm.cap(), &_entrypoint, this), + &_entrypoint, this), _yield_response_sigh_cap(yield_response_sig_cap), _exit_sig_cap(exit_sig_cap) { } diff --git a/repos/os/include/init/child.h b/repos/os/include/init/child.h index a02e12d958..2087d1fe9e 100644 --- a/repos/os/include/init/child.h +++ b/repos/os/include/init/child.h @@ -17,7 +17,6 @@ /* Genode includes */ #include #include -#include #include #include #include @@ -468,7 +467,6 @@ class Init::Child : Genode::Child_policy Genode::Pd_connection pd; Genode::Ram_connection ram; Genode::Cpu_connection cpu; - Genode::Rm_connection rm; inline void transfer_cpu_quota(); @@ -489,7 +487,6 @@ class Init::Child : Genode::Child_policy { /* deduce session costs from usable ram quota */ Genode::size_t session_donations = Genode::Pd_connection::RAM_QUOTA + - Genode::Rm_connection::RAM_QUOTA + Genode::Cpu_connection::RAM_QUOTA + Genode::Ram_connection::RAM_QUOTA; @@ -566,7 +563,7 @@ class Init::Child : Genode::Child_policy _config(_resources.ram.cap(), start_node), _server(_resources.ram.cap()), _child(_binary_rom_ds, _resources.pd.cap(), _resources.ram.cap(), - _resources.cpu.cap(), _resources.rm.cap(), &_entrypoint, this), + _resources.cpu.cap(), &_entrypoint, this), _parent_services(parent_services), _child_services(child_services), _labeling_policy(_name.unique), diff --git a/repos/os/include/init/child_config.h b/repos/os/include/init/child_config.h index 4ebf759e2e..76f8a345bb 100644 --- a/repos/os/include/init/child_config.h +++ b/repos/os/include/init/child_config.h @@ -93,7 +93,7 @@ class Init::Child_config static_cast(addr)[config_size] = 0; env()->rm_session()->detach(addr); - } catch (Rm_session::Attach_failed) { + } catch (Region_map::Attach_failed) { rsc.free(_config_ram_ds); return; } catch (Ram_session::Alloc_failed) { diff --git a/repos/os/include/os/slave.h b/repos/os/include/os/slave.h index bdf9a63266..edd2b27645 100644 --- a/repos/os/include/os/slave.h +++ b/repos/os/include/os/slave.h @@ -163,7 +163,6 @@ class Genode::Slave Genode::Pd_connection pd; Genode::Ram_connection ram; Genode::Cpu_connection cpu; - Genode::Rm_connection rm; class Quota_exceeded : public Genode::Exception { }; @@ -192,7 +191,7 @@ class Genode::Slave _resources(slave_policy.name(), ram_quota, ram_ref_cap), _child(slave_policy.binary(), _resources.pd.cap(), _resources.ram.cap(), _resources.cpu.cap(), - _resources.rm.cap(), &entrypoint, &slave_policy) + &entrypoint, &slave_policy) { } Genode::Ram_connection &ram() { return _resources.ram; } diff --git a/repos/os/run/report_rom.run b/repos/os/run/report_rom.run index 332b975581..aa3dab01f1 100644 --- a/repos/os/run/report_rom.run +++ b/repos/os/run/report_rom.run @@ -52,6 +52,8 @@ append qemu_args "-nographic -m 128" run_genode_until {child "test-report_rom" exited with exit value 0.*\n} 30 grep_output {^\[init -> test-report_rom} +unify_output {\[init \-\> test\-report_rom\] upgrading quota donation for .* \([0-9]+ bytes\)} "" +trim_lines compare_output_to { [init -> test-report_rom] --- test-report_rom started --- diff --git a/repos/os/run/rom_filter.run b/repos/os/run/rom_filter.run index 035cb74861..1c4ddb2595 100644 --- a/repos/os/run/rom_filter.run +++ b/repos/os/run/rom_filter.run @@ -123,6 +123,8 @@ run_genode_until {.*finished.*\n} 20 # pay only attention to the output of the rom_logger grep_output {^\[init -> rom_logger} +unify_output {\[init \-\> rom_logger\] upgrading quota donation for .* \([0-9]+ bytes\)} "" +trim_lines compare_output_to { [init -> rom_logger] ROM 'generated': diff --git a/repos/os/src/drivers/acpi/memory.h b/repos/os/src/drivers/acpi/memory.h index 3503b9bc61..a373817fe4 100644 --- a/repos/os/src/drivers/acpi/memory.h +++ b/repos/os/src/drivers/acpi/memory.h @@ -16,6 +16,7 @@ #include #include +#include namespace Acpi { class Memory; } @@ -37,11 +38,12 @@ class Acpi::Memory } }; - Genode::addr_t const ACPI_REGION_SIZE_LOG2; - Genode::Rm_connection _rm_acpi; - Genode::addr_t const _acpi_base; - Genode::Allocator_avl _range; - Genode::List _io_mem_list; + Genode::addr_t const ACPI_REGION_SIZE_LOG2; + Genode::Rm_connection _rm; + Genode::Region_map_client _rm_acpi; + Genode::addr_t const _acpi_base; + Genode::Allocator_avl _range; + Genode::List _io_mem_list; public: @@ -49,7 +51,7 @@ class Acpi::Memory : /* 1 GB range */ ACPI_REGION_SIZE_LOG2(30), - _rm_acpi(~0UL, 1UL << ACPI_REGION_SIZE_LOG2), + _rm_acpi(_rm.create(1UL << ACPI_REGION_SIZE_LOG2)), _acpi_base(Genode::env()->rm_session()->attach(_rm_acpi.dataspace())), _range(Genode::env()->heap()) { diff --git a/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc b/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc index 712003ad48..bb28967696 100644 --- a/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc +++ b/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include @@ -29,15 +29,11 @@ #include "../pci_device_pd_ipc.h" -/** - * - */ -struct Expanding_rm_session_client : Genode::Rm_session_client -{ - Genode::Rm_session_capability _cap; - Expanding_rm_session_client(Genode::Rm_session_capability cap) - : Rm_session_client(cap), _cap(cap) { } +struct Expanding_region_map_client : Genode::Region_map_client +{ + Expanding_region_map_client(Genode::Capability cap) + : Region_map_client(cap) { } Local_addr attach(Genode::Dataspace_capability ds, Genode::size_t size, Genode::off_t offset, @@ -45,9 +41,9 @@ struct Expanding_rm_session_client : Genode::Rm_session_client Local_addr local_addr, bool executable) override { - return Genode::retry( + return Genode::retry( [&] () { - return Rm_session_client::attach(ds, size, offset, + return Region_map_client::attach(ds, size, offset, use_local_addr, local_addr, executable); }, @@ -61,15 +57,16 @@ struct Expanding_rm_session_client : Genode::Rm_session_client Genode::snprintf(buf, sizeof(buf), "ram_quota=%u", UPGRADE_QUOTA); - Genode::env()->parent()->upgrade(_cap, buf); + Genode::env()->parent()->upgrade(Genode::env()->pd_session_cap(), buf); }); } }; -static Genode::Rm_session *rm_session() { + +static Genode::Region_map &address_space() { using namespace Genode; - static Expanding_rm_session_client rm (static_cap_cast(env()->parent()->session("Env::rm_session", ""))); - return &rm; + static Expanding_region_map_client rm(Genode::env()->pd_session()->address_space()); + return rm; } @@ -94,6 +91,7 @@ static bool map_eager(Genode::addr_t const page, unsigned log2_order) return res == Nova::NOVA_OK; } + void Platform::Device_pd_component::attach_dma_mem(Genode::Dataspace_capability ds_cap) { using namespace Genode; @@ -106,7 +104,7 @@ void Platform::Device_pd_component::attach_dma_mem(Genode::Dataspace_capability addr_t page = ~0UL; try { - page = rm_session()->attach_at(ds_cap, phys); + page = address_space().attach_at(ds_cap, phys); } catch (Rm_session::Out_of_metadata) { throw; } catch (Rm_session::Region_conflict) { @@ -117,7 +115,7 @@ void Platform::Device_pd_component::attach_dma_mem(Genode::Dataspace_capability /* sanity check */ if ((page == ~0UL) || (page != phys)) { if (page != ~0UL) - rm_session()->detach(page); + address_space().detach(page); PERR("attachment of DMA memory @ %lx+%zx failed", phys, size); return; @@ -140,7 +138,7 @@ void Platform::Device_pd_component::assign_pci(Genode::Io_mem_dataspace_capabili Dataspace_client ds_client(io_mem_cap); - addr_t page = rm_session()->attach(io_mem_cap); + addr_t page = address_space().attach(io_mem_cap); /* sanity check */ if (!page) throw Rm_session::Region_conflict(); @@ -159,11 +157,13 @@ void Platform::Device_pd_component::assign_pci(Genode::Io_mem_dataspace_capabili rid >> 8, (rid >> 3) & 0x1f, rid & 0x7); /* we don't need the mapping anymore */ - rm_session()->detach(page); + address_space().detach(page); } + using namespace Genode; + struct Main { Server::Entrypoint &ep; @@ -178,6 +178,7 @@ struct Main } }; + /************ ** Server ** ************/ diff --git a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h index b5beed2efe..eb134f5c76 100644 --- a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h +++ b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h @@ -131,6 +131,13 @@ namespace Platform { { /* associate _ram session with platform_drv _ram session */ _ram.ref_account(Genode::env()->ram_session_cap()); + + /* + * Equip RAM session with initial quota to account for + * core-internal allocation meta-data overhead. + */ + enum { OVERHEAD = 4096 }; + Genode::env()->ram_session()->transfer_quota(_ram, OVERHEAD); } Genode::Ram_connection &ram() { return _ram; } @@ -794,7 +801,7 @@ namespace Platform { [&] () { return _resources.ram().alloc(size, Genode::UNCACHED); }, [&] () { if (!_md_alloc.withdraw(UPGRADE_QUOTA)) { - /* role-back */ + /* roll-back */ if (_resources.ram().transfer_quota(Genode::env()->ram_session_cap(), size)) throw Fatal(); _md_alloc.upgrade(size); diff --git a/repos/os/src/drivers/timer/main.cc b/repos/os/src/drivers/timer/main.cc index 87c46e67bf..a66fa17106 100644 --- a/repos/os/src/drivers/timer/main.cc +++ b/repos/os/src/drivers/timer/main.cc @@ -51,6 +51,6 @@ struct Main namespace Server { char const *name() { return "timer_drv_ep"; } - size_t stack_size() { return 1024*sizeof(long); } + size_t stack_size() { return 2048*sizeof(long); } void construct(Entrypoint &ep) { static Main server(ep); } } diff --git a/repos/os/src/server/iso9660/main.cc b/repos/os/src/server/iso9660/main.cc index 5f1b04e9d5..39611e1b90 100644 --- a/repos/os/src/server/iso9660/main.cc +++ b/repos/os/src/server/iso9660/main.cc @@ -131,7 +131,7 @@ namespace Iso { { size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - size_t session_size = sizeof(Rom_component) + sizeof(File_info) + sizeof(Rm_connection); + size_t session_size = sizeof(Rom_component) + sizeof(File_info); if (ram_quota < session_size) throw Root::Quota_exceeded(); diff --git a/repos/os/src/server/loader/child.h b/repos/os/src/server/loader/child.h index d92d366b1e..41bb3a06d9 100644 --- a/repos/os/src/server/loader/child.h +++ b/repos/os/src/server/loader/child.h @@ -20,9 +20,9 @@ #include #include #include -#include #include #include +#include namespace Loader { @@ -45,7 +45,6 @@ namespace Loader { Pd_connection pd; Ram_connection ram; Cpu_connection cpu; - Rm_connection rm; Resources(char const *label, Ram_session_client &ram_session_client, @@ -54,8 +53,7 @@ namespace Loader { : pd(label), ram(label), cpu(label) { /* deduce session costs from usable ram quota */ - size_t session_donations = Rm_connection::RAM_QUOTA + - Cpu_connection::RAM_QUOTA + + size_t session_donations = Cpu_connection::RAM_QUOTA + Ram_connection::RAM_QUOTA; if (ram_quota > session_donations) @@ -70,7 +68,8 @@ namespace Loader { * the loader client via 'Loader_session::fault_handler'. */ cpu.exception_handler(Thread_capability(), fault_sigh); - rm.fault_handler(fault_sigh); + Region_map_client address_space(pd.address_space()); + address_space.fault_handler(fault_sigh); } } _resources; @@ -79,7 +78,7 @@ namespace Loader { Service &_local_nitpicker_service; Service &_local_rom_service; Service &_local_cpu_service; - Service &_local_rm_service; + Service &_local_pd_service; Rom_session_client _binary_rom_session; @@ -110,7 +109,7 @@ namespace Loader { Service_registry &parent_services, Service &local_rom_service, Service &local_cpu_service, - Service &local_rm_service, + Service &local_pd_service, Service &local_nitpicker_service, Signal_context_capability fault_sigh) : @@ -121,13 +120,12 @@ namespace Loader { _local_nitpicker_service(local_nitpicker_service), _local_rom_service(local_rom_service), _local_cpu_service(local_cpu_service), - _local_rm_service(local_rm_service), + _local_pd_service(local_pd_service), _binary_rom_session(_rom_session(binary_name)), _binary_policy("binary", _binary_rom_session.dataspace(), &_ep), _labeling_policy(_label.string), _child(_binary_rom_session.dataspace(), _resources.pd.cap(), - _resources.ram.cap(), _resources.cpu.cap(), - _resources.rm.cap(), &_ep, this) + _resources.ram.cap(), _resources.cpu.cap(), &_ep, this) { } ~Child() @@ -158,7 +156,7 @@ namespace Loader { if (!strcmp(name, "Nitpicker")) return &_local_nitpicker_service; if (!strcmp(name, "ROM")) return &_local_rom_service; if (!strcmp(name, "CPU")) return &_local_cpu_service; - if (!strcmp(name, "RM")) return &_local_rm_service; + if (!strcmp(name, "PD")) return &_local_pd_service; /* populate session-local parent service registry on demand */ service = _parent_services.find(name); diff --git a/repos/os/src/server/loader/main.cc b/repos/os/src/server/loader/main.cc index d8fee94809..172d4b35e0 100644 --- a/repos/os/src/server/loader/main.cc +++ b/repos/os/src/server/loader/main.cc @@ -128,7 +128,7 @@ class Loader::Session_component : public Rpc_object }; /** - * Common base class of 'Local_cpu_service' and 'Local_rm_service' + * Common base class of 'Local_cpu_service' and 'Local_pd_service' */ struct Intercepted_parent_service : Service { @@ -168,18 +168,22 @@ class Loader::Session_component : public Rpc_object }; /** - * Intercept RM session requests to install default fault handler + * Intercept PD session requests to install default fault handler */ - struct Local_rm_service : Intercepted_parent_service + struct Local_pd_service : Intercepted_parent_service { - Local_rm_service() : Intercepted_parent_service("RM") { } + Local_pd_service() : Intercepted_parent_service("PD") { } Genode::Session_capability session(char const *args, Affinity const &affinity) { - Capability cap = env()->parent()->session(args, affinity); - Rm_session_client(cap).fault_handler(fault_sigh); - return cap; + Pd_session_client pd(env()->parent()->session(args, affinity)); + + Region_map_client(pd.address_space()).fault_handler(fault_sigh); + Region_map_client(pd.stack_area()) .fault_handler(fault_sigh); + Region_map_client(pd.linker_area()) .fault_handler(fault_sigh); + + return pd; } }; @@ -256,7 +260,7 @@ class Loader::Session_component : public Rpc_object Rom_module_registry _rom_modules; Local_rom_service _rom_service; Local_cpu_service _cpu_service; - Local_rm_service _rm_service; + Local_pd_service _pd_service; Local_nitpicker_service _nitpicker_service; Signal_context_capability _fault_sigh; Child *_child; @@ -352,10 +356,10 @@ class Loader::Session_component : public Rpc_object _cpu_service.fault_sigh = sigh; /* - * RM fault handler for RM sessions originating from the + * Region-map fault handler for PD sessions originating from the * subsystem. */ - _rm_service.fault_sigh = sigh; + _pd_service.fault_sigh = sigh; /* * CPU exception and RM fault handler for the immediate child. @@ -379,7 +383,7 @@ class Loader::Session_component : public Rpc_object Child(binary_name.string(), label.string(), _ep, _ram_session_client, ram_quota, _parent_services, _rom_service, - _cpu_service, _rm_service, _nitpicker_service, + _cpu_service, _pd_service, _nitpicker_service, _fault_sigh); } catch (Genode::Parent::Service_denied) { diff --git a/repos/os/src/test/bomb/main.cc b/repos/os/src/test/bomb/main.cc index ea9ab5fb20..1d6b5e78c3 100644 --- a/repos/os/src/test/bomb/main.cc +++ b/repos/os/src/test/bomb/main.cc @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -43,7 +42,6 @@ class Bomb_child_resources Genode::Rom_connection _rom; Genode::Ram_connection _ram; Genode::Cpu_connection _cpu; - Genode::Rm_connection _rm; char _name[32]; Bomb_child_resources(const char *file_name, const char *name, @@ -93,7 +91,7 @@ class Bomb_child : private Bomb_child_resources, Init::Child_policy_enforce_labeling(Bomb_child_resources::_name), _entrypoint(cap_session, STACK_SIZE, "bomb_ep_child", false), _child(_rom.dataspace(), _pd.cap(), _ram.cap(), _cpu.cap(), - _rm.cap(), &_entrypoint, this), + &_entrypoint, this), _parent_services(parent_services), _config_policy("config", _entrypoint, &_ram) { diff --git a/repos/os/src/test/fault_detection/main.cc b/repos/os/src/test/fault_detection/main.cc index af6559326e..c77f07d4c5 100644 --- a/repos/os/src/test/fault_detection/main.cc +++ b/repos/os/src/test/fault_detection/main.cc @@ -16,12 +16,12 @@ #include #include #include -#include #include #include #include #include #include +#include /*************** @@ -56,7 +56,6 @@ class Test_child : public Genode::Child_policy Genode::Pd_connection pd; Genode::Ram_connection ram; Genode::Cpu_connection cpu; - Genode::Rm_connection rm; Resources(Genode::Signal_context_capability sigh, char const *label) : pd(label) @@ -72,7 +71,8 @@ class Test_child : public Genode::Child_policy cpu.exception_handler(Thread_capability(), sigh); /* register handler for unresolvable page faults */ - rm.fault_handler(sigh); + Region_map_client address_space(pd.address_space()); + address_space.fault_handler(sigh); } } _resources; @@ -101,7 +101,7 @@ class Test_child : public Genode::Child_policy _elf(elf_name), _log_service("LOG"), _rm_service("RM"), _child(_elf.dataspace(), _resources.pd.cap(), _resources.ram.cap(), - _resources.cpu.cap(), _resources.rm.cap(), &ep, this) + _resources.cpu.cap(), &ep, this) { } diff --git a/repos/ports-foc/run/l4linux.run b/repos/ports-foc/run/l4linux.run index a7ec92403f..bc56aa079a 100644 --- a/repos/ports-foc/run/l4linux.run +++ b/repos/ports-foc/run/l4linux.run @@ -100,7 +100,7 @@ append_if $use_usb_driver config { append_if $use_nic_driver config { - + } @@ -151,7 +151,7 @@ build_boot_image [join $boot_modules " "] # # Qemu # -append qemu_args " -m 128 -nographic " +append qemu_args " -m 160 -nographic " append qemu_args " -serial mon:stdio " append_if [have_spec x86] qemu_args " -smp 2,cores=2 " append_if [have_spec x86] qemu_args " -net nic,model=e1000 -net user " diff --git a/repos/ports-foc/src/lib/l4lx/include/dataspace.h b/repos/ports-foc/src/lib/l4lx/include/dataspace.h index f88f1147c7..20b680308b 100644 --- a/repos/ports-foc/src/lib/l4lx/include/dataspace.h +++ b/repos/ports-foc/src/lib/l4lx/include/dataspace.h @@ -20,6 +20,7 @@ #include #include #include +#include #include namespace Fiasco { @@ -97,13 +98,41 @@ namespace L4lx { }; + struct Expanding_region_map : private Genode::Rm_connection, + public Genode::Region_map_client + { + typedef Genode::size_t size_t; + typedef Genode::off_t off_t; + + Expanding_region_map(size_t size) + : + Genode::Region_map_client(Genode::Rm_connection::create(size)) + { } + + Local_addr attach(Genode::Dataspace_capability ds, size_t size, off_t offset, + bool use_local_addr, Local_addr local_addr, + bool executable) override + { + return retry( + [&] () { + return Genode::Region_map_client::attach(ds, size, offset, + use_local_addr, + local_addr, + executable); }, + [&] () { + Genode::env()->parent()->upgrade(Rm_connection::cap(), "ram_quota=8K"); + }); + } + }; + + class Chunked_dataspace : public Dataspace { private: - Genode::Rm_connection _rm_con; - Genode::Expanding_rm_session_client _rm; - Genode::Ram_dataspace_capability *_chunks; + Expanding_region_map _rm; + + Genode::Ram_dataspace_capability *_chunks; public: @@ -113,15 +142,15 @@ namespace L4lx { }; Chunked_dataspace(const char* name, - Genode::size_t size, - Fiasco::l4_cap_idx_t ref) - : Dataspace(name, size, ref), _rm_con(0, size), _rm(_rm_con.cap()) + Genode::size_t size, + Fiasco::l4_cap_idx_t ref) + : Dataspace(name, size, ref), _rm(size) { - _chunks = (Genode::Ram_dataspace_capability*) Genode::env()->heap()->alloc( - sizeof(Genode::Ram_dataspace_capability) * (size/CHUNK_SIZE)); + _chunks = (Genode::Ram_dataspace_capability*) + Genode::env()->heap()->alloc(sizeof(Genode::Ram_dataspace_capability) * (size/CHUNK_SIZE)); } - Genode::Dataspace_capability cap() { return _rm_con.dataspace(); } + Genode::Dataspace_capability cap() { return _rm.dataspace(); } void map(Genode::size_t off, bool greedy) { diff --git a/repos/ports-foc/src/lib/l4lx/include/platform_env.h b/repos/ports-foc/src/lib/l4lx/include/platform_env.h index ee1cec1f5e..4ffcc1e75b 100644 --- a/repos/ports-foc/src/lib/l4lx/include/platform_env.h +++ b/repos/ports-foc/src/lib/l4lx/include/platform_env.h @@ -81,31 +81,4 @@ struct Upgradeable_client : CLIENT } }; - -struct Genode::Expanding_rm_session_client : Upgradeable_client -{ - Expanding_rm_session_client(Rm_session_capability cap) - : Upgradeable_client(cap) { } - - Local_addr attach(Dataspace_capability ds, size_t size, off_t offset, - bool use_local_addr, Local_addr local_addr, - bool executable) - { - return retry( - [&] () { - return Rm_session_client::attach(ds, size, offset, - use_local_addr, - local_addr, - executable); }, - [&] () { upgrade_ram(8*1024); }); - } - - Pager_capability add_client(Thread_capability thread) - { - return retry( - [&] () { return Rm_session_client::add_client(thread); }, - [&] () { upgrade_ram(8*1024); }); - } -}; - #endif /* _PLATFORM_ENV_H_ */ diff --git a/repos/ports-foc/src/lib/l4lx/rm.cc b/repos/ports-foc/src/lib/l4lx/rm.cc index 2a21c4a537..0bca5a3ce8 100644 --- a/repos/ports-foc/src/lib/l4lx/rm.cc +++ b/repos/ports-foc/src/lib/l4lx/rm.cc @@ -99,25 +99,28 @@ Region* Region_manager::reserve_range(Genode::size_t size, int align, Genode::addr_t start) { using namespace Genode; - void* addr = 0; + void* addr = nullptr; addr_t original_start = start; while (true) { - Rm_connection *rmc = 0; + Rm_connection *rmc = nullptr; + Region_map *rm = nullptr; try { /* * We attach a managed-dataspace as a placeholder to * Genode's region-map */ - rmc = new (env()->heap()) Rm_connection(0, size); - addr = start ? env()->rm_session()->attach_at(rmc->dataspace(), start) - : env()->rm_session()->attach(rmc->dataspace()); + rmc = new (env()->heap()) Rm_connection; + rm = new (env()->heap()) Region_map_client(rmc->create(size)); + + addr = start ? env()->rm_session()->attach_at(rm->dataspace(), start) + : env()->rm_session()->attach(rm->dataspace()); //PDBG("attach done addr=%p!", addr); break; } catch(Rm_session::Attach_failed e) { - destroy(env()->heap(), rmc); + destroy(env()->heap(), rm); /* attach with pre-defined address failed, so search one */ if (start) { /* the original start address might have a different alignment */ diff --git a/repos/ports/include/noux_session/client.h b/repos/ports/include/noux_session/client.h index b43cc0c8ea..8be0b456f1 100644 --- a/repos/ports/include/noux_session/client.h +++ b/repos/ports/include/noux_session/client.h @@ -49,9 +49,9 @@ namespace Noux { return call(start_fd); } - Rm_session_capability lookup_rm_session(addr_t const addr) + Capability lookup_region_map(addr_t const addr) { - return call(addr); + return call(addr); } }; } diff --git a/repos/ports/include/noux_session/noux_session.h b/repos/ports/include/noux_session/noux_session.h index fdae49a542..d706347d3b 100644 --- a/repos/ports/include/noux_session/noux_session.h +++ b/repos/ports/include/noux_session/noux_session.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #define NOUX_DECL_SYSCALL_NAME(name) \ case SYSCALL_##name: return #name; @@ -35,11 +35,11 @@ namespace Noux { virtual Dataspace_capability sysio_dataspace() = 0; /** - * Return leaf RM session that covers a given address + * Return leaf region map that covers a given address * - * \param addr address that is covered by the requested RM session + * \param addr address that is covered by the requested region map */ - virtual Rm_session_capability lookup_rm_session(addr_t const addr) = 0; + virtual Capability lookup_region_map(addr_t const addr) = 0; enum Syscall { SYSCALL_WRITE, @@ -164,12 +164,12 @@ namespace Noux { *********************/ GENODE_RPC(Rpc_sysio_dataspace, Dataspace_capability, sysio_dataspace); - GENODE_RPC(Rpc_lookup_rm_session, Rm_session_capability, - lookup_rm_session, addr_t); + GENODE_RPC(Rpc_lookup_region_map, Capability, + lookup_region_map, addr_t); GENODE_RPC(Rpc_syscall, bool, syscall, Syscall); GENODE_RPC(Rpc_next_open_fd, int, next_open_fd, int); - GENODE_RPC_INTERFACE(Rpc_sysio_dataspace, Rpc_lookup_rm_session, + GENODE_RPC_INTERFACE(Rpc_sysio_dataspace, Rpc_lookup_region_map, Rpc_syscall, Rpc_next_open_fd); }; } diff --git a/repos/ports/include/vmm/guest_memory.h b/repos/ports/include/vmm/guest_memory.h index 962a34424d..553b890c4a 100644 --- a/repos/ports/include/vmm/guest_memory.h +++ b/repos/ports/include/vmm/guest_memory.h @@ -28,6 +28,7 @@ /* Genode includes */ #include #include +#include /* VMM utilities includes */ #include @@ -45,11 +46,11 @@ namespace Vmm { * part of the address space, which contains the shadow of the VCPU's physical * memory. */ -struct Vmm::Virtual_reservation : Rm_connection +struct Vmm::Virtual_reservation : private Rm_connection, Region_map_client { Virtual_reservation(addr_t vm_size) : - Rm_connection(0, vm_size) + Region_map_client(Rm_connection::create(vm_size)) { try { /* @@ -57,7 +58,7 @@ struct Vmm::Virtual_reservation : Rm_connection * space. We leave out the very first page because core denies * the attachment of anything at the zero page. */ - env()->rm_session()->attach_at(Rm_connection::dataspace(), + env()->rm_session()->attach_at(Region_map_client::dataspace(), PAGE_SIZE, 0, PAGE_SIZE); } catch (Rm_session::Region_conflict) { diff --git a/repos/ports/include/vmm/vcpu_thread.h b/repos/ports/include/vmm/vcpu_thread.h index ea2d68f09a..6727afd4f7 100644 --- a/repos/ports/include/vmm/vcpu_thread.h +++ b/repos/ports/include/vmm/vcpu_thread.h @@ -21,7 +21,7 @@ #include #include #include -#include +#include /* NOVA includes */ #include @@ -50,7 +50,6 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread Genode::Pd_connection _pd_session; Genode::Affinity::Location _location; Genode::Cpu_session *_cpu_session; - Genode::Rm_connection _rm; Genode::addr_t _exc_pt_sel; @@ -75,7 +74,8 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread _pd_session.bind_thread(vcpu_vm); /* create new pager object and assign it to the new thread */ - Pager_capability pager_cap = _rm.add_client(vcpu_vm); + Genode::Region_map_client address_space(_pd_session.address_space()); + Pager_capability pager_cap = address_space.add_client(vcpu_vm); _cpu_session->set_pager(vcpu_vm, pager_cap); diff --git a/repos/ports/run/noux_fork.run b/repos/ports/run/noux_fork.run index 0de92d7aa2..9c33e36329 100644 --- a/repos/ports/run/noux_fork.run +++ b/repos/ports/run/noux_fork.run @@ -23,7 +23,7 @@ install_config { - + diff --git a/repos/ports/run/vbox_win.inc b/repos/ports/run/vbox_win.inc index 0462824fe1..a52a143776 100644 --- a/repos/ports/run/vbox_win.inc +++ b/repos/ports/run/vbox_win.inc @@ -125,7 +125,7 @@ append config_of_app { - + diff --git a/repos/ports/run/virtualbox_auto.inc b/repos/ports/run/virtualbox_auto.inc index 9ca558e6a4..a589954ec8 100644 --- a/repos/ports/run/virtualbox_auto.inc +++ b/repos/ports/run/virtualbox_auto.inc @@ -159,7 +159,7 @@ append_if [expr $use_usb] config { - + @@ -168,7 +168,7 @@ append_if [expr $use_usb] config { - + diff --git a/repos/ports/src/app/gdb_monitor/app_child.h b/repos/ports/src/app/gdb_monitor/app_child.h index 368897ffa7..ef789e2334 100644 --- a/repos/ports/src/app/gdb_monitor/app_child.h +++ b/repos/ports/src/app/gdb_monitor/app_child.h @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -29,7 +28,7 @@ #include "cpu_root.h" #include "gdb_stub_thread.h" #include "ram_root.h" -#include "rm_root.h" +#include "pd_session_component.h" #include "rom.h" @@ -54,17 +53,15 @@ namespace Gdb_monitor { Init::Child_policy_provide_rom_file _config_policy; Gdb_stub_thread _gdb_stub_thread; - Object_pool _managed_ds_map; - - Rm_root _rm_root; - Rm_session_capability _rm_session_cap; + Dataspace_pool _managed_ds_map; Cpu_root _cpu_root; Cpu_session_capability _cpu_session_cap; Ram_session_capability _ram_session_cap; - Pd_connection _pd; + Pd_session_component _pd { _unique_name, _entrypoint, + _managed_ds_map }; Child _child; @@ -72,47 +69,6 @@ namespace Gdb_monitor { Rom_service _rom_service; - class Rm_service : public Genode::Service - { - private: - - Rm_root _rm_root; - - public: - - Rm_service(Genode::Rpc_entrypoint *entrypoint, - Genode::Allocator *md_alloc, - Object_pool *managed_ds_map) - : - Genode::Service("RM"), - _rm_root(entrypoint, md_alloc, managed_ds_map) - { } - - Genode::Session_capability session(const char *args, - Genode::Affinity const &affinity) - { - return _rm_root.session(args, affinity); - } - - void upgrade(Genode::Session_capability, const char *) { } - - void close(Genode::Session_capability cap) - { - _rm_root.close(cap); - } - } _rm_service; - - Rm_session_capability _get_rm_session_cap() - { - _entrypoint.manage(&_rm_root); - Capability cap = static_cap_cast - (_rm_root.session("ram_quota=64K", Affinity())); - Rm_session_client rm(cap); - - rm.fault_handler(_gdb_stub_thread.exception_signal_receiver()->manage(new (env()->heap()) Signal_context())); - return cap; - } - Cpu_session_capability _get_cpu_session_cap() { _entrypoint.manage(&_cpu_root); @@ -282,26 +238,21 @@ namespace Gdb_monitor { _binary_policy("binary", elf_ds, &_entrypoint), _config_policy("config", _child_config.dataspace(), &_entrypoint), _gdb_stub_thread(), - _rm_root(&_entrypoint, env()->heap() /* should be _child.heap() */, &_managed_ds_map, &_gdb_stub_thread), - _rm_session_cap(_get_rm_session_cap()), _cpu_root(&_entrypoint, env()->heap() /* should be _child.heap() */, &_gdb_stub_thread), _cpu_session_cap(_get_cpu_session_cap()), _ram_session_cap(ram_session), - _pd(unique_name), _child(elf_ds, _pd.cap(), ram_session, _cpu_session_cap, - _rm_session_cap, &_entrypoint, this), + &_entrypoint, this), _root_ep(root_ep), - _rom_service(&_entrypoint, _child.heap()), - _rm_service(&_entrypoint, _child.heap(), &_managed_ds_map) + _rom_service(&_entrypoint, _child.heap()) { - _local_services.insert(&_rm_service); + _gdb_stub_thread.set_region_map_component(&_pd.region_map()); _local_services.insert(&_rom_service); _gdb_stub_thread.start(); } ~App_child() { - _rm_root.close(_rm_session_cap); } /**************************** diff --git a/repos/ports/src/app/gdb_monitor/dataspace_object.h b/repos/ports/src/app/gdb_monitor/dataspace_object.h index f7dbb97326..af239e7f61 100644 --- a/repos/ports/src/app/gdb_monitor/dataspace_object.h +++ b/repos/ports/src/app/gdb_monitor/dataspace_object.h @@ -21,23 +21,26 @@ namespace Gdb_monitor { using namespace Genode; - class Rm_session_component; + class Region_map_component; - class Dataspace_object : public Object_pool::Entry + class Dataspace_object; + + typedef Object_pool Dataspace_pool; + + class Dataspace_object : public Dataspace_pool::Entry { private: - Rm_session_component *_rm_session_component; + Region_map_component *_region_map_component; public: - Dataspace_object(Dataspace_capability ds_cap, Rm_session_component *rm_session_component) + Dataspace_object(Dataspace_capability ds_cap, Region_map_component *region_map_component) : Object_pool::Entry(ds_cap), - _rm_session_component(rm_session_component) { } + _region_map_component(region_map_component) { } - Rm_session_component *rm_session_component() { return _rm_session_component; } + Region_map_component *region_map_component() { return _region_map_component; } }; - } #endif /* _DATASPACE_OBJECT_H_ */ diff --git a/repos/ports/src/app/gdb_monitor/gdb_stub_thread.cc b/repos/ports/src/app/gdb_monitor/gdb_stub_thread.cc index ef0c5f4752..b9e7229995 100644 --- a/repos/ports/src/app/gdb_monitor/gdb_stub_thread.cc +++ b/repos/ports/src/app/gdb_monitor/gdb_stub_thread.cc @@ -22,7 +22,7 @@ Gdb_stub_thread::Gdb_stub_thread() : Thread("GDB server thread"), _cpu_session_component(0), - _rm_session_component(0), + _region_map_component(0), _signal_handler_thread(&_exception_signal_receiver) { _signal_handler_thread.start(); diff --git a/repos/ports/src/app/gdb_monitor/gdb_stub_thread.h b/repos/ports/src/app/gdb_monitor/gdb_stub_thread.h index 9548e88629..6c3fafdac3 100644 --- a/repos/ports/src/app/gdb_monitor/gdb_stub_thread.h +++ b/repos/ports/src/app/gdb_monitor/gdb_stub_thread.h @@ -18,7 +18,7 @@ #include "cpu_session_component.h" #include "dataspace_object.h" -#include "rm_session_component.h" +#include "region_map_component.h" #include "signal_handler_thread.h" namespace Gdb_monitor { @@ -32,7 +32,7 @@ namespace Gdb_monitor { private: Cpu_session_component *_cpu_session_component; - Rm_session_component *_rm_session_component; + Region_map_component *_region_map_component; Signal_receiver _exception_signal_receiver; Gdb_monitor::Signal_handler_thread _signal_handler_thread; @@ -46,13 +46,13 @@ namespace Gdb_monitor { _cpu_session_component = cpu_session_component; } - void set_rm_session_component(Rm_session_component *rm_session_component) + void set_region_map_component(Region_map_component *region_map_component) { - _rm_session_component = rm_session_component; + _region_map_component = region_map_component; } Cpu_session_component *cpu_session_component() { return _cpu_session_component; } - Rm_session_component *rm_session_component() { return _rm_session_component; } + Region_map_component *region_map_component() { return _region_map_component; } Signal_receiver *exception_signal_receiver() { return &_exception_signal_receiver; } int signal_fd() { return _signal_handler_thread.pipe_read_fd(); } }; diff --git a/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc b/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc index 2a2a0c6ff3..cac441e80c 100644 --- a/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc +++ b/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc @@ -21,6 +21,7 @@ extern "C" { int linux_detach_one_lwp (struct inferior_list_entry *entry, void *args); } +#include #include #include @@ -233,21 +234,21 @@ class Memory_model Lock _lock; - Rm_session_component * const _address_space; + Region_map_component * const _address_space; /** * Representation of a currently mapped region */ struct Mapped_region { - Rm_session_component::Region *_region; + Region_map_component::Region *_region; unsigned char *_local_base; Mapped_region() : _region(0), _local_base(0) { } bool valid() { return _region != 0; } - bool is_loaded(Rm_session_component::Region const * region) + bool is_loaded(Region_map_component::Region const * region) { return _region == region; } @@ -260,7 +261,7 @@ class Memory_model _region = 0; } - void load(Rm_session_component::Region *region) + void load(Region_map_component::Region *region) { if (region == _region) return; @@ -275,7 +276,7 @@ class Memory_model _region = region; _local_base = env()->rm_session()->attach(_region->ds_cap(), 0, _region->offset()); - } catch (Rm_session::Attach_failed) { + } catch (Region_map::Attach_failed) { flush(); PERR("Memory_model: RM attach failed"); } @@ -295,7 +296,7 @@ class Memory_model * * The function returns 0 if the mapping fails */ - unsigned char *_update_curr_region(Rm_session_component::Region *region) + unsigned char *_update_curr_region(Region_map_component::Region *region) { for (unsigned i = 0; i < NUM_MAPPED_REGIONS; i++) { if (_mapped_region[i].is_loaded(region)) @@ -314,7 +315,7 @@ class Memory_model public: - Memory_model(Rm_session_component *address_space) + Memory_model(Region_map_component *address_space) : _address_space(address_space), _evict_idx(0) { } @@ -325,7 +326,7 @@ class Memory_model addr_t offset_in_region = 0; - Rm_session_component::Region *region = + Region_map_component::Region *region = _address_space->find_region(addr, &offset_in_region); unsigned char *local_base = _update_curr_region(region); @@ -352,7 +353,7 @@ class Memory_model Lock::Guard guard(_lock); addr_t offset_in_region = 0; - Rm_session_component::Region *region = + Region_map_component::Region *region = _address_space->find_region(addr, &offset_in_region); unsigned char *local_base = _update_curr_region(region); @@ -373,7 +374,7 @@ class Memory_model */ static Memory_model *memory_model() { - static Memory_model inst(gdb_stub_thread()->rm_session_component()); + static Memory_model inst(gdb_stub_thread()->region_map_component()); return &inst; } diff --git a/repos/ports/src/app/gdb_monitor/pd_session_component.h b/repos/ports/src/app/gdb_monitor/pd_session_component.h new file mode 100644 index 0000000000..bd7abcd1d5 --- /dev/null +++ b/repos/ports/src/app/gdb_monitor/pd_session_component.h @@ -0,0 +1,111 @@ +/* + * \brief Core-specific instance of the PD session interface + * \author Norman Feske + * \date 2016-04-20 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _PD_SESSION_COMPONENT_H_ +#define _PD_SESSION_COMPONENT_H_ + +/* Genode includes */ +#include +#include + +using namespace Genode; + +class Pd_session_component : public Rpc_object +{ + private: + + Rpc_entrypoint &_ep; + + Pd_connection _pd; + + Region_map_component _address_space; + Region_map_component _stack_area; + Region_map_component _linker_area; + + public: + + /** + * Constructor + */ + Pd_session_component(char const *binary_name, Rpc_entrypoint &ep, + Dataspace_pool &managed_ds_map) + : + _ep(ep), _pd(binary_name), + _address_space(_ep, managed_ds_map, _pd.address_space()), + _stack_area (_ep, managed_ds_map, _pd.stack_area()), + _linker_area (_ep, managed_ds_map, _pd.linker_area()) + { + _ep.manage(this); + } + + ~Pd_session_component() + { + _ep.dissolve(this); + } + + /** + * Accessor used to let the GDB stub thread access the PD's address + * space + */ + Region_map_component ®ion_map() { return _address_space; } + + + /************************** + ** Pd_session interface ** + **************************/ + + void bind_thread(Thread_capability thread) override { + _pd.bind_thread(thread); } + + void assign_parent(Capability parent) override { + _pd.assign_parent(parent); } + + bool assign_pci(addr_t addr, uint16_t bdf) override { + return _pd.assign_pci(addr, bdf); } + + Signal_source_capability alloc_signal_source() override { + return _pd.alloc_signal_source(); } + + void free_signal_source(Signal_source_capability cap) override { + _pd.free_signal_source(cap); } + + Capability alloc_context(Signal_source_capability source, + unsigned long imprint) override { + return _pd.alloc_context(source, imprint); } + + void free_context(Capability cap) override { + _pd.free_context(cap); } + + void submit(Capability context, unsigned cnt) override { + _pd.submit(context, cnt); } + + Native_capability alloc_rpc_cap(Native_capability ep) override { + return _pd.alloc_rpc_cap(ep); } + + void free_rpc_cap(Native_capability cap) override { + _pd.free_rpc_cap(cap); } + + Capability address_space() override { + return _address_space.Rpc_object::cap(); } + + Capability stack_area() override { + return _stack_area.Rpc_object::cap(); } + + Capability linker_area() override { + return _linker_area.Rpc_object::cap(); } + + Capability native_pd() override { + return _pd.native_pd(); } +}; + +#endif /* _PD_SESSION_COMPONENT_H_ */ diff --git a/repos/ports/src/app/gdb_monitor/rm_session_component.cc b/repos/ports/src/app/gdb_monitor/region_map_component.cc similarity index 57% rename from repos/ports/src/app/gdb_monitor/rm_session_component.cc rename to repos/ports/src/app/gdb_monitor/region_map_component.cc index 02f9e72c53..9e3b90aabc 100644 --- a/repos/ports/src/app/gdb_monitor/rm_session_component.cc +++ b/repos/ports/src/app/gdb_monitor/region_map_component.cc @@ -1,5 +1,5 @@ /* - * \brief Implementation of the RM session interface + * \brief Implementation of the region map interface * \author Christian Prochaska * \date 2011-05-06 */ @@ -12,22 +12,24 @@ */ /* Genode includes */ +#include #include #include /* local includes */ -#include "rm_session_component.h" +#include "region_map_component.h" static bool const verbose = false; - -/************************************** - ** Region-manager-session component ** - **************************************/ - using namespace Gdb_monitor; +using namespace Genode; -Rm_session_component::Region *Rm_session_component::find_region(void *local_addr, addr_t *offset_in_region) + +/************************** + ** Region map component ** + **************************/ + +Region_map_component::Region *Region_map_component::find_region(void *local_addr, addr_t *offset_in_region) { Lock::Guard lock_guard(_region_map_lock); @@ -42,10 +44,10 @@ Rm_session_component::Region *Rm_session_component::find_region(void *local_addr *offset_in_region = ((addr_t)local_addr - (addr_t)region->start()); // PDBG("offset_in_region = %lx", *offset_in_region); - _managed_ds_map->apply(region->ds_cap(), [&] (Dataspace_object *managed_ds_obj) { + _managed_ds_map.apply(region->ds_cap(), [&] (Dataspace_object *managed_ds_obj) { if (managed_ds_obj) region = - managed_ds_obj->rm_session_component()->find_region((void*)*offset_in_region, + managed_ds_obj->region_map_component()->find_region((void*)*offset_in_region, offset_in_region); }); @@ -53,10 +55,10 @@ Rm_session_component::Region *Rm_session_component::find_region(void *local_addr } -Rm_session::Local_addr -Rm_session_component::attach(Dataspace_capability ds_cap, size_t size, +Region_map::Local_addr +Region_map_component::attach(Dataspace_capability ds_cap, size_t size, off_t offset, bool use_local_addr, - Rm_session::Local_addr local_addr, + Region_map::Local_addr local_addr, bool executable) { if (verbose) @@ -76,7 +78,7 @@ Rm_session_component::attach(Dataspace_capability ds_cap, size_t size, throw Invalid_args(); } - void *addr = _parent_rm_session.attach(ds_cap, size, offset, + void *addr = _parent_region_map.attach(ds_cap, size, offset, use_local_addr, local_addr, executable); @@ -90,12 +92,12 @@ Rm_session_component::attach(Dataspace_capability ds_cap, size_t size, } -void Rm_session_component::detach(Rm_session::Local_addr local_addr) +void Region_map_component::detach(Region_map::Local_addr local_addr) { if (verbose) PDBG("local_addr = %p", (void *)local_addr); - _parent_rm_session.detach(local_addr); + _parent_region_map.detach(local_addr); Lock::Guard lock_guard(_region_map_lock); Region *region = _region_map.first()->find_by_addr(local_addr); @@ -108,61 +110,67 @@ void Rm_session_component::detach(Rm_session::Local_addr local_addr) } -Pager_capability Rm_session_component::add_client(Thread_capability thread) +Pager_capability Region_map_component::add_client(Thread_capability thread) { if (verbose) PDBG("add_client()"); - return _parent_rm_session.add_client(thread); + return _parent_region_map.add_client(thread); } -void Rm_session_component::remove_client(Pager_capability pager) +void Region_map_component::remove_client(Pager_capability pager) { if (verbose) PDBG("remove_client()"); - return _parent_rm_session.remove_client(pager); + return _parent_region_map.remove_client(pager); } -void Rm_session_component::fault_handler(Signal_context_capability handler) +void Region_map_component::fault_handler(Signal_context_capability handler) { if (verbose) PDBG("fault_handler()"); - _parent_rm_session.fault_handler(handler); + _parent_region_map.fault_handler(handler); } -Rm_session::State Rm_session_component::state() +Region_map::State Region_map_component::state() { if (verbose) PDBG("state()"); - return _parent_rm_session.state(); + return _parent_region_map.state(); } -Dataspace_capability Rm_session_component::dataspace() +Dataspace_capability Region_map_component::dataspace() { if (verbose) PDBG("dataspace()"); - Dataspace_capability ds_cap = _parent_rm_session.dataspace(); - _managed_ds_map->insert(new (env()->heap()) Dataspace_object(ds_cap, this)); + Dataspace_capability ds_cap = _parent_region_map.dataspace(); + _managed_ds_map.insert(new (env()->heap()) Dataspace_object(ds_cap, this)); return ds_cap; } -Rm_session_component::Rm_session_component -(Object_pool *managed_ds_map, const char *args) -: _parent_rm_session(env()->parent()->session(args)), - _managed_ds_map(managed_ds_map) +Region_map_component::Region_map_component(Rpc_entrypoint &ep, + Dataspace_pool &managed_ds_map, + Capability parent_region_map) +: + _ep(ep), + _parent_region_map(parent_region_map), + _managed_ds_map(managed_ds_map) { + _ep.manage(this); if (verbose) - PDBG("Rm_session_component()"); + PDBG("Region_map_component()"); } -Rm_session_component::~Rm_session_component() -{ } +Region_map_component::~Region_map_component() +{ + _ep.dissolve(this); +} diff --git a/repos/ports/src/app/gdb_monitor/rm_session_component.h b/repos/ports/src/app/gdb_monitor/region_map_component.h similarity index 77% rename from repos/ports/src/app/gdb_monitor/rm_session_component.h rename to repos/ports/src/app/gdb_monitor/region_map_component.h index e99ed62e96..2fdbc6e3ed 100644 --- a/repos/ports/src/app/gdb_monitor/rm_session_component.h +++ b/repos/ports/src/app/gdb_monitor/region_map_component.h @@ -1,5 +1,5 @@ /* - * \brief RM session interface + * \brief Region map interface * \author Christian Helmuth * \author Norman Feske * \date 2006-07-17 @@ -12,12 +12,11 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _RM_SESSION_COMPONENT_H_ -#define _RM_SESSION_COMPONENT_H_ +#ifndef _REGION_MAP_COMPONENT_H_ +#define _REGION_MAP_COMPONENT_H_ /* Genode includes */ -#include -#include +#include #include /* GDB monitor includes */ @@ -27,11 +26,13 @@ namespace Gdb_monitor { using namespace Genode; - class Rm_session_component : public Rpc_object + class Region_map_component : public Rpc_object { private: - Genode::Rm_session_client _parent_rm_session; + Rpc_entrypoint &_ep; + + Genode::Region_map_client _parent_region_map; public: @@ -65,19 +66,20 @@ namespace Gdb_monitor { private: - Avl_tree _region_map; - Lock _region_map_lock; - Object_pool *_managed_ds_map; + Avl_tree _region_map; + Lock _region_map_lock; + Dataspace_pool &_managed_ds_map; public: /** * Constructor */ - Rm_session_component(Object_pool *managed_ds_map, - const char *args); + Region_map_component(Rpc_entrypoint &ep, + Dataspace_pool &managed_ds_map, + Capability parent_region_map); - ~Rm_session_component(); + ~Region_map_component(); /** * Find region for given address @@ -104,4 +106,4 @@ namespace Gdb_monitor { } -#endif /* _RM_SESSION_COMPONENT_H_ */ +#endif /* _REGION_MAP_COMPONENT_H_ */ diff --git a/repos/ports/src/app/gdb_monitor/rm_root.h b/repos/ports/src/app/gdb_monitor/rm_root.h deleted file mode 100644 index 453cb1a4ea..0000000000 --- a/repos/ports/src/app/gdb_monitor/rm_root.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * \brief RM root interface - * \author Christian Helmuth - * \date 2006-07-17 - */ - -/* - * Copyright (C) 2006-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _RM_ROOT_H_ -#define _RM_ROOT_H_ - -/* Genode includes */ -#include - -#include "gdb_stub_thread.h" -#include "rm_session_component.h" - -namespace Gdb_monitor { - - class Rm_root : public Root_component - { - private: - - Object_pool *_managed_ds_map; - Gdb_stub_thread *_gdb_stub_thread; - - protected: - - Rm_session_component *_create_session(const char *args) - { - Rm_session_component *rm_session_component = - new (md_alloc()) Rm_session_component(_managed_ds_map, args); - - if (_gdb_stub_thread) - _gdb_stub_thread->set_rm_session_component(rm_session_component); - - return rm_session_component; - } - - public: - - /** - * Constructor - * - * \param session_ep entry point for managing RM session objects - * \param md_alloc meta data allocator to be used by root component - */ - Rm_root(Rpc_entrypoint *session_ep, - Allocator *md_alloc, - Object_pool *managed_ds_map, - Gdb_stub_thread *gdb_stub_thread = 0) - : - Root_component(session_ep, md_alloc), - _managed_ds_map(managed_ds_map), - _gdb_stub_thread(gdb_stub_thread) - { } - }; -} - -#endif /* _RM_ROOT_H_ */ diff --git a/repos/ports/src/app/gdb_monitor/target.mk b/repos/ports/src/app/gdb_monitor/target.mk index a763436d95..81d782b37a 100644 --- a/repos/ports/src/app/gdb_monitor/target.mk +++ b/repos/ports/src/app/gdb_monitor/target.mk @@ -36,7 +36,7 @@ SRC_CC = genode-low.cc \ gdb_stub_thread.cc \ cpu_session_component.cc \ ram_session_component.cc \ - rm_session_component.cc \ + region_map_component.cc \ signal_handler_thread.cc \ main.cc diff --git a/repos/ports/src/lib/libc_noux/plugin.cc b/repos/ports/src/lib/libc_noux/plugin.cc index 7f6d2d5b13..18e3783b58 100644 --- a/repos/ports/src/lib/libc_noux/plugin.cc +++ b/repos/ports/src/lib/libc_noux/plugin.cc @@ -20,6 +20,7 @@ #include #include #include +#include /* noux includes */ #include @@ -94,13 +95,13 @@ class Noux_connection Noux_connection() : _sysio(_obtain_sysio()) { } /** - * Return the capability of the local stack-area RM session + * Return the capability of the local stack-area region map * * \param ptr some address within the stack-area */ - Genode::Rm_session_capability stack_area_rm_session(void * const ptr) + Genode::Capability stack_area_region_map(void * const ptr) { - return _connection.lookup_rm_session((Genode::addr_t)ptr); + return _connection.lookup_region_map((Genode::addr_t)ptr); } Noux::Session *session() { return &_connection; } @@ -535,7 +536,7 @@ extern "C" void fork_trampoline() construct_at(noux_connection()); /* reinitialize main-thread object which implies reinit of stack area */ - auto stack_area_rm = noux_connection()->stack_area_rm_session(in_stack_area); + auto stack_area_rm = noux_connection()->stack_area_region_map(in_stack_area); Genode::env()->reinit_main_thread(stack_area_rm); /* apply processor state that the forker had when he did the fork */ diff --git a/repos/ports/src/noux/child.h b/repos/ports/src/noux/child.h index c1e33a9679..d4241e0fa2 100644 --- a/repos/ports/src/noux/child.h +++ b/repos/ports/src/noux/child.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -123,8 +124,6 @@ namespace Noux { enum { STACK_SIZE = 4*1024*sizeof(long) }; Rpc_entrypoint _entrypoint; - Pd_connection _pd; - /** * Resources assigned to the child */ @@ -146,26 +145,25 @@ namespace Noux { */ Ram_session_component ram; Cpu_session_component cpu; - Rm_session_component rm; Resources(char const *label, Rpc_entrypoint &ep, bool forked) : - ep(ep), ram(ds_registry), cpu(label, forked), rm(ds_registry) + ep(ep), ram(ds_registry), cpu(label, forked) { ep.manage(&ram); - ep.manage(&rm); ep.manage(&cpu); } ~Resources() { ep.dissolve(&ram); - ep.dissolve(&rm); ep.dissolve(&cpu); } } _resources; + Pd_session_component _pd; + /** * Command line arguments */ @@ -214,7 +212,6 @@ namespace Noux { Local_noux_service _local_noux_service; Parent_service _parent_ram_service; Local_cpu_service _local_cpu_service; - Local_rm_service _local_rm_service; Local_rom_service _local_rom_service; Service_registry &_parent_services; @@ -352,8 +349,8 @@ namespace Noux { _destruct_context_cap(sig_rec->manage(&_destruct_dispatcher)), _cap_session(cap_session), _entrypoint(cap_session, STACK_SIZE, "noux_process", false), - _pd(binary_name), _resources(binary_name, resources_ep, false), + _pd(binary_name, resources_ep, _resources.ds_registry), _args(ARGS_DS_SIZE, args), _env(env), _elf(binary_name, root_dir, root_dir->dataspace(binary_name)), @@ -363,7 +360,6 @@ namespace Noux { _local_noux_service(_noux_session_cap), _parent_ram_service(""), _local_cpu_service(_entrypoint, _resources.cpu.cpu_cap()), - _local_rm_service(_entrypoint, _resources.ds_registry), _local_rom_service(_entrypoint, _resources.ds_registry), _parent_services(parent_services), _binary_ds_info(_resources.ds_registry, _elf._binary_ds), @@ -373,14 +369,13 @@ namespace Noux { _env_ds_info(_resources.ds_registry, _env.cap()), _child_policy(_elf._name, _elf._binary_ds, _args.cap(), _env.cap(), _entrypoint, _local_noux_service, - _local_rm_service, _local_rom_service, - _parent_services, + _local_rom_service, _parent_services, *this, parent_exit, *this, _destruct_context_cap, _resources.ram, verbose), _child(forked ? Dataspace_capability() : _elf._binary_ds, _pd.cap(), _resources.ram.cap(), _resources.cpu.cap(), - _resources.rm.cap(), &_entrypoint, &_child_policy, - _parent_ram_service, _local_cpu_service, _local_rm_service) + &_entrypoint, &_child_policy, _parent_ram_service, + _local_cpu_service) { if (verbose) _args.dump(); @@ -406,7 +401,8 @@ namespace Noux { /* poke parent_cap_addr into child's address space */ Capability const &cap = _child.parent_cap(); Capability::Raw raw = { cap.dst(), cap.local_name() }; - _resources.rm.poke(parent_cap_addr, &raw, sizeof(raw)); + + _pd.poke(parent_cap_addr, &raw, sizeof(raw)); /* start execution of new main thread at supplied trampoline */ _resources.cpu.start_main_thread(ip, sp); @@ -425,7 +421,7 @@ namespace Noux { } Ram_session_capability ram() const { return _resources.ram.cap(); } - Rm_session_capability rm() const { return _resources.rm.cap(); } + Pd_session_capability pd() const { return _pd.cap(); } Dataspace_registry &ds_registry() { return _resources.ds_registry; } @@ -438,9 +434,9 @@ namespace Noux { return _sysio_ds.cap(); } - Rm_session_capability lookup_rm_session(addr_t const addr) + Capability lookup_region_map(addr_t const addr) { - return _resources.rm.lookup_rm_session(addr); + return _pd.lookup_region_map(addr); } bool syscall(Syscall sc); diff --git a/repos/ports/src/noux/child_policy.h b/repos/ports/src/noux/child_policy.h index afbe307d76..5121390912 100644 --- a/repos/ports/src/noux/child_policy.h +++ b/repos/ports/src/noux/child_policy.h @@ -22,7 +22,6 @@ #include #include #include -#include #include namespace Noux { @@ -37,7 +36,6 @@ namespace Noux { Init::Child_policy_provide_rom_file _args_policy; Init::Child_policy_provide_rom_file _env_policy; Local_noux_service &_local_noux_service; - Local_rm_service &_local_rm_service; Local_rom_service &_local_rom_service; Service_registry &_parent_services; Family_member &_family_member; @@ -56,7 +54,6 @@ namespace Noux { Dataspace_capability env_ds, Rpc_entrypoint &entrypoint, Local_noux_service &local_noux_service, - Local_rm_service &local_rm_service, Local_rom_service &local_rom_service, Service_registry &parent_services, Family_member &family_member, @@ -72,7 +69,6 @@ namespace Noux { _args_policy( "args", args_ds, &entrypoint), _env_policy( "env", env_ds, &entrypoint), _local_noux_service(local_noux_service), - _local_rm_service(local_rm_service), _local_rom_service(local_rom_service), _parent_services(parent_services), _family_member(family_member), @@ -107,14 +103,6 @@ namespace Noux { if (strcmp(service_name, Session::service_name()) == 0) return &_local_noux_service; - /* - * Check for the creation of an RM session, which is used by - * the dynamic linker to manually manage a part of the address - * space. - */ - if (strcmp(service_name, Rm_session::service_name()) == 0) - return &_local_rm_service; - /* * Check for local ROM service */ diff --git a/repos/ports/src/noux/dataspace_registry.h b/repos/ports/src/noux/dataspace_registry.h index cc44905f9f..c42bfa5d18 100644 --- a/repos/ports/src/noux/dataspace_registry.h +++ b/repos/ports/src/noux/dataspace_registry.h @@ -106,14 +106,14 @@ namespace Noux { virtual void poke(addr_t dst_offset, void const *src, size_t len) = 0; /** - * Return leaf RM session that covers a given address + * Return leaf region map that covers a given address * - * \param addr address that is covered by the requested RM session + * \param addr address that is covered by the requested region map */ - virtual Rm_session_capability lookup_rm_session(addr_t const addr) + virtual Capability lookup_region_map(addr_t const addr) { - /* by default a dataspace is no sub RM, so return invalid */ - return Rm_session_capability(); + /* by default a dataspace is no sub region map, so return invalid */ + return Capability(); } }; diff --git a/repos/ports/src/noux/local_rm_service.h b/repos/ports/src/noux/local_rm_service.h deleted file mode 100644 index 328fab8832..0000000000 --- a/repos/ports/src/noux/local_rm_service.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * \brief RM service provided to Noux processes - * \author Norman Feske - * \date 2012-02-22 - */ - -/* - * Copyright (C) 2012-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _NOUX__LOCAL_RM_SERVICE_H_ -#define _NOUX__LOCAL_RM_SERVICE_H_ - -/* Genode includes */ -#include - -/* Noux includes */ -#include -#include - -namespace Noux { - - class Rm_dataspace_info : public Dataspace_info - { - private: - - Rm_session_component * const _sub_rm; - Rpc_entrypoint &_ep; - Rm_session_capability _rm_cap; - - public: - - /** - * Constructor - * - * \param sub_rm pointer to 'Rm_session_component' that belongs - * to the 'Rm_dataspace_info' object - * \param ep entrypoint to manage the 'Rm_session_component' - * - * The ownership of the pointed-to object gets transferred to the - * 'Rm_dataspace_info' object. I.e., 'sub_rm' will get destructed - * on the destruction of its corresponding 'Rm_dataspace_info' - * object. Also, 'Rm_dataspace_info' takes care of associating - * 'sub_rm' with 'ep'. - */ - Rm_dataspace_info(Rm_session_component *sub_rm, - Rpc_entrypoint &ep) - : - Dataspace_info(sub_rm->dataspace()), - _sub_rm(sub_rm), _ep(ep), _rm_cap(_ep.manage(_sub_rm)) - { } - - ~Rm_dataspace_info() - { - _ep.dissolve(_sub_rm); - destroy(env()->heap(), _sub_rm); - } - - Rm_session_capability rm_cap() { return _rm_cap; } - - Dataspace_capability fork(Ram_session_capability ram, - Dataspace_registry &ds_registry, - Rpc_entrypoint &ep) - { - Rm_session_component *new_sub_rm = - new Rm_session_component(ds_registry, 0, size()); - - Rm_dataspace_info *rm_info = new Rm_dataspace_info(new_sub_rm, ep); - - _sub_rm->replay(ram, rm_info->rm_cap(), ds_registry, ep); - - ds_registry.insert(rm_info); - - return new_sub_rm->dataspace(); - } - - void poke(addr_t dst_offset, void const *src, size_t len) - { - if ((dst_offset >= size()) || (dst_offset + len > size())) { - PERR("illegal attemt to write beyond RM boundary"); - return; - } - _sub_rm->poke(dst_offset, src, len); - } - - Rm_session_capability lookup_rm_session(addr_t const addr) - { - /* the dataspace is a sub RM, so traverse into it */ - return _sub_rm->lookup_rm_session(addr); - } - }; - - - class Local_rm_service : public Service - { - private: - - Rpc_entrypoint &_ep; - Dataspace_registry &_ds_registry; - - public: - - Local_rm_service(Rpc_entrypoint &ep, Dataspace_registry &ds_registry) - : - Service(Rm_session::service_name()), _ep(ep), - _ds_registry(ds_registry) - { } - - Genode::Session_capability session(const char *args, Affinity const &) - { - addr_t start = Arg_string::find_arg(args, "start").ulong_value(~0UL); - size_t size = Arg_string::find_arg(args, "size").ulong_value(0); - - Rm_session_component *rm = - new Rm_session_component(_ds_registry, start, size); - - Rm_dataspace_info *info = new Rm_dataspace_info(rm, _ep); - _ds_registry.insert(info); - return info->rm_cap(); - } - - void upgrade(Genode::Session_capability, const char *args) { } - - void close(Genode::Session_capability session) - { - Dataspace_info *info = nullptr;; - - auto lambda = [&] (Rm_session_component *rm_session) { - if (!rm_session) { - PWRN("Unexpected call of close with non-RM-session argument"); - return; - } - - /* use RM dataspace as key to obtain the dataspace info object */ - Dataspace_capability ds_cap = rm_session->dataspace(); - - /* release dataspace info */ - _ds_registry.apply(ds_cap, [&] (Dataspace_info *di) { - info = di; - if (!info) { - PWRN("Could not lookup dataspace info for local RM session"); - return; - } - - _ds_registry.remove(info); - - info->dissolve_users(); - }); - }; - _ep.apply(session, lambda); - - /* 'rm_session' is deleted by deleting Rm_dataspace_info 'info' */ - destroy(env()->heap(), info); - - } - }; -} - -#endif /* _NOUX__LOCAL_RM_SERVICE_H_ */ diff --git a/repos/ports/src/noux/main.cc b/repos/ports/src/noux/main.cc index c80697e909..c6756bbce3 100644 --- a/repos/ports/src/noux/main.cc +++ b/repos/ports/src/noux/main.cc @@ -624,8 +624,8 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) _assign_io_channels_to(child); /* copy our address space into the new child */ - _resources.rm.replay(child->ram(), child->rm(), - child->ds_registry(), _resources.ep); + _pd.replay(child->ram(), child->pd(), + child->ds_registry(), _resources.ep); /* start executing the main thread of the new process */ child->start_forked_main_thread(ip, sp, parent_cap_addr); diff --git a/repos/ports/src/noux/pd_session_component.h b/repos/ports/src/noux/pd_session_component.h new file mode 100644 index 0000000000..b98be9b4fe --- /dev/null +++ b/repos/ports/src/noux/pd_session_component.h @@ -0,0 +1,149 @@ +/* + * \brief PD service used by Noux processes + * \author Norman Feske + * \date 2016-04-20 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _NOUX__PD_SESSION_COMPONENT_H_ +#define _NOUX__PD_SESSION_COMPONENT_H_ + +/* Genode includes */ +#include +#include +#include + +/* Noux includes */ +#include + +namespace Noux { class Pd_session_component; } + + +class Noux::Pd_session_component : public Rpc_object +{ + private: + + Rpc_entrypoint &_ep; + + Pd_connection _pd; + + Region_map_component _address_space; + Region_map_component _stack_area; + Region_map_component _linker_area; + + public: + + /** + * Constructor + */ + Pd_session_component(char const *binary_name, + Rpc_entrypoint &ep, Dataspace_registry &ds_registry) + : + _ep(ep), _pd(binary_name), + _address_space(_ep, ds_registry, _pd, _pd.address_space()), + _stack_area (_ep, ds_registry, _pd, _pd.stack_area()), + _linker_area (_ep, ds_registry, _pd, _pd.linker_area()) + { + _ep.manage(this); + } + + ~Pd_session_component() + { + _ep.dissolve(this); + } + + void poke(addr_t dst_addr, void const *src, size_t len) + { + _address_space.poke(dst_addr, src, len); + } + + Capability lookup_region_map(addr_t const addr) + { + return _address_space.lookup_region_map(addr); + } + + void replay(Ram_session_capability dst_ram, + Capability dst_pd_cap, + Dataspace_registry &ds_registry, + Rpc_entrypoint &ep) + { + Pd_session_client dst_pd(dst_pd_cap); + + /* replay region map into new protection domain */ + _stack_area .replay(dst_ram, dst_pd.stack_area(), ds_registry, ep); + _linker_area .replay(dst_ram, dst_pd.linker_area(), ds_registry, ep); + _address_space.replay(dst_ram, dst_pd.address_space(), ds_registry, ep); + + Region_map_client dst_address_space(dst_pd.address_space()); + + /* attach stack area */ + Region_map_client dst_stack_area(dst_pd.stack_area()); + dst_address_space.attach(dst_stack_area.dataspace(), + Dataspace_client(dst_stack_area.dataspace()).size(), + 0, true, + _address_space.lookup_region_base(_stack_area.dataspace())); + + /* attach linker area */ + Region_map_client dst_linker_area(dst_pd.linker_area()); + dst_address_space.attach(dst_linker_area.dataspace(), + Dataspace_client(dst_linker_area.dataspace()).size(), + 0, true, + _address_space.lookup_region_base(_linker_area.dataspace())); + } + + + /************************** + ** Pd_session interface ** + **************************/ + + void bind_thread(Thread_capability thread) override { + _pd.bind_thread(thread); } + + void assign_parent(Capability parent) override { + _pd.assign_parent(parent); } + + bool assign_pci(addr_t addr, uint16_t bdf) override { + return _pd.assign_pci(addr, bdf); } + + Signal_source_capability alloc_signal_source() override { + return _pd.alloc_signal_source(); } + + void free_signal_source(Signal_source_capability cap) override { + _pd.free_signal_source(cap); } + + Capability alloc_context(Signal_source_capability source, + unsigned long imprint) override { + return _pd.alloc_context(source, imprint); } + + void free_context(Capability cap) override { + _pd.free_context(cap); } + + void submit(Capability context, unsigned cnt) override { + _pd.submit(context, cnt); } + + Native_capability alloc_rpc_cap(Native_capability ep) override { + return _pd.alloc_rpc_cap(ep); } + + void free_rpc_cap(Native_capability cap) override { + _pd.free_rpc_cap(cap); } + + Capability address_space() override { + return _address_space.Rpc_object::cap(); } + + Capability stack_area() override { + return _stack_area.Rpc_object::cap(); } + + Capability linker_area() override { + return _linker_area.Rpc_object::cap(); } + + Capability native_pd() override { + return _pd.native_pd(); } +}; + +#endif /* _NOUX__PD_SESSION_COMPONENT_H_ */ diff --git a/repos/ports/src/noux/rm_session_component.h b/repos/ports/src/noux/region_map_component.h similarity index 59% rename from repos/ports/src/noux/rm_session_component.h rename to repos/ports/src/noux/region_map_component.h index d2f8d69313..8624c4b589 100644 --- a/repos/ports/src/noux/rm_session_component.h +++ b/repos/ports/src/noux/region_map_component.h @@ -1,55 +1,55 @@ /* - * \brief RM session implementation used by Noux processes + * \brief Region map implementation used by Noux processes * \author Norman Feske * \author Martin Stein * \date 2012-02-22 * - * The custom RM implementation is used for recording all RM regions attached - * to the region-manager session. Using the recorded information, the address- + * The custom region-map implementation is used for recording all regions + * attached to the region map. Using the recorded information, the address- * space layout can then be replayed onto a new process created via fork. */ /* - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ -#ifndef _NOUX__RM_SESSION_COMPONENT_H_ -#define _NOUX__RM_SESSION_COMPONENT_H_ +#ifndef _NOUX__REGION_MAP_COMPONENT_H_ +#define _NOUX__REGION_MAP_COMPONENT_H_ /* Genode includes */ -#include +#include #include #include +#include -namespace Noux -{ - static bool verbose_attach = false; +namespace Noux { class Region_map_component; } - /** - * Server sided back-end of an RM session of a Noux process - */ - class Rm_session_component; -} -class Noux::Rm_session_component : public Rpc_object +class Noux::Region_map_component : public Rpc_object, + public Dataspace_info { private: + static constexpr bool verbose_attach = false; + static constexpr bool verbose_replay = false; + + Rpc_entrypoint &_ep; + /** * Record of an attached dataspace */ struct Region : List::Element, Dataspace_user { - Rm_session_component &rm; + Region_map_component &rm; Dataspace_capability ds; size_t size; off_t offset; addr_t local_addr; - Region(Rm_session_component &rm, + Region(Region_map_component &rm, Dataspace_capability ds, size_t size, off_t offset, addr_t local_addr) : @@ -87,9 +87,11 @@ class Noux::Rm_session_component : public Rpc_object } /** - * Wrapped RM session at core + * Wrapped region map at core */ - Rm_connection _rm; + Region_map_client _rm; + + Pd_session_capability _pd; Dataspace_registry &_ds_registry; @@ -107,54 +109,56 @@ class Noux::Rm_session_component : public Rpc_object /** * Constructor + * + * \param pd protection domain the region map belongs to, used for + * quota upgrades + * \param rm region map at core */ - Rm_session_component(Dataspace_registry & ds_registry, - addr_t start = ~0UL, size_t size = 0) + Region_map_component(Rpc_entrypoint &ep, + Dataspace_registry &ds_registry, + Pd_session_capability pd, + Capability rm) : - _rm(start, size), _ds_registry(ds_registry) - { } + Dataspace_info(Region_map_client(rm).dataspace()), + _ep(ep), _rm(rm), _pd(pd), _ds_registry(ds_registry) + { + _ep.manage(this); + _ds_registry.insert(this); + } /** * Destructor */ - ~Rm_session_component() + ~Region_map_component() { + _ds_registry.remove(this); + _ep.dissolve(this); + Region *curr; while ((curr = _regions.first())) detach(curr->local_addr); } /** - * Return leaf RM session that covers a given address + * Return address where the specified dataspace is attached * - * \param addr address that is covered by the requested RM session + * This function is used by the 'Pd_session_component' to look up + * the base addresses for the stack area and linker area. */ - Rm_session_capability lookup_rm_session(addr_t const addr) + addr_t lookup_region_base(Dataspace_capability ds) { - /* if there's no region that could be a sub RM then we're a leaf */ - Region * const region = _lookup_region_by_addr(addr); - if (!region) { return cap(); } + Lock::Guard guard(_region_lock); - auto lambda = [&] (Dataspace_info *info) - { - /* if there is no info for the region it can't be a sub RM */ - if (!info) { return cap(); } - - /* ask the dataspace info for an appropriate sub RM */ - addr_t const region_base = region->local_addr; - addr_t const region_off = region->offset; - addr_t const sub_addr = addr - region_base + region_off; - Rm_session_capability sub_rm = info->lookup_rm_session(sub_addr); - - /* if the result is invalid the dataspace is no sub RM */ - if (!sub_rm.valid()) { return cap(); } - return sub_rm; - }; - return _ds_registry.apply(region->ds, lambda); + Region *curr = _regions.first(); + for (; curr; curr = curr->next_region()) { + if (curr->ds.local_name() == ds.local_name()) + return curr->local_addr; + } + return 0; } /** - * Replay attachments onto specified RM session + * Replay attachments onto specified region map * * \param dst_ram backing store used for allocating the * the copies of RAM dataspaces @@ -164,12 +168,13 @@ class Noux::Rm_session_component : public Rpc_object * of forked managed dataspaces */ void replay(Ram_session_capability dst_ram, - Rm_session_capability dst_rm, + Capability dst_rm, Dataspace_registry &ds_registry, Rpc_entrypoint &ep) { Lock::Guard guard(_region_lock); for (Region *curr = _regions.first(); curr; curr = curr->next_region()) { + auto lambda = [&] (Dataspace_info *info) { Dataspace_capability ds; @@ -186,7 +191,7 @@ class Noux::Rm_session_component : public Rpc_object } else { PWRN("replay: missing ds_info for dataspace at addr 0x%lx", - curr->local_addr); + curr->local_addr); /* * If the dataspace is not a RAM dataspace, assume that @@ -201,21 +206,186 @@ class Noux::Rm_session_component : public Rpc_object ds = curr->ds; } + /* + * The call of 'info->fork' returns a invalid dataspace + * capability for the stack area and linker area. Those + * region maps are directly replayed and attached in + * 'Pd_session_component::replay'. So we can skip them + * here. + */ if (!ds.valid()) { - PERR("replay: Error while forking dataspace"); + if (verbose_replay) + PWRN("replay: skip dataspace of region 0x%lx", + curr->local_addr); return; } - Rm_session_client(dst_rm).attach(ds, curr->size, - curr->offset, - true, - curr->local_addr); + Region_map_client(dst_rm).attach(ds, curr->size, + curr->offset, + true, + curr->local_addr); }; _ds_registry.apply(curr->ds, lambda); }; } - void poke(addr_t dst_addr, void const *src, size_t len) + + /************************** + ** Region_map interface ** + **************************/ + + Local_addr attach(Dataspace_capability ds, + size_t size = 0, off_t offset = 0, + bool use_local_addr = false, + Local_addr local_addr = (addr_t)0, + bool executable = false) override + { + /* + * Region map subtracts offset from size if size is 0 + */ + if (size == 0) size = Dataspace_client(ds).size() - offset; + + for (;;) { + try { + local_addr = _rm.attach(ds, size, offset, use_local_addr, + local_addr, executable); + break; + } catch (Region_map::Out_of_metadata) { + Genode::env()->parent()->upgrade(_pd, "ram_quota=8096"); + } + } + + Region * region = new (env()->heap()) + Region(*this, ds, size, offset, local_addr); + + /* register region as user of RAM dataspaces */ + auto lambda = [&] (Dataspace_info *info) + { + if (info) { + info->register_user(*region); + } else { + if (verbose_attach) { + PWRN("Trying to attach unknown dataspace type ds=%ld", ds.local_name()); + PWRN(" ds_info@%p at 0x%lx size=%zd offset=0x%lx", + info, (long)local_addr, + Dataspace_client(ds).size(), (long)offset); + } + } + }; + _ds_registry.apply(ds, lambda); + + /* + * Record attachment for later replay (needed during fork) + */ + Lock::Guard guard(_region_lock); + _regions.insert(region); + + return local_addr; + } + + void detach(Local_addr local_addr) override + { + Region * region = 0; + { + Lock::Guard guard(_region_lock); + region = _lookup_region_by_addr(local_addr); + if (!region) { + PWRN("Attempt to detach unknown region at 0x%p", + (void *)local_addr); + return; + } + + _regions.remove(region); + } + + _ds_registry.apply(region->ds, [&] (Dataspace_info *info) { + if (info) info->unregister_user(*region); }); + + destroy(env()->heap(), region); + + _rm.detach(local_addr); + + } + + Pager_capability add_client(Thread_capability thread) override + { + return retry( + [&] () { + Pager_capability cap = _rm.add_client(thread); + _last_pager = cap; + return cap; + }, [&] () { Genode::env()->parent()->upgrade(_pd, "ram_quota=8192"); }); + } + + void remove_client(Pager_capability pager) override + { + _rm.remove_client(pager); + } + + void fault_handler(Signal_context_capability handler) override + { + return _rm.fault_handler(handler); + } + + State state() override + { + return _rm.state(); + } + + Dataspace_capability dataspace() override + { + /* + * We cannot call '_rm.dataspace()' here because NOVA would + * hand out a capability that is unequal to the one we got + * during the construction of the 'Dataspace_info' base class. + * To work around this problem, we return the capability + * that is kept in the 'Dataspace_info'. + */ + return ds_cap(); + } + + + /****************************** + ** Dataspace_info interface ** + ******************************/ + + Dataspace_capability fork(Ram_session_capability ram, + Dataspace_registry &ds_registry, + Rpc_entrypoint &ep) override + { + return Dataspace_capability(); + } + + /** + * Return leaf region map that covers a given address + * + * \param addr address that is covered by the requested region map + */ + Capability lookup_region_map(addr_t const addr) override + { + /* if there's no region that could be a sub RM then we're a leaf */ + Region * const region = _lookup_region_by_addr(addr); + if (!region) { return Rpc_object::cap(); } + + auto lambda = [&] (Dataspace_info *info) + { + /* if there is no info for the region it can't be a sub RM */ + if (!info) { return Rpc_object::cap(); } + + /* ask the dataspace info for an appropriate sub RM */ + addr_t const region_base = region->local_addr; + addr_t const region_off = region->offset; + addr_t const sub_addr = addr - region_base + region_off; + Capability sub_rm = info->lookup_region_map(sub_addr); + + /* if the result is invalid the dataspace is no sub RM */ + if (!sub_rm.valid()) { return Rpc_object::cap(); } + return sub_rm; + }; + return _ds_registry.apply(region->ds, lambda); + } + + void poke(addr_t dst_addr, void const *src, size_t len) override { Dataspace_capability ds_cap; addr_t local_addr; @@ -255,123 +425,13 @@ class Noux::Rm_session_component : public Rpc_object info->poke(dst_addr - local_addr, src, len); }); } - - - /************************** - ** RM session interface ** - **************************/ - - Local_addr attach(Dataspace_capability ds, - size_t size = 0, off_t offset = 0, - bool use_local_addr = false, - Local_addr local_addr = (addr_t)0, - bool executable = false) - { - /* - * Rm_session subtracts offset from size if size is 0 - */ - if (size == 0) size = Dataspace_client(ds).size() - offset; - - for (;;) { - try { - local_addr = _rm.attach(ds, size, offset, use_local_addr, - local_addr, executable); - break; - } catch (Rm_session::Out_of_metadata) { - Genode::env()->parent()->upgrade(_rm, "ram_quota=8096"); - } - } - - Region * region = new (env()->heap()) - Region(*this, ds, size, offset, local_addr); - - /* register region as user of RAM dataspaces */ - auto lambda = [&] (Dataspace_info *info) - { - if (info) { - info->register_user(*region); - } else { - if (verbose_attach) { - PWRN("Trying to attach unknown dataspace type"); - PWRN(" ds_info@%p at 0x%lx size=%zd offset=0x%lx", - info, (long)local_addr, - Dataspace_client(ds).size(), (long)offset); - } - } - }; - _ds_registry.apply(ds, lambda); - - - /* - * Record attachment for later replay (needed during - * fork) - */ - Lock::Guard guard(_region_lock); - _regions.insert(region); - - return local_addr; - } - - void detach(Local_addr local_addr) - { - Region * region = 0; - { - Lock::Guard guard(_region_lock); - region = _lookup_region_by_addr(local_addr); - if (!region) { - PWRN("Attempt to detach unknown region at 0x%p", - (void *)local_addr); - return; - } - - _regions.remove(region); - } - - _ds_registry.apply(region->ds, [&] (Dataspace_info *info) { - if (info) info->unregister_user(*region); }); - - destroy(env()->heap(), region); - - _rm.detach(local_addr); - - } - - Pager_capability add_client(Thread_capability thread) - { - return retry( - [&] () { - Pager_capability cap = _rm.add_client(thread); - _last_pager = cap; - return cap; - }, [&] () { Genode::env()->parent()->upgrade(_rm, "ram_quota=8192"); }); - } - - void remove_client(Pager_capability pager) - { - _rm.remove_client(pager); - } - - void fault_handler(Signal_context_capability handler) - { - return _rm.fault_handler(handler); - } - - State state() - { - return _rm.state(); - } - - Dataspace_capability dataspace() - { - return _rm.dataspace(); - } }; -inline void Noux::Rm_session_component::Region::dissolve(Dataspace_info &ds) +inline void Noux::Region_map_component::Region::dissolve(Dataspace_info &ds) { rm.detach(local_addr); } -#endif /* _NOUX__RM_SESSION_COMPONENT_H_ */ +#endif /* _NOUX__REGION_MAP_COMPONENT_H_ */ diff --git a/repos/ports/src/virtualbox/mm.cc b/repos/ports/src/virtualbox/mm.cc index b50643f3c7..8e43382fcb 100644 --- a/repos/ports/src/virtualbox/mm.cc +++ b/repos/ports/src/virtualbox/mm.cc @@ -15,6 +15,7 @@ #include #include #include +#include /* VirtualBox includes */ #include @@ -40,7 +41,8 @@ * internally pointers at several places in base + offset, whereby offset is * a int32_t type. */ -class Sub_rm_connection : public Genode::Rm_connection +class Sub_rm_connection : private Genode::Rm_connection, + public Genode::Region_map_client { private: @@ -52,7 +54,7 @@ class Sub_rm_connection : public Genode::Rm_connection Sub_rm_connection(Genode::size_t size) : - Genode::Rm_connection(0, size), + Genode::Region_map_client(Rm_connection::create(size)), _offset(Genode::env()->rm_session()->attach(dataspace())), _size(size) { } @@ -63,9 +65,9 @@ class Sub_rm_connection : public Genode::Rm_connection Local_addr local_addr = (void *)0, bool executable = false) { - Local_addr addr = Rm_connection::attach(ds, size, offset, - use_local_addr, local_addr, - executable); + Local_addr addr = Region_map_client::attach(ds, size, offset, + use_local_addr, local_addr, + executable); Genode::addr_t new_addr = addr; new_addr += _offset; return Local_addr(new_addr); diff --git a/repos/ports/src/virtualbox/vmm_memory.h b/repos/ports/src/virtualbox/vmm_memory.h index 52cb6247c5..e04023a30b 100644 --- a/repos/ports/src/virtualbox/vmm_memory.h +++ b/repos/ports/src/virtualbox/vmm_memory.h @@ -27,6 +27,7 @@ #include #include #include +#include #define PAGE_SIZE BACKUP_PAGESIZE @@ -39,14 +40,16 @@ class Vmm_memory struct Region; typedef Genode::Ram_session Ram_session; - typedef Genode::Rm_session Rm_session; + typedef Genode::Region_map Region_map; typedef Genode::size_t size_t; typedef Genode::Lock Lock; typedef Genode::List Region_list; private: - struct Region : Region_list::Element, Genode::Rm_connection + struct Region : public Region_list::Element, + private Genode::Rm_connection, + public Genode::Region_map_client { PPDMDEVINS pDevIns; unsigned const iRegion; @@ -61,11 +64,11 @@ class Vmm_memory Region(Ram_session &ram, size_t size, PPDMDEVINS pDevIns, unsigned iRegion, unsigned sub_rm_max_ds = 32 * 1024 * 1024) : - Rm_connection(0, size), + Region_map_client(Rm_connection::create(size)), pDevIns(pDevIns), iRegion(iRegion), vm_phys(0), pfnHandlerR3(0), pvUserR3(0), - _base(Genode::env()->rm_session()->attach(Rm_connection::dataspace())), + _base(Genode::env()->rm_session()->attach(Region_map_client::dataspace())), _size(size) { Genode::addr_t rest_size = _size; @@ -119,7 +122,7 @@ class Vmm_memory /** * \throw Ram_session::Alloc_failed - * \throw Rm_session::Attach_failed + * \throw Region_map::Attach_failed */ void *alloc(size_t cb, PPDMDEVINS pDevIns, unsigned iRegion) { @@ -135,7 +138,7 @@ class Vmm_memory } catch (Ram_session::Alloc_failed) { PERR("Vmm_memory::alloc(0x%zx): RAM allocation failed", cb); throw; - } catch (Rm_session::Attach_failed) { + } catch (Region_map::Attach_failed) { PERR("Vmm_memory::alloc(0x%zx): RM attach failed", cb); throw; }