ソースを参照

替换 local_irq_save 为 IrqFlagsGuard 实现 (#317)

Chiichen 1 年間 前
コミット
9550910ae1

+ 7 - 6
kernel/src/arch/x86_64/fpu.rs

@@ -9,9 +9,10 @@ use core::{
 
 use alloc::boxed::Box;
 
-use crate::include::bindings::bindings::process_control_block;
+use crate::{exception::InterruptArch, include::bindings::bindings::process_control_block};
+
+use crate::arch::CurrentIrqArch;
 
-use super::asm::irqflags::{local_irq_restore, local_irq_save};
 /// https://www.felixcloutier.com/x86/fxsave#tbl-3-47
 #[repr(C, align(16))]
 #[derive(Debug, Copy, Clone)]
@@ -79,7 +80,7 @@ impl FpState {
 /// @brief 从用户态进入内核时,保存浮点寄存器,并关闭浮点功能
 pub fn fp_state_save(pcb: &mut process_control_block) {
     // 该过程中不允许中断
-    let rflags: usize = local_irq_save();
+    let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
 
     let fp: &mut FpState = if pcb.fp_state == null_mut() {
         let f = Box::leak(Box::new(FpState::default()));
@@ -111,13 +112,13 @@ pub fn fp_state_save(pcb: &mut process_control_block) {
                                 "mov cr4, rax" */
         )
     }
-    local_irq_restore(rflags);
+    drop(guard);
 }
 
 /// @brief 从内核态返回用户态时,恢复浮点寄存器,并开启浮点功能
 pub fn fp_state_restore(pcb: &mut process_control_block) {
     // 该过程中不允许中断
-    let rflags = local_irq_save();
+    let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
 
     if pcb.fp_state == null_mut() {
         panic!("fp_state_restore: fp_state is null. pid={}", pcb.pid);
@@ -141,5 +142,5 @@ pub fn fp_state_restore(pcb: &mut process_control_block) {
     fp.restore();
     fp.clear();
 
-    local_irq_restore(rflags);
+    drop(guard);
 }

+ 5 - 6
kernel/src/exception/softirq.rs

@@ -10,13 +10,12 @@ use alloc::{boxed::Box, sync::Arc};
 use num_traits::FromPrimitive;
 
 use crate::{
+    arch::CurrentIrqArch,
     arch::{
-        asm::{
-            current::current_pcb,
-            irqflags::{local_irq_restore, local_irq_save},
-        },
+        asm::current::current_pcb,
         interrupt::{cli, sti},
     },
+    exception::InterruptArch,
     include::bindings::bindings::MAX_CPU_NUM,
     kdebug, kinfo,
     libs::rwlock::RwLock,
@@ -226,14 +225,14 @@ impl Softirq {
     }
 
     pub fn raise_softirq(&self, softirq_num: SoftirqNumber) {
-        let flags = local_irq_save();
+        let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
         let processor_id = smp_get_processor_id() as usize;
 
         cpu_pending(processor_id).insert(VecStatus::from(softirq_num));
 
         compiler_fence(Ordering::SeqCst);
 
-        local_irq_restore(flags);
+        drop(guard);
         // kdebug!("raise_softirq exited");
     }
     pub unsafe fn clear_softirq_pending(&self, softirq_num: SoftirqNumber) {

+ 4 - 3
kernel/src/mm/kernel_mapper.rs

@@ -1,9 +1,10 @@
 use super::{page::PageFlags, PageTableKind, PhysAddr, VirtAddr};
 use crate::{
     arch::{
-        asm::irqflags::{local_irq_restore, local_irq_save},
         mm::{LockedFrameAllocator, PageMapper},
+        CurrentIrqArch,
     },
+    exception::InterruptArch,
     libs::align::page_align_up,
     mm::allocator::page_frame::PageFrameCount,
     mm::{MMArch, MemoryManagementArch},
@@ -126,12 +127,12 @@ impl KernelMapper {
 impl Drop for KernelMapper {
     fn drop(&mut self) {
         // 为了防止fetch_sub和store之间,由于中断,导致store错误清除了owner,导致错误,因此需要关中断。
-        let flags = local_irq_save();
+        let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
         let prev_count = KERNEL_MAPPER_LOCK_COUNT.fetch_sub(1, Ordering::Relaxed);
         if prev_count == 1 {
             KERNEL_MAPPER_LOCK_OWNER.store(KERNEL_MAPPER_NO_PROCESSOR, Ordering::Release);
         }
-        local_irq_restore(flags);
+        drop(guard);
         compiler_fence(Ordering::Release);
     }
 }

+ 2 - 1
kernel/src/mm/ucontext.rs

@@ -1118,7 +1118,8 @@ impl VMA {
         // kdebug!("VMA::zeroed: flusher dropped");
 
         // 清空这些内存
-        let virt_iter: VirtPageFrameIter = VirtPageFrameIter::new(destination, destination.add(page_count));
+        let virt_iter: VirtPageFrameIter =
+            VirtPageFrameIter::new(destination, destination.add(page_count));
         for frame in virt_iter {
             let paddr = mapper.translate(frame.virt_address()).unwrap().0;