base: unify page-fault notification for kernels

* Enable page-fault messages for regions not directly managed by core
* Unify output given when a page-fault occurs related to those regions

Fix #2082
This commit is contained in:
Stefan Kalkowski 2016-09-05 11:24:51 +02:00 committed by Christian Helmuth
parent 97201e6778
commit 2147c42ec6
27 changed files with 142 additions and 141 deletions

View File

@ -98,18 +98,6 @@ namespace Genode {
constexpr size_t get_super_page_size() { return L4_SUPERPAGESIZE; }
constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; }
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Region_map::State::Fault_type pf_type,
unsigned long badge)
{
Fiasco::l4_threadid_t tid;
tid.raw = badge;
printf("%s (%s pf_addr=%p pf_ip=%p from %x.%02x)\n", msg,
pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
(void *)pf_addr, (void *)pf_ip,
(int)tid.id.task, (int)tid.id.lthread);
}
inline addr_t map_src_addr(addr_t core_local_addr, addr_t phys_addr) {
return core_local_addr; }

View File

@ -133,7 +133,9 @@ static void _core_pager_loop()
Platform::Sigma0::Sigma0()
:
Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location())
Pager_object(Cpu_session_capability(), Thread_capability(),
0, Affinity::Location(), Session_label(),
Cpu_session::Name("sigma0"))
{
cap(Capability_space::import(Fiasco::sigma0_threadid, Rpc_obj_key()));
}
@ -149,7 +151,9 @@ Platform::Sigma0 *Platform::sigma0()
Platform::Core_pager::Core_pager(Platform_pd *core_pd)
:
Platform_thread(0, "core.pager"),
Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location())
Pager_object(Cpu_session_capability(), Thread_capability(),
0, Affinity::Location(), Session_label(),
Cpu_session::Name(name()))
{
Platform_thread::pager(sigma0());

View File

@ -97,15 +97,6 @@ namespace Genode {
constexpr size_t get_super_page_size() { return L4_SUPERPAGESIZE; }
constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; }
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Region_map::State::Fault_type pf_type,
unsigned long badge)
{
printf("%s (%s pf_addr=%p pf_ip=%p from %lx)\n", msg,
pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
(void *)pf_addr, (void *)pf_ip, badge);
}
inline addr_t map_src_addr(addr_t core_local_addr, addr_t phys_addr) {
return core_local_addr; }

View File

@ -69,9 +69,9 @@ void Pager_entrypoint::entry()
/* handle request */
if (obj->pager(_pager)) {
/* could not resolv - leave thread in pagefault */
warning("could not resolve "
"pf=", Hex(_pager.fault_addr()), " ",
"ip=", Hex(_pager.fault_ip()));
warning("page-fault, ", *obj,
" ip=", Hex(_pager.fault_ip()),
" pf-addr=", Hex(_pager.fault_addr()));
} else {
_pager.set_reply_dst(Native_thread(obj->badge()));
reply_pending = true;

View File

@ -126,7 +126,9 @@ static void _core_pager_loop()
Platform::Sigma0::Sigma0(Cap_index* i)
:
Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location())
Pager_object(Cpu_session_capability(), Thread_capability(),
0, Affinity::Location(), Session_label(),
Cpu_session::Name("sigma0"))
{
/*
* We use the Pager_object here in a slightly different manner,
@ -139,7 +141,9 @@ Platform::Sigma0::Sigma0(Cap_index* i)
Platform::Core_pager::Core_pager(Platform_pd *core_pd, Sigma0 *sigma0)
:
Platform_thread("core.pager"),
Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location())
Pager_object(Cpu_session_capability(), Thread_capability(),
0, Affinity::Location(), Session_label(),
Cpu_session::Name(name()))
{
Platform_thread::pager(sigma0);

View File

@ -15,6 +15,7 @@
#define _CORE__INCLUDE__PAGER_H_
/* Genode includes */
#include <base/session_label.h>
#include <base/thread.h>
#include <base/object_pool.h>
#include <base/signal.h>
@ -142,7 +143,8 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry,
*/
Pager_object(Cpu_session_capability cpu_session_cap,
Thread_capability thread_cap, unsigned const badge,
Affinity::Location);
Affinity::Location, Session_label const&,
Cpu_session::Name const&);
/**
* User identification of pager object
@ -171,6 +173,8 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry,
*/
void unresolved_page_fault_occurred();
void print(Output &out) const;
/******************
** Pure virtual **

View File

@ -104,41 +104,6 @@ namespace Genode
if (size_log2<20) return 12;
return 20;
}
/**
* Print debug output on page faults
*
* \param fault_msg introductory message
* \param fault_addr target address of the fault access
* \param fault_ip instruction pointer of the faulter
* \param fault_type access type of fault
* \param faulter_badge user identification of faulter
*/
inline void print_page_fault(char const * const fault_msg,
addr_t const fault_addr,
addr_t const fault_ip,
Region_map::State::Fault_type const fault_type,
unsigned const faulter_badge);
}
void Genode::print_page_fault(char const * const fault_msg,
addr_t const fault_addr,
addr_t const fault_ip,
Region_map::State::Fault_type const fault_type,
unsigned const faulter_badge)
{
const char read[] = "read from";
const char write[] = "write to";
printf("\033[31m%s\033[0m (faulter %x", fault_msg, faulter_badge);
printf(" with IP %p attempts to", (void *)fault_ip);
printf(" %s", fault_type == Region_map::State::READ_FAULT ? read : write);
printf(" address %p)\n", (void *)fault_addr);
if (ACTIVITY_TABLE_ON_FAULTS) {
printf("---------- activity table ----------\n");
Kernel::print_char(0);
printf("\n");
}
}
#endif /* _CORE__INCLUDE__UTIL_H_ */

