mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
sel4: handle non pagefault exceptions
by checking for it in core, submitting a signal (if registered) and not replying instantly. Before this commit, an exception (a non page fault) caused and endless "unknown exception" loop between originator and core. This was handled before commit "core: kernel-agnostic 'Mapping' type" by throwing an exception, which was with that commit not working anymore. Fixes #4751
This commit is contained in:
parent
79d389d812
commit
d089e80906
@ -31,10 +31,10 @@ class Genode::Ipc_pager : public Native_capability
|
||||
addr_t _reply_sel = 0; /* selector to save reply cap */
|
||||
addr_t _pf_addr = 0; /* page-fault address */
|
||||
addr_t _pf_ip = 0; /* instruction pointer of faulter */
|
||||
addr_t _fault_type = 0; /* type of fault */
|
||||
bool _pf_write = false; /* true on write fault */
|
||||
bool _pf_exec = false; /* true on exec fault */
|
||||
bool _pf_align = false; /* true on unaligned fault */
|
||||
bool _exception = false; /* true on non page fault */
|
||||
bool _pf_write = false; /* true on write fault */
|
||||
bool _pf_exec = false; /* true on exec fault */
|
||||
bool _pf_align = false; /* true on unaligned fault */
|
||||
|
||||
Mapping _reply_mapping { };
|
||||
|
||||
@ -99,6 +99,11 @@ class Genode::Ipc_pager : public Native_capability
|
||||
* Install memory mapping after pager code executed.
|
||||
*/
|
||||
bool install_mapping();
|
||||
|
||||
/**
|
||||
* Return true if last fault was an exception
|
||||
*/
|
||||
bool exception() const { return _exception; }
|
||||
};
|
||||
|
||||
#endif /* _CORE__INCLUDE__IPC_PAGER_H_ */
|
||||
|
@ -87,6 +87,8 @@ void Ipc_pager::reply_and_wait_for_fault()
|
||||
|
||||
addr_t const fault_type = seL4_MessageInfo_get_label(page_fault_msg_info);
|
||||
|
||||
_exception = fault_type != seL4_Fault_VMFault;
|
||||
|
||||
auto fault_name = [] (addr_t type)
|
||||
{
|
||||
switch (type) {
|
||||
@ -203,6 +205,22 @@ void Pager_entrypoint::entry()
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
/* on exception (beside page fault) don't reply and submit signal */
|
||||
if (_pager.exception()) {
|
||||
warning("exception ", _pager.fault_addr(), " ",
|
||||
*obj, " ip=", Hex(_pager.fault_ip()));
|
||||
obj->submit_exception_signal();
|
||||
return;
|
||||
}
|
||||
|
||||
/* on alignment fault don't reply and submit signal */
|
||||
if (_pager.align_fault()) {
|
||||
warning("alignment fault, addr=", Hex(_pager.fault_addr()),
|
||||
" ip=", Hex(_pager.fault_ip()));
|
||||
reply_pending = false;
|
||||
obj->submit_exception_signal();
|
||||
}
|
||||
|
||||
/* send reply if page-fault handling succeeded */
|
||||
reply_pending = !obj->pager(_pager);
|
||||
if (!reply_pending) {
|
||||
@ -213,20 +231,9 @@ void Pager_entrypoint::entry()
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
/* install memory mappings */
|
||||
if (_pager.install_mapping())
|
||||
return;
|
||||
|
||||
/* on alignment fault don't reply and submit signal */
|
||||
if (_pager.align_fault()) {
|
||||
warning("alignment fault, addr=", Hex(_pager.fault_addr()),
|
||||
" ip=", Hex(_pager.fault_ip()));
|
||||
throw 1;
|
||||
}
|
||||
} catch (...) {
|
||||
reply_pending = false;
|
||||
obj->submit_exception_signal();
|
||||
/* install memory mappings */
|
||||
if (_pager.install_mapping()) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 Genode Labs GmbH
|
||||
* Copyright (C) 2017-2023 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
@ -26,10 +26,29 @@ struct Fault_info
|
||||
DFSR_WRITE_FAULT = 1UL << 11
|
||||
};
|
||||
|
||||
Fault_info(seL4_MessageInfo_t)
|
||||
Genode::addr_t _ip_from_message(seL4_MessageInfo_t &info) const
|
||||
{
|
||||
auto const fault_type = seL4_MessageInfo_get_label(info);
|
||||
|
||||
if (fault_type == seL4_Fault_UserException)
|
||||
return seL4_Fault_UserException_get_FaultIP(seL4_getFault(info));
|
||||
else
|
||||
return seL4_GetMR(0);
|
||||
}
|
||||
|
||||
Genode::addr_t _pf_from_message(seL4_MessageInfo_t &info) const
|
||||
{
|
||||
auto const fault_type = seL4_MessageInfo_get_label(info);
|
||||
if (fault_type == seL4_Fault_UserException)
|
||||
return seL4_Fault_UserException_get_Number(seL4_getFault(info));
|
||||
else
|
||||
return seL4_GetMR(1);
|
||||
}
|
||||
|
||||
Fault_info(seL4_MessageInfo_t info)
|
||||
:
|
||||
ip(seL4_GetMR(0)),
|
||||
pf(seL4_GetMR(1)),
|
||||
ip(_ip_from_message(info)),
|
||||
pf(_pf_from_message(info)),
|
||||
data_abort(seL4_GetMR(2) != IFSR_FAULT),
|
||||
/* Instruction Fault Status Register (IFSR) resp. Data FSR (DFSR) */
|
||||
write(data_abort && (seL4_GetMR(3) & DFSR_WRITE_FAULT)),
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 Genode Labs GmbH
|
||||
* Copyright (C) 2017-2023 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
@ -13,9 +13,9 @@
|
||||
|
||||
struct Fault_info
|
||||
{
|
||||
Genode::addr_t ip = 0;
|
||||
Genode::addr_t pf = 0;
|
||||
bool write = 0;
|
||||
Genode::addr_t const ip;
|
||||
Genode::addr_t const pf;
|
||||
bool const write;
|
||||
|
||||
/*
|
||||
* Intel manual: 6.15 EXCEPTION AND INTERRUPT REFERENCE
|
||||
@ -29,10 +29,30 @@ struct Fault_info
|
||||
ERR_P = 1 << 0,
|
||||
};
|
||||
|
||||
Fault_info(seL4_MessageInfo_t)
|
||||
Genode::addr_t _ip_from_message(seL4_MessageInfo_t &info) const
|
||||
{
|
||||
auto const fault_type = seL4_MessageInfo_get_label(info);
|
||||
|
||||
if (fault_type == seL4_Fault_UserException)
|
||||
return seL4_Fault_UserException_get_FaultIP(seL4_getFault(info));
|
||||
else
|
||||
return seL4_GetMR(0);
|
||||
}
|
||||
|
||||
Genode::addr_t _pf_from_message(seL4_MessageInfo_t &info) const
|
||||
{
|
||||
auto const fault_type = seL4_MessageInfo_get_label(info);
|
||||
|
||||
if (fault_type == seL4_Fault_UserException)
|
||||
return seL4_Fault_UserException_get_Number(seL4_getFault(info));
|
||||
else
|
||||
return seL4_GetMR(1);
|
||||
}
|
||||
|
||||
Fault_info(seL4_MessageInfo_t info)
|
||||
:
|
||||
ip(seL4_GetMR(0)),
|
||||
pf(seL4_GetMR(1)),
|
||||
ip(_ip_from_message(info)),
|
||||
pf(_pf_from_message(info)),
|
||||
write(seL4_GetMR(3) & ERR_W)
|
||||
{ }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user