From d732bdb6c2dd16c9eab8fceab9d9814d11b8de33 Mon Sep 17 00:00:00 2001 From: "Raphael O." Date: Wed, 17 Jan 2024 20:12:51 +0100 Subject: [PATCH] Add lock_with_ipl macro to easily create a OnDrop type to elevate IPL while holding a lock and rename spl to ipl --- .../kernel/src/arch/amd64/interrupts/dpc.rs | 6 ++-- .../kernel/src/arch/amd64/interrupts/ipl.rs | 30 ++++++++++++++----- .../kernel/src/arch/amd64/interrupts/mod.rs | 6 ++-- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/xernel/kernel/src/arch/amd64/interrupts/dpc.rs b/xernel/kernel/src/arch/amd64/interrupts/dpc.rs index 3cbb1449..7a56062d 100644 --- a/xernel/kernel/src/arch/amd64/interrupts/dpc.rs +++ b/xernel/kernel/src/arch/amd64/interrupts/dpc.rs @@ -1,7 +1,7 @@ use alloc::boxed::Box; use crate::{ - arch::amd64::interrupts::ipl::{raise_spl, set_ipl, IPL}, + arch::amd64::interrupts::ipl::{raise_ipl, set_ipl, IPL}, cpu::{current_cpu, PerCpu}, sched::scheduler::switch_threads, }; @@ -43,10 +43,10 @@ impl Dpc { pub fn dpc_interrupt_dispatch() { let cpu = current_cpu(); - let ipl = raise_spl(IPL::IPLDPC); + let ipl = raise_ipl(IPL::IPLDPC); while let Some(dpc) = { - let old = raise_spl(IPL::IPLHigh); + let old = raise_ipl(IPL::IPLHigh); let mut lock = cpu.dpc_queue.write(); let dpc = lock.dequeue(); set_ipl(old); diff --git a/xernel/kernel/src/arch/amd64/interrupts/ipl.rs b/xernel/kernel/src/arch/amd64/interrupts/ipl.rs index 5b47b6d5..85e2ed8c 100644 --- a/xernel/kernel/src/arch/amd64/interrupts/ipl.rs +++ b/xernel/kernel/src/arch/amd64/interrupts/ipl.rs @@ -4,6 +4,22 @@ use crate::cpu::current_cpu; use super::dpc::dpc_interrupt_dispatch; +#[macro_export] +macro_rules! lock_with_ipl { + ($name:ident) => { + { + let old = raise_ipl(IPL::IPLDPC); + OnDrop::new($name.lock(), || { set_ipl(old); }) + } + }; + ($name:ident, $ipl:expr) => { + { + let _ = raise_ipl(IPL::IPLDPC); + OnDrop::new($name.lock(), || { set_ipl($ipl); }) + } + }; +} + #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] #[repr(u8)] pub enum IPL { @@ -41,7 +57,7 @@ impl From for IPL { } } -pub fn get_spl() -> IPL { +pub fn get_ipl() -> IPL { let ipl: u64; unsafe { @@ -53,7 +69,7 @@ pub fn get_spl() -> IPL { pub fn set_ipl(ipl: IPL) -> IPL { let requested_ipl = ipl as u64; - let old_ipl = get_spl() as u64; + let old_ipl = get_ipl() as u64; unsafe { asm!("mov cr8, {}", in(reg) requested_ipl, options(nomem, nostack, preserves_flags)); @@ -66,13 +82,13 @@ pub fn set_ipl(ipl: IPL) -> IPL { IPL::from(old_ipl) } -pub fn raise_spl(spl: IPL) -> IPL { - let old_ipl = get_spl(); +pub fn raise_ipl(ipl: IPL) -> IPL { + let old_ipl = get_ipl(); - assert!(old_ipl as u64 <= spl as u64); + assert!(old_ipl as u64 <= ipl as u64); - if old_ipl < spl { - set_ipl(spl); + if old_ipl < ipl { + set_ipl(ipl); } old_ipl diff --git a/xernel/kernel/src/arch/amd64/interrupts/mod.rs b/xernel/kernel/src/arch/amd64/interrupts/mod.rs index 94c1f5b5..47f82f94 100644 --- a/xernel/kernel/src/arch/amd64/interrupts/mod.rs +++ b/xernel/kernel/src/arch/amd64/interrupts/mod.rs @@ -11,7 +11,7 @@ use core::sync::atomic::{compiler_fence, Ordering}; use idt::{IRQHandler, IDT_ENTRIES}; use ipl::IPL; -use self::ipl::{get_spl, raise_spl, set_ipl}; +use self::ipl::{get_ipl, raise_ipl, set_ipl}; use super::apic::apic_spurious_interrupt; use libxernel::sync::{Spinlock, SpinlockIRQ}; @@ -33,11 +33,11 @@ pub fn init() { extern "sysv64" fn generic_interrupt_handler(isr: usize, ctx: *mut TrapFrame) { let mut ipl = IPL::from(isr >> 4); - if (ipl as u8) < (get_spl() as u8) { + if (ipl as u8) < (get_ipl() as u8) { panic!("IPL not less or equal"); } - ipl = raise_spl(ipl); + ipl = raise_ipl(ipl); let handlers = INTERRUPT_HANDLERS.lock();