diff --git a/repos/base-nova/src/core/ram_dataspace_support.cc b/repos/base-nova/src/core/ram_dataspace_support.cc index 066e4ca203..3b7f241f9a 100644 --- a/repos/base-nova/src/core/ram_dataspace_support.cc +++ b/repos/base-nova/src/core/ram_dataspace_support.cc @@ -56,30 +56,35 @@ static inline void * alloc_region(Dataspace_component &ds, const size_t size) void Ram_dataspace_factory::_clear_ds(Dataspace_component &ds) { + size_t const page_rounded_size = align_addr(ds.size(), get_page_size_log2()); - //size_t memset_count = page_rounded_size / 4; - //addr_t memset_ptr = ds.core_local_addr(); + size_t memset_count = page_rounded_size / 32; + addr_t memset_ptr = ds.core_local_addr(); - /* - if ((memset_count * 4 == page_rounded_size) && !(memset_ptr & 0x3)) - asm volatile ("rep stosl" : "+D" (memset_ptr), "+c" (memset_count) + if ((memset_count * 32 == page_rounded_size) && !(memset_ptr & 0x3)) + { + asm volatile ("rep stosq" : "+D" (memset_ptr), "+c" (memset_count) : "a" (0) : "memory"); - else + } else memset(reinterpret_cast(memset_ptr), 0, page_rounded_size); - */ +} + +void Ram_dataspace_factory::_unmap_ds_from_core(Dataspace_component &ds) +{ + size_t const page_rounded_size = align_addr(ds.size(), get_page_size_log2()); + /* we don't keep any core-local mapping */ unmap_local(*reinterpret_cast(Thread::myself()->utcb()), - ds.core_local_addr(), - page_rounded_size >> get_page_size_log2()); + ds.core_local_addr(), + page_rounded_size >> get_page_size_log2()); - platform().region_alloc().free((void*)ds.core_local_addr(), - page_rounded_size); + platform().region_alloc().free((void *)ds.core_local_addr(), + page_rounded_size); ds.assign_core_local_addr(nullptr); } - 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/src/core/include/ram_dataspace_factory.h b/repos/base/src/core/include/ram_dataspace_factory.h index 01defb4302..c0a2294a0c 100644 --- a/repos/base/src/core/include/ram_dataspace_factory.h +++ b/repos/base/src/core/include/ram_dataspace_factory.h @@ -82,6 +82,11 @@ class Genode::Ram_dataspace_factory : public Ram_allocator, */ void _clear_ds(Dataspace_component &ds); + /** + * Remove core-local mappings of dataspace + */ + void _unmap_ds_from_core(Dataspace_component &ds); + public: Ram_dataspace_factory(Rpc_entrypoint &ep, diff --git a/repos/base/src/core/ram_dataspace_factory.cc b/repos/base/src/core/ram_dataspace_factory.cc index 05079bc4eb..a8b8f158f7 100644 --- a/repos/base/src/core/ram_dataspace_factory.cc +++ b/repos/base/src/core/ram_dataspace_factory.cc @@ -123,6 +123,7 @@ Ram_dataspace_factory::try_alloc(size_t ds_size, Cache cache) Dataspace_component &ds = *ds_ptr; /* create native shared memory representation of dataspace */ +#ifdef ZERO_AT_ALLOC try { _export_ram_ds(ds); } catch (Core_virtual_memory_exhausted) { warning("could not export RAM dataspace of size ", ds.size()); @@ -137,8 +138,8 @@ Ram_dataspace_factory::try_alloc(size_t ds_size, Cache cache) * function must also make sure to flush all cache lines related to the * address range used by the dataspace. */ - _clear_ds(ds); - + _unmap_ds_from_core(ds); +#endif Dataspace_capability ds_cap = _ep.manage(&ds); phys_alloc_guard.keep = true; @@ -181,8 +182,25 @@ void Ram_dataspace_factory::free(Ram_dataspace_capability ds_cap) }); /* call dataspace destructor and free memory */ - if (ds) + if (ds) { + 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); + return; + } + + /* + * 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); + _unmap_ds_from_core(*ds); destroy(_ds_slab, ds); + } }