diff --git a/repos/base-fiasco/lib/mk/core-fiasco.inc b/repos/base-fiasco/lib/mk/core-fiasco.inc index f8c89da330..1223cad37e 100644 --- a/repos/base-fiasco/lib/mk/core-fiasco.inc +++ b/repos/base-fiasco/lib/mk/core-fiasco.inc @@ -23,6 +23,7 @@ SRC_CC += stack_area.cc \ pager_object.cc \ pd_session_component.cc \ rpc_cap_factory_l4.cc \ + ram_dataspace_factory.cc \ pd_assign_pci.cc \ pd_upgrade_ram_quota.cc \ platform.cc \ @@ -30,7 +31,7 @@ SRC_CC += stack_area.cc \ platform_services.cc \ platform_thread.cc \ ram_session_component.cc \ - ram_session_support.cc \ + ram_dataspace_support.cc \ region_map_component.cc \ region_map_support.cc \ rom_session_component.cc \ @@ -59,6 +60,7 @@ vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) vpath capability_space.cc $(GEN_CORE_DIR) vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) +vpath ram_dataspace_factory.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath core_region_map.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) diff --git a/repos/base-fiasco/src/core/ram_session_support.cc b/repos/base-fiasco/src/core/ram_dataspace_support.cc similarity index 69% rename from repos/base-fiasco/src/core/ram_session_support.cc rename to repos/base-fiasco/src/core/ram_dataspace_support.cc index 78c47abf1b..489f72fe48 100644 --- a/repos/base-fiasco/src/core/ram_session_support.cc +++ b/repos/base-fiasco/src/core/ram_dataspace_support.cc @@ -14,14 +14,14 @@ * under the terms of the GNU Affero General Public License version 3. */ -#include "ram_session_component.h" +#include using namespace Genode; -void Ram_session_component::_export_ram_ds(Dataspace_component *ds) { } -void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { } +void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *ds) { } +void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component *ds) { } -void Ram_session_component::_clear_ds(Dataspace_component *ds) +void Ram_dataspace_factory::_clear_ds(Dataspace_component *ds) { memset((void *)ds->phys_addr(), 0, ds->size()); } diff --git a/repos/base-foc/lib/mk/core-foc.inc b/repos/base-foc/lib/mk/core-foc.inc index 98930fc702..3fbd42874a 100644 --- a/repos/base-foc/lib/mk/core-foc.inc +++ b/repos/base-foc/lib/mk/core-foc.inc @@ -29,7 +29,8 @@ SRC_CC += stack_area.cc \ platform_services.cc \ platform_thread.cc \ ram_session_component.cc \ - ram_session_support.cc \ + ram_dataspace_support.cc \ + ram_dataspace_factory.cc \ region_map_component.cc \ region_map_support.cc \ rom_session_component.cc \ @@ -63,6 +64,7 @@ vpath ram_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 ram_dataspace_factory.cc $(GEN_CORE_DIR) vpath signal_transmitter_proxy.cc $(GEN_CORE_DIR) vpath signal_receiver.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) diff --git a/repos/base-foc/src/core/platform.cc b/repos/base-foc/src/core/platform.cc index ca282a1996..6034a2c4bd 100644 --- a/repos/base-foc/src/core/platform.cc +++ b/repos/base-foc/src/core/platform.cc @@ -25,7 +25,6 @@ /* core includes */ #include -#include #include #include #include diff --git a/repos/base-foc/src/core/ram_session_support.cc b/repos/base-foc/src/core/ram_dataspace_support.cc similarity index 73% rename from repos/base-foc/src/core/ram_session_support.cc rename to repos/base-foc/src/core/ram_dataspace_support.cc index 75bec3d731..5e3dd97efa 100644 --- a/repos/base-foc/src/core/ram_session_support.cc +++ b/repos/base-foc/src/core/ram_dataspace_support.cc @@ -12,7 +12,7 @@ */ /* core-local includes */ -#include +#include #include namespace Fiasco { @@ -21,11 +21,11 @@ namespace Fiasco { using namespace Genode; -void Ram_session_component::_export_ram_ds(Dataspace_component *ds) { } -void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { } +void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *ds) { } +void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component *ds) { } -void Ram_session_component::_clear_ds(Dataspace_component *ds) +void Ram_dataspace_factory::_clear_ds(Dataspace_component *ds) { memset((void *)ds->phys_addr(), 0, ds->size()); diff --git a/repos/base-hw/lib/mk/core-hw.inc b/repos/base-hw/lib/mk/core-hw.inc index 72974919e4..1627994bb7 100644 --- a/repos/base-hw/lib/mk/core-hw.inc +++ b/repos/base-hw/lib/mk/core-hw.inc @@ -37,11 +37,12 @@ SRC_CC += platform_pd.cc SRC_CC += platform_thread.cc SRC_CC += stack_area.cc SRC_CC += ram_session_component.cc -SRC_CC += ram_session_support.cc +SRC_CC += ram_dataspace_support.cc SRC_CC += region_map_component.cc SRC_CC += rom_session_component.cc SRC_CC += trace_session_component.cc SRC_CC += signal_receiver.cc +SRC_CC += ram_dataspace_factory.cc SRC_CC += signal_transmitter_noinit.cc SRC_CC += thread_start.cc SRC_CC += env.cc diff --git a/repos/base-hw/src/core/platform.cc b/repos/base-hw/src/core/platform.cc index f72c6e4905..926668ec57 100644 --- a/repos/base-hw/src/core/platform.cc +++ b/repos/base-hw/src/core/platform.cc @@ -18,7 +18,6 @@ /* core includes */ #include #include -#include #include #include #include diff --git a/repos/base-hw/src/core/ram_session_support.cc b/repos/base-hw/src/core/ram_dataspace_support.cc similarity index 85% rename from repos/base-hw/src/core/ram_session_support.cc rename to repos/base-hw/src/core/ram_dataspace_support.cc index c15d2614fe..4208202639 100644 --- a/repos/base-hw/src/core/ram_session_support.cc +++ b/repos/base-hw/src/core/ram_dataspace_support.cc @@ -5,7 +5,7 @@ * \date 2012-02-12 * * TODO: this file is almost identical to - * base-okl4/src/core/ram_session_support.cc, we should merge them + * base-okl4/src/core/ram_dataspace_support.cc, we should merge them */ /* @@ -19,16 +19,16 @@ #include /* core includes */ -#include +#include #include #include using namespace Genode; -void Ram_session_component::_export_ram_ds(Dataspace_component *ds) { } -void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { } +void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *ds) { } +void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component *ds) { } -void Ram_session_component::_clear_ds (Dataspace_component * ds) +void Ram_dataspace_factory::_clear_ds (Dataspace_component * ds) { size_t page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask(); diff --git a/repos/base-linux/src/core/linux/target.mk b/repos/base-linux/src/core/linux/target.mk index 3e8efc23ee..fe5fce4b55 100644 --- a/repos/base-linux/src/core/linux/target.mk +++ b/repos/base-linux/src/core/linux/target.mk @@ -9,7 +9,7 @@ SRC_CC = main.cc \ platform_thread.cc \ platform_services.cc \ ram_session_component.cc \ - ram_session_support.cc \ + ram_dataspace_support.cc \ rom_session_component.cc \ cpu_session_component.cc \ cpu_session_support.cc \ @@ -21,6 +21,7 @@ SRC_CC = main.cc \ native_cpu_component.cc \ capability_space.cc \ rpc_cap_factory_l4.cc \ + ram_dataspace_factory.cc \ core_rpc_cap_alloc.cc \ io_mem_session_component.cc \ signal_source_component.cc \ @@ -54,6 +55,7 @@ vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath capability_space.cc $(GEN_CORE_DIR) vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) +vpath ram_dataspace_factory.cc $(GEN_CORE_DIR) vpath platform_services.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) vpath signal_transmitter_proxy.cc $(GEN_CORE_DIR) diff --git a/repos/base-linux/src/core/ram_session_support.cc b/repos/base-linux/src/core/ram_dataspace_support.cc similarity index 87% rename from repos/base-linux/src/core/ram_session_support.cc rename to repos/base-linux/src/core/ram_dataspace_support.cc index 6bfe7ccba1..116210643d 100644 --- a/repos/base-linux/src/core/ram_session_support.cc +++ b/repos/base-linux/src/core/ram_dataspace_support.cc @@ -18,7 +18,7 @@ #include /* local includes */ -#include +#include #include /* base-internal includes */ @@ -33,7 +33,7 @@ using namespace Genode; static int ram_ds_cnt = 0; /* counter for creating unique dataspace IDs */ -void Ram_session_component::_export_ram_ds(Dataspace_component *ds) +void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *ds) { char fname[Linux_dataspace::FNAME_LEN]; @@ -56,7 +56,7 @@ void Ram_session_component::_export_ram_ds(Dataspace_component *ds) } -void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) +void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component *ds) { int const fd = Capability_space::ipc_cap_data(ds->fd()).dst.socket; if (fd != -1) @@ -64,4 +64,4 @@ void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) } -void Ram_session_component::_clear_ds(Dataspace_component *ds) { } +void Ram_dataspace_factory::_clear_ds(Dataspace_component *ds) { } diff --git a/repos/base-nova/lib/mk/core-nova.inc b/repos/base-nova/lib/mk/core-nova.inc index 928cacd565..ec9a7e67c0 100644 --- a/repos/base-nova/lib/mk/core-nova.inc +++ b/repos/base-nova/lib/mk/core-nova.inc @@ -28,12 +28,13 @@ SRC_CC += stack_area.cc \ pd_upgrade_ram_quota.cc \ pd_assign_pci.cc \ rpc_cap_factory.cc \ + ram_dataspace_factory.cc \ platform.cc \ platform_pd.cc \ platform_services.cc \ platform_thread.cc \ ram_session_component.cc \ - ram_session_support.cc \ + ram_dataspace_support.cc \ region_map_component.cc \ region_map_support.cc \ rom_session_component.cc \ @@ -66,6 +67,7 @@ vpath io_port_session_component.cc $(GEN_CORE_DIR)/spec/x86 vpath io_port_session_support.cc $(GEN_CORE_DIR)/spec/x86 vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) +vpath ram_dataspace_factory.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR) vpath core_mem_alloc.cc $(GEN_CORE_DIR) vpath default_log.cc $(GEN_CORE_DIR) diff --git a/repos/base-nova/src/core/ram_session_support.cc b/repos/base-nova/src/core/ram_dataspace_support.cc similarity index 92% rename from repos/base-nova/src/core/ram_session_support.cc rename to repos/base-nova/src/core/ram_dataspace_support.cc index be54ed027a..4b3465d779 100644 --- a/repos/base-nova/src/core/ram_session_support.cc +++ b/repos/base-nova/src/core/ram_dataspace_support.cc @@ -15,7 +15,7 @@ #include /* core includes */ -#include +#include #include #include #include @@ -26,7 +26,7 @@ using namespace Genode; -void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { } +void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component *ds) { } static inline void * alloc_region(Dataspace_component *ds, const size_t size) @@ -49,7 +49,7 @@ static inline void * alloc_region(Dataspace_component *ds, const size_t size) } -void Ram_session_component::_clear_ds(Dataspace_component *ds) +void Ram_dataspace_factory::_clear_ds(Dataspace_component *ds) { size_t page_rounded_size = align_addr(ds->size(), get_page_size_log2()); @@ -74,7 +74,7 @@ void Ram_session_component::_clear_ds(Dataspace_component *ds) } -void Ram_session_component::_export_ram_ds(Dataspace_component *ds) { +void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *ds) { size_t page_rounded_size = align_addr(ds->size(), get_page_size_log2()); diff --git a/repos/base-okl4/lib/mk/core-okl4.inc b/repos/base-okl4/lib/mk/core-okl4.inc index 0cc17aa7f0..be09ee35b4 100644 --- a/repos/base-okl4/lib/mk/core-okl4.inc +++ b/repos/base-okl4/lib/mk/core-okl4.inc @@ -28,12 +28,13 @@ SRC_CC += stack_area.cc \ pd_upgrade_ram_quota.cc \ pd_assign_pci.cc \ rpc_cap_factory_l4.cc \ + ram_dataspace_factory.cc \ platform.cc \ platform_pd.cc \ platform_services.cc \ platform_thread.cc \ ram_session_component.cc \ - ram_session_support.cc \ + ram_dataspace_support.cc \ region_map_component.cc \ region_map_support.cc \ rom_session_component.cc \ @@ -56,6 +57,7 @@ vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath capability_space.cc $(GEN_CORE_DIR) vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) +vpath ram_dataspace_factory.cc $(GEN_CORE_DIR) 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) diff --git a/repos/base-okl4/src/core/ram_session_support.cc b/repos/base-okl4/src/core/ram_dataspace_support.cc similarity index 88% rename from repos/base-okl4/src/core/ram_session_support.cc rename to repos/base-okl4/src/core/ram_dataspace_support.cc index b0e2572c8b..0f65bd3a01 100644 --- a/repos/base-okl4/src/core/ram_session_support.cc +++ b/repos/base-okl4/src/core/ram_dataspace_support.cc @@ -20,7 +20,7 @@ /* core includes */ #include #include -#include +#include /* OKL4 includes */ namespace Okl4 { extern "C" { @@ -29,10 +29,10 @@ namespace Okl4 { extern "C" { using namespace Genode; -void Ram_session_component::_export_ram_ds(Dataspace_component *ds) { } -void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { } +void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *ds) { } +void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component *ds) { } -void Ram_session_component::_clear_ds (Dataspace_component *ds) +void Ram_dataspace_factory::_clear_ds (Dataspace_component *ds) { size_t page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask(); diff --git a/repos/base-pistachio/lib/mk/core-pistachio.inc b/repos/base-pistachio/lib/mk/core-pistachio.inc index 2a38646adb..f3a2140326 100644 --- a/repos/base-pistachio/lib/mk/core-pistachio.inc +++ b/repos/base-pistachio/lib/mk/core-pistachio.inc @@ -21,6 +21,7 @@ SRC_CC = stack_area.cc \ main.cc \ pd_session_component.cc \ rpc_cap_factory_l4.cc \ + ram_dataspace_factory.cc \ pd_assign_pci.cc \ pd_upgrade_ram_quota.cc \ pager.cc \ @@ -31,7 +32,7 @@ SRC_CC = stack_area.cc \ platform_services.cc \ platform_thread.cc \ ram_session_component.cc \ - ram_session_support.cc \ + ram_dataspace_support.cc \ region_map_component.cc \ region_map_support.cc \ rom_session_component.cc \ @@ -57,6 +58,7 @@ vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath region_map_component.cc $(GEN_CORE_DIR) vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) +vpath ram_dataspace_factory.cc $(GEN_CORE_DIR) vpath capability_space.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) diff --git a/repos/base-pistachio/src/core/ram_session_support.cc b/repos/base-pistachio/src/core/ram_dataspace_support.cc similarity index 67% rename from repos/base-pistachio/src/core/ram_session_support.cc rename to repos/base-pistachio/src/core/ram_dataspace_support.cc index 78c47abf1b..b1e0ebb19e 100644 --- a/repos/base-pistachio/src/core/ram_session_support.cc +++ b/repos/base-pistachio/src/core/ram_dataspace_support.cc @@ -14,14 +14,14 @@ * under the terms of the GNU Affero General Public License version 3. */ -#include "ram_session_component.h" +#include using namespace Genode; -void Ram_session_component::_export_ram_ds(Dataspace_component *ds) { } -void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { } +void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *) { } +void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component *) { } -void Ram_session_component::_clear_ds(Dataspace_component *ds) +void Ram_dataspace_factory::_clear_ds(Dataspace_component *ds) { memset((void *)ds->phys_addr(), 0, ds->size()); } diff --git a/repos/base-sel4/lib/mk/core-sel4.mk b/repos/base-sel4/lib/mk/core-sel4.mk index 47af7aa9d9..36f2ddb200 100644 --- a/repos/base-sel4/lib/mk/core-sel4.mk +++ b/repos/base-sel4/lib/mk/core-sel4.mk @@ -3,13 +3,14 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core SRC_CC += \ main.cc \ ram_session_component.cc \ - ram_session_support.cc \ + ram_dataspace_support.cc \ rom_session_component.cc \ cpu_session_component.cc \ cpu_session_support.cc \ cpu_thread_component.cc \ pd_session_component.cc \ rpc_cap_factory.cc \ + ram_dataspace_factory.cc \ pd_assign_pci.cc \ pd_upgrade_ram_quota.cc \ io_mem_session_component.cc \ @@ -62,6 +63,7 @@ vpath platform_services.cc $(GEN_CORE_DIR)/spec/x86 vpath trace_session_component.cc $(GEN_CORE_DIR) vpath signal_transmitter_proxy.cc $(GEN_CORE_DIR) vpath signal_receiver.cc $(GEN_CORE_DIR) +vpath ram_dataspace_factory.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR) vpath core_mem_alloc.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) diff --git a/repos/base-sel4/src/core/ram_session_support.cc b/repos/base-sel4/src/core/ram_dataspace_support.cc similarity index 89% rename from repos/base-sel4/src/core/ram_session_support.cc rename to repos/base-sel4/src/core/ram_dataspace_support.cc index 213f086f82..5277e8a27c 100644 --- a/repos/base-sel4/src/core/ram_session_support.cc +++ b/repos/base-sel4/src/core/ram_dataspace_support.cc @@ -12,7 +12,7 @@ */ /* core includes */ -#include +#include #include #include #include @@ -20,7 +20,7 @@ using namespace Genode; -void Ram_session_component::_export_ram_ds(Dataspace_component *ds) +void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *ds) { size_t const page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask(); size_t const num_pages = page_rounded_size >> get_page_size_log2(); @@ -29,7 +29,7 @@ void Ram_session_component::_export_ram_ds(Dataspace_component *ds) } -void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) +void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component *ds) { size_t const page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask(); @@ -37,7 +37,7 @@ void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) } -void Ram_session_component::_clear_ds (Dataspace_component *ds) +void Ram_dataspace_factory::_clear_ds (Dataspace_component *ds) { size_t const page_rounded_size = (ds->size() + get_page_size() - 1) & get_page_mask(); diff --git a/repos/base/src/core/include/core_env.h b/repos/base/src/core/include/core_env.h index 7d78e68447..fae7331e5a 100644 --- a/repos/base/src/core/include/core_env.h +++ b/repos/base/src/core/include/core_env.h @@ -66,7 +66,7 @@ class Genode::Core_env : public Env_deprecated Session::Diag{false}, *platform()->ram_alloc(), _region_map, - Ram_session_component::any_phys_range()) + Ram_dataspace_factory::any_phys_range()) { _ram_session.init_ram_account(); } diff --git a/repos/base/src/core/include/ram_dataspace_factory.h b/repos/base/src/core/include/ram_dataspace_factory.h new file mode 100644 index 0000000000..3ba6c62370 --- /dev/null +++ b/repos/base/src/core/include/ram_dataspace_factory.h @@ -0,0 +1,117 @@ +/* + * \brief RAM dataspace factory + * \author Norman Feske + * \date 2017-05-11 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _CORE__INCLUDE__RAM_DATASPACE_FACTORY_H_ +#define _CORE__INCLUDE__RAM_DATASPACE_FACTORY_H_ + +/* Genode includes */ +#include +#include + +/* base-internal includes */ +#include + +/* core includes */ +#include + +namespace Genode { class Ram_dataspace_factory; } + + +class Genode::Ram_dataspace_factory : public Ram_allocator, + public Dataspace_owner +{ + public: + + struct Phys_range { addr_t start, end; }; + + static Phys_range any_phys_range() { return { 0UL, ~0UL }; } + + /* + * Dimension '_ds_slab' such that slab blocks (including the + * meta-data overhead of the sliced-heap blocks) are page sized. + */ + static constexpr size_t SLAB_BLOCK_SIZE = + get_page_size() - Sliced_heap::meta_data_size(); + + private: + + Rpc_entrypoint &_ep; + + Range_allocator &_phys_alloc; + Phys_range const _phys_range; + + + /* + * Statically allocated initial slab block for '_ds_slab', needed to + * untangle the hen-and-egg problem of allocating the meta data for + * core's RAM allocator from itself. I also saves the allocation + * of one dataspace (along with a dataspace capability) per session. + */ + uint8_t _initial_sb[SLAB_BLOCK_SIZE]; + + Tslab _ds_slab; + + + /******************************************** + ** Platform-implemented support functions ** + ********************************************/ + + struct Core_virtual_memory_exhausted : Exception { }; + + /** + * Export RAM dataspace as shared memory block + * + * \throw Core_virtual_memory_exhausted + */ + void _export_ram_ds(Dataspace_component *ds); + + /** + * Revert export of RAM dataspace + */ + void _revoke_ram_ds(Dataspace_component *ds); + + /** + * Zero-out content of dataspace + */ + void _clear_ds(Dataspace_component *ds); + + public: + + Ram_dataspace_factory(Rpc_entrypoint &ep, + Range_allocator &phys_alloc, + Phys_range phys_range, + Region_map &local_rm, + Sliced_heap &sliced_heap) + : + _ep(ep), _phys_alloc(phys_alloc), _phys_range(phys_range), + _ds_slab(sliced_heap, _initial_sb) + { } + + ~Ram_dataspace_factory() + { + while (Dataspace_component *ds = _ds_slab.first_object()) + free(static_cap_cast( + static_cap_cast(ds->cap()))); + } + + + /***************************** + ** Ram_allocator interface ** + *****************************/ + + Ram_dataspace_capability alloc(size_t, Cache_attribute) override; + void free(Ram_dataspace_capability) override; + size_t dataspace_size(Ram_dataspace_capability ds) const override; +}; + +#endif /* _CORE__INCLUDE__RAM_DATASPACE_FACTORY_H_ */ diff --git a/repos/base/src/core/include/ram_root.h b/repos/base/src/core/include/ram_root.h index e15b978576..9a2cf37d5e 100644 --- a/repos/base/src/core/include/ram_root.h +++ b/repos/base/src/core/include/ram_root.h @@ -34,8 +34,8 @@ namespace Genode { addr_t const size = Arg_string::find_arg(args, "phys_size").ulong_value(0); addr_t const end = start + size - 1; - return (start <= end) ? Ram_session_component::Phys_range { start, end } - : Ram_session_component::any_phys_range(); + return (start <= end) ? Ram_dataspace_factory::Phys_range { start, end } + : Ram_dataspace_factory::any_phys_range(); } protected: diff --git a/repos/base/src/core/include/ram_session_component.h b/repos/base/src/core/include/ram_session_component.h index 025db5c633..2f6d570c08 100644 --- a/repos/base/src/core/include/ram_session_component.h +++ b/repos/base/src/core/include/ram_session_component.h @@ -15,96 +15,34 @@ #define _CORE__INCLUDE__RAM_SESSION_COMPONENT_H_ /* Genode includes */ -#include #include -#include #include -#include -#include -#include /* core includes */ -#include -#include +#include #include namespace Genode { class Ram_session_component; } -class Genode::Ram_session_component : public Session_object, - public Dataspace_owner +class Genode::Ram_session_component : public Session_object { - public: - - struct Phys_range { addr_t start, end; }; - - static Phys_range any_phys_range() { return { 0UL, ~0UL }; } - private: - class Invalid_dataspace : public Exception { }; - - /* - * Dimension 'Ds_slab' such that slab blocks (including the - * meta-data overhead of the sliced-heap blocks) are page sized. - */ - static constexpr size_t SBS = get_page_size() - Sliced_heap::meta_data_size(); - - using Ds_slab = Tslab; - Rpc_entrypoint &_ep; - Range_allocator &_phys_alloc; - Constrained_ram_allocator _constrained_md_ram_alloc; - Constructible _sliced_heap; - - /* - * Statically allocated initial slab block for '_ds_slab', needed to - * untangle the hen-and-egg problem of allocating the meta data for - * core's RAM allocator from itself. I also saves the allocation - * of one dataspace (along with a dataspace capability) per session. - */ - uint8_t _initial_sb[SBS]; - - Constructible _ds_slab; - - Phys_range const _phys_range; + Sliced_heap _sliced_heap; Constructible > _ram_account; - /** - * Free dataspace - */ - void _free_ds(Dataspace_capability ds_cap); - - - /******************************************** - ** Platform-implemented support functions ** - ********************************************/ - - struct Core_virtual_memory_exhausted : Exception { }; - - /** - * Export RAM dataspace as shared memory block - * - * \throw Core_virtual_memory_exhausted - */ - void _export_ram_ds(Dataspace_component *ds); - - /** - * Revert export of RAM dataspace - */ - void _revoke_ram_ds(Dataspace_component *ds); - - /** - * Zero-out content of dataspace - */ - void _clear_ds(Dataspace_component *ds); + Ram_dataspace_factory _ram_ds_factory; public: + typedef Ram_dataspace_factory::Phys_range Phys_range; + Ram_session_component(Rpc_entrypoint &ep, Resources resources, Session_label const &label, @@ -113,8 +51,6 @@ class Genode::Ram_session_component : public Session_object, Region_map &local_rm, Phys_range phys_range); - ~Ram_session_component(); - /** * Initialize RAM account without providing a reference account * @@ -124,15 +60,6 @@ class Genode::Ram_session_component : public Session_object, */ void init_ram_account() { _ram_account.construct(*this, _label); } - /** - * Get physical address of the RAM that backs a dataspace - * - * \param ds targeted dataspace - * - * \throw Invalid_dataspace - */ - addr_t phys_addr(Ram_dataspace_capability ds); - /***************************** ** Ram_allocator interface ** @@ -142,7 +69,7 @@ class Genode::Ram_session_component : public Session_object, void free(Ram_dataspace_capability) override; - size_t dataspace_size(Ram_dataspace_capability ds) const override; + size_t dataspace_size(Ram_dataspace_capability) const override; /*************************** diff --git a/repos/base/src/core/ram_dataspace_factory.cc b/repos/base/src/core/ram_dataspace_factory.cc new file mode 100644 index 0000000000..e8c011d063 --- /dev/null +++ b/repos/base/src/core/ram_dataspace_factory.cc @@ -0,0 +1,175 @@ +/* + * \brief Core-internal RAM-dataspace factory + * \author Norman Feske + * \date 2006-05-19 + */ + +/* + * Copyright (C) 2006-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* Genode includes */ +#include + +/* core includes */ +#include + +using namespace Genode; + + +Ram_dataspace_capability +Ram_dataspace_factory::alloc(size_t ds_size, Cache_attribute cached) +{ + /* zero-sized dataspaces are not allowed */ + if (!ds_size) return Ram_dataspace_capability(); + + /* dataspace allocation granularity is page size */ + ds_size = align_addr(ds_size, 12); + + /* + * Allocate physical backing store + * + * As an optimization for the use of large mapping sizes, we try to + * align the dataspace in physical memory naturally (size-aligned). + * If this does not work, we subsequently weaken the alignment constraint + * until the allocation succeeds. + */ + void *ds_addr = 0; + bool alloc_succeeded = false; + + /* + * If no physical constraint exists, try to allocate physical memory at + * high locations (3G for 32-bit / 4G for 64-bit platforms) in order to + * preserve lower physical regions for device drivers, which may have DMA + * constraints. + */ + if (_phys_range.start == 0 && _phys_range.end == ~0UL) { + addr_t const high_start = (sizeof(void *) == 4 ? 3UL : 4UL) << 30; + for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { + if (_phys_alloc.alloc_aligned(ds_size, &ds_addr, align_log2, + high_start, _phys_range.end).ok()) { + alloc_succeeded = true; + break; + } + } + } + + /* apply constraints or re-try because higher memory allocation failed */ + if (!alloc_succeeded) { + for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { + if (_phys_alloc.alloc_aligned(ds_size, &ds_addr, align_log2, + _phys_range.start, _phys_range.end).ok()) { + alloc_succeeded = true; + break; + } + } + } + + /* + * Helper to release the allocated physical memory whenever we leave the + * scope via an exception. + */ + struct Phys_alloc_guard + { + Range_allocator &phys_alloc; + void * const ds_addr; + bool ack = false; + + Phys_alloc_guard(Range_allocator &phys_alloc, void *ds_addr) + : phys_alloc(phys_alloc), ds_addr(ds_addr) { } + + ~Phys_alloc_guard() { if (!ack) phys_alloc.free(ds_addr); } + + } phys_alloc_guard(_phys_alloc, ds_addr); + + /* + * Normally, init's quota equals the size of physical memory and this quota + * is distributed among the processes. As we check the quota before + * allocating, the allocation should always succeed in theory. However, + * fragmentation could cause a failing allocation. + */ + if (!alloc_succeeded) { + error("out of physical memory while allocating ", ds_size, " bytes ", + "in range [", Hex(_phys_range.start), "-", Hex(_phys_range.end), "]"); + throw Out_of_ram(); + } + + /* + * For non-cached RAM dataspaces, we mark the dataspace as write + * combined and expect the pager to evaluate this dataspace property + * when resolving page faults. + * + * \throw Out_of_ram + * \throw Out_of_caps + */ + Dataspace_component * const ds = new (_ds_slab) + Dataspace_component(ds_size, (addr_t)ds_addr, cached, true, this); + + /* create native shared memory representation of dataspace */ + try { _export_ram_ds(ds); } + catch (Core_virtual_memory_exhausted) { + warning("could not export RAM dataspace of size ", ds->size()); + + /* cleanup unneeded resources */ + destroy(_ds_slab, ds); + throw Out_of_ram(); + } + + /* + * Fill new dataspaces with zeros. For non-cached RAM dataspaces, this + * function must also make sure to flush all cache lines related to the + * address range used by the dataspace. + */ + _clear_ds(ds); + + Dataspace_capability result = _ep.manage(ds); + + phys_alloc_guard.ack = true; + + return static_cap_cast(result); +} + + +void Ram_dataspace_factory::free(Ram_dataspace_capability ds_cap) +{ + Dataspace_component *ds = nullptr; + _ep.apply(ds_cap, [&] (Dataspace_component *c) + { + if (!c) return; + if (!c->owner(this)) return; + + ds = c; + + size_t const ds_size = ds->size(); + + /* tell entry point to forget the dataspace */ + _ep.dissolve(ds); + + /* remove dataspace from all RM sessions */ + ds->detach_from_rm_sessions(); + + /* destroy native shared memory representation */ + _revoke_ram_ds(ds); + + /* free physical memory that was backing the dataspace */ + _phys_alloc.free((void *)ds->phys_addr(), ds_size); + }); + + /* call dataspace destructor and free memory */ + if (ds) + destroy(_ds_slab, ds); +} + + +size_t Ram_dataspace_factory::dataspace_size(Ram_dataspace_capability ds_cap) const +{ + size_t result = 0; + _ep.apply(ds_cap, [&] (Dataspace_component *c) { + if (c && c->owner(this)) + result = c->size(); }); + + return result; +} diff --git a/repos/base/src/core/ram_session_component.cc b/repos/base/src/core/ram_session_component.cc index 7ab1191c8a..d4ecaee7ac 100644 --- a/repos/base/src/core/ram_session_component.cc +++ b/repos/base/src/core/ram_session_component.cc @@ -13,7 +13,6 @@ /* Genode includes */ #include -#include /* core includes */ #include @@ -21,53 +20,8 @@ using namespace Genode; -addr_t Ram_session_component::phys_addr(Ram_dataspace_capability ds) -{ - auto lambda = [] (Dataspace_component *dsc) { - if (!dsc) throw Invalid_dataspace(); - return dsc->phys_addr(); - }; - - return _ep.apply(ds, lambda); -} - - -void Ram_session_component::_free_ds(Dataspace_capability ds_cap) -{ - Dataspace_component *ds = nullptr; - _ep.apply(ds_cap, [&] (Dataspace_component *c) - { - if (!c) return; - if (!c->owner(this)) return; - - ds = c; - - size_t ds_size = ds->size(); - - /* tell entry point to forget the dataspace */ - _ep.dissolve(ds); - - /* remove dataspace from all RM sessions */ - ds->detach_from_rm_sessions(); - - /* destroy native shared memory representation */ - _revoke_ram_ds(ds); - - /* free physical memory that was backing the dataspace */ - _phys_alloc.free((void *)ds->phys_addr(), ds_size); - - _ram_account->replenish(Ram_quota{ds_size}); - }); - - /* call dataspace destructors and free memory */ - if (ds) { - destroy(*_ds_slab, ds); - Cap_quota_guard::replenish(Cap_quota{1}); - } -} - - -Ram_dataspace_capability Ram_session_component::alloc(size_t ds_size, Cache_attribute cached) +Ram_dataspace_capability +Ram_session_component::alloc(size_t ds_size, Cache_attribute cached) { /* zero-sized dataspaces are not allowed */ if (!ds_size) return Ram_dataspace_capability(); @@ -91,7 +45,8 @@ Ram_dataspace_capability Ram_session_component::alloc(size_t ds_size, Cache_attr * account does not have enough room for the meta data. */ { - Ram_quota_guard::Reservation sbs_ram_costs(*this, Ram_quota{SBS}); + Ram_quota const overhead { Ram_dataspace_factory::SLAB_BLOCK_SIZE }; + Ram_quota_guard::Reservation sbs_ram_costs(*this, overhead); } /* @@ -100,114 +55,39 @@ Ram_dataspace_capability Ram_session_component::alloc(size_t ds_size, Cache_attr Cap_quota_guard::Reservation dataspace_cap_costs(*this, Cap_quota{1}); /* - * Allocate physical backing store - * - * As an optimization for the use of large mapping sizes, we try to - * align the dataspace in physical memory naturally (size-aligned). - * If this does not work, we subsequently weaken the alignment constraint - * until the allocation succeeds. - */ - void *ds_addr = 0; - bool alloc_succeeded = false; - - /* - * If no physical constraint exists, try to allocate physical memory at - * high locations (3G for 32-bit / 4G for 64-bit platforms) in order to - * preserve lower physical regions for device drivers, which may have DMA - * constraints. - */ - if (_phys_range.start == 0 && _phys_range.end == ~0UL) { - addr_t const high_start = (sizeof(void *) == 4 ? 3UL : 4UL) << 30; - for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { - if (_phys_alloc.alloc_aligned(ds_size, &ds_addr, align_log2, - high_start, _phys_range.end).ok()) { - alloc_succeeded = true; - break; - } - } - } - - /* apply constraints or re-try because higher memory allocation failed */ - if (!alloc_succeeded) { - for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { - if (_phys_alloc.alloc_aligned(ds_size, &ds_addr, align_log2, - _phys_range.start, _phys_range.end).ok()) { - alloc_succeeded = true; - break; - } - } - } - - /* - * Helper to release the allocated physical memory whenever we leave the - * scope via an exception. - */ - struct Phys_alloc_guard - { - Range_allocator &phys_alloc; - void * const ds_addr; - bool ack = false; - - Phys_alloc_guard(Range_allocator &phys_alloc, void *ds_addr) - : phys_alloc(phys_alloc), ds_addr(ds_addr) { } - - ~Phys_alloc_guard() { if (!ack) phys_alloc.free(ds_addr); } - - } phys_alloc_guard(_phys_alloc, ds_addr); - - /* - * Normally, init's quota equals the size of physical memory and this quota - * is distributed among the processes. As we check the quota before - * allocating, the allocation should always succeed in theory. However, - * fragmentation could cause a failing allocation. - */ - if (!alloc_succeeded) { - error("out of physical memory while allocating ", ds_size, " bytes ", - "in range [", Hex(_phys_range.start), "-", Hex(_phys_range.end), "]"); - throw Out_of_ram(); - } - - /* - * For non-cached RAM dataspaces, we mark the dataspace as write - * combined and expect the pager to evaluate this dataspace property - * when resolving page faults. + * Allocate physical dataspace * * \throw Out_of_ram * \throw Out_of_caps */ - Dataspace_component *ds = new (*_ds_slab) - Dataspace_component(ds_size, (addr_t)ds_addr, cached, true, this); - - /* create native shared memory representation of dataspace */ - try { _export_ram_ds(ds); } - catch (Core_virtual_memory_exhausted) { - warning("could not export RAM dataspace of size ", ds->size()); - - /* cleanup unneeded resources */ - destroy(*_ds_slab, ds); - throw Out_of_ram(); - } + Ram_dataspace_capability ram_ds = _ram_ds_factory.alloc(ds_size, cached); /* - * Fill new dataspaces with zeros. For non-cached RAM dataspaces, this - * function must also make sure to flush all cache lines related to the - * address range used by the dataspace. + * We returned from '_ram_ds_factory.alloc' with a valid dataspace. */ - _clear_ds(ds); - - Dataspace_capability result = _ep.manage(ds); - dataspace_ram_costs.acknowledge(); dataspace_cap_costs.acknowledge(); - phys_alloc_guard.ack = true; - return static_cap_cast(result); + return ram_ds; } void Ram_session_component::free(Ram_dataspace_capability ds_cap) { - _free_ds(ds_cap); + if (this->cap() == ds_cap) + return; + + size_t const size = _ram_ds_factory.dataspace_size(ds_cap); + if (size == 0) + return; + + _ram_ds_factory.free(ds_cap); + + /* physical memory */ + _ram_account->replenish(Ram_quota{size}); + + /* capability of the dataspace RPC object */ + Cap_quota_guard::replenish(Cap_quota{1}); } @@ -216,12 +96,7 @@ size_t Ram_session_component::dataspace_size(Ram_dataspace_capability ds_cap) co if (this->cap() == ds_cap) return 0; - size_t result = 0; - _ep.apply(ds_cap, [&] (Dataspace_component *c) { - if (c && c->owner(this)) - result = c->size(); }); - - return result; + return _ram_ds_factory.dataspace_size(ds_cap); } @@ -284,19 +159,7 @@ Ram_session_component::Ram_session_component(Rpc_entrypoint &ep, : Session_object(ep, resources, label, diag), _ep(ep), - _phys_alloc(phys_alloc), _constrained_md_ram_alloc(*this, *this, *this), - _phys_range(phys_range) -{ - _sliced_heap.construct(_constrained_md_ram_alloc, local_rm); - _ds_slab.construct(*_sliced_heap, _initial_sb); -} - - -Ram_session_component::~Ram_session_component() -{ - /* destroy all dataspaces */ - Ds_slab &ds_slab = *_ds_slab; - for (Dataspace_component *ds; (ds = ds_slab.first_object()); - _free_ds(ds->cap())); -} + _sliced_heap(_constrained_md_ram_alloc, local_rm), + _ram_ds_factory(ep, phys_alloc, phys_range, local_rm, _sliced_heap) +{ }