Merge "[rialto] Handle page table exceptions in rialto" into main
diff --git a/rialto/src/exceptions.rs b/rialto/src/exceptions.rs
index 3c12c25..b806b08 100644
--- a/rialto/src/exceptions.rs
+++ b/rialto/src/exceptions.rs
@@ -14,13 +14,37 @@
//! Exception handlers.
-use vmbase::{console::emergency_write_str, eprintln, power::reboot, read_sysreg};
+use vmbase::{
+ console::emergency_write_str,
+ eprintln,
+ exceptions::{ArmException, Esr, HandleExceptionError},
+ logger,
+ memory::{handle_permission_fault, handle_translation_fault},
+ power::reboot,
+ read_sysreg,
+};
+
+fn handle_exception(exception: &ArmException) -> Result<(), HandleExceptionError> {
+ // Handle all translation faults on both read and write, and MMIO guard map
+ // flagged invalid pages or blocks that caused the exception.
+ // Handle permission faults for DBM flagged entries, and flag them as dirty on write.
+ match exception.esr {
+ Esr::DataAbortTranslationFault => handle_translation_fault(exception.far),
+ Esr::DataAbortPermissionFault => handle_permission_fault(exception.far),
+ _ => Err(HandleExceptionError::UnknownException),
+ }
+}
#[no_mangle]
-extern "C" fn sync_exception_current() {
- emergency_write_str("sync_exception_current\n");
- print_esr();
- reboot();
+extern "C" fn sync_exception_current(elr: u64, _spsr: u64) {
+ // Disable logging in exception handler to prevent unsafe writes to UART.
+ let _guard = logger::suppress();
+
+ let exception = ArmException::from_el1_regs();
+ if let Err(e) = handle_exception(&exception) {
+ exception.print("sync_exception_current", e, elr);
+ reboot()
+ }
}
#[no_mangle]