From a16b7042e6e4761b71009f08500c3d2f5241373c Mon Sep 17 00:00:00 2001 From: Sergey Bargamon Date: Sat, 6 Nov 2021 19:24:19 +0100 Subject: [PATCH 1/2] Panic on irq_handler overwrite --- kernel/interrupt.rs | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/kernel/interrupt.rs b/kernel/interrupt.rs index 01540572..8aef7009 100644 --- a/kernel/interrupt.rs +++ b/kernel/interrupt.rs @@ -4,28 +4,42 @@ use crate::arch::{enable_irq, SpinLock}; use alloc::boxed::Box; use core::mem::MaybeUninit; -fn empty_irq_handler() {} +fn empty_irq_callback() {} -type IrqHandler = dyn FnMut() + Send + Sync; -const UNINITIALIZED_IRQ_HANDLER: MaybeUninit> = MaybeUninit::uninit(); -static IRQ_HANDLERS: SpinLock<[MaybeUninit>; 256]> = +struct IrqHandler { + callback: Box, + attached: bool, +} + +const UNINITIALIZED_IRQ_HANDLER: MaybeUninit = MaybeUninit::uninit(); +static IRQ_HANDLERS: SpinLock<[MaybeUninit; 256]> = SpinLock::new([UNINITIALIZED_IRQ_HANDLER; 256]); pub fn init() { let mut handlers = IRQ_HANDLERS.lock(); for handler in handlers.iter_mut() { - handler.write(Box::new(empty_irq_handler)); + handler.write(IrqHandler { + callback: Box::new(empty_irq_callback), + attached: false, + }); } } -pub fn attach_irq(irq: u8, f: F) { - IRQ_HANDLERS.lock()[irq as usize].write(Box::new(f)); - enable_irq(irq); +pub fn attach_irq(irq: u8, callback: F) { + let h = &mut IRQ_HANDLERS.lock()[irq as usize]; + let irq_handler = unsafe { h.assume_init_mut() }; + if irq_handler.attached { + panic!("handler for IRQ #{} is already attached", irq); + } else { + irq_handler.attached = true; + irq_handler.callback = Box::new(callback); + enable_irq(irq); + } } pub fn handle_irq(irq: u8) { let handler = &mut IRQ_HANDLERS.lock()[irq as usize]; unsafe { - (*handler.assume_init_mut())(); + (*handler.assume_init_mut().callback)(); } } From 99e6607de90d5a0260d2c5b34b2ec7ad6855ec40 Mon Sep 17 00:00:00 2001 From: Sergey Bargamon Date: Mon, 8 Nov 2021 20:43:33 +0100 Subject: [PATCH 2/2] using BitMap to track attached IRQ numbers --- kernel/interrupt.rs | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/kernel/interrupt.rs b/kernel/interrupt.rs index 8aef7009..fd2e29c6 100644 --- a/kernel/interrupt.rs +++ b/kernel/interrupt.rs @@ -3,43 +3,39 @@ use crate::arch::{enable_irq, SpinLock}; use alloc::boxed::Box; use core::mem::MaybeUninit; +use kerla_utils::bitmap::BitMap; -fn empty_irq_callback() {} +fn empty_irq_handler() {} -struct IrqHandler { - callback: Box, - attached: bool, -} - -const UNINITIALIZED_IRQ_HANDLER: MaybeUninit = MaybeUninit::uninit(); -static IRQ_HANDLERS: SpinLock<[MaybeUninit; 256]> = +type IrqHandler = dyn FnMut() + Send + Sync; +const UNINITIALIZED_IRQ_HANDLER: MaybeUninit> = MaybeUninit::uninit(); +static IRQ_HANDLERS: SpinLock<[MaybeUninit>; 256]> = SpinLock::new([UNINITIALIZED_IRQ_HANDLER; 256]); +static ATTACHED_IRQS: SpinLock> = SpinLock::new(BitMap::zeroed()); pub fn init() { let mut handlers = IRQ_HANDLERS.lock(); for handler in handlers.iter_mut() { - handler.write(IrqHandler { - callback: Box::new(empty_irq_callback), - attached: false, - }); + handler.write(Box::new(empty_irq_handler)); } } -pub fn attach_irq(irq: u8, callback: F) { - let h = &mut IRQ_HANDLERS.lock()[irq as usize]; - let irq_handler = unsafe { h.assume_init_mut() }; - if irq_handler.attached { - panic!("handler for IRQ #{} is already attached", irq); - } else { - irq_handler.attached = true; - irq_handler.callback = Box::new(callback); - enable_irq(irq); +pub fn attach_irq(irq: u8, f: F) { + let mut attached_irq_map = ATTACHED_IRQS.lock(); + match attached_irq_map.get(irq as usize) { + Some(true) => panic!("handler for IRQ #{} is already attached", irq), + Some(false) => { + attached_irq_map.set(irq as usize); + IRQ_HANDLERS.lock()[irq as usize].write(Box::new(f)); + enable_irq(irq); + } + None => panic!("IRQ #{} is out of bound", irq), } } pub fn handle_irq(irq: u8) { let handler = &mut IRQ_HANDLERS.lock()[irq as usize]; unsafe { - (*handler.assume_init_mut().callback)(); + (*handler.assume_init_mut())(); } }