From 511acad5074878bbaae46ae0aebab1b52fbb97b1 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Fri, 15 Apr 2016 15:19:22 +0200 Subject: [PATCH] Consolidate RM service into PD session This patch integrates three region maps into each PD session to reduce the session overhead and to simplify the PD creation procedure. Please refer to the issue cited below for an elaborative discussion. Note the API change: With this patch, the semantics of core's RM service have changed. Now, the service is merely a tool for creating and destroying managed dataspaces, which are rarely needed. Regular components no longer need a RM session. For this reason, the corresponding argument for the 'Process' and 'Child' constructors has been removed. The former interface of the 'Rm_session' is not named 'Region_map'. As a minor refinement, the 'Fault_type' enum values are now part of the 'Region_map::State' struct. Issue #1938 --- repos/base-fiasco/lib/mk/base-common.mk | 1 + .../src/core/include/platform_pd.h | 2 +- .../src/core/include/platform_thread.h | 9 + repos/base-fiasco/src/core/include/util.h | 6 +- ...ssion_support.cc => region_map_support.cc} | 0 repos/base-fiasco/src/core/target.inc | 6 +- repos/base-foc/lib/mk/base-common.inc | 1 + .../base-foc/src/base/thread/thread_start.cc | 8 +- repos/base-foc/src/core/include/platform_pd.h | 2 +- .../src/core/include/platform_thread.h | 9 + repos/base-foc/src/core/include/util.h | 4 +- ...ssion_support.cc => region_map_support.cc} | 0 repos/base-foc/src/core/target.inc | 6 +- repos/base-hw/include/pd_session/connection.h | 42 - repos/base-hw/lib/mk/base-common.inc | 1 + repos/base-hw/lib/mk/core.inc | 6 +- repos/base-hw/src/base/thread/start.cc | 9 +- ...{core_rm_session.cc => core_region_map.cc} | 8 +- .../src/core/include/core_region_map.h | 57 ++ .../src/core/include/core_rm_session.h | 61 -- repos/base-hw/src/core/include/platform.h | 2 +- repos/base-hw/src/core/include/util.h | 6 +- ...ssion_support.cc => region_map_support.cc} | 0 repos/base-linux/lib/mk/base-common.mk | 3 +- ...m_session_mmap.run => region_map_mmap.run} | 6 +- repos/base-linux/src/base/env/platform_env.cc | 36 +- ...{rm_session_mmap.cc => region_map_mmap.cc} | 36 +- repos/base-linux/src/base/process/process.cc | 4 +- .../base-linux/src/base/region_map_client.cc | 77 ++ .../base-linux/src/base/rm_session_client.cc | 47 +- .../src/core/include/region_map_component.h | 74 ++ .../src/core/include/rm_session_component.h | 78 -- repos/base-linux/src/core/platform.cc | 16 +- repos/base-linux/src/core/stack_area.cc | 13 +- .../src/include/base/internal/platform_env.h | 811 +++++++++--------- .../src/include/base/internal/stack_area.h | 4 +- repos/base-linux/src/test/lx_rmap/main.cc | 13 +- .../main.cc | 2 +- .../target.mk | 2 +- repos/base-nova/lib/mk/base-common.mk | 1 + ...session_client.cc => region_map_client.cc} | 24 +- ...{core_rm_session.cc => core_region_map.cc} | 12 +- .../src/core/include/core_region_map.h | 56 ++ .../src/core/include/core_rm_session.h | 56 -- .../src/core/include/platform_thread.h | 9 + repos/base-nova/src/core/include/util.h | 4 +- repos/base-nova/src/core/pager.cc | 18 +- repos/base-nova/src/core/platform.cc | 3 +- ...ssion_support.cc => region_map_support.cc} | 2 +- repos/base-nova/src/core/target.inc | 8 +- repos/base-nova/src/test/platform/main.cc | 10 +- repos/base-okl4/lib/mk/base-common.mk | 1 + ...{core_rm_session.cc => core_region_map.cc} | 10 +- .../src/core/include/core_region_map.h | 56 ++ .../src/core/include/core_rm_session.h | 60 -- repos/base-okl4/src/core/include/platform.h | 2 +- repos/base-okl4/src/core/include/util.h | 4 +- ...ssion_support.cc => region_map_support.cc} | 4 +- repos/base-okl4/src/core/target.inc | 8 +- repos/base-pistachio/lib/mk/base-common.mk | 1 + .../src/core/include/platform_pd.h | 2 +- .../src/core/include/platform_thread.h | 9 + repos/base-pistachio/src/core/include/util.h | 4 +- ...ssion_support.cc => region_map_support.cc} | 2 +- repos/base-pistachio/src/core/target.inc | 6 +- .../base-sel4/include/pd_session/connection.h | 39 - repos/base-sel4/lib/mk/base-common.inc | 1 + repos/base-sel4/lib/mk/core.mk | 8 +- ...{core_rm_session.cc => core_region_map.cc} | 10 +- .../{core_rm_session.h => core_region_map.h} | 10 +- .../src/core/include/platform_thread.h | 9 + repos/base-sel4/src/core/include/util.h | 4 +- ...ssion_support.cc => region_map_support.cc} | 2 +- repos/base-sel4/src/core/stack_area.cc | 11 +- repos/base/include/base/child.h | 16 +- repos/base/include/base/component.h | 4 +- repos/base/include/base/env.h | 12 +- repos/base/include/base/heap.h | 34 +- repos/base/include/base/process.h | 5 +- repos/base/include/pager/capability.h | 2 +- repos/base/include/pd_session/client.h | 9 + repos/base/include/pd_session/connection.h | 2 +- repos/base/include/pd_session/pd_session.h | 37 +- repos/base/include/ram_session/connection.h | 3 +- repos/base/include/region_map/client.h | 57 ++ repos/base/include/region_map/region_map.h | 210 +++++ repos/base/include/rm_session/client.h | 40 +- repos/base/include/rm_session/connection.h | 12 +- repos/base/include/rm_session/rm_session.h | 205 +---- repos/base/run/mp_server.run | 2 +- repos/base/run/rm_nested.run | 33 + repos/base/run/thread.run | 2 +- repos/base/src/base/child/child.cc | 13 +- repos/base/src/base/component/component.cc | 2 +- repos/base/src/base/env/reinitialize.cc | 8 +- repos/base/src/base/env/stack_area.cc | 2 +- repos/base/src/base/heap/heap.cc | 8 +- repos/base/src/base/heap/sliced_heap.cc | 10 +- repos/base/src/base/process/process.cc | 27 +- repos/base/src/base/region_map_client.cc | 54 ++ repos/base/src/base/rm_session_client.cc | 35 +- repos/base/src/base/thread/thread.cc | 8 +- repos/base/src/base/thread/thread_start.cc | 6 +- repos/base/src/core/dataspace_component.cc | 4 +- repos/base/src/core/include/core_env.h | 12 +- repos/base/src/core/include/core_pd_session.h | 6 + repos/base/src/core/include/core_region_map.h | 65 ++ repos/base/src/core/include/core_rm_session.h | 68 -- .../src/core/include/dataspace_component.h | 4 +- repos/base/src/core/include/pd_root.h | 17 +- .../src/core/include/pd_session_component.h | 36 +- .../src/core/include/region_map_component.h | 401 +++++++++ repos/base/src/core/include/rm_root.h | 125 +-- .../src/core/include/rm_session_component.h | 421 ++------- repos/base/src/core/main.cc | 23 +- repos/base/src/core/pd_session_component.cc | 3 +- ...n_component.cc => region_map_component.cc} | 365 ++++---- repos/base/src/core/stack_area.cc | 10 +- .../src/include/base/internal/platform_env.h | 16 +- .../base/internal/platform_env_common.h | 56 +- repos/base/src/lib/ldso/file.cc | 57 +- .../base/src/lib/startup/init_main_thread.cc | 2 +- repos/base/src/test/rm_fault/main.cc | 35 +- repos/base/src/test/rm_nested/main.cc | 59 +- repos/base/src/test/rm_nested/target.mk | 7 +- repos/base/src/test/sub_rm/main.cc | 13 +- repos/dde_bsd/src/lib/audio/mem.cc | 8 +- .../dde_ipxe/src/lib/dde_ipxe/dde_support.cc | 8 +- .../impl/internal/mapped_io_mem_range.h | 8 +- .../impl/internal/slab_backend_alloc.h | 8 +- repos/dde_linux/src/lib/lxip/lxcc_emul.cc | 11 +- repos/dde_linux/src/lib/usb/lx_emul.cc | 11 +- repos/dde_linux/src/lib/wifi/lxcc_emul.cc | 8 +- repos/dde_rump/include/util/allocator_fap.h | 14 +- repos/demo/include/launchpad/launchpad.h | 8 +- repos/demo/src/lib/launchpad/launchpad.cc | 16 +- repos/libports/ports/qt5.hash | 2 +- repos/libports/run/ldso.run | 2 + repos/libports/src/lib/libc/libc_mem_alloc.cc | 6 +- repos/libports/src/lib/libc/libc_mem_alloc.h | 20 +- .../src/lib/qt5/patches/qt5_qml.patch | 47 +- repos/libports/src/test/ldso/lib_1.cc | 2 +- repos/libports/src/test/ldso/main.cc | 2 +- repos/os/include/cli_monitor/child.h | 4 +- repos/os/include/init/child.h | 5 +- repos/os/include/init/child_config.h | 2 +- repos/os/include/os/slave.h | 3 +- repos/os/run/report_rom.run | 2 + repos/os/run/rom_filter.run | 2 + repos/os/src/drivers/acpi/memory.h | 14 +- .../platform/spec/x86/device_pd/main.cc | 39 +- .../platform/spec/x86/pci_session_component.h | 9 +- repos/os/src/drivers/timer/main.cc | 2 +- repos/os/src/server/iso9660/main.cc | 2 +- repos/os/src/server/loader/child.h | 20 +- repos/os/src/server/loader/main.cc | 26 +- repos/os/src/test/bomb/main.cc | 4 +- repos/os/src/test/fault_detection/main.cc | 8 +- repos/ports-foc/run/l4linux.run | 4 +- .../src/lib/l4lx/include/dataspace.h | 47 +- .../src/lib/l4lx/include/platform_env.h | 27 - repos/ports-foc/src/lib/l4lx/rm.cc | 15 +- repos/ports/include/noux_session/client.h | 4 +- .../ports/include/noux_session/noux_session.h | 14 +- repos/ports/include/vmm/guest_memory.h | 7 +- repos/ports/include/vmm/vcpu_thread.h | 6 +- repos/ports/run/noux_fork.run | 2 +- repos/ports/run/vbox_win.inc | 2 +- repos/ports/run/virtualbox_auto.inc | 4 +- repos/ports/src/app/gdb_monitor/app_child.h | 63 +- .../src/app/gdb_monitor/dataspace_object.h | 17 +- .../src/app/gdb_monitor/gdb_stub_thread.cc | 2 +- .../src/app/gdb_monitor/gdb_stub_thread.h | 10 +- .../app/gdb_monitor/gdbserver/genode-low.cc | 21 +- .../app/gdb_monitor/pd_session_component.h | 111 +++ ...n_component.cc => region_map_component.cc} | 76 +- ...ion_component.h => region_map_component.h} | 30 +- repos/ports/src/app/gdb_monitor/rm_root.h | 65 -- repos/ports/src/app/gdb_monitor/target.mk | 2 +- repos/ports/src/lib/libc_noux/plugin.cc | 9 +- repos/ports/src/noux/child.h | 30 +- repos/ports/src/noux/child_policy.h | 12 - repos/ports/src/noux/dataspace_registry.h | 10 +- repos/ports/src/noux/local_rm_service.h | 162 ---- repos/ports/src/noux/main.cc | 4 +- repos/ports/src/noux/pd_session_component.h | 149 ++++ ...ion_component.h => region_map_component.h} | 396 +++++---- repos/ports/src/virtualbox/mm.cc | 12 +- repos/ports/src/virtualbox/vmm_memory.h | 15 +- 189 files changed, 3314 insertions(+), 2934 deletions(-) rename repos/base-fiasco/src/core/{rm_session_support.cc => region_map_support.cc} (100%) rename repos/base-foc/src/core/{rm_session_support.cc => region_map_support.cc} (100%) delete mode 100644 repos/base-hw/include/pd_session/connection.h rename repos/base-hw/src/core/{core_rm_session.cc => core_region_map.cc} (91%) create mode 100644 repos/base-hw/src/core/include/core_region_map.h delete mode 100644 repos/base-hw/src/core/include/core_rm_session.h rename repos/base-hw/src/core/{rm_session_support.cc => region_map_support.cc} (100%) rename repos/base-linux/run/{rm_session_mmap.run => region_map_mmap.run} (83%) rename repos/base-linux/src/base/env/{rm_session_mmap.cc => region_map_mmap.cc} (90%) create mode 100644 repos/base-linux/src/base/region_map_client.cc create mode 100644 repos/base-linux/src/core/include/region_map_component.h delete mode 100644 repos/base-linux/src/core/include/rm_session_component.h rename repos/base-linux/src/test/{rm_session_mmap => region_map_mmap}/main.cc (95%) rename repos/base-linux/src/test/{rm_session_mmap => region_map_mmap}/target.mk (50%) rename repos/base-nova/src/base/{rm_session_client.cc => region_map_client.cc} (55%) rename repos/base-nova/src/core/{core_rm_session.cc => core_region_map.cc} (90%) create mode 100644 repos/base-nova/src/core/include/core_region_map.h delete mode 100644 repos/base-nova/src/core/include/core_rm_session.h rename repos/base-nova/src/core/{rm_session_support.cc => region_map_support.cc} (94%) rename repos/base-okl4/src/core/{core_rm_session.cc => core_region_map.cc} (85%) create mode 100644 repos/base-okl4/src/core/include/core_region_map.h delete mode 100644 repos/base-okl4/src/core/include/core_rm_session.h rename repos/base-okl4/src/core/{rm_session_support.cc => region_map_support.cc} (85%) rename repos/base-pistachio/src/core/{rm_session_support.cc => region_map_support.cc} (95%) delete mode 100644 repos/base-sel4/include/pd_session/connection.h rename repos/base-sel4/src/core/{core_rm_session.cc => core_region_map.cc} (87%) rename repos/base-sel4/src/core/include/{core_rm_session.h => core_region_map.h} (83%) rename repos/base-sel4/src/core/{rm_session_support.cc => region_map_support.cc} (88%) create mode 100644 repos/base/include/region_map/client.h create mode 100644 repos/base/include/region_map/region_map.h create mode 100644 repos/base/run/rm_nested.run create mode 100644 repos/base/src/base/region_map_client.cc create mode 100644 repos/base/src/core/include/core_region_map.h delete mode 100644 repos/base/src/core/include/core_rm_session.h create mode 100644 repos/base/src/core/include/region_map_component.h rename repos/base/src/core/{rm_session_component.cc => region_map_component.cc} (68%) create mode 100644 repos/ports/src/app/gdb_monitor/pd_session_component.h rename repos/ports/src/app/gdb_monitor/{rm_session_component.cc => region_map_component.cc} (57%) rename repos/ports/src/app/gdb_monitor/{rm_session_component.h => region_map_component.h} (77%) delete mode 100644 repos/ports/src/app/gdb_monitor/rm_root.h delete mode 100644 repos/ports/src/noux/local_rm_service.h create mode 100644 repos/ports/src/noux/pd_session_component.h rename repos/ports/src/noux/{rm_session_component.h => region_map_component.h} (59%) diff --git a/repos/base-fiasco/lib/mk/base-common.mk b/repos/base-fiasco/lib/mk/base-common.mk index 2920278b0..a0a4c7daa 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 6878e1369..a6ae468a1 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 52330036e..4d157f152 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 6f927b154..23c729025 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 a087fb25a..85266de73 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 5c2ecd633..30b7d61d2 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 ae337590b..8aee5ecc5 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 7a19ee477..b80343efe 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 b200b0362..6564de489 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 45388fd21..50a264b56 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 7e8d67f09..68fff8597 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 1d42c5a40..000000000 --- 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 570bd1c73..b371cfa03 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 9912106da..75420f562 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 3341b42dc..178ac5eb9 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 398c8f014..1ad0c25f8 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 000000000..176cf06d0 --- /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 58a7e000a..000000000 --- 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 6b68a03ef..25b267caf 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 bfdd0499a..9704d862c 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 18575c461..e73a0e629 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 6ac885b2c..3dde49d0c 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 12afea271..5e91ac7ac 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 ab0cb00a3..3a6d375b1 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 074d90717..7515f6854 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 000000000..e5ee05537 --- /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 6cc58eba5..a5826866a 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 000000000..5942112c2 --- /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 09479ae61..000000000 --- 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 9467c06d6..85b0f4356 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 95f47c1af..ee830177f 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 7b3892fc6..70e4a8e17 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 8c3066249..76f7f4a32 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 6f8cedebd..33f31384d 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 7ec6b0af1..2aeeca07e 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 158a12112..5f55e7dea 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 48b53b96e..5109da58c 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 0f2b3bcb4..5f252691c 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 212949737..23b006ca2 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 000000000..9f995243c --- /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 ed7c48466..000000000 --- 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 820d7c869..899e3c90b 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 3e24d0882..7dbf9ea46 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 3f4e656d4..0e73d8eca 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 52ee95b5c..5c603f165 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 b422106c8..5cfa91bc8 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 8d06bb0ec..c92a1a0b5 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 490143513..0df899c3f 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 2920278b0..a0a4c7daa 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 4bc93e081..509d012d8 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 000000000..1343c2225 --- /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 f89eda67a..000000000 --- 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 df33f0621..c35be27bf 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 cd61c9712..e30fb51c0 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 49fddeb1a..94710d37e 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 014c44bda..ecc1f4971 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 7717bb813..93b7ee797 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 c5cb994f9..2f4500a66 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 a7e622d99..220a5863b 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 a18d39282..e5f601b13 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 8130d0bff..ab15abac1 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 ef57fe5b6..a55d4c80b 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 ff88ee8db..000000000 --- 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 9c6cd6ae0..1db231895 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 004b095e3..5e9d1e5ba 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 428522e3a..75415a33c 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 3507c5c48..a58d16d09 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 ee62c294e..1f5b6cb7c 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 9c7f52a30..6607845de 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 e1ecd12b2..ae88da3a5 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 de5ce48ac..6d455c78e 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 496562095..e79a78b2f 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 030b50336..a7e2f8491 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 b6920c184..be18e1e7e 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 982f6f297..4b92131b2 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 700f8eb60..cc972a8ee 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 7c57614f1..cec4dff61 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 d8971849f..ab42423d7 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 9280547a0..6eee00fe2 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 b819d834d..c2974c65c 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 60089aabb..bd79e8a27 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 000000000..48e790b0f --- /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 000000000..d1987a577 --- /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 6065ae324..aa5ee57d0 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 88afd1173..9fc2f0b22 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 baa139a12..e93266805 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 ad143eb47..91f34725f 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 000000000..0c23669da --- /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 71fd4f61a..0dc3eb697 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 5ad4ae075..2469dea6b 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 5cd12f21b..4a224685f 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 e0b7b0981..7bca94e84 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 34c6b40d0..416cf7e61 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 49b0f73f5..0288b4410 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 44264f7e9..7d7f88a5c 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 6a83dbf31..7d5d37225 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 000000000..181cf13cf --- /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 b5a19694c..ce7ff7e0d 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 f07548aed..62245deb1 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 b0b9a5c05..6548ab775 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 1567ac1a5..21e3dee3f 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 20d109fc6..fdc0e5ed3 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 26b4ba8bc..37abd8428 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 000000000..dc52bdd0f --- /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 7cafff5a5..000000000 --- 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 5a9a14fd2..e112da4f9 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 6c0d9c572..185aeb95b 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 61a6fd205..2feb7f6a4 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 000000000..298c8899d --- /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 4e5affa5a..850a8c5b7 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 3c919127f..df16fe97a 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 70b5eecbb..0135038ac 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 efdd30177..548800ea3 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 433b30873..9dc3c005b 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 c3960cc10..b264d59ae 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 72cb5141c..24b140abd 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 1db60c4a6..a8913e434 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 3c42844e2..6df2c54c2 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 b28a93be2..bd3118870 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 4be95adff..59fca09bd 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 525f2c9ca..dff4b6a45 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 4d5f2a156..3ba1b099e 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 808c52e15..d65d75f15 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 29233c8f9..207474f17 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 9e3a9adf7..b577ed269 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 ba5d4768c..0b2dcbd33 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 e36ee91ae..b4a548578 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 7c0782c3f..f7257a813 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 04cf17ebb..5d5490d7e 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 79f46c75d..2b5506bd3 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 8f6578e29..9ad7a10a9 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 9aa0ed579..06b1ce948 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 d60ad5162..4fc403511 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 26e70c0d8..228779fba 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 fc48912e6..fe9154816 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 b211df91d..6dd0b7d90 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 5e9ad5480..4f9e3122a 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 9e02f63ac..06cd7038d 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 3ffd76ea8..3846d6d1b 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 1cf6e4a7f..5ce4baa54 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 bd9bec541..e1afd24c9 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 a02e12d95..2087d1fe9 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 4ebf759e2..76f8a345b 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 bdf9a6326..edd2b2764 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 332b97558..aa3dab01f 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 035cb7486..1c4ddb259 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 3503b9bc6..a373817fe 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 712003ad4..bb2896769 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 b5beed2ef..eb134f5c7 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 87c46e67b..a66fa1710 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 5f1b04e9d..39611e1b9 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 d92d366b1..41bb3a06d 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 d8fee9480..172d4b35e 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 ea9ab5fb2..1d6b5e78c 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 af6559326..c77f07d4c 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 a7ec92403..bc56aa079 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 f88f1147c..20b680308 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 ee1cec1f5..4ffcc1e75 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 2a21c4a53..0bca5a3ce 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 b43cc0c8e..8be0b456f 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 fdae49a54..d706347d3 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 962a34424..553b890c4 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 ea2d68f09..6727afd4f 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 0de92d7aa..9c33e3632 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 0462824fe..a52a14377 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 9ca558e6a..a589954ec 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 368897ffa..ef789e233 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 f7dbb9732..af239e7f6 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 ef0c5f475..b9e722999 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 9548e8862..6c3fafdac 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 2a2a0c6ff..cac441e80 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 000000000..bd7abcd1d --- /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 02f9e72c5..9e3b90aab 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 e99ed62e9..2fdbc6e3e 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 453cb1a4e..000000000 --- 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 a763436d9..81d782b37 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 7f6d2d5b1..18e3783b5 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 c1e33a967..d4241e0fa 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 afbe307d7..512139091 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 cc44905f9..c42bfa5d1 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 328fab883..000000000 --- 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 c80697e90..c6756bbce 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 000000000..b98be9b4f --- /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 d2f8d6931..8624c4b58 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 b50643f3c..8e43382fc 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 52cb6247c..e04023a30 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; }