View File

@ -86,15 +86,24 @@ void Pager_object::unresolved_page_fault_occurred()
{
Platform_thread * const pt = (Platform_thread *)badge();
if (pt && pt->pd())
error(pt->pd()->label(), " -> ", pt->label(), ": unresolved pagefault at "
"ip=", pt->kernel_object()->ip, " "
"sp=", pt->kernel_object()->sp, " "
"fault address=", pt->kernel_object()->fault_addr());
warning("page fault, pager_object: pd='", pt->pd()->label(),
"' thread='", pt->label(),
"' ip=", Hex(pt->kernel_object()->ip),
" pf-addr=", Hex(pt->kernel_object()->fault_addr()));
}
void Pager_object::print(Output &out) const
{
Platform_thread * const pt = (Platform_thread *)badge();
if (pt && pt->pd())
Genode::print(out, "pager_object: pd='", pt->pd()->label(),
"' thread='", pt->label(), "'");
}
Pager_object::Pager_object(Cpu_session_capability cpu_session_cap,
Thread_capability thread_cap, unsigned const badge,
Affinity::Location)
Affinity::Location, Session_label const &,
Cpu_session::Name const &)
:
Object_pool<Pager_object>::Entry(Kernel_object<Kernel::Signal_context>::_cap),
_badge(badge), _cpu_session_cap(cpu_session_cap), _thread_cap(thread_cap)

View File

@ -20,6 +20,7 @@
#include <util/list.h>
#include <base/allocator.h>
#include <base/rpc_server.h>
#include <base/session_label.h>
#include <region_map/region_map.h>
/* core includes */
@ -73,7 +74,8 @@ struct Genode::Rm_client : Pager_object, Rm_member
Rm_client(Cpu_session_capability, Thread_capability,
Region_map_component *rm, unsigned long badge,
Weak_ptr<Address_space> &address_space,
Affinity::Location location)
Affinity::Location location, Cpu_session::Name const&,
Session_label const&)
{ }
};

View File

