From d0884a9019a7e940ea5e620ce64f491239570163 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Tue, 7 Jul 2020 17:38:21 +0800 Subject: [PATCH] Fix rdhwr simulation --- kernel/src/arch/aarch64/interrupt/consts.rs | 4 ++++ kernel/src/arch/aarch64/interrupt/mod.rs | 4 ++++ kernel/src/arch/mipsel/interrupt/consts.rs | 9 +++++++ kernel/src/arch/mipsel/interrupt/mod.rs | 26 ++++++--------------- kernel/src/arch/riscv/interrupt/consts.rs | 4 ++++ kernel/src/arch/riscv/interrupt/mod.rs | 4 ++++ kernel/src/arch/x86_64/interrupt/consts.rs | 4 ++++ kernel/src/arch/x86_64/interrupt/mod.rs | 4 ++++ kernel/src/process/thread.rs | 14 +++++++++-- 9 files changed, 52 insertions(+), 21 deletions(-) diff --git a/kernel/src/arch/aarch64/interrupt/consts.rs b/kernel/src/arch/aarch64/interrupt/consts.rs index 7023e8c1..b0362c37 100644 --- a/kernel/src/arch/aarch64/interrupt/consts.rs +++ b/kernel/src/arch/aarch64/interrupt/consts.rs @@ -40,3 +40,7 @@ pub fn is_intr(trap: usize) -> bool { pub fn is_timer_intr(trap: usize) -> bool { trap == Timer } + +pub fn is_reserved_inst(trap: usize) -> bool { + false +} diff --git a/kernel/src/arch/aarch64/interrupt/mod.rs b/kernel/src/arch/aarch64/interrupt/mod.rs index 8cc79e30..9eb6e307 100644 --- a/kernel/src/arch/aarch64/interrupt/mod.rs +++ b/kernel/src/arch/aarch64/interrupt/mod.rs @@ -74,3 +74,7 @@ pub fn wait_for_interrupt() { pub fn handle_user_page_fault(thread: &Arc, addr: usize) -> bool { thread.vm.lock().handle_page_fault(addr) } + +pub fn handle_reserved_inst(tf: &mut UserContext) -> bool { + false +} diff --git a/kernel/src/arch/mipsel/interrupt/consts.rs b/kernel/src/arch/mipsel/interrupt/consts.rs index 0da9800b..f2a5cdb9 100644 --- a/kernel/src/arch/mipsel/interrupt/consts.rs +++ b/kernel/src/arch/mipsel/interrupt/consts.rs @@ -37,3 +37,12 @@ pub fn is_timer_intr(trap: usize) -> bool { _ => false, } } + +pub fn is_reserved_inst(trap: usize) -> bool { + use cp0::cause::Exception as E; + let cause = cp0::cause::Cause { bits: trap as u32 }; + match cause.cause() { + E::ReservedInstruction => true, + _ => false, + } +} diff --git a/kernel/src/arch/mipsel/interrupt/mod.rs b/kernel/src/arch/mipsel/interrupt/mod.rs index 7d11d28b..1fd94525 100644 --- a/kernel/src/arch/mipsel/interrupt/mod.rs +++ b/kernel/src/arch/mipsel/interrupt/mod.rs @@ -71,16 +71,6 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) { E::TLBModification => page_fault(tf), E::TLBLoadMiss => page_fault(tf), E::TLBStoreMiss => page_fault(tf), - E::ReservedInstruction => { - if !reserved_inst(tf) { - error!("Unhandled Exception @ CPU{}: {:?} ", 0, cause.cause()); - } else { - tf.epc = tf.epc + 4; - } - } - E::CoprocessorUnusable => { - tf.epc = tf.epc + 4; - } _ => { error!("Unhandled Exception @ CPU{}: {:?} ", 0, cause.cause()); } @@ -163,7 +153,7 @@ fn syscall(tf: &mut TrapFrame) { } } -fn set_trapframe_register(rt: usize, val: usize, tf: &mut TrapFrame) { +fn set_trapframe_register(rt: usize, val: usize, tf: &mut UserContext) { match rt { 1 => tf.general.at = val, 2 => tf.general.v0 = val, @@ -203,7 +193,7 @@ fn set_trapframe_register(rt: usize, val: usize, tf: &mut TrapFrame) { } } -fn reserved_inst(tf: &mut TrapFrame) -> bool { +pub fn handle_reserved_inst(tf: &mut UserContext) -> bool { let inst = unsafe { *(tf.epc as *const usize) }; let opcode = inst >> 26; @@ -214,20 +204,18 @@ fn reserved_inst(tf: &mut TrapFrame) -> bool { if inst == 0x42000020 { // ignore WAIT + tf.epc = tf.epc + 4; return true; } if opcode == 0b011111 && format == 0b111011 { - // RDHWR + // RDHWR UserLocal if rd == 29 && sel == 0 { - extern "C" { - fn _cur_tls(); - } - - let tls = unsafe { *(_cur_tls as *const usize) }; + let tls = tf.tls; set_trapframe_register(rt, tls, tf); - debug!("Read TLS by rdhdr {:x} to register {:?}", tls, rt); + debug!("Read TLS by rdhwr {:x} to register {:?}", tls, rt); + tf.epc = tf.epc + 4; return true; } else { return false; diff --git a/kernel/src/arch/riscv/interrupt/consts.rs b/kernel/src/arch/riscv/interrupt/consts.rs index 92392de9..01e20bc9 100644 --- a/kernel/src/arch/riscv/interrupt/consts.rs +++ b/kernel/src/arch/riscv/interrupt/consts.rs @@ -25,3 +25,7 @@ pub fn is_intr(trap: usize) -> bool { pub fn is_timer_intr(trap: usize) -> bool { trap == Timer } + +pub fn is_reserved_inst(trap: usize) -> bool { + false +} diff --git a/kernel/src/arch/riscv/interrupt/mod.rs b/kernel/src/arch/riscv/interrupt/mod.rs index 5b5f33d9..ea4f1d44 100644 --- a/kernel/src/arch/riscv/interrupt/mod.rs +++ b/kernel/src/arch/riscv/interrupt/mod.rs @@ -119,3 +119,7 @@ pub fn wait_for_interrupt() { pub fn handle_user_page_fault(thread: &Arc, addr: usize) -> bool { thread.vm.lock().handle_page_fault(addr) } + +pub fn handle_reserved_inst(tf: &mut UserContext) -> bool { + false +} diff --git a/kernel/src/arch/x86_64/interrupt/consts.rs b/kernel/src/arch/x86_64/interrupt/consts.rs index 80f9d7e4..58126f9e 100644 --- a/kernel/src/arch/x86_64/interrupt/consts.rs +++ b/kernel/src/arch/x86_64/interrupt/consts.rs @@ -61,3 +61,7 @@ pub fn is_intr(trap: usize) -> bool { pub fn is_timer_intr(trap: usize) -> bool { trap == Timer } + +pub fn is_reserved_inst(trap: usize) -> bool { + false +} diff --git a/kernel/src/arch/x86_64/interrupt/mod.rs b/kernel/src/arch/x86_64/interrupt/mod.rs index 3e8453c6..aec2c1cc 100644 --- a/kernel/src/arch/x86_64/interrupt/mod.rs +++ b/kernel/src/arch/x86_64/interrupt/mod.rs @@ -66,3 +66,7 @@ pub fn wait_for_interrupt() { pub fn handle_user_page_fault(thread: &Arc, addr: usize) -> bool { thread.vm.lock().handle_page_fault(addr) } + +pub fn handle_reserved_inst(tf: &mut UserContext) -> bool { + false +} diff --git a/kernel/src/process/thread.rs b/kernel/src/process/thread.rs index c05131cc..0f4e1a78 100644 --- a/kernel/src/process/thread.rs +++ b/kernel/src/process/thread.rs @@ -2,8 +2,10 @@ use super::{ abi::{self, ProcInitInfo}, add_to_process_table, Pid, Process, PROCESSORS, }; -use crate::arch::interrupt::consts::{is_intr, is_page_fault, is_syscall, is_timer_intr}; -use crate::arch::interrupt::{get_trap_num, handle_user_page_fault}; +use crate::arch::interrupt::consts::{ + is_intr, is_page_fault, is_reserved_inst, is_syscall, is_timer_intr, +}; +use crate::arch::interrupt::{get_trap_num, handle_reserved_inst, handle_user_page_fault}; use crate::arch::{ cpu, fp::FpState, @@ -525,6 +527,14 @@ pub fn spawn(thread: Arc) { } IRQ_MANAGER.read().try_handle_interrupt(Some(trap_num)); } + _ if is_reserved_inst(trap_num) => { + if !handle_reserved_inst(cx) { + panic!( + "unhandled reserved intr in thread {} trap {:#x} {:x?}", + thread.tid, trap_num, cx + ); + } + } _ => { panic!( "unhandled trap in thread {} trap {:#x} {:x?}",