From dacbea02d63c70afaa6dc3952f3aebe2bd15d6d3 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Wed, 10 Nov 2021 09:53:44 +0200 Subject: [PATCH] fix: unhandled data abort in EL1 in syscalls --- kernel/src/arch/aarch64/exception.rs | 24 ++++++++++++------------ kernel/src/proc/process.rs | 2 +- kernel/src/proc/sched.rs | 4 ++++ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/kernel/src/arch/aarch64/exception.rs b/kernel/src/arch/aarch64/exception.rs index 35ade3a..7be2b26 100644 --- a/kernel/src/arch/aarch64/exception.rs +++ b/kernel/src/arch/aarch64/exception.rs @@ -3,7 +3,7 @@ use crate::arch::machine; use crate::debug::Level; use crate::dev::irq::{IntController, IrqContext}; -use crate::proc::Process; +use crate::proc::{sched, Process}; use crate::mem; use crate::syscall; use ::syscall::abi; @@ -65,7 +65,7 @@ extern "C" fn __aa64_exc_irq_handler(_exc: &mut ExceptionFrame) { fn dump_data_abort(level: Level, esr: u64, far: u64) { let iss = esr & 0x1FFFFFF; - println!(level, "Data Abort:"); + println!(level, "\x1B[41;1mData Abort:"); print!(level, " Illegal {}", data_abort_access_type(iss),); if iss & (1 << 24) != 0 { @@ -86,30 +86,30 @@ extern "C" fn __aa64_exc_sync_handler(exc: &mut ExceptionFrame) { #[allow(clippy::single_match)] match err_code { - EC_DATA_ABORT_ELX => { - let far = FAR_EL1.get(); - dump_data_abort(Level::Error, esr, far); - } - EC_DATA_ABORT_EL0 => { + EC_DATA_ABORT_EL0 | EC_DATA_ABORT_ELX => { let far = FAR_EL1.get() as usize; - let proc = Process::current(); - if far < mem::KERNEL_OFFSET { + if far < mem::KERNEL_OFFSET && sched::is_ready() { + let proc = Process::current(); + if let Err(e) = proc.manipulate_space(|space| space.try_cow_copy(far)) { // Kill program + dump_data_abort(Level::Error, esr, far as u64); panic!("CoW copy returned {:?}", e); } + unsafe { use cortex_a::registers::TTBR0_EL1; let ttbr = TTBR0_EL1.get() as usize; let asid = (ttbr >> 48) & 0xFF; asm!("tlbi aside1, {}", in(reg) (asid << 48)); } + return; - } else { - // Kill program - todo!() } + + errorln!("Unresolved data abort"); + dump_data_abort(Level::Error, esr, far as u64); } EC_SVC_AA64 => { unsafe { diff --git a/kernel/src/proc/process.rs b/kernel/src/proc/process.rs index a63e786..9d2c2c1 100644 --- a/kernel/src/proc/process.rs +++ b/kernel/src/proc/process.rs @@ -295,8 +295,8 @@ impl Process { if let Some(space) = lock.space.take() { unsafe { - // TODO invalidate everything related to this ASID Space::release(space); + asm!("tlbi aside1, {}", in(reg) ((lock.id.asid() as usize) << 48)); } } diff --git a/kernel/src/proc/sched.rs b/kernel/src/proc/sched.rs index 82d5f5f..333aca8 100644 --- a/kernel/src/proc/sched.rs +++ b/kernel/src/proc/sched.rs @@ -126,6 +126,10 @@ impl Scheduler { } } +pub fn is_ready() -> bool { + SCHED.inner.is_initialized() +} + #[inline(never)] extern "C" fn idle_fn(_a: usize) -> ! { loop {