fix: unhandled data abort in EL1 in syscalls

This commit is contained in:
2021-11-10 09:53:44 +02:00
parent 8db1120b92
commit dacbea02d6
3 changed files with 17 additions and 13 deletions
+12 -12
View File
@@ -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 {
+1 -1
View File
@@ -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));
}
}
+4
View File
@@ -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 {