From 5e1fdf8605e0c8f9052a26f41efbfb10f225c33a Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Thu, 19 May 2022 22:52:32 +0200 Subject: [PATCH] Remove unsafe from certain IRQ related code While turning IRQs on or off is something that "sounds critical", it is not unsafe in these sense of compromising memory safety. Rust's unsafe should be about memory safety only, hence removing it from certain functions. --- 13_exceptions_part2_peripheral_IRQs/README.md | 89 ++++++++----------- .../_arch/aarch64/exception/asynchronous.rs | 49 ++++------ .../kernel/src/exception/asynchronous.rs | 10 +-- .../kernel/src/panic_wait.rs | 2 +- .../kernel/tests/04_exception_irq_sanity.rs | 14 +-- 14_virtual_mem_part2_mmio_remap/README.md | 2 +- .../_arch/aarch64/exception/asynchronous.rs | 49 ++++------ .../kernel/src/exception/asynchronous.rs | 10 +-- .../kernel/src/panic_wait.rs | 2 +- .../kernel/tests/04_exception_irq_sanity.rs | 14 +-- .../_arch/aarch64/exception/asynchronous.rs | 49 ++++------ .../kernel/src/exception/asynchronous.rs | 10 +-- .../kernel/src/panic_wait.rs | 2 +- .../kernel/tests/04_exception_irq_sanity.rs | 14 +-- .../_arch/aarch64/exception/asynchronous.rs | 49 ++++------ .../kernel/src/exception/asynchronous.rs | 10 +-- .../kernel/src/panic_wait.rs | 2 +- .../kernel/tests/04_exception_irq_sanity.rs | 14 +-- .../_arch/aarch64/exception/asynchronous.rs | 49 ++++------ .../kernel/src/exception/asynchronous.rs | 10 +-- 17_kernel_symbols/kernel/src/panic_wait.rs | 2 +- .../kernel/tests/04_exception_irq_sanity.rs | 14 +-- .../_arch/aarch64/exception/asynchronous.rs | 49 ++++------ .../kernel/src/exception/asynchronous.rs | 10 +-- 18_backtrace/kernel/src/panic_wait.rs | 2 +- .../kernel/tests/04_exception_irq_sanity.rs | 14 +-- .../_arch/aarch64/exception/asynchronous.rs | 49 ++++------ .../kernel/src/exception/asynchronous.rs | 10 +-- 19_kernel_heap/kernel/src/panic_wait.rs | 2 +- .../kernel/tests/04_exception_irq_sanity.rs | 14 +-- 30 files changed, 246 insertions(+), 370 deletions(-) diff --git a/13_exceptions_part2_peripheral_IRQs/README.md b/13_exceptions_part2_peripheral_IRQs/README.md index 9a5b7b4f..65be428a 100644 --- a/13_exceptions_part2_peripheral_IRQs/README.md +++ b/13_exceptions_part2_peripheral_IRQs/README.md @@ -421,13 +421,9 @@ core are masked before the `f(data)` is being executed, and restored afterwards: /// previous state before returning, so this is deemed safe. #[inline(always)] pub fn exec_with_irq_masked(f: impl FnOnce() -> T) -> T { - let ret: T; - - unsafe { - let saved = local_irq_mask_save(); - ret = f(); - local_irq_restore(saved); - } + let saved = local_irq_mask_save(); + let ret = f(); + local_irq_restore(saved); ret } @@ -814,7 +810,7 @@ diff -uNr 12_integrated_testing/kernel/src/_arch/aarch64/exception/asynchronous. trait DaifField { fn daif_field() -> tock_registers::fields::Field; } -@@ -66,6 +71,71 @@ +@@ -66,6 +71,60 @@ // Public Code //-------------------------------------------------------------------------------------------------- @@ -830,42 +826,32 @@ diff -uNr 12_integrated_testing/kernel/src/_arch/aarch64/exception/asynchronous. +/// +/// "Writes to PSTATE.{PAN, D, A, I, F} occur in program order without the need for additional +/// synchronization." -+/// -+/// # Safety -+/// -+/// - Changes the HW state of the executing core. +#[inline(always)] -+pub unsafe fn local_irq_unmask() { -+ #[rustfmt::skip] -+ asm!( -+ "msr DAIFClr, {arg}", -+ arg = const daif_bits::IRQ, -+ options(nomem, nostack, preserves_flags) -+ ); ++pub fn local_irq_unmask() { ++ unsafe { ++ asm!( ++ "msr DAIFClr, {arg}", ++ arg = const daif_bits::IRQ, ++ options(nomem, nostack, preserves_flags) ++ ); ++ } +} + +/// Mask IRQs on the executing core. -+/// -+/// # Safety -+/// -+/// - Changes the HW state of the executing core. +#[inline(always)] -+pub unsafe fn local_irq_mask() { -+ #[rustfmt::skip] -+ asm!( -+ "msr DAIFSet, {arg}", -+ arg = const daif_bits::IRQ, -+ options(nomem, nostack, preserves_flags) -+ ); ++pub fn local_irq_mask() { ++ unsafe { ++ asm!( ++ "msr DAIFSet, {arg}", ++ arg = const daif_bits::IRQ, ++ options(nomem, nostack, preserves_flags) ++ ); ++ } +} + +/// Mask IRQs on the executing core and return the previously saved interrupt mask bits (DAIF). -+/// -+/// # Safety -+/// -+/// - Changes the HW state of the executing core. +#[inline(always)] -+pub unsafe fn local_irq_mask_save() -> u64 { ++pub fn local_irq_mask_save() -> u64 { + let saved = DAIF.get(); + local_irq_mask(); + @@ -874,12 +860,11 @@ diff -uNr 12_integrated_testing/kernel/src/_arch/aarch64/exception/asynchronous. + +/// Restore the interrupt mask bits (DAIF) using the callee's argument. +/// -+/// # Safety ++/// # Invariant +/// -+/// - Changes the HW state of the executing core. +/// - No sanity checks on the input. +#[inline(always)] -+pub unsafe fn local_irq_restore(saved: u64) { ++pub fn local_irq_restore(saved: u64) { + DAIF.set(saved); +} + @@ -2245,7 +2230,7 @@ diff -uNr 12_integrated_testing/kernel/src/driver.rs 13_exceptions_part2_periphe diff -uNr 12_integrated_testing/kernel/src/exception/asynchronous.rs 13_exceptions_part2_peripheral_IRQs/kernel/src/exception/asynchronous.rs --- 12_integrated_testing/kernel/src/exception/asynchronous.rs +++ 13_exceptions_part2_peripheral_IRQs/kernel/src/exception/asynchronous.rs -@@ -8,7 +8,153 @@ +@@ -8,7 +8,149 @@ #[path = "../_arch/aarch64/exception/asynchronous.rs"] mod arch_asynchronous; @@ -2383,13 +2368,9 @@ diff -uNr 12_integrated_testing/kernel/src/exception/asynchronous.rs 13_exceptio +/// previous state before returning, so this is deemed safe. +#[inline(always)] +pub fn exec_with_irq_masked(f: impl FnOnce() -> T) -> T { -+ let ret: T; -+ -+ unsafe { -+ let saved = local_irq_mask_save(); -+ ret = f(); -+ local_irq_restore(saved); -+ } ++ let saved = local_irq_mask_save(); ++ let ret = f(); ++ local_irq_restore(saved); + + ret +} @@ -2497,7 +2478,7 @@ diff -uNr 12_integrated_testing/kernel/src/panic_wait.rs 13_exceptions_part2_per fn panic(info: &PanicInfo) -> ! { use crate::time::interface::TimeManager; -+ unsafe { exception::asynchronous::local_irq_mask() }; ++ exception::asynchronous::local_irq_mask(); + // Protect against panic infinite loops if any of the following code panics itself. panic_prevent_reenter(); @@ -2773,21 +2754,21 @@ diff -uNr 12_integrated_testing/kernel/tests/04_exception_irq_sanity.rs 13_excep + // Precondition: IRQs are unmasked. + assert!(exception::asynchronous::is_local_irq_masked()); + -+ unsafe { exception::asynchronous::local_irq_mask() }; ++ exception::asynchronous::local_irq_mask(); + assert!(!exception::asynchronous::is_local_irq_masked()); + + // Restore earlier state. -+ unsafe { exception::asynchronous::local_irq_unmask() }; ++ exception::asynchronous::local_irq_unmask(); +} + +/// Check that IRQ unmasking works. +#[kernel_test] +fn local_irq_unmask_works() { + // Precondition: IRQs are masked. -+ unsafe { exception::asynchronous::local_irq_mask() }; ++ exception::asynchronous::local_irq_mask(); + assert!(!exception::asynchronous::is_local_irq_masked()); + -+ unsafe { exception::asynchronous::local_irq_unmask() }; ++ exception::asynchronous::local_irq_unmask(); + assert!(exception::asynchronous::is_local_irq_masked()); +} + @@ -2797,13 +2778,13 @@ diff -uNr 12_integrated_testing/kernel/tests/04_exception_irq_sanity.rs 13_excep + // Precondition: IRQs are unmasked. + assert!(exception::asynchronous::is_local_irq_masked()); + -+ let first = unsafe { exception::asynchronous::local_irq_mask_save() }; ++ let first = exception::asynchronous::local_irq_mask_save(); + assert!(!exception::asynchronous::is_local_irq_masked()); + -+ let second = unsafe { exception::asynchronous::local_irq_mask_save() }; ++ let second = exception::asynchronous::local_irq_mask_save(); + assert_ne!(first, second); + -+ unsafe { exception::asynchronous::local_irq_restore(first) }; ++ exception::asynchronous::local_irq_restore(first); + assert!(exception::asynchronous::is_local_irq_masked()); +} diff --git a/13_exceptions_part2_peripheral_IRQs/kernel/src/_arch/aarch64/exception/asynchronous.rs b/13_exceptions_part2_peripheral_IRQs/kernel/src/_arch/aarch64/exception/asynchronous.rs index 73b82e65..cf6f97ac 100644 --- a/13_exceptions_part2_peripheral_IRQs/kernel/src/_arch/aarch64/exception/asynchronous.rs +++ b/13_exceptions_part2_peripheral_IRQs/kernel/src/_arch/aarch64/exception/asynchronous.rs @@ -83,42 +83,32 @@ pub fn is_local_irq_masked() -> bool { /// /// "Writes to PSTATE.{PAN, D, A, I, F} occur in program order without the need for additional /// synchronization." -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_unmask() { - #[rustfmt::skip] - asm!( - "msr DAIFClr, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_unmask() { + unsafe { + asm!( + "msr DAIFClr, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core. -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask() { - #[rustfmt::skip] - asm!( - "msr DAIFSet, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_mask() { + unsafe { + asm!( + "msr DAIFSet, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core and return the previously saved interrupt mask bits (DAIF). -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask_save() -> u64 { +pub fn local_irq_mask_save() -> u64 { let saved = DAIF.get(); local_irq_mask(); @@ -127,12 +117,11 @@ pub unsafe fn local_irq_mask_save() -> u64 { /// Restore the interrupt mask bits (DAIF) using the callee's argument. /// -/// # Safety +/// # Invariant /// -/// - Changes the HW state of the executing core. /// - No sanity checks on the input. #[inline(always)] -pub unsafe fn local_irq_restore(saved: u64) { +pub fn local_irq_restore(saved: u64) { DAIF.set(saved); } diff --git a/13_exceptions_part2_peripheral_IRQs/kernel/src/exception/asynchronous.rs b/13_exceptions_part2_peripheral_IRQs/kernel/src/exception/asynchronous.rs index 17938692..31800ffe 100644 --- a/13_exceptions_part2_peripheral_IRQs/kernel/src/exception/asynchronous.rs +++ b/13_exceptions_part2_peripheral_IRQs/kernel/src/exception/asynchronous.rs @@ -141,13 +141,9 @@ impl fmt::Display for IRQNumber<{ MAX_INCLUSIVE }> { /// previous state before returning, so this is deemed safe. #[inline(always)] pub fn exec_with_irq_masked(f: impl FnOnce() -> T) -> T { - let ret: T; - - unsafe { - let saved = local_irq_mask_save(); - ret = f(); - local_irq_restore(saved); - } + let saved = local_irq_mask_save(); + let ret = f(); + local_irq_restore(saved); ret } diff --git a/13_exceptions_part2_peripheral_IRQs/kernel/src/panic_wait.rs b/13_exceptions_part2_peripheral_IRQs/kernel/src/panic_wait.rs index e4256b61..61831213 100644 --- a/13_exceptions_part2_peripheral_IRQs/kernel/src/panic_wait.rs +++ b/13_exceptions_part2_peripheral_IRQs/kernel/src/panic_wait.rs @@ -61,7 +61,7 @@ fn panic_prevent_reenter() { fn panic(info: &PanicInfo) -> ! { use crate::time::interface::TimeManager; - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); // Protect against panic infinite loops if any of the following code panics itself. panic_prevent_reenter(); diff --git a/13_exceptions_part2_peripheral_IRQs/kernel/tests/04_exception_irq_sanity.rs b/13_exceptions_part2_peripheral_IRQs/kernel/tests/04_exception_irq_sanity.rs index 1204dca4..9deac6cc 100644 --- a/13_exceptions_part2_peripheral_IRQs/kernel/tests/04_exception_irq_sanity.rs +++ b/13_exceptions_part2_peripheral_IRQs/kernel/tests/04_exception_irq_sanity.rs @@ -32,21 +32,21 @@ fn local_irq_mask_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); // Restore earlier state. - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); } /// Check that IRQ unmasking works. #[kernel_test] fn local_irq_unmask_works() { // Precondition: IRQs are masked. - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); assert!(exception::asynchronous::is_local_irq_masked()); } @@ -56,12 +56,12 @@ fn local_irq_mask_save_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - let first = unsafe { exception::asynchronous::local_irq_mask_save() }; + let first = exception::asynchronous::local_irq_mask_save(); assert!(!exception::asynchronous::is_local_irq_masked()); - let second = unsafe { exception::asynchronous::local_irq_mask_save() }; + let second = exception::asynchronous::local_irq_mask_save(); assert_ne!(first, second); - unsafe { exception::asynchronous::local_irq_restore(first) }; + exception::asynchronous::local_irq_restore(first); assert!(exception::asynchronous::is_local_irq_masked()); } diff --git a/14_virtual_mem_part2_mmio_remap/README.md b/14_virtual_mem_part2_mmio_remap/README.md index 911a2d76..30aa848b 100644 --- a/14_virtual_mem_part2_mmio_remap/README.md +++ b/14_virtual_mem_part2_mmio_remap/README.md @@ -2300,7 +2300,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/exception/asynchronous. impl<'irq_context> IRQContext<'irq_context> { /// Creates an IRQContext token. -@@ -152,9 +162,17 @@ +@@ -148,9 +158,17 @@ ret } diff --git a/14_virtual_mem_part2_mmio_remap/kernel/src/_arch/aarch64/exception/asynchronous.rs b/14_virtual_mem_part2_mmio_remap/kernel/src/_arch/aarch64/exception/asynchronous.rs index 73b82e65..cf6f97ac 100644 --- a/14_virtual_mem_part2_mmio_remap/kernel/src/_arch/aarch64/exception/asynchronous.rs +++ b/14_virtual_mem_part2_mmio_remap/kernel/src/_arch/aarch64/exception/asynchronous.rs @@ -83,42 +83,32 @@ pub fn is_local_irq_masked() -> bool { /// /// "Writes to PSTATE.{PAN, D, A, I, F} occur in program order without the need for additional /// synchronization." -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_unmask() { - #[rustfmt::skip] - asm!( - "msr DAIFClr, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_unmask() { + unsafe { + asm!( + "msr DAIFClr, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core. -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask() { - #[rustfmt::skip] - asm!( - "msr DAIFSet, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_mask() { + unsafe { + asm!( + "msr DAIFSet, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core and return the previously saved interrupt mask bits (DAIF). -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask_save() -> u64 { +pub fn local_irq_mask_save() -> u64 { let saved = DAIF.get(); local_irq_mask(); @@ -127,12 +117,11 @@ pub unsafe fn local_irq_mask_save() -> u64 { /// Restore the interrupt mask bits (DAIF) using the callee's argument. /// -/// # Safety +/// # Invariant /// -/// - Changes the HW state of the executing core. /// - No sanity checks on the input. #[inline(always)] -pub unsafe fn local_irq_restore(saved: u64) { +pub fn local_irq_restore(saved: u64) { DAIF.set(saved); } diff --git a/14_virtual_mem_part2_mmio_remap/kernel/src/exception/asynchronous.rs b/14_virtual_mem_part2_mmio_remap/kernel/src/exception/asynchronous.rs index d9d2767c..3544e621 100644 --- a/14_virtual_mem_part2_mmio_remap/kernel/src/exception/asynchronous.rs +++ b/14_virtual_mem_part2_mmio_remap/kernel/src/exception/asynchronous.rs @@ -151,13 +151,9 @@ impl fmt::Display for IRQNumber<{ MAX_INCLUSIVE }> { /// previous state before returning, so this is deemed safe. #[inline(always)] pub fn exec_with_irq_masked(f: impl FnOnce() -> T) -> T { - let ret: T; - - unsafe { - let saved = local_irq_mask_save(); - ret = f(); - local_irq_restore(saved); - } + let saved = local_irq_mask_save(); + let ret = f(); + local_irq_restore(saved); ret } diff --git a/14_virtual_mem_part2_mmio_remap/kernel/src/panic_wait.rs b/14_virtual_mem_part2_mmio_remap/kernel/src/panic_wait.rs index e4256b61..61831213 100644 --- a/14_virtual_mem_part2_mmio_remap/kernel/src/panic_wait.rs +++ b/14_virtual_mem_part2_mmio_remap/kernel/src/panic_wait.rs @@ -61,7 +61,7 @@ fn panic_prevent_reenter() { fn panic(info: &PanicInfo) -> ! { use crate::time::interface::TimeManager; - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); // Protect against panic infinite loops if any of the following code panics itself. panic_prevent_reenter(); diff --git a/14_virtual_mem_part2_mmio_remap/kernel/tests/04_exception_irq_sanity.rs b/14_virtual_mem_part2_mmio_remap/kernel/tests/04_exception_irq_sanity.rs index 7a344874..c9e244ce 100644 --- a/14_virtual_mem_part2_mmio_remap/kernel/tests/04_exception_irq_sanity.rs +++ b/14_virtual_mem_part2_mmio_remap/kernel/tests/04_exception_irq_sanity.rs @@ -44,21 +44,21 @@ fn local_irq_mask_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); // Restore earlier state. - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); } /// Check that IRQ unmasking works. #[kernel_test] fn local_irq_unmask_works() { // Precondition: IRQs are masked. - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); assert!(exception::asynchronous::is_local_irq_masked()); } @@ -68,12 +68,12 @@ fn local_irq_mask_save_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - let first = unsafe { exception::asynchronous::local_irq_mask_save() }; + let first = exception::asynchronous::local_irq_mask_save(); assert!(!exception::asynchronous::is_local_irq_masked()); - let second = unsafe { exception::asynchronous::local_irq_mask_save() }; + let second = exception::asynchronous::local_irq_mask_save(); assert_ne!(first, second); - unsafe { exception::asynchronous::local_irq_restore(first) }; + exception::asynchronous::local_irq_restore(first); assert!(exception::asynchronous::is_local_irq_masked()); } diff --git a/15_virtual_mem_part3_precomputed_tables/kernel/src/_arch/aarch64/exception/asynchronous.rs b/15_virtual_mem_part3_precomputed_tables/kernel/src/_arch/aarch64/exception/asynchronous.rs index 73b82e65..cf6f97ac 100644 --- a/15_virtual_mem_part3_precomputed_tables/kernel/src/_arch/aarch64/exception/asynchronous.rs +++ b/15_virtual_mem_part3_precomputed_tables/kernel/src/_arch/aarch64/exception/asynchronous.rs @@ -83,42 +83,32 @@ pub fn is_local_irq_masked() -> bool { /// /// "Writes to PSTATE.{PAN, D, A, I, F} occur in program order without the need for additional /// synchronization." -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_unmask() { - #[rustfmt::skip] - asm!( - "msr DAIFClr, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_unmask() { + unsafe { + asm!( + "msr DAIFClr, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core. -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask() { - #[rustfmt::skip] - asm!( - "msr DAIFSet, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_mask() { + unsafe { + asm!( + "msr DAIFSet, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core and return the previously saved interrupt mask bits (DAIF). -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask_save() -> u64 { +pub fn local_irq_mask_save() -> u64 { let saved = DAIF.get(); local_irq_mask(); @@ -127,12 +117,11 @@ pub unsafe fn local_irq_mask_save() -> u64 { /// Restore the interrupt mask bits (DAIF) using the callee's argument. /// -/// # Safety +/// # Invariant /// -/// - Changes the HW state of the executing core. /// - No sanity checks on the input. #[inline(always)] -pub unsafe fn local_irq_restore(saved: u64) { +pub fn local_irq_restore(saved: u64) { DAIF.set(saved); } diff --git a/15_virtual_mem_part3_precomputed_tables/kernel/src/exception/asynchronous.rs b/15_virtual_mem_part3_precomputed_tables/kernel/src/exception/asynchronous.rs index d9d2767c..3544e621 100644 --- a/15_virtual_mem_part3_precomputed_tables/kernel/src/exception/asynchronous.rs +++ b/15_virtual_mem_part3_precomputed_tables/kernel/src/exception/asynchronous.rs @@ -151,13 +151,9 @@ impl fmt::Display for IRQNumber<{ MAX_INCLUSIVE }> { /// previous state before returning, so this is deemed safe. #[inline(always)] pub fn exec_with_irq_masked(f: impl FnOnce() -> T) -> T { - let ret: T; - - unsafe { - let saved = local_irq_mask_save(); - ret = f(); - local_irq_restore(saved); - } + let saved = local_irq_mask_save(); + let ret = f(); + local_irq_restore(saved); ret } diff --git a/15_virtual_mem_part3_precomputed_tables/kernel/src/panic_wait.rs b/15_virtual_mem_part3_precomputed_tables/kernel/src/panic_wait.rs index e4256b61..61831213 100644 --- a/15_virtual_mem_part3_precomputed_tables/kernel/src/panic_wait.rs +++ b/15_virtual_mem_part3_precomputed_tables/kernel/src/panic_wait.rs @@ -61,7 +61,7 @@ fn panic_prevent_reenter() { fn panic(info: &PanicInfo) -> ! { use crate::time::interface::TimeManager; - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); // Protect against panic infinite loops if any of the following code panics itself. panic_prevent_reenter(); diff --git a/15_virtual_mem_part3_precomputed_tables/kernel/tests/04_exception_irq_sanity.rs b/15_virtual_mem_part3_precomputed_tables/kernel/tests/04_exception_irq_sanity.rs index 7b9628d5..e93a4caf 100644 --- a/15_virtual_mem_part3_precomputed_tables/kernel/tests/04_exception_irq_sanity.rs +++ b/15_virtual_mem_part3_precomputed_tables/kernel/tests/04_exception_irq_sanity.rs @@ -34,21 +34,21 @@ fn local_irq_mask_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); // Restore earlier state. - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); } /// Check that IRQ unmasking works. #[kernel_test] fn local_irq_unmask_works() { // Precondition: IRQs are masked. - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); assert!(exception::asynchronous::is_local_irq_masked()); } @@ -58,12 +58,12 @@ fn local_irq_mask_save_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - let first = unsafe { exception::asynchronous::local_irq_mask_save() }; + let first = exception::asynchronous::local_irq_mask_save(); assert!(!exception::asynchronous::is_local_irq_masked()); - let second = unsafe { exception::asynchronous::local_irq_mask_save() }; + let second = exception::asynchronous::local_irq_mask_save(); assert_ne!(first, second); - unsafe { exception::asynchronous::local_irq_restore(first) }; + exception::asynchronous::local_irq_restore(first); assert!(exception::asynchronous::is_local_irq_masked()); } diff --git a/16_virtual_mem_part4_higher_half_kernel/kernel/src/_arch/aarch64/exception/asynchronous.rs b/16_virtual_mem_part4_higher_half_kernel/kernel/src/_arch/aarch64/exception/asynchronous.rs index 73b82e65..cf6f97ac 100644 --- a/16_virtual_mem_part4_higher_half_kernel/kernel/src/_arch/aarch64/exception/asynchronous.rs +++ b/16_virtual_mem_part4_higher_half_kernel/kernel/src/_arch/aarch64/exception/asynchronous.rs @@ -83,42 +83,32 @@ pub fn is_local_irq_masked() -> bool { /// /// "Writes to PSTATE.{PAN, D, A, I, F} occur in program order without the need for additional /// synchronization." -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_unmask() { - #[rustfmt::skip] - asm!( - "msr DAIFClr, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_unmask() { + unsafe { + asm!( + "msr DAIFClr, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core. -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask() { - #[rustfmt::skip] - asm!( - "msr DAIFSet, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_mask() { + unsafe { + asm!( + "msr DAIFSet, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core and return the previously saved interrupt mask bits (DAIF). -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask_save() -> u64 { +pub fn local_irq_mask_save() -> u64 { let saved = DAIF.get(); local_irq_mask(); @@ -127,12 +117,11 @@ pub unsafe fn local_irq_mask_save() -> u64 { /// Restore the interrupt mask bits (DAIF) using the callee's argument. /// -/// # Safety +/// # Invariant /// -/// - Changes the HW state of the executing core. /// - No sanity checks on the input. #[inline(always)] -pub unsafe fn local_irq_restore(saved: u64) { +pub fn local_irq_restore(saved: u64) { DAIF.set(saved); } diff --git a/16_virtual_mem_part4_higher_half_kernel/kernel/src/exception/asynchronous.rs b/16_virtual_mem_part4_higher_half_kernel/kernel/src/exception/asynchronous.rs index d9d2767c..3544e621 100644 --- a/16_virtual_mem_part4_higher_half_kernel/kernel/src/exception/asynchronous.rs +++ b/16_virtual_mem_part4_higher_half_kernel/kernel/src/exception/asynchronous.rs @@ -151,13 +151,9 @@ impl fmt::Display for IRQNumber<{ MAX_INCLUSIVE }> { /// previous state before returning, so this is deemed safe. #[inline(always)] pub fn exec_with_irq_masked(f: impl FnOnce() -> T) -> T { - let ret: T; - - unsafe { - let saved = local_irq_mask_save(); - ret = f(); - local_irq_restore(saved); - } + let saved = local_irq_mask_save(); + let ret = f(); + local_irq_restore(saved); ret } diff --git a/16_virtual_mem_part4_higher_half_kernel/kernel/src/panic_wait.rs b/16_virtual_mem_part4_higher_half_kernel/kernel/src/panic_wait.rs index e4256b61..61831213 100644 --- a/16_virtual_mem_part4_higher_half_kernel/kernel/src/panic_wait.rs +++ b/16_virtual_mem_part4_higher_half_kernel/kernel/src/panic_wait.rs @@ -61,7 +61,7 @@ fn panic_prevent_reenter() { fn panic(info: &PanicInfo) -> ! { use crate::time::interface::TimeManager; - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); // Protect against panic infinite loops if any of the following code panics itself. panic_prevent_reenter(); diff --git a/16_virtual_mem_part4_higher_half_kernel/kernel/tests/04_exception_irq_sanity.rs b/16_virtual_mem_part4_higher_half_kernel/kernel/tests/04_exception_irq_sanity.rs index 7b9628d5..e93a4caf 100644 --- a/16_virtual_mem_part4_higher_half_kernel/kernel/tests/04_exception_irq_sanity.rs +++ b/16_virtual_mem_part4_higher_half_kernel/kernel/tests/04_exception_irq_sanity.rs @@ -34,21 +34,21 @@ fn local_irq_mask_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); // Restore earlier state. - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); } /// Check that IRQ unmasking works. #[kernel_test] fn local_irq_unmask_works() { // Precondition: IRQs are masked. - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); assert!(exception::asynchronous::is_local_irq_masked()); } @@ -58,12 +58,12 @@ fn local_irq_mask_save_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - let first = unsafe { exception::asynchronous::local_irq_mask_save() }; + let first = exception::asynchronous::local_irq_mask_save(); assert!(!exception::asynchronous::is_local_irq_masked()); - let second = unsafe { exception::asynchronous::local_irq_mask_save() }; + let second = exception::asynchronous::local_irq_mask_save(); assert_ne!(first, second); - unsafe { exception::asynchronous::local_irq_restore(first) }; + exception::asynchronous::local_irq_restore(first); assert!(exception::asynchronous::is_local_irq_masked()); } diff --git a/17_kernel_symbols/kernel/src/_arch/aarch64/exception/asynchronous.rs b/17_kernel_symbols/kernel/src/_arch/aarch64/exception/asynchronous.rs index 73b82e65..cf6f97ac 100644 --- a/17_kernel_symbols/kernel/src/_arch/aarch64/exception/asynchronous.rs +++ b/17_kernel_symbols/kernel/src/_arch/aarch64/exception/asynchronous.rs @@ -83,42 +83,32 @@ pub fn is_local_irq_masked() -> bool { /// /// "Writes to PSTATE.{PAN, D, A, I, F} occur in program order without the need for additional /// synchronization." -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_unmask() { - #[rustfmt::skip] - asm!( - "msr DAIFClr, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_unmask() { + unsafe { + asm!( + "msr DAIFClr, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core. -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask() { - #[rustfmt::skip] - asm!( - "msr DAIFSet, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_mask() { + unsafe { + asm!( + "msr DAIFSet, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core and return the previously saved interrupt mask bits (DAIF). -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask_save() -> u64 { +pub fn local_irq_mask_save() -> u64 { let saved = DAIF.get(); local_irq_mask(); @@ -127,12 +117,11 @@ pub unsafe fn local_irq_mask_save() -> u64 { /// Restore the interrupt mask bits (DAIF) using the callee's argument. /// -/// # Safety +/// # Invariant /// -/// - Changes the HW state of the executing core. /// - No sanity checks on the input. #[inline(always)] -pub unsafe fn local_irq_restore(saved: u64) { +pub fn local_irq_restore(saved: u64) { DAIF.set(saved); } diff --git a/17_kernel_symbols/kernel/src/exception/asynchronous.rs b/17_kernel_symbols/kernel/src/exception/asynchronous.rs index d9d2767c..3544e621 100644 --- a/17_kernel_symbols/kernel/src/exception/asynchronous.rs +++ b/17_kernel_symbols/kernel/src/exception/asynchronous.rs @@ -151,13 +151,9 @@ impl fmt::Display for IRQNumber<{ MAX_INCLUSIVE }> { /// previous state before returning, so this is deemed safe. #[inline(always)] pub fn exec_with_irq_masked(f: impl FnOnce() -> T) -> T { - let ret: T; - - unsafe { - let saved = local_irq_mask_save(); - ret = f(); - local_irq_restore(saved); - } + let saved = local_irq_mask_save(); + let ret = f(); + local_irq_restore(saved); ret } diff --git a/17_kernel_symbols/kernel/src/panic_wait.rs b/17_kernel_symbols/kernel/src/panic_wait.rs index e4256b61..61831213 100644 --- a/17_kernel_symbols/kernel/src/panic_wait.rs +++ b/17_kernel_symbols/kernel/src/panic_wait.rs @@ -61,7 +61,7 @@ fn panic_prevent_reenter() { fn panic(info: &PanicInfo) -> ! { use crate::time::interface::TimeManager; - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); // Protect against panic infinite loops if any of the following code panics itself. panic_prevent_reenter(); diff --git a/17_kernel_symbols/kernel/tests/04_exception_irq_sanity.rs b/17_kernel_symbols/kernel/tests/04_exception_irq_sanity.rs index 7b9628d5..e93a4caf 100644 --- a/17_kernel_symbols/kernel/tests/04_exception_irq_sanity.rs +++ b/17_kernel_symbols/kernel/tests/04_exception_irq_sanity.rs @@ -34,21 +34,21 @@ fn local_irq_mask_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); // Restore earlier state. - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); } /// Check that IRQ unmasking works. #[kernel_test] fn local_irq_unmask_works() { // Precondition: IRQs are masked. - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); assert!(exception::asynchronous::is_local_irq_masked()); } @@ -58,12 +58,12 @@ fn local_irq_mask_save_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - let first = unsafe { exception::asynchronous::local_irq_mask_save() }; + let first = exception::asynchronous::local_irq_mask_save(); assert!(!exception::asynchronous::is_local_irq_masked()); - let second = unsafe { exception::asynchronous::local_irq_mask_save() }; + let second = exception::asynchronous::local_irq_mask_save(); assert_ne!(first, second); - unsafe { exception::asynchronous::local_irq_restore(first) }; + exception::asynchronous::local_irq_restore(first); assert!(exception::asynchronous::is_local_irq_masked()); } diff --git a/18_backtrace/kernel/src/_arch/aarch64/exception/asynchronous.rs b/18_backtrace/kernel/src/_arch/aarch64/exception/asynchronous.rs index 73b82e65..cf6f97ac 100644 --- a/18_backtrace/kernel/src/_arch/aarch64/exception/asynchronous.rs +++ b/18_backtrace/kernel/src/_arch/aarch64/exception/asynchronous.rs @@ -83,42 +83,32 @@ pub fn is_local_irq_masked() -> bool { /// /// "Writes to PSTATE.{PAN, D, A, I, F} occur in program order without the need for additional /// synchronization." -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_unmask() { - #[rustfmt::skip] - asm!( - "msr DAIFClr, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_unmask() { + unsafe { + asm!( + "msr DAIFClr, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core. -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask() { - #[rustfmt::skip] - asm!( - "msr DAIFSet, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_mask() { + unsafe { + asm!( + "msr DAIFSet, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core and return the previously saved interrupt mask bits (DAIF). -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask_save() -> u64 { +pub fn local_irq_mask_save() -> u64 { let saved = DAIF.get(); local_irq_mask(); @@ -127,12 +117,11 @@ pub unsafe fn local_irq_mask_save() -> u64 { /// Restore the interrupt mask bits (DAIF) using the callee's argument. /// -/// # Safety +/// # Invariant /// -/// - Changes the HW state of the executing core. /// - No sanity checks on the input. #[inline(always)] -pub unsafe fn local_irq_restore(saved: u64) { +pub fn local_irq_restore(saved: u64) { DAIF.set(saved); } diff --git a/18_backtrace/kernel/src/exception/asynchronous.rs b/18_backtrace/kernel/src/exception/asynchronous.rs index d9d2767c..3544e621 100644 --- a/18_backtrace/kernel/src/exception/asynchronous.rs +++ b/18_backtrace/kernel/src/exception/asynchronous.rs @@ -151,13 +151,9 @@ impl fmt::Display for IRQNumber<{ MAX_INCLUSIVE }> { /// previous state before returning, so this is deemed safe. #[inline(always)] pub fn exec_with_irq_masked(f: impl FnOnce() -> T) -> T { - let ret: T; - - unsafe { - let saved = local_irq_mask_save(); - ret = f(); - local_irq_restore(saved); - } + let saved = local_irq_mask_save(); + let ret = f(); + local_irq_restore(saved); ret } diff --git a/18_backtrace/kernel/src/panic_wait.rs b/18_backtrace/kernel/src/panic_wait.rs index c8e86fbd..c11ec67e 100644 --- a/18_backtrace/kernel/src/panic_wait.rs +++ b/18_backtrace/kernel/src/panic_wait.rs @@ -61,7 +61,7 @@ fn panic_prevent_reenter() { fn panic(info: &PanicInfo) -> ! { use crate::time::interface::TimeManager; - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); // Protect against panic infinite loops if any of the following code panics itself. panic_prevent_reenter(); diff --git a/18_backtrace/kernel/tests/04_exception_irq_sanity.rs b/18_backtrace/kernel/tests/04_exception_irq_sanity.rs index 7b9628d5..e93a4caf 100644 --- a/18_backtrace/kernel/tests/04_exception_irq_sanity.rs +++ b/18_backtrace/kernel/tests/04_exception_irq_sanity.rs @@ -34,21 +34,21 @@ fn local_irq_mask_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); // Restore earlier state. - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); } /// Check that IRQ unmasking works. #[kernel_test] fn local_irq_unmask_works() { // Precondition: IRQs are masked. - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); assert!(exception::asynchronous::is_local_irq_masked()); } @@ -58,12 +58,12 @@ fn local_irq_mask_save_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - let first = unsafe { exception::asynchronous::local_irq_mask_save() }; + let first = exception::asynchronous::local_irq_mask_save(); assert!(!exception::asynchronous::is_local_irq_masked()); - let second = unsafe { exception::asynchronous::local_irq_mask_save() }; + let second = exception::asynchronous::local_irq_mask_save(); assert_ne!(first, second); - unsafe { exception::asynchronous::local_irq_restore(first) }; + exception::asynchronous::local_irq_restore(first); assert!(exception::asynchronous::is_local_irq_masked()); } diff --git a/19_kernel_heap/kernel/src/_arch/aarch64/exception/asynchronous.rs b/19_kernel_heap/kernel/src/_arch/aarch64/exception/asynchronous.rs index 73b82e65..cf6f97ac 100644 --- a/19_kernel_heap/kernel/src/_arch/aarch64/exception/asynchronous.rs +++ b/19_kernel_heap/kernel/src/_arch/aarch64/exception/asynchronous.rs @@ -83,42 +83,32 @@ pub fn is_local_irq_masked() -> bool { /// /// "Writes to PSTATE.{PAN, D, A, I, F} occur in program order without the need for additional /// synchronization." -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_unmask() { - #[rustfmt::skip] - asm!( - "msr DAIFClr, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_unmask() { + unsafe { + asm!( + "msr DAIFClr, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core. -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask() { - #[rustfmt::skip] - asm!( - "msr DAIFSet, {arg}", - arg = const daif_bits::IRQ, - options(nomem, nostack, preserves_flags) - ); +pub fn local_irq_mask() { + unsafe { + asm!( + "msr DAIFSet, {arg}", + arg = const daif_bits::IRQ, + options(nomem, nostack, preserves_flags) + ); + } } /// Mask IRQs on the executing core and return the previously saved interrupt mask bits (DAIF). -/// -/// # Safety -/// -/// - Changes the HW state of the executing core. #[inline(always)] -pub unsafe fn local_irq_mask_save() -> u64 { +pub fn local_irq_mask_save() -> u64 { let saved = DAIF.get(); local_irq_mask(); @@ -127,12 +117,11 @@ pub unsafe fn local_irq_mask_save() -> u64 { /// Restore the interrupt mask bits (DAIF) using the callee's argument. /// -/// # Safety +/// # Invariant /// -/// - Changes the HW state of the executing core. /// - No sanity checks on the input. #[inline(always)] -pub unsafe fn local_irq_restore(saved: u64) { +pub fn local_irq_restore(saved: u64) { DAIF.set(saved); } diff --git a/19_kernel_heap/kernel/src/exception/asynchronous.rs b/19_kernel_heap/kernel/src/exception/asynchronous.rs index d9d2767c..3544e621 100644 --- a/19_kernel_heap/kernel/src/exception/asynchronous.rs +++ b/19_kernel_heap/kernel/src/exception/asynchronous.rs @@ -151,13 +151,9 @@ impl fmt::Display for IRQNumber<{ MAX_INCLUSIVE }> { /// previous state before returning, so this is deemed safe. #[inline(always)] pub fn exec_with_irq_masked(f: impl FnOnce() -> T) -> T { - let ret: T; - - unsafe { - let saved = local_irq_mask_save(); - ret = f(); - local_irq_restore(saved); - } + let saved = local_irq_mask_save(); + let ret = f(); + local_irq_restore(saved); ret } diff --git a/19_kernel_heap/kernel/src/panic_wait.rs b/19_kernel_heap/kernel/src/panic_wait.rs index c8e86fbd..c11ec67e 100644 --- a/19_kernel_heap/kernel/src/panic_wait.rs +++ b/19_kernel_heap/kernel/src/panic_wait.rs @@ -61,7 +61,7 @@ fn panic_prevent_reenter() { fn panic(info: &PanicInfo) -> ! { use crate::time::interface::TimeManager; - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); // Protect against panic infinite loops if any of the following code panics itself. panic_prevent_reenter(); diff --git a/19_kernel_heap/kernel/tests/04_exception_irq_sanity.rs b/19_kernel_heap/kernel/tests/04_exception_irq_sanity.rs index 7b9628d5..e93a4caf 100644 --- a/19_kernel_heap/kernel/tests/04_exception_irq_sanity.rs +++ b/19_kernel_heap/kernel/tests/04_exception_irq_sanity.rs @@ -34,21 +34,21 @@ fn local_irq_mask_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); // Restore earlier state. - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); } /// Check that IRQ unmasking works. #[kernel_test] fn local_irq_unmask_works() { // Precondition: IRQs are masked. - unsafe { exception::asynchronous::local_irq_mask() }; + exception::asynchronous::local_irq_mask(); assert!(!exception::asynchronous::is_local_irq_masked()); - unsafe { exception::asynchronous::local_irq_unmask() }; + exception::asynchronous::local_irq_unmask(); assert!(exception::asynchronous::is_local_irq_masked()); } @@ -58,12 +58,12 @@ fn local_irq_mask_save_works() { // Precondition: IRQs are unmasked. assert!(exception::asynchronous::is_local_irq_masked()); - let first = unsafe { exception::asynchronous::local_irq_mask_save() }; + let first = exception::asynchronous::local_irq_mask_save(); assert!(!exception::asynchronous::is_local_irq_masked()); - let second = unsafe { exception::asynchronous::local_irq_mask_save() }; + let second = exception::asynchronous::local_irq_mask_save(); assert_ne!(first, second); - unsafe { exception::asynchronous::local_irq_restore(first) }; + exception::asynchronous::local_irq_restore(first); assert!(exception::asynchronous::is_local_irq_masked()); }