@ -58,7 +58,7 @@ void Thread::_thread_start()
lx_sigaltstack(stack_base, stack_size);
if (stack_size < 0x1000)
raw("small stack of ", stack_size, " bytes for \"", thread->name(),
"\" may may break Linux signal handling");
"\" may break Linux signal handling");
/*
* Set signal handler such that canceled system calls get not

View File

@ -18,6 +18,7 @@
#include <base/thread.h>
#include <base/object_pool.h>
#include <base/capability.h>
#include <base/session_label.h>
#include <cap_session/cap_session.h>
#include <pager/capability.h>
@ -152,7 +153,9 @@ namespace Genode {
Pager_object(Cpu_session_capability cpu_session_cap,
Thread_capability thread_cap,
unsigned long badge, Affinity::Location location);
unsigned long badge, Affinity::Location location,
Genode::Session_label const &,
Cpu_session::Name const &);
virtual ~Pager_object();
@ -362,6 +365,8 @@ namespace Genode {
const char * pd = "core",
const char * thread = "unknown",
Policy = Policy::UPGRADE_CORE_TO_DST);
void print(Output &out) const;
};
/**

View File

@ -41,19 +41,6 @@ namespace Genode {
}
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Region_map::State::Fault_type pf_type,
unsigned long faulter_badge)
{
Platform_thread * faulter = reinterpret_cast<Platform_thread *>(faulter_badge);
printf("%s (%s pf_addr=%p pf_ip=%p from %02lx '%s':'%s')\n", msg,
pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
(void *)pf_addr, (void *)pf_ip,
faulter_badge, faulter ? faulter->pd_name() : "unknown",
faulter ? faulter->name() : "unknown");
}
inline void backtrace()
{
using namespace Genode;

View File

@ -470,6 +470,15 @@ void Pager_object::cleanup_call()
}
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", "'");
}
static uint8_t create_portal(addr_t pt, addr_t pd, addr_t ec, Mtd mtd,
addr_t eip, Pager_object * oom_handler)
{
@ -564,7 +573,8 @@ Exception_handlers::Exception_handlers(Pager_object *obj)
Pager_object::Pager_object(Cpu_session_capability cpu_session_cap,
Thread_capability thread_cap, unsigned long badge,
Affinity::Location location)
Affinity::Location location, Session_label const &,
Cpu_session::Name const &)
:
_badge(badge),
_selectors(cap_map()->insert(2)),

View File

@ -120,9 +120,8 @@ static void page_fault_handler()
addr_t pf_sp = utcb->sp;
addr_t pf_type = utcb->qual[0];
print_page_fault("\nPAGE-FAULT IN CORE", pf_addr, pf_ip,
(pf_type & Ipc_pager::ERR_W) ? Region_map::State::WRITE_FAULT
: Region_map::State::READ_FAULT, 0);
error("\nPAGE-FAULT IN CORE addr=", Hex(pf_addr), " ip=", Hex(pf_ip),
" (", (pf_type & Ipc_pager::ERR_W) ? "write" : "read", ")");
log("\nstack pointer ", Hex(pf_sp), ", qualifiers ", Hex(pf_type), " ",
pf_type & Ipc_pager::ERR_I ? "I" : "i",

View File

@ -113,15 +113,6 @@ namespace Genode {
return trunc_page(page + get_page_size() - 1);
}
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Region_map::State::Fault_type pf_type,
unsigned long faulter_badge)
{
log(pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ", " (",
msg, " pf_addr=", Hex(pf_addr), " pf_ip=", Hex(pf_ip), " "
"from ", Hex(faulter_badge), ")");
}
inline addr_t map_src_addr(addr_t core_local, addr_t phys) { return phys; }
inline size_t constrain_map_size_log2(size_t size_log2) { return size_log2; }

View File

@ -107,18 +107,6 @@ namespace Genode {
return trunc_page(addr + get_page_size() - 1);
}
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Region_map::State::Fault_type pf_type,
unsigned long badge)
{
Pistachio::L4_ThreadId_t tid;
tid.raw = badge;
log(msg, " (",
pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ", " "
"pf_addr=", Hex(pf_addr), " pf_ip=", Hex(pf_ip), " "
"from ", Formatted_tid(tid), ")");
}
inline addr_t map_src_addr(addr_t core_local_addr, addr_t phys_addr) {
return core_local_addr; }

View File

@ -204,7 +204,9 @@ static void _core_pager_loop()
Platform::Sigma0::Sigma0()
:
Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location())
Pager_object(Cpu_session_capability(), Thread_capability(),
0, Affinity::Location(),
Session_label(), Cpu_session::Name("sigma0"))
{
cap(Capability_space::import(Pistachio::get_sigma0(), Rpc_obj_key()));
}
@ -220,7 +222,9 @@ Platform::Sigma0 *Platform::sigma0()
Platform::Core_pager::Core_pager(Platform_pd *core_pd)
:
Platform_thread(0, "core.pager"),
Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location())
Pager_object(Cpu_session_capability(), Thread_capability(),
0, Affinity::Location(),
Session_label(), Cpu_session::Name(name()))
{
Platform_thread::pager(sigma0());

View File

@ -19,6 +19,7 @@
/* Genode includes */
#include <base/thread.h>
#include <base/object_pool.h>
#include <base/session_label.h>
#include <cap_session/cap_session.h>
#include <pager/capability.h>
#include <ipc_pager.h>
@ -66,6 +67,9 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry
*/
Signal_context_capability _exception_sigh;
Session_label _pd_label;
Cpu_session::Name _name;
public:
/**
@ -78,8 +82,10 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry
*
* \param location affinity of paged thread to physical CPU
*/
Pager_object(Cpu_session_capability cpu_sesion, Thread_capability thread,
unsigned long badge, Affinity::Location location);
Pager_object(Cpu_session_capability cpu_session, Thread_capability thread,
unsigned long badge, Affinity::Location location,
Session_label const &pd_label,
Cpu_session::Name const &name);
~Pager_object();
@ -138,6 +144,15 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry
* fault occurred.
*/
void unresolved_page_fault_occurred();
/*
* Print pager object belonging
*/
void print(Output &out) const
{
Genode::print(out, "pager_object: pd='", _pd_label,
"' thread='", _name, "'");
}
};

