core: remove unmap from rm_client

The flush/unmap of memory is tied to an address space and not to a thread.
Move the handling from the Rm_client to the Adress_space class.

Issue #2209
This commit is contained in:
Alexander Boettcher 2017-08-14 11:32:07 +02:00 committed by Christian Helmuth
parent 6792456e4e
commit 430bde3636
47 changed files with 92 additions and 415 deletions

View File

@ -32,7 +32,6 @@ SRC_CC += stack_area.cc \
pd_session_component.cc \
ram_dataspace_support.cc \
region_map_component.cc \
region_map_support.cc \
rom_session_component.cc \
signal_source_component.cc \
signal_transmitter_proxy.cc \

View File

@ -187,11 +187,7 @@ namespace Genode {
** Address-space interface **
*****************************/
/*
* On L4/Fiasco, we don't use directed unmap but rely on the
* in-kernel mapping database. See 'region_map_support.cc'.
*/
void flush(addr_t, size_t) { warning(__func__, " not implemented"); }
void flush(addr_t, size_t, Core_local_addr) override;
};
}

View File

@ -21,7 +21,6 @@
/* core includes */
#include <pager.h>
#include <platform_pd.h>
#include <address_space.h>
/* Fiasco includes */
namespace Fiasco {
@ -134,12 +133,6 @@ namespace Genode {
*/
Affinity::Location affinity() const { return Affinity::Location(); }
/**
* Return the address space to which the thread is bound
*/
Weak_ptr<Address_space> address_space();
/************************
** Accessor functions **
************************/

View File

@ -230,6 +230,22 @@ void Platform_pd::unbind_thread(Platform_thread *thread)
}
void Platform_pd::flush(addr_t, size_t size, Core_local_addr core_local_base)
{
/*
* Fiasco's 'unmap' syscall unmaps the specified flexpage from all address
* spaces to which we mapped the pages. We cannot target this operation to
* a specific L4 task. Hence, we unmap the dataspace from all tasks.
*/
using namespace Fiasco;
addr_t addr = core_local_base.value;
for (; addr < core_local_base.value + size; addr += L4_PAGESIZE)
l4_fpage_unmap(l4_fpage(addr, L4_LOG2_PAGESIZE, 0, 0),
L4_FP_FLUSH_PAGE);
}
Platform_pd::Platform_pd(Allocator * md_alloc, char const *,
signed pd_id, bool create)
{
@ -251,9 +267,6 @@ Platform_pd::Platform_pd(Allocator * md_alloc, char const *,
Platform_pd::~Platform_pd()
{
/* invalidate weak pointers to this object */
Address_space::lock_for_destruction();
/* unbind all threads */
while (Platform_thread *t = _next_thread()) unbind_thread(t);

View File

@ -153,12 +153,6 @@ void Platform_thread::cancel_blocking()
}
Weak_ptr<Address_space> Platform_thread::address_space()
{
return _platform_pd->Address_space::weak_ptr();
}
Platform_thread::Platform_thread(size_t, const char *name, unsigned,
Affinity::Location, addr_t,
int thread_id)

View File

@ -1,49 +0,0 @@
/*
* \brief Fiasco-specific part of RM-session implementation
* \author Norman Feske
* \date 2009-04-10
*/
/*
* Copyright (C) 2009-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.
*/
/* core includes */
#include <rm_session_component.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/syscalls.h>
#include <l4/sys/types.h>
}
using namespace Genode;
static const bool verbose_unmap = false;
void Rm_client::unmap(addr_t core_local_base, addr_t virt_base, size_t size)
{
/*
* Fiasco's 'unmap' syscall unmaps the specified flexpage from all address
* spaces to which we mapped the pages. We cannot target this operation to
* a specific L4 task. Hence, we unmap the dataspace from all tasks, not
* only for this RM client.
*/
if (verbose_unmap) {
Fiasco::l4_threadid_t tid; tid.raw = badge();
log("RM client ", this, " (", (unsigned)tid.id.task, ".",
(unsigned)tid.id.lthread, ") unmap core-local [",
Hex(core_local_base), ",", Hex(core_local_base + size), ")");
}
using namespace Fiasco;
addr_t addr = core_local_base;
for (; addr < core_local_base + size; addr += L4_PAGESIZE)
l4_fpage_unmap(l4_fpage(addr, L4_LOG2_PAGESIZE, 0, 0),
L4_FP_FLUSH_PAGE);
}

View File

@ -31,7 +31,6 @@ SRC_CC += stack_area.cc \
ram_dataspace_support.cc \
ram_dataspace_factory.cc \
region_map_component.cc \
region_map_support.cc \
rom_session_component.cc \
signal_source_component.cc \
signal_transmitter_proxy.cc \

View File

@ -109,11 +109,7 @@ namespace Genode {
** Address-space interface **
*****************************/
/*
* On Fiasco.OC, we don't use directed unmap but rely on the
* in-kernel mapping database. See 'region_map_support.cc'.
*/
void flush(addr_t, size_t) { warning(__func__, " not implemented"); }
void flush(addr_t, size_t, Core_local_addr) override;
};
}

View File

@ -23,7 +23,6 @@
#include <pager.h>
#include <platform_pd.h>
#include <cap_mapping.h>
#include <address_space.h>
namespace Genode {
@ -150,12 +149,6 @@ namespace Genode {
*/
Affinity::Location affinity() const;
/**
* Return the address space to which the thread is bound
*/
Weak_ptr<Address_space> address_space();
/************************
** Accessor functions **
************************/

View File

@ -20,6 +20,7 @@
#include <util.h>
#include <platform.h>
#include <platform_pd.h>
#include <map_local.h>
/* Fiasco includes */
namespace Fiasco {
@ -107,6 +108,12 @@ void Platform_pd::assign_parent(Native_capability parent)
}
void Platform_pd::flush(addr_t, size_t size, Core_local_addr core_local)
{
unmap_local(core_local.value, size >> get_page_size_log2());
}
static Core_cap_index & debug_cap()
{
unsigned long id = platform_specific()->cap_id_alloc()->alloc();
@ -139,9 +146,6 @@ Platform_pd::Platform_pd(Allocator *, char const *)
Platform_pd::~Platform_pd()
{
/* invalidate weak pointers to this object */
Address_space::lock_for_destruction();
for (unsigned i = 0; i < THREAD_MAX; i++) {
if (_threads[i])
_threads[i]->unbind();

View File

@ -274,12 +274,6 @@ void Platform_thread::_finalize_construction(const char *name)
}
Weak_ptr<Address_space> Platform_thread::address_space()
{
return _platform_pd->Address_space::weak_ptr();
}
Platform_thread::Platform_thread(size_t, const char *name, unsigned prio,
Affinity::Location location, addr_t)
: _state(DEAD),

View File

@ -1,24 +0,0 @@
/*
* \brief Fiasco-specific part of RM-session implementation
* \author Stefan Kalkowski
* \date 2011-01-18
*/
/*
* Copyright (C) 2011-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.
*/
/* core includes */
#include <rm_session_component.h>
#include <map_local.h>
using namespace Genode;
void Rm_client::unmap(addr_t core_local_base, addr_t virt_base, size_t size)
{
// TODO unmap it only from target space
unmap_local(core_local_base, size >> get_page_size_log2());
}

View File

@ -63,7 +63,7 @@ bool Hw::Address_space::insert_translation(addr_t virt, addr_t phys,
}
void Hw::Address_space::flush(addr_t virt, size_t size)
void Hw::Address_space::flush(addr_t virt, size_t size, Core_local_addr)
{
Lock::Guard guard(_lock);

View File

@ -116,7 +116,9 @@ class Hw::Address_space : public Genode::Address_space
** Address-space interface **
*****************************/
void flush(Genode::addr_t, Genode::size_t);
void flush(addr_t, size_t, Core_local_addr) override;
void flush(addr_t addr, size_t size) {
flush(addr, size, Core_local_addr{0}); }
/***************

View File

@ -42,7 +42,8 @@ Platform_thread::~Platform_thread()
if (_main_thread) {
Locked_ptr<Address_space> locked_ptr(_address_space);
if (locked_ptr.valid())
locked_ptr->flush((addr_t)_utcb_pd_addr, sizeof(Native_utcb));
locked_ptr->flush((addr_t)_utcb_pd_addr, sizeof(Native_utcb),
Address_space::Core_local_addr{0});
}
/* free UTCB */

View File

@ -14,8 +14,6 @@
/* core includes */
#include <pager.h>
#include <rm_session_component.h>
#include <platform.h>
#include <platform_pd.h>
#include <platform_thread.h>
#include <translation_table.h>
@ -25,19 +23,6 @@
using namespace Genode;
/***************
** Rm_client **
***************/
void Rm_client::unmap(addr_t, addr_t virt_base, size_t size)
{
Locked_ptr<Address_space> locked_address_space(_address_space);
if (locked_address_space.valid())
locked_address_space->flush(virt_base, size);
}
/**********************
** Pager_entrypoint **
**********************/

View File

@ -31,8 +31,6 @@ namespace Genode {
class Platform_thread;
class Address_space;
/*
* We hold all Platform_thread objects in a list in order to be able to
* reflect SIGCHLD as exception signals. When a SIGCHILD occurs, we
@ -179,8 +177,6 @@ namespace Genode {
*/
unsigned long long execution_time() const { return 0; }
Weak_ptr<Address_space> address_space() { return Weak_ptr<Address_space>(); }
unsigned long pager_object_badge() const { return 0; }
};
}

View File

@ -63,6 +63,8 @@ class Genode::Region_map_component : public Rpc_object<Region_map>,
Dataspace_capability dataspace() { return Dataspace_capability(); }
Rm_dataspace_component *dataspace_component() { return 0; }
void address_space(Platform_pd *) { }
};
@ -73,7 +75,6 @@ struct Genode::Rm_client : Pager_object, Rm_member
{
Rm_client(Cpu_session_capability, Thread_capability,
Region_map_component *rm, unsigned long badge,
Weak_ptr<Address_space> &address_space,
Affinity::Location location, Cpu_session::Name const&,
Session_label const&)
{ }

View File

@ -35,7 +35,6 @@ SRC_CC += stack_area.cc \
pd_session_component.cc \
ram_dataspace_support.cc \
region_map_component.cc \
region_map_support.cc \
rom_session_component.cc \
thread_start.cc \
bios_data_area.cc \

View File

@ -84,7 +84,7 @@ namespace Genode {
** Address-space interface **
*****************************/
void flush(addr_t, size_t);
void flush(addr_t, size_t, Core_local_addr) override;
};
}

View File

@ -26,7 +26,6 @@
/* core includes */
#include <pager.h>
#include <address_space.h>
namespace Genode {
@ -136,12 +135,6 @@ namespace Genode {
*/
Thread_state state();
/**
* Return the address space to which the thread is bound
*/
Weak_ptr<Address_space> address_space();
/************************
** Accessor functions **
************************/

View File

@ -70,9 +70,6 @@ Platform_pd::Platform_pd(Allocator * md_alloc, char const *label,
Platform_pd::~Platform_pd()
{
/* invalidate weak pointers to this object */
Address_space::lock_for_destruction();
if (_pd_sel == Native_thread::INVALID_INDEX)
return;
@ -82,7 +79,7 @@ Platform_pd::~Platform_pd()
}
void Platform_pd::flush(addr_t remote_virt, size_t size)
void Platform_pd::flush(addr_t remote_virt, size_t size, Core_local_addr)
{
Nova::Rights const revoke_rwx(true, true, true);

View File

@ -295,15 +295,6 @@ void Platform_thread::single_step(bool on)
const char * Platform_thread::pd_name() const {
return _pd ? _pd->name() : "unknown"; }
Weak_ptr<Address_space> Platform_thread::address_space()
{
if (!_pd) {
error(__PRETTY_FUNCTION__, ": protection domain undefined");
return Weak_ptr<Address_space>();
}
return _pd->Address_space::weak_ptr();
}
unsigned long long Platform_thread::execution_time() const
{

View File

@ -1,31 +0,0 @@
/*
* \brief Region map implementation
* \author Norman Feske
* \author Sebastian Sumpf
* \date 2009-10-02
*/
/*
* Copyright (C) 2009-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.
*/
/* core includes */
#include <rm_session_component.h>
using namespace Genode;
/***************
** Rm_client **
***************/
void Rm_client::unmap(addr_t, addr_t virt_base, size_t size)
{
Locked_ptr<Address_space> locked_address_space(_address_space);
if (locked_address_space.valid())
locked_address_space->flush(virt_base, size);
}

View File

@ -35,7 +35,6 @@ SRC_CC += stack_area.cc \
pd_session_component.cc \
ram_dataspace_support.cc \
region_map_component.cc \
region_map_support.cc \
rom_session_component.cc \
signal_source_component.cc \
signal_transmitter_proxy.cc \

View File

@ -198,7 +198,7 @@ namespace Genode {
** Address-space interface **
*****************************/
void flush(addr_t, size_t);
void flush(addr_t, size_t, Core_local_addr) override;
};
}

View File

@ -20,7 +20,6 @@
/* core includes */
#include <pager.h>
#include <platform_pd.h>
#include <address_space.h>
namespace Genode {
@ -116,12 +115,6 @@ namespace Genode {
*/
Thread_state state();
/**
* Return the address space to which the thread is bound
*/
Weak_ptr<Address_space> address_space();
/************************
** Accessor functions **
************************/

View File

@ -252,7 +252,7 @@ static void unmap_log2_range(unsigned pd_id, addr_t base, size_t size_log2)
}
void Platform_pd::flush(addr_t addr, size_t size)
void Platform_pd::flush(addr_t addr, size_t size, Core_local_addr)
{
using namespace Okl4;
@ -327,9 +327,6 @@ Platform_pd::Platform_pd(Allocator *, char const *label)
Platform_pd::~Platform_pd()
{
/* invalidate weak pointers to this object */
Address_space::lock_for_destruction();
/* unbind all threads */
while (Platform_thread *t = _next_thread()) unbind_thread(t);

View File

@ -178,12 +178,6 @@ unsigned long Platform_thread::pager_object_badge() const
}
Weak_ptr<Address_space> Platform_thread::address_space()
{
return _platform_pd->Address_space::weak_ptr();
}
Platform_thread::Platform_thread(size_t, const char *name, unsigned prio,
Affinity::Location, addr_t, int thread_id)
: _thread_id(thread_id), _l4_thread_id(L4_nilthread), _platform_pd(0),

View File

@ -1,26 +0,0 @@
/*
* \brief OKL4-specific part of region-map implementation
* \author Norman Feske
* \date 2009-04-10
*/
/*
* Copyright (C) 2009-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.
*/
/* core includes */
#include <region_map_component.h>
using namespace Genode;
void Rm_client::unmap(addr_t, addr_t virt_base, size_t size)
{
Locked_ptr<Address_space> locked_address_space(_address_space);
if (locked_address_space.valid())
locked_address_space->flush(virt_base, size);
}

View File

@ -33,7 +33,6 @@ SRC_CC = stack_area.cc \
pd_session_component.cc \
ram_dataspace_support.cc \
region_map_component.cc \
region_map_support.cc \
rom_session_component.cc \
signal_source_component.cc \
signal_transmitter_proxy.cc \

View File

@ -228,11 +228,7 @@ namespace Genode {
** Address-space interface **
*****************************/
/*
* On Pistachio, we don't use directed unmap but rely on the
* in-kernel mapping database. See 'region_map_support.cc'.
*/
void flush(addr_t, size_t) { warning(__func__, "not implemented"); }
void flush(addr_t, size_t, Core_local_addr) override;
};
}

View File

@ -21,7 +21,6 @@
/* core includes */
#include <pager.h>
#include <platform_pd.h>
#include <address_space.h>
/* Pistachio includes */
namespace Pistachio {
@ -133,11 +132,6 @@ namespace Genode {
*/
Thread_state state();
/**
* Return the address space to which the thread is bound
*/
Weak_ptr<Address_space> address_space();
/************************
** Accessor functions **

View File

@ -22,6 +22,8 @@ namespace Pistachio {
#include <l4/thread.h>
#include <l4/sigma0.h>
#include <l4/schedule.h>
#include <l4/space.h>
#include <l4/types.h>
}
using namespace Pistachio;
@ -280,6 +282,27 @@ L4_Word_t Platform_pd::_utcb_location(unsigned int thread_id)
}
void Platform_pd::flush(addr_t, size_t size, Core_local_addr core_local_base)
{
/*
* Pistachio's 'unmap' syscall unmaps the specified flexpage from all
* address spaces to which we mapped the pages. We cannot target this
* operation to a specific L4 task. Hence, we unmap the dataspace from
* all tasks, not only for this RM client.
*/
using namespace Pistachio;
L4_Word_t page_size = get_page_size();
addr_t addr = core_local_base.value;
for (; addr < core_local_base.value + size; addr += page_size) {
L4_Fpage_t fp = L4_Fpage(addr, page_size);
L4_Unmap(L4_FpageAddRightsTo(&fp, L4_FullyAccessible));
}
}
Platform_pd::Platform_pd(bool core) :
_l4_task_id(L4_MyGlobalId())
{
@ -325,9 +348,6 @@ Platform_pd::Platform_pd(Allocator * md_alloc, char const *,
Platform_pd::~Platform_pd()
{
/* invalidate weak pointers to this object */
Address_space::lock_for_destruction();
/* unbind all threads */
while (Platform_thread *t = _next_thread()) unbind_thread(t);

View File

@ -223,12 +223,6 @@ void Platform_thread::cancel_blocking()
}
Weak_ptr<Address_space> Platform_thread::address_space()
{
return _platform_pd->Address_space::weak_ptr();
}
Platform_thread::Platform_thread(size_t, const char *name, unsigned prio,
Affinity::Location, addr_t, int id)
: _thread_id(id), _l4_thread_id(L4_nilthread), _priority(prio), _pager(0)

View File

@ -1,45 +0,0 @@
/*
* \brief Pistachio-specific part of region-map implementation
* \author Norman Feske
* \date 2009-04-10
*/
/*
* Copyright (C) 2009-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.
*/
#include <base/printf.h>
/* core includes */
#include <rm_session_component.h>
/* Pistachio includes */
namespace Pistachio {
#include <l4/types.h>
#include <l4/space.h>
}
using namespace Genode;
void Rm_client::unmap(addr_t core_local_base, addr_t virt_base, size_t size)
{
/*
* Pistachio's 'unmap' syscall unmaps the specified flexpage from all
* address spaces to which we mapped the pages. We cannot target this
* operation to a specific L4 task. Hence, we unmap the dataspace from
* all tasks, not only for this RM client.
*/
using namespace Pistachio;
L4_Word_t page_size = get_page_size();
addr_t addr = core_local_base;
for (; addr < core_local_base + size; addr += page_size) {
L4_Fpage_t fp = L4_Fpage(addr, page_size);
L4_Unmap(L4_FpageAddRightsTo(&fp, L4_FullyAccessible));
}
}

View File

@ -20,7 +20,6 @@ SRC_CC += \
platform.cc \
dataspace_component.cc \
region_map_component.cc \
region_map_support.cc \
irq_session_component.cc \
signal_source_component.cc \
signal_transmitter_proxy.cc \

View File

@ -99,7 +99,7 @@ class Genode::Platform_pd : public Address_space
** Address-space interface **
*****************************/
void flush(addr_t, size_t);
void flush(addr_t, size_t, Core_local_addr) override;
/*****************************

View File

@ -21,7 +21,6 @@
/* core includes */
#include <pager.h>
#include <ipc_pager.h>
#include <address_space.h>
#include <thread_sel4.h>
#include <install_mapping.h>
@ -129,11 +128,6 @@ class Genode::Platform_thread : public List<Platform_thread>::Element
*/
Thread_state state();
/**
* Return the address space to which the thread is bound
*/
Weak_ptr<Address_space> address_space();
/**
* Return execution time consumed by the thread
*/

View File

@ -193,7 +193,7 @@ bool Platform_pd::install_mapping(Mapping const &mapping,
}
void Platform_pd::flush(addr_t virt_addr, size_t size)
void Platform_pd::flush(addr_t virt_addr, size_t size, Core_local_addr)
{
_vm_space.unmap(virt_addr, round_page(size) >> get_page_size_log2());
}
@ -251,7 +251,4 @@ Platform_pd::~Platform_pd()
_cspace_cnode_1st.destruct(*platform()->ram_alloc(), true);
platform_specific()->core_sel_alloc().free(_cspace_cnode_1st.sel());
/* invalidate weak pointers to this object */
Address_space::lock_for_destruction();
}

View File

@ -204,13 +204,6 @@ void Platform_thread::cancel_blocking()
}
Weak_ptr<Address_space> Platform_thread::address_space()
{
ASSERT(_pd);
return _pd->weak_ptr();
}
bool Platform_thread::install_mapping(Mapping const &mapping)
{
return _pd->install_mapping(mapping, name());

View File

@ -1,26 +0,0 @@
/*
* \brief Kernel-specific supplements of the region-map implementation
* \author Norman Feske
* \date 2015-05-01
*/
/*
* Copyright (C) 2015-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.
*/
/* core includes */
#include <rm_session_component.h>
using namespace Genode;
void Rm_client::unmap(addr_t core_local_base, addr_t virt_base, size_t size)
{
Locked_ptr<Address_space> locked_address_space(_address_space);
if (locked_address_space.valid())
locked_address_space->flush(virt_base, size);
}

View File

@ -21,13 +21,15 @@ namespace Genode { struct Address_space; }
struct Genode::Address_space : Genode::Weak_object<Genode::Address_space>
{
struct Core_local_addr { addr_t value; };
/**
* Flush memory mappings of virtual address range
*
* \param virt_addr start address of range to flush
* \param size size of range in bytes, must be a multiple of page size
*/
virtual void flush(addr_t virt_addr, size_t size) = 0;
virtual void flush(addr_t virt_addr, size_t size, Core_local_addr) = 0;
};
#endif /* _CORE__INCLUDE__ADDRESS_SPACE_H_ */

View File

@ -96,8 +96,6 @@ class Genode::Cpu_thread_component : public Rpc_object<Cpu_thread>,
Trace::Source_registry &_trace_sources;
Weak_ptr<Address_space> _address_space = _platform_thread.address_space();
Rm_client _rm_client;
/**
@ -148,7 +146,7 @@ class Genode::Cpu_thread_component : public Rpc_object<Cpu_thread>,
_rm_client(cpu_session_cap, _ep.manage(this),
&_address_space_region_map,
_platform_thread.pager_object_badge(),
_address_space, _platform_thread.affinity(),
_platform_thread.affinity(),
pd.label(), name)
{
_address_space_region_map.add_client(_rm_client);

View File

@ -135,8 +135,10 @@ class Genode::Pd_session_component : public Session_object<Pd_session>
_stack_area (ep, _sliced_heap, pager_ep, 0, stack_area_virtual_size()),
_linker_area(ep, _sliced_heap, pager_ep, 0, LINKER_AREA_SIZE)
{
if (platform()->core_needs_platform_pd() || label != "core")
if (platform()->core_needs_platform_pd() || label != "core") {
_pd.construct(&_sliced_heap, _label.string());
_address_space.address_space(&*_pd);
}
}
/**

View File

@ -175,7 +175,6 @@ class Genode::Rm_client : public Pager_object, public Rm_faulter,
private:
Region_map_component *_region_map;
Weak_ptr<Address_space> _address_space;
public:
@ -190,27 +189,16 @@ class Genode::Rm_client : public Pager_object, public Rm_faulter,
Rm_client(Cpu_session_capability cpu_session,
Thread_capability thread,
Region_map_component *rm, unsigned long badge,
Weak_ptr<Address_space> &address_space,
Affinity::Location location,
Session_label const &pd_label,
Cpu_session::Name const &name)
:
Pager_object(cpu_session, thread, badge, location, pd_label, name),
Rm_faulter(this), _region_map(rm), _address_space(address_space)
Rm_faulter(this), _region_map(rm)
{ }
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
*/
@ -233,6 +221,8 @@ class Genode::Region_map_component : public Genode::Weak_object<Genode::Region_m
Signal_transmitter _fault_notifier; /* notification mechanism for
region-manager faults */
Address_space *_address_space { nullptr };
/*********************
** Paging facility **
*********************/
@ -349,6 +339,9 @@ class Genode::Region_map_component : public Genode::Weak_object<Genode::Region_m
~Region_map_component();
void address_space(Address_space *space) { _address_space = space; }
Address_space *address_space() { return _address_space; }
class Fault_area;
/**
@ -369,8 +362,6 @@ class Genode::Region_map_component : public Genode::Weak_object<Genode::Region_m
*/
void discard_faulter(Rm_faulter *faulter, bool do_lock);
List<Rm_client> *clients() { return &_clients; }
/**
* Return the dataspace representation of this region map
*/

View File

@ -457,12 +457,16 @@ static void unmap_managed(Region_map_component *rm, Rm_region *region, int level
<= region->base() - region->offset() + region->size())
unmap_managed(managed->rm(), managed, level + 1);
if (!managed->rm()->address_space())
continue;
/* 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<Rm_client>::Element::next())
rc->unmap(region->dataspace()->core_local_addr() + region->offset(),
managed->base() + region->base() - managed->offset(), region->size());
Address_space::Core_local_addr core_local
= { region->dataspace()->core_local_addr() + region->offset() };
managed->rm()->address_space()->flush(managed->base() + region->base() -
managed->offset(),
region->size(), core_local);
}
}
@ -526,49 +530,15 @@ void Region_map_component::detach(Local_addr local_addr)
* function 'managed'.
*/
/*
* 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;
Rm_client *rc = _clients.first();
for (; rc; rc = rc->List<Rm_client>::Element::next(), prev_rc = rc) {
/*
* XXX Unmapping managed dataspaces on kernels, which take a core-
* local virtual address as unmap argument is not supported yet.
* This is the case for Fiasco and Pistachio. On those
* kernels, the unmap operation must be issued for each leaf
* dataspace the managed dataspace is composed of. For kernels with
* support for directed unmap (OKL4), unmap can be
* simply applied for the contiguous virtual address region in the
* client.
*/
if (!platform()->supports_direct_unmap()
&& dsc->managed() && dsc->core_local_addr() == 0) {
if (_address_space) {
if (!platform()->supports_direct_unmap() && dsc->managed() &&
dsc->core_local_addr() == 0) {
warning("unmapping of managed dataspaces not yet supported");
break;
} else {
Address_space::Core_local_addr core_local
= { dsc->core_local_addr() + region.offset() };
_address_space->flush(region.base(), region.size(), core_local);
}
/*
* Don't unmap from the same address space twice. If multiple threads
* reside in one PD, each thread will have a corresponding 'Rm_client'
* object. Consequenlty, an unmap operation referring to the PD is
* issued multiple times, one time for each thread. By comparing the
* membership to the thread's respective address spaces, we reduce
* superfluous unmap operations.
*
* Note that the list of 'Rm_client' object may contain threads of
* different address spaces in any order. So superfluous unmap
* operations can still happen if 'Rm_client' objects of one PD are
* interleaved with 'Rm_client' objects of another PD. In practice,
* however, this corner case is rare.
*/
if (prev_rc && prev_rc->has_same_address_space(*rc))
continue;
rc->unmap(dsc->core_local_addr() + region.offset(),
region.base(), region.size());
}
/*