mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-21 01:37:42 +00:00
If an RM client gets dissolved the RM server tries to first dissolve and then destruct the according pager object. As pager objects previously cancelled unresolved faults only in destructor the dissolve operation blocked forever when an unresolved fault existed. As every pager object should get dissolved before it gets destructed (signal-context complains otherwise) no more unresolved-fault cancelling is needed in the destructor. ref #989
135 lines
2.9 KiB
C++
135 lines
2.9 KiB
C++
/*
|
|
* \brief Pager implementations that are specific for the HW-core
|
|
* \author Martin Stein
|
|
* \date 2012-03-29
|
|
*/
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
|
|
/* Genode includes */
|
|
#include <base/pager.h>
|
|
#include <base/printf.h>
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
/*************
|
|
** Mapping **
|
|
*************/
|
|
|
|
Mapping::Mapping(addr_t const va, addr_t const pa, bool const wc,
|
|
bool const io, unsigned const sl2, bool const w)
|
|
:
|
|
virt_address(va), phys_address(pa), write_combined(wc),
|
|
io_mem(io), size_log2(sl2), writable(w)
|
|
{ }
|
|
|
|
|
|
Mapping::Mapping()
|
|
:
|
|
virt_address(0), phys_address(0), write_combined(0),
|
|
io_mem(0), size_log2(0), writable(0)
|
|
{ }
|
|
|
|
|
|
void Mapping::prepare_map_operation() { }
|
|
|
|
|
|
/***************
|
|
** Ipc_pager **
|
|
***************/
|
|
|
|
addr_t Ipc_pager::fault_ip() const { return _fault.ip; }
|
|
|
|
addr_t Ipc_pager::fault_addr() const { return _fault.addr; }
|
|
|
|
bool Ipc_pager::is_write_fault() const { return _fault.writes; }
|
|
|
|
void Ipc_pager::set_reply_mapping(Mapping m) { _mapping = m; }
|
|
|
|
|
|
/******************
|
|
** Pager_object **
|
|
******************/
|
|
|
|
Thread_capability Pager_object::thread_cap() const { return _thread_cap; }
|
|
|
|
void Pager_object::thread_cap(Thread_capability const & c) { _thread_cap = c; }
|
|
|
|
Signal * Pager_object::_signal() const { return (Signal *)_signal_buf; }
|
|
|
|
void Pager_object::wake_up() { fault_resolved(); }
|
|
|
|
void Pager_object::exception_handler(Signal_context_capability) { }
|
|
|
|
|
|
Pager_object::Pager_object(unsigned const badge, Affinity::Location)
|
|
:
|
|
_signal_valid(0),
|
|
_badge(badge)
|
|
{ }
|
|
|
|
|
|
unsigned Pager_object::signal_context_id() const
|
|
{
|
|
return _signal_context_cap.dst();
|
|
}
|
|
|
|
|
|
/***************************
|
|
** Pager_activation_base **
|
|
***************************/
|
|
|
|
void Pager_activation_base::ep(Pager_entrypoint * const ep) { _ep = ep; }
|
|
|
|
|
|
Pager_activation_base::Pager_activation_base(char const * const name,
|
|
size_t const stack_size)
|
|
:
|
|
Thread_base(name, stack_size), _cap_valid(Lock::LOCKED), _ep(0)
|
|
{ }
|
|
|
|
|
|
Native_capability Pager_activation_base::cap()
|
|
{
|
|
if (!_cap.valid()) { _cap_valid.lock(); }
|
|
return _cap;
|
|
}
|
|
|
|
|
|
/**********************
|
|
** Pager_entrypoint **
|
|
**********************/
|
|
|
|
void Pager_entrypoint::dissolve(Pager_object * const o)
|
|
{
|
|
remove_locked(o);
|
|
o->stop_paging();
|
|
_activation->Signal_receiver::dissolve(o);
|
|
}
|
|
|
|
|
|
Pager_entrypoint::Pager_entrypoint(Cap_session *,
|
|
Pager_activation_base * const activation)
|
|
:
|
|
_activation(activation)
|
|
{
|
|
_activation->ep(this);
|
|
}
|
|
|
|
|
|
Pager_capability Pager_entrypoint::manage(Pager_object * const o)
|
|
{
|
|
unsigned const d = _activation->cap().dst();
|
|
unsigned const b = o->badge();
|
|
auto const p = reinterpret_cap_cast<Pager_object>(Native_capability(d, b));
|
|
o->start_paging(_activation->Signal_receiver::manage(o), p);
|
|
insert(o);
|
|
return p;
|
|
}
|