Add in_interrupt and refactor line discipline

This commit is contained in:
Jianfeng Jiang
2023-11-06 14:34:00 +08:00
committed by Tate, Hongliang Tian
parent e0d7b140ce
commit 22c2cebdec
5 changed files with 49 additions and 20 deletions

View File

@ -39,14 +39,14 @@ macro_rules! cpu_local {
// multiple declarations
($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => {
$(#[$attr])* $vis static $name: CpuLocal<$t> = unsafe { CpuLocal::new($init) };
$(#[$attr])* $vis static $name: $crate::CpuLocal<$t> = unsafe { $crate::CpuLocal::new($init) };
$crate::cpu_local!($($rest)*);
};
// single declaration
($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr) => (
// TODO: reimplement cpu-local variable to support multi-core
$(#[$attr])* $vis static $name: CpuLocal<$t> = CpuLocal::new($init);
$(#[$attr])* $vis static $name: $crate::CpuLocal<$t> = $crate::CpuLocal::new($init);
);
}

View File

@ -4,7 +4,7 @@ use core::sync::atomic::AtomicUsize;
use crate::cpu_local;
use crate::sync::Mutex;
use crate::{cpu::CpuLocal, trap::disable_local};
use crate::trap::disable_local;
use core::sync::atomic::Ordering::Relaxed;

View File

@ -1,6 +1,8 @@
// SPDX-License-Identifier: MPL-2.0
use crate::{arch::irq::IRQ_LIST, cpu::CpuException};
use core::sync::atomic::{AtomicBool, Ordering};
use crate::{arch::irq::IRQ_LIST, cpu::CpuException, cpu_local};
#[cfg(feature = "intel_tdx")]
use crate::arch::tdx_guest::{handle_virtual_exception, TdxTrapFrame};
@ -71,6 +73,12 @@ extern "sysv64" fn trap_handler(f: &mut TrapFrame) {
}
pub(crate) fn call_irq_callback_functions(trap_frame: &TrapFrame) {
// For x86 CPUs, interrupts are not re-entrant. Local interrupts will be disabled when
// an interrupt handler is called (Unless interrupts are re-enabled in an interrupt handler).
//
// FIXME: For arch that supports re-entrant interrupts, we may need to record nested level here.
IN_INTERRUPT_CONTEXT.store(true, Ordering::Release);
let irq_line = IRQ_LIST.get().unwrap().get(trap_frame.trap_num).unwrap();
let callback_functions = irq_line.callback_list();
for callback_function in callback_functions.iter() {
@ -79,4 +87,18 @@ pub(crate) fn call_irq_callback_functions(trap_frame: &TrapFrame) {
if !CpuException::is_cpu_exception(trap_frame.trap_num as u16) {
crate::arch::interrupts_ack();
}
IN_INTERRUPT_CONTEXT.store(false, Ordering::Release);
}
cpu_local! {
static IN_INTERRUPT_CONTEXT: AtomicBool = AtomicBool::new(false);
}
/// Returns whether we are in the interrupt context.
///
/// FIXME: Here only hardware irq is taken into account. According to linux implementation, if
/// we are in softirq context, or bottom half is disabled, this function also returns true.
pub fn in_interrupt_context() -> bool {
IN_INTERRUPT_CONTEXT.load(Ordering::Acquire)
}

View File

@ -5,6 +5,7 @@ mod irq;
pub(crate) use self::handler::call_irq_callback_functions;
pub use self::irq::{disable_local, DisabledLocalIrqGuard, IrqCallbackFunction, IrqLine};
pub use handler::in_interrupt_context;
pub use trapframe::TrapFrame;
pub(crate) fn init() {