summaryrefslogtreecommitdiff
path: root/Kernel/Arch
diff options
context:
space:
mode:
authorTimon Kruiper <timonkruiper@gmail.com>2023-02-18 10:26:30 +0100
committerJelle Raaijmakers <jelle@gmta.nl>2023-02-18 19:17:21 +0100
commit5d587ea5626e92f91edcd522ea7eb0effef68eca (patch)
tree7b66cf9dd7a4440ead539d804733bbff4121ad87 /Kernel/Arch
parent6b66e39df443d4be087cb1b9cb1eeba5341811b0 (diff)
downloadserenity-5d587ea5626e92f91edcd522ea7eb0effef68eca.zip
Kernel/aarch64: Call handle_crash on unknown exceptions
This is useful for debugging, as it will now print out a userspace backtrace, and optionally also dump the memory regions of the process.
Diffstat (limited to 'Kernel/Arch')
-rw-r--r--Kernel/Arch/aarch64/Interrupts.cpp17
1 files changed, 11 insertions, 6 deletions
diff --git a/Kernel/Arch/aarch64/Interrupts.cpp b/Kernel/Arch/aarch64/Interrupts.cpp
index 955392a4fb..d05ce2bf02 100644
--- a/Kernel/Arch/aarch64/Interrupts.cpp
+++ b/Kernel/Arch/aarch64/Interrupts.cpp
@@ -53,7 +53,7 @@ void dump_registers(RegisterState const& regs)
dbgln("x30={:p}", regs.x[30]);
}
-static PageFault page_fault_from_exception_syndrome_register(VirtualAddress fault_address, Aarch64::ESR_EL1 esr_el1)
+static ErrorOr<PageFault> page_fault_from_exception_syndrome_register(VirtualAddress fault_address, Aarch64::ESR_EL1 esr_el1)
{
PageFault fault { fault_address };
@@ -63,7 +63,8 @@ static PageFault page_fault_from_exception_syndrome_register(VirtualAddress faul
} else if (data_fault_status_code >= 0b000100 && data_fault_status_code <= 0b000111) {
fault.set_type(PageFault::Type::PageNotPresent);
} else {
- PANIC("Unknown DFSC: {}", data_fault_status_code);
+ dbgln("Unknown DFSC: {}", Aarch64::data_fault_status_code_to_string(esr_el1.ISS));
+ return Error::from_errno(EFAULT);
}
fault.set_access((esr_el1.ISS & (1 << 6)) == (1 << 6) ? PageFault::Access::Write : PageFault::Access::Read);
@@ -86,13 +87,17 @@ extern "C" void exception_common(Kernel::TrapFrame* trap_frame)
Processor::enable_interrupts();
if (Aarch64::exception_class_is_data_abort(esr_el1.EC) || Aarch64::exception_class_is_instruction_abort(esr_el1.EC)) {
- auto page_fault = page_fault_from_exception_syndrome_register(VirtualAddress(fault_address), esr_el1);
- page_fault.handle(*trap_frame->regs);
+ auto page_fault_or_error = page_fault_from_exception_syndrome_register(VirtualAddress(fault_address), esr_el1);
+ if (page_fault_or_error.is_error()) {
+ handle_crash(*trap_frame->regs, "Unknown page fault", SIGSEGV, false);
+ } else {
+ auto page_fault = page_fault_or_error.release_value();
+ page_fault.handle(*trap_frame->regs);
+ }
} else if (Aarch64::exception_class_is_svc_instruction_execution(esr_el1.EC)) {
syscall_handler(trap_frame);
} else {
- dump_registers(*trap_frame->regs);
- PANIC("Unexpected exception!");
+ handle_crash(*trap_frame->regs, "Unexpected exception", SIGSEGV, false);
}
Processor::disable_interrupts();