View File

@ -33,17 +33,6 @@ namespace Genode {
inline addr_t map_src_addr(addr_t core_local, addr_t phys) { return phys; }
inline size_t constrain_map_size_log2(size_t size_log2) { return get_page_size_log2(); }
inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip,
Region_map::State::Fault_type pf_type,
unsigned long faulter_badge)
{
printf("%s (%s pf_addr=%p pf_ip=%p from %02lx)\n", msg,
pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
(void *)pf_addr, (void *)pf_ip,
faulter_badge);
}
}
#endif /* _CORE__INCLUDE__UTIL_H_ */

View File

@ -101,12 +101,15 @@ Ipc_pager::Ipc_pager() : _last(0), _reply_sel(0) { }
** Pager object **
******************/
Pager_object::Pager_object(Cpu_session_capability cpu_sesion,
Pager_object::Pager_object(Cpu_session_capability cpu_session,
Thread_capability thread,
unsigned long badge, Affinity::Location location)
unsigned long badge, Affinity::Location location,
Session_label const &pd_label,
Cpu_session::Name const &name)
:
_badge(badge), _cpu_session_cap(cpu_sesion), _thread_cap(thread),
_reply_cap(platform_specific()->core_sel_alloc().alloc())
_badge(badge), _cpu_session_cap(cpu_session), _thread_cap(thread),
_reply_cap(platform_specific()->core_sel_alloc().alloc()),
_pd_label(pd_label), _name(name)
{ }
@ -192,8 +195,12 @@ void Pager_entrypoint::entry()
/* send reply if page-fault handling succeeded */
reply_pending = !obj->pager(_pager);
if (!reply_pending)
if (!reply_pending) {
warning("page-fault, ", *obj,
" ip=", Hex(_pager.fault_ip()),
" pf-addr=", Hex(_pager.fault_addr()));
_pager.reply_save_caller(obj->reply_cap_sel());
}
});
}
}

View File

@ -18,9 +18,9 @@
#include <util/list.h>
#include <base/allocator_guard.h>
#include <base/lock.h>
#include <base/session_label.h>
#include <base/rpc_server.h>
#include <cpu_session/cpu_session.h>
#include <base/session_label.h>
/* core includes */
#include <pager.h>

View File

@ -149,7 +149,8 @@ class Genode::Cpu_thread_component : public Rpc_object<Cpu_thread>,
_rm_client(cpu_session_cap, _ep.manage(this),
&_address_space_region_map,
_platform_thread.pager_object_badge(),
_address_space, _platform_thread.affinity())
_address_space, _platform_thread.affinity(),
pd.label(), name)
{
_address_space_region_map.add_client(_rm_client);

View File

@ -17,6 +17,7 @@
#define _CORE__INCLUDE__PAGER_H_
/* Genode includes */
#include <base/session_label.h>
#include <base/thread.h>
#include <base/object_pool.h>
#include <cap_session/cap_session.h>
@ -64,6 +65,9 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry
*/
Signal_context_capability _exception_sigh;
Session_label _pd_label;
Cpu_session::Name _name;
public:
/**
@ -76,10 +80,14 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry
*
* \param location affinity of paged thread to physical CPU
*/
Pager_object(Cpu_session_capability cpu_sesion, Thread_capability thread,
unsigned long badge, Affinity::Location location)
Pager_object(Cpu_session_capability cpu_sesion,
Thread_capability thread,
unsigned long badge, Affinity::Location location,
Session_label const &pd_label,
Cpu_session::Name const &name)
:
_badge(badge), _cpu_session_cap(cpu_sesion), _thread_cap(thread)
_badge(badge), _cpu_session_cap(cpu_sesion), _thread_cap(thread),
_pd_label(pd_label), _name(name)
{ }
virtual ~Pager_object() { }
@ -137,6 +145,15 @@ class Genode::Pager_object : public Object_pool<Pager_object>::Entry
* fault occurred.
*/
void unresolved_page_fault_occurred();
/*
* Print pager object belonging
*/
void print(Output &out) const
{
Genode::print(out, "pager_object: pd='", _pd_label,
"' thread='", _name, "'");
}
};

