2011-12-22 15:19:25 +00:00
|
|
|
/*
|
|
|
|
* \brief Pager framework
|
|
|
|
* \author Norman Feske
|
|
|
|
* \author Sebastian Sumpf
|
2012-08-01 14:16:51 +00:00
|
|
|
* \author Alexander Boettcher
|
2011-12-22 15:19:25 +00:00
|
|
|
* \date 2010-01-25
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 12:23:52 +00:00
|
|
|
* Copyright (C) 2010-2017 Genode Labs GmbH
|
2011-12-22 15:19:25 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 12:23:52 +00:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* Genode includes */
|
2014-09-05 15:00:31 +00:00
|
|
|
#include <util/construct_at.h>
|
|
|
|
#include <rm_session/rm_session.h>
|
|
|
|
|
2016-03-11 16:32:43 +00:00
|
|
|
/* base-internal includes */
|
|
|
|
#include <base/internal/native_thread.h>
|
|
|
|
|
2016-01-19 19:24:22 +00:00
|
|
|
/* core-local includes */
|
2015-06-19 12:58:18 +00:00
|
|
|
#include <pager.h>
|
2016-11-04 12:01:09 +00:00
|
|
|
#include <platform.h>
|
2016-05-19 18:33:36 +00:00
|
|
|
#include <platform_thread.h>
|
2016-01-19 19:24:22 +00:00
|
|
|
#include <imprint_badge.h>
|
2016-11-30 18:36:32 +00:00
|
|
|
#include <cpu_thread_component.h>
|
|
|
|
#include <core_env.h>
|
2015-06-19 12:58:18 +00:00
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
/* NOVA includes */
|
|
|
|
#include <nova/syscalls.h>
|
2014-09-05 15:00:31 +00:00
|
|
|
#include <nova_util.h> /* map_local */
|
2016-06-15 13:04:54 +00:00
|
|
|
#include <nova/capability_space.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2015-06-09 17:33:53 +00:00
|
|
|
static bool verbose_oom = false;
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
using namespace Genode;
|
|
|
|
using namespace Nova;
|
|
|
|
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
static Nova::Hip * kernel_hip()
|
2012-08-23 09:02:31 +00:00
|
|
|
{
|
2014-09-05 15:00:31 +00:00
|
|
|
/**
|
|
|
|
* Initial value of esp register, saved by the crt0 startup code.
|
|
|
|
* This value contains the address of the hypervisor information page.
|
|
|
|
*/
|
|
|
|
extern addr_t __initial_sp;
|
|
|
|
return reinterpret_cast<Hip *>(__initial_sp);
|
|
|
|
}
|
2012-08-23 09:02:31 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* pager activation threads storage and handling - one thread per CPU */
|
2016-11-04 12:01:09 +00:00
|
|
|
enum { PAGER_CPUS = Platform::MAX_SUPPORTED_CPUS, PAGER_STACK_SIZE = 2*4096 };
|
2012-08-23 09:02:31 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
static char pager_activation_mem[sizeof (Pager_activation<PAGER_STACK_SIZE>) * PAGER_CPUS];
|
|
|
|
static Pager_activation_base * pager_threads[PAGER_CPUS];
|
2012-08-23 09:02:31 +00:00
|
|
|
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
static unsigned which_cpu(Pager_activation_base * pager)
|
|
|
|
{
|
|
|
|
Pager_activation_base * start = reinterpret_cast<Pager_activation_base *>(&pager_activation_mem);
|
|
|
|
Pager_activation_base * end = start + PAGER_CPUS;
|
2012-08-23 09:02:31 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
if (start <= pager && pager < end) {
|
|
|
|
/* pager of one of the non boot CPUs */
|
|
|
|
unsigned cpu_id = pager - start;
|
|
|
|
return cpu_id;
|
|
|
|
}
|
2012-08-23 09:02:31 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* pager of boot CPU */
|
2016-11-04 12:01:09 +00:00
|
|
|
return 0;
|
2012-08-23 09:02:31 +00:00
|
|
|
}
|
|
|
|
|
2013-01-11 22:10:21 +00:00
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
/**
|
|
|
|
* Utility for the formatted output of page-fault information
|
|
|
|
*/
|
|
|
|
struct Page_fault_info
|
|
|
|
{
|
|
|
|
char const * const pd;
|
|
|
|
char const * const thread;
|
|
|
|
unsigned const cpu;
|
2016-11-10 10:46:30 +00:00
|
|
|
addr_t const ip, addr, sp;
|
|
|
|
uint8_t const pf_type;
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
|
|
|
Page_fault_info(char const *pd, char const *thread, unsigned cpu,
|
2016-11-10 10:46:30 +00:00
|
|
|
addr_t ip, addr_t addr, addr_t sp, unsigned type)
|
|
|
|
: pd(pd), thread(thread), cpu(cpu), ip(ip), addr(addr),
|
|
|
|
sp(sp), pf_type(type) { }
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
|
|
|
void print(Genode::Output &out) const
|
|
|
|
{
|
|
|
|
Genode::print(out, "pd='", pd, "' "
|
|
|
|
"thread='", thread, "' "
|
|
|
|
"cpu=", cpu, " "
|
|
|
|
"ip=", Hex(ip), " "
|
2016-11-10 10:46:30 +00:00
|
|
|
"address=", Hex(addr), " "
|
|
|
|
"stack pointer=", Hex(sp), " "
|
|
|
|
"qualifiers=", Hex(pf_type), " ",
|
|
|
|
pf_type & Ipc_pager::ERR_I ? "I" : "i",
|
|
|
|
pf_type & Ipc_pager::ERR_R ? "R" : "r",
|
|
|
|
pf_type & Ipc_pager::ERR_U ? "U" : "u",
|
|
|
|
pf_type & Ipc_pager::ERR_W ? "W" : "w",
|
|
|
|
pf_type & Ipc_pager::ERR_P ? "P" : "p");
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
void Pager_object::_page_fault_handler(addr_t pager_obj)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2016-05-04 10:27:17 +00:00
|
|
|
Thread * myself = Thread::myself();
|
2014-09-05 15:00:31 +00:00
|
|
|
Pager_object * obj = reinterpret_cast<Pager_object *>(pager_obj);
|
|
|
|
Utcb * utcb = reinterpret_cast<Utcb *>(myself->utcb());
|
2016-11-10 10:46:30 +00:00
|
|
|
|
|
|
|
Ipc_pager ipc_pager(reinterpret_cast<Nova::Utcb *>(utcb), obj->pd_sel(),
|
|
|
|
platform_specific()->core_pd_sel());
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
Pager_activation_base * pager_thread = static_cast<Pager_activation_base *>(myself);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2016-11-30 18:36:32 +00:00
|
|
|
/* potential request to ask for EC cap or signal SM cap */
|
|
|
|
if (utcb->msg_words() == 1)
|
|
|
|
_invoke_handler(pager_obj);
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* lookup fault address and decide what to do */
|
2016-11-10 10:46:30 +00:00
|
|
|
int error = obj->pager(ipc_pager);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* don't open receive window for pager threads */
|
|
|
|
if (utcb->crd_rcv.value())
|
|
|
|
nova_die();
|
2013-02-19 10:14:21 +00:00
|
|
|
|
2016-11-10 10:46:30 +00:00
|
|
|
if (!error && ipc_pager.syscall_result() != Nova::NOVA_OK) {
|
|
|
|
/* something went wrong - by default don't answer the page fault */
|
|
|
|
error = 4;
|
|
|
|
|
|
|
|
/* dst pd has not enough kernel quota ? - try to recover */
|
|
|
|
if (ipc_pager.syscall_result() == Nova::NOVA_PD_OOM) {
|
|
|
|
uint8_t res = obj->handle_oom();
|
|
|
|
if (res == Nova::NOVA_PD_OOM)
|
|
|
|
/* block until revoke is due */
|
|
|
|
ipc_pager.reply_and_wait_for_fault(obj->sel_sm_block_oom());
|
|
|
|
else if (res == Nova::NOVA_OK)
|
|
|
|
/* succeeded to recover - continue normally */
|
|
|
|
error = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* good case - found a valid region which is mappable */
|
2016-11-10 10:46:30 +00:00
|
|
|
if (!error)
|
2014-09-05 15:00:31 +00:00
|
|
|
ipc_pager.reply_and_wait_for_fault();
|
2013-01-31 10:59:38 +00:00
|
|
|
|
2016-11-10 10:46:30 +00:00
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
obj->_state_lock.lock();
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
obj->_state.thread.ip = ipc_pager.fault_ip();
|
|
|
|
obj->_state.thread.sp = 0;
|
|
|
|
obj->_state.thread.trapno = PT_SEL_PAGE_FAULT;
|
2013-01-31 10:59:38 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
obj->_state.block();
|
2013-02-27 10:32:49 +00:00
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
obj->_state_lock.unlock();
|
|
|
|
|
2016-05-19 18:33:36 +00:00
|
|
|
const char * client_thread = obj->client_thread();
|
|
|
|
const char * client_pd = obj->client_pd();
|
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
Page_fault_info const fault_info(client_pd, client_thread,
|
|
|
|
which_cpu(pager_thread),
|
2016-11-10 10:46:30 +00:00
|
|
|
ipc_pager.fault_ip(),
|
|
|
|
ipc_pager.fault_addr(),
|
|
|
|
ipc_pager.sp(),
|
|
|
|
ipc_pager.fault_type());
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* region manager fault - to be handled */
|
2016-11-10 10:46:30 +00:00
|
|
|
log("page fault, ", fault_info, " reason=", error);
|
2014-09-05 15:00:31 +00:00
|
|
|
|
2016-11-10 10:46:30 +00:00
|
|
|
/* block the faulting thread until region manager is done */
|
|
|
|
ipc_pager.reply_and_wait_for_fault(obj->sel_sm_block_pause());
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
2013-01-11 22:10:21 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
void Pager_object::exception(uint8_t exit_id)
|
2012-08-23 09:02:31 +00:00
|
|
|
{
|
2016-05-04 10:27:17 +00:00
|
|
|
Thread *myself = Thread::myself();
|
2014-09-05 15:00:31 +00:00
|
|
|
Utcb * utcb = reinterpret_cast<Utcb *>(myself->utcb());
|
|
|
|
Pager_activation_base * pager_thread = static_cast<Pager_activation_base *>(myself);
|
|
|
|
|
|
|
|
if (exit_id > PT_SEL_PARENT || !pager_thread)
|
|
|
|
nova_die();
|
|
|
|
|
2013-01-16 15:07:04 +00:00
|
|
|
addr_t fault_ip = utcb->ip;
|
2013-11-04 10:05:10 +00:00
|
|
|
uint8_t res = 0xFF;
|
2015-01-06 13:20:16 +00:00
|
|
|
addr_t mtd = 0;
|
2012-08-23 09:02:31 +00:00
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
_state_lock.lock();
|
2014-09-05 15:00:31 +00:00
|
|
|
|
|
|
|
/* remember exception type for cpu_session()->state() calls */
|
|
|
|
_state.thread.trapno = exit_id;
|
|
|
|
|
|
|
|
if (_exception_sigh.valid()) {
|
|
|
|
_state.submit_signal();
|
2016-05-17 14:13:56 +00:00
|
|
|
res = _unsynchronized_client_recall(true);
|
2014-09-05 15:00:31 +00:00
|
|
|
}
|
2013-09-26 12:31:56 +00:00
|
|
|
|
|
|
|
if (res != NOVA_OK) {
|
2014-09-05 15:00:31 +00:00
|
|
|
/* nobody handles this exception - so thread will be stopped finally */
|
|
|
|
_state.mark_dead();
|
2013-02-19 10:14:21 +00:00
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
warning("unresolvable exception ", exit_id, ", "
|
|
|
|
"pd '", client_pd(), "', "
|
|
|
|
"thread '", client_thread(), "', "
|
|
|
|
"cpu ", which_cpu(pager_thread), ", "
|
|
|
|
"ip=", Hex(fault_ip), " ",
|
|
|
|
res == 0xFF ? "no signal handler"
|
|
|
|
: (res == NOVA_OK ? "" : "recall failed"));
|
2013-01-16 15:07:04 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
Nova::revoke(Obj_crd(exc_pt_sel_client(), NUM_INITIAL_PT_LOG2));
|
2015-01-06 13:20:16 +00:00
|
|
|
|
|
|
|
enum { TRAP_BREAKPOINT = 3 };
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
if (exit_id == TRAP_BREAKPOINT) {
|
2015-01-06 13:20:16 +00:00
|
|
|
utcb->ip = fault_ip - 1;
|
|
|
|
mtd = Mtd::EIP;
|
|
|
|
}
|
2012-08-23 09:02:31 +00:00
|
|
|
}
|
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
_state_lock.unlock();
|
|
|
|
|
2012-08-23 09:02:31 +00:00
|
|
|
utcb->set_msg_word(0);
|
2015-01-06 13:20:16 +00:00
|
|
|
utcb->mtd = mtd;
|
2012-08-23 09:02:31 +00:00
|
|
|
|
|
|
|
reply(myself->stack_top());
|
|
|
|
}
|
|
|
|
|
2013-01-11 22:10:21 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
void Pager_object::_recall_handler(addr_t pager_obj)
|
2012-08-24 08:25:24 +00:00
|
|
|
{
|
2016-05-04 10:27:17 +00:00
|
|
|
Thread * myself = Thread::myself();
|
2014-09-05 15:00:31 +00:00
|
|
|
Pager_object * obj = reinterpret_cast<Pager_object *>(pager_obj);
|
|
|
|
Utcb * utcb = reinterpret_cast<Utcb *>(myself->utcb());
|
2012-08-24 08:25:24 +00:00
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
obj->_state_lock.lock();
|
2012-08-24 08:25:24 +00:00
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
if (obj->_state.modified) {
|
|
|
|
obj->_copy_state_to_utcb(utcb);
|
|
|
|
obj->_state.modified = false;
|
|
|
|
} else
|
|
|
|
utcb->mtd = 0;
|
2012-08-24 08:25:24 +00:00
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
/* switch on/off single step */
|
|
|
|
bool singlestep_state = obj->_state.thread.eflags & 0x100UL;
|
|
|
|
if (obj->_state.singlestep() && !singlestep_state) {
|
|
|
|
utcb->flags |= 0x100UL;
|
|
|
|
utcb->mtd |= Mtd::EFL;
|
|
|
|
} else if (!obj->_state.singlestep() && singlestep_state) {
|
|
|
|
utcb->flags &= ~0x100UL;
|
|
|
|
utcb->mtd |= Mtd::EFL;
|
|
|
|
}
|
2012-08-24 08:25:24 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* deliver signal if it was requested */
|
|
|
|
if (obj->_state.to_submit())
|
|
|
|
obj->submit_exception_signal();
|
2012-08-24 08:25:24 +00:00
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
/* block until cpu_session()->resume() respectively wake_up() call */
|
2012-08-24 08:25:24 +00:00
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
unsigned long sm = obj->_state.blocked() ? obj->sel_sm_block_pause() : 0;
|
|
|
|
|
|
|
|
obj->_state_lock.unlock();
|
2013-09-26 13:16:01 +00:00
|
|
|
|
2012-08-24 08:25:24 +00:00
|
|
|
utcb->set_msg_word(0);
|
2016-05-17 14:13:56 +00:00
|
|
|
reply(myself->stack_top(), sm);
|
2012-08-24 08:25:24 +00:00
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2013-01-11 22:10:21 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
void Pager_object::_startup_handler(addr_t pager_obj)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2016-05-04 10:27:17 +00:00
|
|
|
Thread *myself = Thread::myself();
|
2014-09-05 15:00:31 +00:00
|
|
|
Pager_object * obj = reinterpret_cast<Pager_object *>(pager_obj);
|
|
|
|
Utcb * utcb = reinterpret_cast<Utcb *>(myself->utcb());
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2012-08-24 08:25:24 +00:00
|
|
|
utcb->ip = obj->_initial_eip;
|
|
|
|
utcb->sp = obj->_initial_esp;
|
2012-08-23 09:02:31 +00:00
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
utcb->mtd = Mtd::EIP | Mtd::ESP;
|
2016-05-17 14:13:56 +00:00
|
|
|
|
|
|
|
if (obj->_state.singlestep()) {
|
|
|
|
utcb->flags = 0x100UL;
|
|
|
|
utcb->mtd |= Mtd::EFL;
|
|
|
|
}
|
|
|
|
|
|
|
|
obj->_state.unblock();
|
|
|
|
|
2012-06-26 11:43:30 +00:00
|
|
|
utcb->set_msg_word(0);
|
2012-08-23 09:02:31 +00:00
|
|
|
|
|
|
|
reply(myself->stack_top());
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
void Pager_object::_invoke_handler(addr_t pager_obj)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2016-05-04 10:27:17 +00:00
|
|
|
Thread *myself = Thread::myself();
|
2014-09-05 15:00:31 +00:00
|
|
|
Pager_object * obj = reinterpret_cast<Pager_object *>(pager_obj);
|
|
|
|
Utcb * utcb = reinterpret_cast<Utcb *>(myself->utcb());
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* receive window must be closed - otherwise implementation bug */
|
|
|
|
if (utcb->crd_rcv.value())
|
|
|
|
nova_die();
|
2013-11-14 09:35:44 +00:00
|
|
|
|
2016-11-30 18:36:32 +00:00
|
|
|
/* if protocol is violated ignore request */
|
|
|
|
if (utcb->msg_words() != 1) {
|
|
|
|
utcb->mtd = 0;
|
|
|
|
utcb->set_msg_word(0);
|
|
|
|
reply(myself->stack_top());
|
|
|
|
}
|
|
|
|
|
2017-04-12 09:55:08 +00:00
|
|
|
addr_t const event = utcb->msg()[0];
|
2013-09-25 09:53:49 +00:00
|
|
|
|
2016-11-24 20:57:33 +00:00
|
|
|
/* check for translated pager portals - required for vCPU in remote PDs */
|
|
|
|
if (utcb->msg_items() == 1 && utcb->msg_words() == 1 && event == 0xaffe) {
|
|
|
|
|
|
|
|
Nova::Utcb::Item const * const item = utcb->get_item(0);
|
|
|
|
Nova::Crd const cap(item->crd);
|
|
|
|
|
|
|
|
/* valid item which got translated ? */
|
|
|
|
if (!cap.is_null() && !item->is_del()) {
|
2016-11-30 18:36:32 +00:00
|
|
|
Rpc_entrypoint *e = core_env()->entrypoint();
|
|
|
|
e->apply(cap.base(),
|
|
|
|
[&] (Cpu_thread_component *source) {
|
|
|
|
if (!source)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Platform_thread &p = source->platform_thread();
|
|
|
|
addr_t const sel_exc_base = p.remote_vcpu();
|
|
|
|
if (sel_exc_base == Native_thread::INVALID_INDEX)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* delegate VM-exit portals */
|
|
|
|
map_vcpu_portals(*p.pager(), sel_exc_base, sel_exc_base,
|
|
|
|
utcb, obj->pd_sel());
|
|
|
|
|
|
|
|
/* delegate portal to contact pager */
|
|
|
|
map_pagefault_portal(*obj, p.pager()->exc_pt_sel_client(),
|
|
|
|
sel_exc_base, obj->pd_sel(), utcb);
|
|
|
|
});
|
2014-09-05 15:00:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
utcb->mtd = 0;
|
|
|
|
utcb->set_msg_word(0);
|
|
|
|
reply(myself->stack_top());
|
|
|
|
}
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
utcb->mtd = 0;
|
2012-06-26 11:43:30 +00:00
|
|
|
utcb->set_msg_word(0);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2013-09-26 12:31:56 +00:00
|
|
|
/* native ec cap requested */
|
2013-09-25 09:53:49 +00:00
|
|
|
if (event == ~0UL) {
|
|
|
|
/**
|
|
|
|
* Return native EC cap with specific rights mask set.
|
|
|
|
* If the cap is mapped the kernel will demote the
|
|
|
|
* rights of the EC as specified by the rights mask.
|
|
|
|
*
|
|
|
|
* The cap is supposed to be returned to clients,
|
|
|
|
* which they have to use as argument to identify
|
|
|
|
* the thread to which they want attach portals.
|
|
|
|
*
|
|
|
|
* The demotion by the kernel during the map operation
|
|
|
|
* takes care that the EC cap itself contains
|
|
|
|
* no usable rights for the clients.
|
|
|
|
*/
|
|
|
|
bool res = utcb->append_item(Obj_crd(obj->_state.sel_client_ec, 0,
|
|
|
|
Obj_crd::RIGHT_EC_RECALL), 0);
|
|
|
|
(void)res;
|
|
|
|
}
|
|
|
|
|
2013-09-26 12:31:56 +00:00
|
|
|
/* semaphore for signaling thread is requested, reuse PT_SEL_STARTUP. */
|
|
|
|
if (event == ~0UL - 1) {
|
|
|
|
/* create semaphore only once */
|
|
|
|
if (!obj->_state.has_signal_sm()) {
|
|
|
|
|
|
|
|
revoke(Obj_crd(obj->exc_pt_sel_client() + PT_SEL_STARTUP, 0));
|
|
|
|
|
|
|
|
bool res = Nova::create_sm(obj->exc_pt_sel_client() + PT_SEL_STARTUP,
|
2016-11-10 10:46:30 +00:00
|
|
|
platform_specific()->core_pd_sel(), 0);
|
2013-09-26 12:31:56 +00:00
|
|
|
if (res != Nova::NOVA_OK)
|
|
|
|
reply(myself->stack_top());
|
|
|
|
|
|
|
|
obj->_state.mark_signal_sm();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool res = utcb->append_item(Obj_crd(obj->exc_pt_sel_client() +
|
|
|
|
PT_SEL_STARTUP, 0), 0);
|
|
|
|
(void)res;
|
|
|
|
}
|
|
|
|
|
2012-08-23 09:02:31 +00:00
|
|
|
reply(myself->stack_top());
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-26 13:16:01 +00:00
|
|
|
void Pager_object::wake_up()
|
|
|
|
{
|
2016-05-17 14:13:56 +00:00
|
|
|
Lock::Guard _state_lock_guard(_state_lock);
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
if (!_state.blocked())
|
|
|
|
return;
|
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
_state.thread.exception = false;
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
_state.unblock();
|
2013-09-26 13:16:01 +00:00
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
uint8_t res = sm_ctrl(sel_sm_block_pause(), SEMAPHORE_UP);
|
2014-09-05 15:00:31 +00:00
|
|
|
if (res != NOVA_OK)
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
warning("canceling blocked client failed (thread sm)");
|
2013-09-26 13:16:01 +00:00
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2012-08-22 10:10:04 +00:00
|
|
|
|
2013-01-11 22:10:21 +00:00
|
|
|
void Pager_object::client_cancel_blocking()
|
|
|
|
{
|
2013-09-23 07:07:33 +00:00
|
|
|
uint8_t res = sm_ctrl(exc_pt_sel_client() + SM_SEL_EC, SEMAPHORE_UP);
|
2012-08-24 08:25:24 +00:00
|
|
|
if (res != NOVA_OK)
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
warning("canceling blocked client failed (thread sm)");
|
2013-09-26 12:31:56 +00:00
|
|
|
|
|
|
|
if (!_state.has_signal_sm())
|
|
|
|
return;
|
|
|
|
|
|
|
|
res = sm_ctrl(exc_pt_sel_client() + PT_SEL_STARTUP, SEMAPHORE_UP);
|
|
|
|
if (res != NOVA_OK)
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
warning("canceling blocked client failed (signal sm)");
|
2012-08-24 08:25:24 +00:00
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2012-08-22 10:10:04 +00:00
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
uint8_t Pager_object::client_recall(bool get_state_and_block)
|
|
|
|
{
|
|
|
|
Lock::Guard _state_lock_guard(_state_lock);
|
|
|
|
return _unsynchronized_client_recall(get_state_and_block);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t Pager_object::_unsynchronized_client_recall(bool get_state_and_block)
|
2013-01-11 22:10:21 +00:00
|
|
|
{
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
enum { STATE_REQUESTED = 1UL, STATE_INVALID = ~0UL };
|
2016-05-17 14:13:56 +00:00
|
|
|
|
|
|
|
uint8_t res = ec_ctrl(EC_RECALL, _state.sel_client_ec,
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
get_state_and_block ? STATE_REQUESTED : STATE_INVALID);
|
2016-05-17 14:13:56 +00:00
|
|
|
|
|
|
|
if (res != NOVA_OK)
|
|
|
|
return res;
|
|
|
|
|
|
|
|
if (get_state_and_block) {
|
|
|
|
Utcb *utcb = reinterpret_cast<Utcb *>(Thread::myself()->utcb());
|
|
|
|
_copy_state_from_utcb(utcb);
|
|
|
|
_state.block();
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
2012-08-22 10:10:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-04 08:49:01 +00:00
|
|
|
void Pager_object::cleanup_call()
|
|
|
|
{
|
2014-09-05 15:00:31 +00:00
|
|
|
_state.mark_dissolved();
|
|
|
|
|
2016-04-20 19:12:57 +00:00
|
|
|
/* revoke ec and sc cap of client before the sm cap */
|
|
|
|
if (_state.sel_client_ec != Native_thread::INVALID_INDEX)
|
|
|
|
revoke(Obj_crd(_state.sel_client_ec, 2));
|
|
|
|
|
2013-09-23 07:07:33 +00:00
|
|
|
/* revoke all portals handling the client. */
|
|
|
|
revoke(Obj_crd(exc_pt_sel_client(), NUM_INITIAL_PT_LOG2));
|
2012-12-04 08:49:01 +00:00
|
|
|
|
2016-05-04 10:27:17 +00:00
|
|
|
Utcb *utcb = reinterpret_cast<Utcb *>(Thread::myself()->utcb());
|
2012-12-04 08:49:01 +00:00
|
|
|
utcb->set_msg_word(0);
|
2014-09-05 15:00:31 +00:00
|
|
|
utcb->mtd = 0;
|
|
|
|
if (uint8_t res = call(sel_pt_cleanup()))
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
error(utcb, " - cleanup call to pager failed res=", res);
|
2012-12-04 08:49:01 +00:00
|
|
|
}
|
|
|
|
|
2013-09-26 12:31:56 +00:00
|
|
|
|
2016-09-05 09:24:51 +00:00
|
|
|
void Pager_object::print(Output &out) const
|
|
|
|
{
|
|
|
|
Platform_thread * faulter = reinterpret_cast<Platform_thread *>(_badge);
|
|
|
|
Genode::print(out, "pager_object: pd='",
|
|
|
|
faulter ? faulter->pd_name() : "unknown", "' thread='",
|
|
|
|
faulter ? faulter->name() : "unknown", "'");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-22 14:26:43 +00:00
|
|
|
static uint8_t create_portal(addr_t pt, addr_t pd, addr_t ec, Mtd mtd,
|
2015-06-09 17:33:53 +00:00
|
|
|
addr_t eip, Pager_object * oom_handler)
|
2013-02-22 14:26:43 +00:00
|
|
|
{
|
2016-11-30 18:36:32 +00:00
|
|
|
uint8_t res = syscall_retry(*oom_handler,
|
|
|
|
[&]() { return create_pt(pt, pd, ec, mtd, eip); });
|
2013-02-22 14:26:43 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
if (res != NOVA_OK)
|
|
|
|
return res;
|
|
|
|
|
2016-11-30 18:36:32 +00:00
|
|
|
addr_t const badge_localname = reinterpret_cast<addr_t>(oom_handler);
|
|
|
|
|
2015-06-09 17:33:53 +00:00
|
|
|
res = pt_ctrl(pt, badge_localname);
|
2013-02-22 14:26:43 +00:00
|
|
|
if (res == NOVA_OK)
|
|
|
|
revoke(Obj_crd(pt, 0, Obj_crd::RIGHT_PT_CTRL));
|
2014-09-05 15:00:31 +00:00
|
|
|
else
|
|
|
|
revoke(Obj_crd(pt, 0));
|
2013-02-22 14:26:43 +00:00
|
|
|
|
2013-09-26 12:31:56 +00:00
|
|
|
return res;
|
2013-02-22 14:26:43 +00:00
|
|
|
}
|
2012-12-04 08:49:01 +00:00
|
|
|
|
2013-09-26 12:31:56 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/************************
|
|
|
|
** Exception handlers **
|
|
|
|
************************/
|
|
|
|
|
|
|
|
template <uint8_t EV>
|
|
|
|
void Exception_handlers::register_handler(Pager_object *obj, Mtd mtd,
|
|
|
|
void (* __attribute__((regparm(1))) func)(addr_t))
|
|
|
|
{
|
2016-11-04 12:01:09 +00:00
|
|
|
unsigned const genode_cpu_id = obj->location().xpos();
|
|
|
|
unsigned const kernel_cpu_id = platform_specific()->kernel_cpu_id(genode_cpu_id);
|
2016-09-23 15:47:36 +00:00
|
|
|
|
2016-11-04 12:01:09 +00:00
|
|
|
if (!kernel_hip()->is_cpu_enabled(kernel_cpu_id) ||
|
|
|
|
!pager_threads[genode_cpu_id]) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
warning("invalid CPU parameter used in pager object");
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
throw Invalid_thread();
|
2015-10-06 11:49:49 +00:00
|
|
|
}
|
2014-09-05 15:00:31 +00:00
|
|
|
|
2016-11-04 12:01:09 +00:00
|
|
|
addr_t const ec_sel = pager_threads[genode_cpu_id]->native_thread().ec_sel;
|
2014-09-05 15:00:31 +00:00
|
|
|
|
|
|
|
/* compiler generates instance of exception entry if not specified */
|
|
|
|
addr_t entry = func ? (addr_t)func : (addr_t)(&_handler<EV>);
|
|
|
|
uint8_t res = create_portal(obj->exc_pt_sel_client() + EV,
|
2016-11-10 10:46:30 +00:00
|
|
|
platform_specific()->core_pd_sel(), ec_sel, mtd, entry, obj);
|
2014-09-05 15:00:31 +00:00
|
|
|
if (res != Nova::NOVA_OK)
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
throw Invalid_thread();
|
2014-09-05 15:00:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <uint8_t EV>
|
|
|
|
void Exception_handlers::_handler(addr_t obj)
|
|
|
|
{
|
|
|
|
Pager_object * pager_obj = reinterpret_cast<Pager_object *>(obj);
|
|
|
|
pager_obj->exception(EV);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Exception_handlers::Exception_handlers(Pager_object *obj)
|
|
|
|
{
|
|
|
|
register_handler<0>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<1>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<2>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<3>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<4>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<5>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<6>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<7>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<8>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<9>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<10>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<11>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<12>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<13>(obj, Mtd(Mtd::EIP));
|
|
|
|
|
|
|
|
register_handler<15>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<16>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<17>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<18>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<19>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<20>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<21>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<22>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<23>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<24>(obj, Mtd(Mtd::EIP));
|
|
|
|
register_handler<25>(obj, Mtd(Mtd::EIP));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************
|
|
|
|
** Pager object **
|
|
|
|
******************/
|
|
|
|
|
|
|
|
|
2016-04-20 19:12:57 +00:00
|
|
|
Pager_object::Pager_object(Cpu_session_capability cpu_session_cap,
|
|
|
|
Thread_capability thread_cap, unsigned long badge,
|
2016-09-05 09:24:51 +00:00
|
|
|
Affinity::Location location, Session_label const &,
|
|
|
|
Cpu_session::Name const &)
|
2013-11-14 09:35:44 +00:00
|
|
|
:
|
2014-09-05 15:00:31 +00:00
|
|
|
_badge(badge),
|
|
|
|
_selectors(cap_map()->insert(2)),
|
|
|
|
_client_exc_pt_sel(cap_map()->insert(NUM_INITIAL_PT_LOG2)),
|
2016-04-20 19:12:57 +00:00
|
|
|
_cpu_session_cap(cpu_session_cap), _thread_cap(thread_cap),
|
2016-09-23 15:47:36 +00:00
|
|
|
_location(location),
|
2016-11-24 20:57:33 +00:00
|
|
|
_exceptions(this),
|
2016-11-30 18:36:32 +00:00
|
|
|
_pd_target(Native_thread::INVALID_INDEX)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2012-08-23 09:02:31 +00:00
|
|
|
uint8_t res;
|
|
|
|
|
2016-11-10 10:46:30 +00:00
|
|
|
addr_t const pd_sel = platform_specific()->core_pd_sel();
|
2013-09-26 13:16:01 +00:00
|
|
|
_state._status = 0;
|
2016-05-17 14:13:56 +00:00
|
|
|
_state.modified = false;
|
2012-08-23 09:02:31 +00:00
|
|
|
_state.sel_client_ec = Native_thread::INVALID_INDEX;
|
2016-05-17 14:13:56 +00:00
|
|
|
_state.block();
|
2012-08-23 09:02:31 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
if (Native_thread::INVALID_INDEX == _selectors ||
|
|
|
|
Native_thread::INVALID_INDEX == _client_exc_pt_sel)
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
throw Invalid_thread();
|
2013-09-23 07:07:33 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* ypos information not supported by now */
|
|
|
|
if (location.ypos()) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
warning("unsupported location ", location.xpos(), "x", location.ypos());
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
throw Invalid_thread();
|
2012-08-23 09:02:31 +00:00
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* place Pager_object on specified CPU by selecting proper pager thread */
|
2016-11-04 12:01:09 +00:00
|
|
|
unsigned const genode_cpu_id = location.xpos();
|
|
|
|
unsigned const kernel_cpu_id = platform_specific()->kernel_cpu_id(genode_cpu_id);
|
|
|
|
if (!kernel_hip()->is_cpu_enabled(kernel_cpu_id) ||
|
|
|
|
!pager_threads[genode_cpu_id]) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
warning("invalid CPU parameter used in pager object");
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
throw Invalid_thread();
|
2015-10-06 11:49:49 +00:00
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2016-11-04 12:01:09 +00:00
|
|
|
addr_t ec_sel = pager_threads[genode_cpu_id]->native_thread().ec_sel;
|
2012-08-23 09:02:31 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* create portal for page-fault handler - 14 */
|
|
|
|
_exceptions.register_handler<14>(this, Mtd::QUAL | Mtd::EIP,
|
|
|
|
_page_fault_handler);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* create portal for startup handler - 26 */
|
|
|
|
Mtd const mtd_startup(Mtd::ESP | Mtd::EIP);
|
|
|
|
_exceptions.register_handler<PT_SEL_STARTUP>(this, mtd_startup,
|
|
|
|
_startup_handler);
|
|
|
|
|
|
|
|
/* create portal for recall handler - 31 */
|
|
|
|
Mtd const mtd_recall(Mtd::ESP | Mtd::EIP | Mtd::ACDB | Mtd::EFL |
|
|
|
|
Mtd::EBSD | Mtd::FSGS);
|
|
|
|
_exceptions.register_handler<PT_SEL_RECALL>(this, mtd_recall,
|
|
|
|
_recall_handler);
|
2012-08-24 08:25:24 +00:00
|
|
|
|
2013-09-23 07:07:33 +00:00
|
|
|
/*
|
|
|
|
* Create semaphore required for Genode locking. It can be later on
|
|
|
|
* requested by the thread the same way as all exception portals.
|
|
|
|
*/
|
|
|
|
res = Nova::create_sm(exc_pt_sel_client() + SM_SEL_EC, pd_sel, 0);
|
|
|
|
if (res != Nova::NOVA_OK) {
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
throw Invalid_thread();
|
2013-09-23 07:07:33 +00:00
|
|
|
}
|
|
|
|
|
2013-01-11 22:10:21 +00:00
|
|
|
/* create portal for final cleanup call used during destruction */
|
2014-09-05 15:00:31 +00:00
|
|
|
res = create_portal(sel_pt_cleanup(), pd_sel, ec_sel, Mtd(0),
|
2015-06-09 17:33:53 +00:00
|
|
|
reinterpret_cast<addr_t>(_invoke_handler), this);
|
2014-09-05 15:00:31 +00:00
|
|
|
if (res != Nova::NOVA_OK) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
error("could not create pager cleanup portal, error=", res);
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
throw Invalid_thread();
|
2014-09-05 15:00:31 +00:00
|
|
|
}
|
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
/* semaphore used to block paged thread during recall */
|
|
|
|
res = Nova::create_sm(sel_sm_block_pause(), pd_sel, 0);
|
2014-09-05 15:00:31 +00:00
|
|
|
if (res != Nova::NOVA_OK) {
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
throw Invalid_thread();
|
2012-08-24 08:25:24 +00:00
|
|
|
}
|
|
|
|
|
2016-05-17 14:13:56 +00:00
|
|
|
/* semaphore used to block paged thread during OOM memory revoke */
|
|
|
|
res = Nova::create_sm(sel_sm_block_oom(), pd_sel, 0);
|
2012-08-24 08:25:24 +00:00
|
|
|
if (res != Nova::NOVA_OK) {
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
throw Invalid_thread();
|
2012-08-24 08:25:24 +00:00
|
|
|
}
|
2012-06-19 13:54:41 +00:00
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2013-01-11 22:10:21 +00:00
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
Pager_object::~Pager_object()
|
|
|
|
{
|
2014-09-05 15:00:31 +00:00
|
|
|
/* sanity check that object got dissolved already - otherwise bug */
|
|
|
|
if (!_state.dissolved())
|
|
|
|
nova_die();
|
2013-01-16 15:07:04 +00:00
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/* revoke portal used for the cleanup call and sm cap for blocking state */
|
|
|
|
revoke(Obj_crd(_selectors, 2));
|
|
|
|
cap_map()->remove(_selectors, 2, false);
|
2013-09-11 08:45:23 +00:00
|
|
|
cap_map()->remove(exc_pt_sel_client(), NUM_INITIAL_PT_LOG2, false);
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
2016-11-24 20:57:33 +00:00
|
|
|
|
2015-06-09 17:33:53 +00:00
|
|
|
uint8_t Pager_object::handle_oom(addr_t transfer_from,
|
|
|
|
char const * src_pd, char const * src_thread,
|
|
|
|
enum Pager_object::Policy policy)
|
|
|
|
{
|
2016-11-28 09:54:06 +00:00
|
|
|
return handle_oom(transfer_from, pd_sel(), src_pd, src_thread, policy,
|
|
|
|
sel_sm_block_oom(), client_pd(), client_thread());
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t Pager_object::handle_oom(addr_t pd_from, addr_t pd_to,
|
|
|
|
char const * src_pd, char const * src_thread,
|
|
|
|
Policy policy, addr_t sm_notify,
|
|
|
|
char const * dst_pd, char const * dst_thread)
|
|
|
|
{
|
2016-11-10 10:46:30 +00:00
|
|
|
addr_t const core_pd_sel = platform_specific()->core_pd_sel();
|
2015-06-09 17:33:53 +00:00
|
|
|
|
|
|
|
enum { QUOTA_TRANSFER_PAGES = 2 };
|
|
|
|
|
2016-11-28 09:54:06 +00:00
|
|
|
if (pd_from == SRC_CORE_PD)
|
|
|
|
pd_from = core_pd_sel;
|
2015-06-09 17:33:53 +00:00
|
|
|
|
|
|
|
/* request current kernel quota usage of target pd */
|
|
|
|
addr_t limit_before = 0, usage_before = 0;
|
2016-11-28 09:54:06 +00:00
|
|
|
Nova::pd_ctrl_debug(pd_to, limit_before, usage_before);
|
2015-06-09 17:33:53 +00:00
|
|
|
|
|
|
|
if (verbose_oom) {
|
|
|
|
addr_t limit_source = 0, usage_source = 0;
|
|
|
|
/* request current kernel quota usage of source pd */
|
2016-11-28 09:54:06 +00:00
|
|
|
Nova::pd_ctrl_debug(pd_from, limit_source, usage_source);
|
2015-06-09 17:33:53 +00:00
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
log("oom - '", dst_pd, "':'", dst_thread, "' "
|
|
|
|
"(", usage_before, "/", limit_before, ") - "
|
|
|
|
"transfer ", (long)QUOTA_TRANSFER_PAGES, " pages "
|
|
|
|
"from '", src_pd, "':'", src_thread, "' "
|
|
|
|
"(", usage_source, "/", limit_source, ")");
|
2015-06-09 17:33:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t res = Nova::NOVA_PD_OOM;
|
|
|
|
|
2016-11-28 09:54:06 +00:00
|
|
|
if (pd_from != pd_to) {
|
2015-06-09 17:33:53 +00:00
|
|
|
/* upgrade quota */
|
2016-11-28 09:54:06 +00:00
|
|
|
uint8_t res = Nova::pd_ctrl(pd_from, Pd_op::TRANSFER_QUOTA,
|
|
|
|
pd_to, QUOTA_TRANSFER_PAGES);
|
2015-06-09 17:33:53 +00:00
|
|
|
if (res == Nova::NOVA_OK)
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* retry upgrade using core quota if policy permits */
|
|
|
|
if (policy == UPGRADE_PREFER_SRC_TO_DST) {
|
2016-11-28 09:54:06 +00:00
|
|
|
if (pd_from != core_pd_sel) {
|
2016-11-10 10:46:30 +00:00
|
|
|
res = Nova::pd_ctrl(core_pd_sel, Pd_op::TRANSFER_QUOTA,
|
2016-11-28 09:54:06 +00:00
|
|
|
pd_to, QUOTA_TRANSFER_PAGES);
|
2015-06-09 17:33:53 +00:00
|
|
|
if (res == Nova::NOVA_OK)
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
warning("kernel memory quota upgrade failed - trigger memory free up for "
|
|
|
|
"causing '", dst_pd, "':'", dst_thread, "' - "
|
|
|
|
"donator is '", src_pd, "':'", src_thread, "', "
|
|
|
|
"policy=", (int)policy);
|
2015-06-09 17:33:53 +00:00
|
|
|
|
|
|
|
/* if nothing helps try to revoke memory */
|
|
|
|
enum { REMOTE_REVOKE = true, PD_SELF = true };
|
|
|
|
Mem_crd crd_all(0, ~0U, Rights(true, true, true));
|
2016-11-28 09:54:06 +00:00
|
|
|
Nova::revoke(crd_all, PD_SELF, REMOTE_REVOKE, pd_to, sm_notify);
|
2015-06-09 17:33:53 +00:00
|
|
|
|
|
|
|
/* re-request current kernel quota usage of target pd */
|
|
|
|
addr_t limit_after = 0, usage_after = 0;
|
2016-11-28 09:54:06 +00:00
|
|
|
Nova::pd_ctrl_debug(pd_to, limit_after, usage_after);
|
2015-06-09 17:33:53 +00:00
|
|
|
/* if we could free up memory we continue */
|
|
|
|
if (usage_after < usage_before)
|
|
|
|
return Nova::NOVA_OK;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* There is still the chance that memory gets freed up, but one has to
|
|
|
|
* wait until RCU period is over. If we are in the pager code, we can
|
|
|
|
* instruct the kernel to block the faulting client thread during the reply
|
|
|
|
* syscall. If we are in a normal (non-pagefault) RPC service call,
|
|
|
|
* we can't block. The caller of this function can decide based on
|
|
|
|
* the return value what to do and whether blocking is ok.
|
|
|
|
*/
|
|
|
|
return Nova::NOVA_PD_OOM;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Pager_object::_oom_handler(addr_t pager_dst, addr_t pager_src,
|
|
|
|
addr_t reason)
|
|
|
|
{
|
|
|
|
if (sizeof(void *) == 4) {
|
|
|
|
/* On 32 bit edx and ecx as second and third regparm parameter is not
|
|
|
|
* available. It is used by the kernel internally to store ip/sp.
|
|
|
|
*/
|
|
|
|
asm volatile ("" : "=D" (pager_src));
|
|
|
|
asm volatile ("" : "=S" (reason));
|
|
|
|
}
|
|
|
|
|
2016-05-04 10:27:17 +00:00
|
|
|
Thread * myself = Thread::myself();
|
2015-06-09 17:33:53 +00:00
|
|
|
Utcb * utcb = reinterpret_cast<Utcb *>(myself->utcb());
|
|
|
|
Pager_object * obj_dst = reinterpret_cast<Pager_object *>(pager_dst);
|
|
|
|
Pager_object * obj_src = reinterpret_cast<Pager_object *>(pager_src);
|
|
|
|
|
|
|
|
/* Policy used if the Process of the paged thread runs out of memory */
|
|
|
|
enum Policy policy = Policy::UPGRADE_CORE_TO_DST;
|
|
|
|
|
|
|
|
|
|
|
|
/* check assertions - cases that should not happen on Genode@Nova */
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
enum { NO_OOM_PT = 0UL };
|
2015-06-09 17:33:53 +00:00
|
|
|
|
|
|
|
/* all relevant (user) threads should have a OOM PT */
|
|
|
|
bool assert = pager_dst == NO_OOM_PT;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This pager thread does solely reply to IPC calls - it should never
|
|
|
|
* cause OOM during the sending phase of a IPC.
|
|
|
|
*/
|
|
|
|
assert |= ((reason & (SELF | SEND)) == (SELF | SEND));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This pager thread should never send words (untyped items) - it just
|
|
|
|
* answers page faults by typed items (memory mappings).
|
|
|
|
*/
|
|
|
|
assert |= utcb->msg_words();
|
|
|
|
|
|
|
|
if (assert) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
error("unknown OOM case - stop core pager thread");
|
2015-06-09 17:33:53 +00:00
|
|
|
utcb->set_msg_word(0);
|
2016-03-11 16:32:43 +00:00
|
|
|
reply(myself->stack_top(), myself->native_thread().exc_pt_sel + Nova::SM_SEL_EC);
|
2015-06-09 17:33:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* be strict in case of the -strict- STOP policy - stop causing thread */
|
|
|
|
if (policy == STOP) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
error("PD has insufficient kernel memory left - stop thread");
|
2015-06-09 17:33:53 +00:00
|
|
|
utcb->set_msg_word(0);
|
2016-05-17 14:13:56 +00:00
|
|
|
reply(myself->stack_top(), obj_dst->sel_sm_block_pause());
|
2015-06-09 17:33:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char const * src_pd = "core";
|
|
|
|
char const * src_thread = "pager";
|
|
|
|
|
|
|
|
addr_t transfer_from = SRC_CORE_PD;
|
|
|
|
|
|
|
|
switch (pager_src) {
|
|
|
|
case SRC_PD_UNKNOWN:
|
|
|
|
/* should not happen on Genode - we create and know every PD in core */
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
error("Unknown PD has insufficient kernel memory left - stop thread");
|
2015-06-09 17:33:53 +00:00
|
|
|
utcb->set_msg_word(0);
|
2016-03-11 16:32:43 +00:00
|
|
|
reply(myself->stack_top(), myself->native_thread().exc_pt_sel + Nova::SM_SEL_EC);
|
2015-06-09 17:33:53 +00:00
|
|
|
|
|
|
|
case SRC_CORE_PD:
|
|
|
|
/* core PD -> other PD, which has insufficient kernel resources */
|
|
|
|
|
|
|
|
if (!(reason & SELF)) {
|
|
|
|
/* case that src thread != this thread in core */
|
|
|
|
src_thread = "unknown";
|
|
|
|
utcb->set_msg_word(0);
|
|
|
|
}
|
|
|
|
|
2016-11-10 10:46:30 +00:00
|
|
|
transfer_from = platform_specific()->core_pd_sel();
|
2015-06-09 17:33:53 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* non core PD -> non core PD */
|
|
|
|
utcb->set_msg_word(0);
|
|
|
|
|
|
|
|
if (pager_src == pager_dst || policy == UPGRADE_CORE_TO_DST)
|
2016-11-10 10:46:30 +00:00
|
|
|
transfer_from = platform_specific()->core_pd_sel();
|
2015-06-09 17:33:53 +00:00
|
|
|
else {
|
|
|
|
/* delegation of items between different PDs */
|
2016-05-19 18:33:36 +00:00
|
|
|
src_pd = obj_src->client_pd();
|
|
|
|
src_thread = obj_src->client_thread();
|
2015-06-09 17:33:53 +00:00
|
|
|
transfer_from = obj_src->pd_sel();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t res = obj_dst->handle_oom(transfer_from, src_pd, src_thread,
|
|
|
|
policy);
|
|
|
|
if (res == Nova::NOVA_OK)
|
|
|
|
/* handling succeeded - continue with original IPC */
|
|
|
|
reply(myself->stack_top());
|
|
|
|
|
|
|
|
/* transfer nothing */
|
|
|
|
utcb->set_msg_word(0);
|
|
|
|
|
|
|
|
if (res != Nova::NOVA_PD_OOM)
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
error("upgrading kernel memory failed, policy ", (int)policy, ", "
|
|
|
|
"error ", (int)res, " - stop thread finally");
|
|
|
|
|
2015-06-09 17:33:53 +00:00
|
|
|
/* else: caller will get blocked until RCU period is over */
|
|
|
|
|
|
|
|
/* block caller in semaphore */
|
2016-05-17 14:13:56 +00:00
|
|
|
reply(myself->stack_top(), obj_dst->sel_sm_block_oom());
|
2015-06-09 17:33:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
addr_t Pager_object::get_oom_portal()
|
|
|
|
{
|
2016-11-04 12:01:09 +00:00
|
|
|
addr_t const pt_oom = sel_oom_portal();
|
|
|
|
unsigned const genode_cpu_id = _location.xpos();
|
|
|
|
unsigned const kernel_cpu_id = platform_specific()->kernel_cpu_id(genode_cpu_id);
|
2016-11-10 10:46:30 +00:00
|
|
|
addr_t const core_pd_sel = platform_specific()->core_pd_sel();
|
2015-06-09 17:33:53 +00:00
|
|
|
|
2016-11-04 12:01:09 +00:00
|
|
|
if (kernel_hip()->is_cpu_enabled(kernel_cpu_id) &&
|
|
|
|
pager_threads[genode_cpu_id]) {
|
2015-10-06 11:49:49 +00:00
|
|
|
|
2016-11-04 12:01:09 +00:00
|
|
|
addr_t const ec_sel = pager_threads[genode_cpu_id]->native_thread().ec_sel;
|
2016-11-10 10:46:30 +00:00
|
|
|
uint8_t res = create_portal(pt_oom, core_pd_sel, ec_sel, Mtd(0),
|
2015-10-06 11:49:49 +00:00
|
|
|
reinterpret_cast<addr_t>(_oom_handler),
|
|
|
|
this);
|
|
|
|
if (res == Nova::NOVA_OK)
|
|
|
|
return pt_oom;
|
|
|
|
}
|
2015-06-09 17:33:53 +00:00
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
error("creating portal for out of memory notification failed");
|
2015-06-09 17:33:53 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2016-05-19 18:33:36 +00:00
|
|
|
const char * Pager_object::client_thread() const
|
|
|
|
{
|
|
|
|
Platform_thread * client = reinterpret_cast<Platform_thread *>(_badge);
|
|
|
|
return client ? client->name() : "unknown";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char * Pager_object::client_pd() const
|
|
|
|
{
|
|
|
|
Platform_thread * client = reinterpret_cast<Platform_thread *>(_badge);
|
|
|
|
return client ? client->pd_name() : "unknown";
|
|
|
|
}
|
|
|
|
|
2014-09-05 15:00:31 +00:00
|
|
|
/**********************
|
|
|
|
** Pager activation **
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
Pager_activation_base::Pager_activation_base(const char *name, size_t stack_size)
|
|
|
|
:
|
2016-05-04 10:27:17 +00:00
|
|
|
Thread(Cpu_session::Weight::DEFAULT_WEIGHT, name, stack_size,
|
|
|
|
Affinity::Location(which_cpu(this), 0)),
|
2014-09-05 15:00:31 +00:00
|
|
|
_cap(Native_capability()), _ep(0), _cap_valid(Lock::LOCKED)
|
|
|
|
{
|
|
|
|
/* creates local EC */
|
2016-05-04 10:27:17 +00:00
|
|
|
Thread::start();
|
2014-09-05 15:00:31 +00:00
|
|
|
|
2016-05-04 10:27:17 +00:00
|
|
|
reinterpret_cast<Nova::Utcb *>(Thread::utcb())->crd_xlt = Obj_crd(0, ~0UL);
|
2014-09-05 15:00:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Pager_activation_base::entry() { }
|
|
|
|
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
** Pager entrypoint **
|
|
|
|
**********************/
|
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &)
|
2014-09-05 15:00:31 +00:00
|
|
|
{
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
/* sanity check for pager threads */
|
2014-09-05 15:00:31 +00:00
|
|
|
if (kernel_hip()->cpu_max() > PAGER_CPUS) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
error("kernel supports more CPUs (", kernel_hip()->cpu_max(), ") "
|
|
|
|
"than Genode (", (unsigned)PAGER_CPUS, ")");
|
2014-09-05 15:00:31 +00:00
|
|
|
nova_die();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* detect enabled CPUs and create per CPU a pager thread */
|
|
|
|
typedef Pager_activation<PAGER_STACK_SIZE> Pager;
|
|
|
|
Pager * pager_of_cpu = reinterpret_cast<Pager *>(&pager_activation_mem);
|
|
|
|
|
2016-11-04 12:01:09 +00:00
|
|
|
for (unsigned i = 0; i < kernel_hip()->cpus(); i++, pager_of_cpu++) {
|
|
|
|
unsigned const kernel_cpu_id = platform_specific()->kernel_cpu_id(i);
|
|
|
|
if (!kernel_hip()->is_cpu_enabled(kernel_cpu_id))
|
2014-09-05 15:00:31 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
pager_threads[i] = pager_of_cpu;
|
|
|
|
construct_at<Pager>(pager_threads[i]);
|
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Pager_entrypoint::dissolve(Pager_object *obj)
|
|
|
|
{
|
2014-09-05 15:00:31 +00:00
|
|
|
/* take care that no faults are in-flight */
|
2012-12-04 08:49:01 +00:00
|
|
|
obj->cleanup_call();
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|