diff --git a/repos/base-sel4/src/core/include/ipc_pager.h b/repos/base-sel4/src/core/include/ipc_pager.h index 0f3838a974..c140aac982 100644 --- a/repos/base-sel4/src/core/include/ipc_pager.h +++ b/repos/base-sel4/src/core/include/ipc_pager.h @@ -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_ */ diff --git a/repos/base-sel4/src/core/pager.cc b/repos/base-sel4/src/core/pager.cc index ee1f0d6dca..f67c775548 100644 --- a/repos/base-sel4/src/core/pager.cc +++ b/repos/base-sel4/src/core/pager.cc @@ -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; } }); } diff --git a/repos/base-sel4/src/core/spec/arm/fault_info.h b/repos/base-sel4/src/core/spec/arm/fault_info.h index 4a6ceebaa0..29cee4b3d4 100644 --- a/repos/base-sel4/src/core/spec/arm/fault_info.h +++ b/repos/base-sel4/src/core/spec/arm/fault_info.h @@ -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)), diff --git a/repos/base-sel4/src/core/spec/x86/fault_info.h b/repos/base-sel4/src/core/spec/x86/fault_info.h index 00e7be1822..6c2de35b4c 100644 --- a/repos/base-sel4/src/core/spec/x86/fault_info.h +++ b/repos/base-sel4/src/core/spec/x86/fault_info.h @@ -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) { }