View File

@ -18,6 +18,7 @@
/* Genode includes */
#include <base/allocator_guard.h>
#include <base/session_label.h>
#include <base/rpc_server.h>
#include <pd_session/pd_session.h>
#include <util/arg_string.h>
@ -134,6 +135,8 @@ class Genode::Pd_session_component : public Rpc_object<Pd_session>
return _address_space;
}
Session_label label() { return Session_label(_label.string); }
/**************************
** PD session interface **

View File

@ -21,6 +21,7 @@
#include <base/capability.h>
#include <pager.h>
#include <base/allocator_avl.h>
#include <base/session_label.h>
#include <base/synced_allocator.h>
#include <base/signal.h>
#include <base/rpc_server.h>
@ -190,10 +191,12 @@ class Genode::Rm_client : public Pager_object, public Rm_faulter,
Thread_capability thread,
Region_map_component *rm, unsigned long badge,
Weak_ptr<Address_space> &address_space,
Affinity::Location location)
Affinity::Location location,
Session_label const &pd_label,
Cpu_session::Name const &name)
:
Pager_object(cpu_session, thread, badge, location), Rm_faulter(this),
_region_map(rm), _address_space(address_space)
Pager_object(cpu_session, thread, badge, location, pd_label, name),
Rm_faulter(this), _region_map(rm), _address_space(address_space)
{ }
int pager(Ipc_pager &pager);

View File

@ -40,6 +40,10 @@ void Pager_entrypoint::entry()
else
/* send reply if page-fault handling succeeded */
reply_pending = !obj->pager(_pager);
if (!reply_pending)
warning("page-fault, ", *obj,
" ip=", Hex(_pager.fault_ip()),
" pf-addr=", Hex(_pager.fault_addr()));
} else {
/*

View File

@ -149,6 +149,17 @@ struct Genode::Region_map_component::Fault_area
using namespace Genode;
static void print_page_fault(char const *msg,
addr_t pf_addr,
addr_t pf_ip,
Region_map::State::Fault_type pf_type,
Pager_object const &obj)
{
log(msg, " (",
pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
" pf_addr=", Hex(pf_addr), " pf_ip=", Hex(pf_ip), " from ", obj, ")");
}
/***********************
** Region-map client **
@ -168,7 +179,7 @@ int Rm_client::pager(Ipc_pager &pager)
addr_t pf_ip = pager.fault_ip();
if (verbose_page_faults)
print_page_fault("page fault", pf_addr, pf_ip, pf_type, badge());
print_page_fault("page fault", pf_addr, pf_ip, pf_type, *this);
auto lambda = [&] (Region_map_component *region_map,
Rm_region *region,
@ -187,7 +198,7 @@ int Rm_client::pager(Ipc_pager &pager)
/* print a warning if it's no managed-dataspace */
if (region_map == member_rm())
print_page_fault("no RM attachment", pf_addr, pf_ip,
pf_type, badge());
pf_type, *this);
/* register fault at responsible region map */
if (region_map)
@ -223,7 +234,7 @@ int Rm_client::pager(Ipc_pager &pager)
/* attempted there is no attachment return an error condition */
print_page_fault("attempted write at read-only memory",
pf_addr, pf_ip, pf_type, badge());
pf_addr, pf_ip, pf_type, *this);
/* register fault at responsible region map */
region_map->fault(this, src_fault_area.fault_addr(), pf_type);