From 753b564fc60e3c24902cbc1bc82d7a75b89faba3 Mon Sep 17 00:00:00 2001 From: Raphael Ob Date: Wed, 11 Sep 2024 21:24:06 +0200 Subject: [PATCH] Fix ipl level setting when switching to new thread --- xernel/kernel/src/arch/amd64/interrupts/mod.rs | 18 +++++++----------- xernel/kernel/src/dpc.rs | 7 +------ xernel/kernel/src/sched/context.rs | 6 +++++- xernel/kernel/src/sched/scheduler.rs | 4 ---- xernel/kernel/src/timer/mod.rs | 3 --- xernel/kernel/src/timer/timer_queue.rs | 2 -- 6 files changed, 13 insertions(+), 27 deletions(-) diff --git a/xernel/kernel/src/arch/amd64/interrupts/mod.rs b/xernel/kernel/src/arch/amd64/interrupts/mod.rs index cfe698bb..909b893b 100644 --- a/xernel/kernel/src/arch/amd64/interrupts/mod.rs +++ b/xernel/kernel/src/arch/amd64/interrupts/mod.rs @@ -7,10 +7,9 @@ use crate::sched::context::TrapFrame; use core::arch::asm; use core::sync::atomic::{compiler_fence, Ordering}; use idt::{IRQHandler, IDT_ENTRIES}; -use libxernel::ipl::{get_ipl, IPL}; +use libxernel::ipl::{get_ipl, raise_ipl, splx, IPL}; use super::apic::apic_spurious_interrupt; -use super::write_cr8; use libxernel::sync::SpinlockIRQ; static INTERRUPT_HANDLERS: SpinlockIRQ<[IRQHandler; IDT_ENTRIES]> = SpinlockIRQ::new([IRQHandler::None; IDT_ENTRIES]); @@ -32,22 +31,21 @@ extern "sysv64" fn generic_interrupt_handler(isr: usize, ctx: *mut TrapFrame) { let new_ipl = IPL::from(isr >> 4); let current_ipl = get_ipl(); - debug!( - "getting interrupted with vector {} and dpc level {:?} on current level {:?}", - isr, new_ipl, current_ipl - ); - if (new_ipl as u8) < (current_ipl as u8) { panic!("IPL not less or equal"); } - write_cr8(new_ipl); + raise_ipl(new_ipl); enable(); let handlers = INTERRUPT_HANDLERS.lock(); let ctx = unsafe { &mut *ctx }; + if isr == 0x2f { + APIC.eoi(); + } + match &handlers[isr] { IRQHandler::Handler(handler) => { let handler = *handler; @@ -64,9 +62,7 @@ extern "sysv64" fn generic_interrupt_handler(isr: usize, ctx: *mut TrapFrame) { disable(); - debug!("returning from interrupt with ipl {:?}", current_ipl); - - write_cr8(current_ipl); + splx(current_ipl); } #[inline] diff --git a/xernel/kernel/src/dpc.rs b/xernel/kernel/src/dpc.rs index 91210315..423d75af 100644 --- a/xernel/kernel/src/dpc.rs +++ b/xernel/kernel/src/dpc.rs @@ -73,7 +73,6 @@ pub fn enqueue_dpc(dpc: Box) { if get_ipl() < IPL::DPC { let ipl = raise_ipl(IPL::DPC); - log!("calling dpc directly"); dpc.call(); splx(ipl); @@ -85,13 +84,10 @@ pub fn enqueue_dpc(dpc: Box) { } pub fn raise_dpc_interrupt() { - log!("raise dpc"); - warning!("{:?}", get_ipl()); APIC.send_ipi(current_cpu().lapic_id, 0x2f) } pub fn dispatch_dpcs(_: &mut TrapFrame) { - log!("working off dpcs"); let cpu = current_cpu(); assert!(get_ipl() == IPL::DPC); @@ -109,11 +105,10 @@ pub fn dispatch_dpcs(_: &mut TrapFrame) { let old = cpu.current_thread.read().clone(); let new = cpu.next.read().clone(); - debug!("switching to thread"); - if old.is_some() && new.is_some() { *cpu.next.write() = None; let ipl = get_ipl(); + switch_threads(old.unwrap(), new.unwrap()); splx(ipl); } diff --git a/xernel/kernel/src/sched/context.rs b/xernel/kernel/src/sched/context.rs index 88dc3d9a..40b3ccbc 100644 --- a/xernel/kernel/src/sched/context.rs +++ b/xernel/kernel/src/sched/context.rs @@ -1,5 +1,7 @@ use core::arch::asm; +use crate::arch::amd64::write_cr8; + #[derive(Debug, Clone, Copy, Default)] #[repr(C)] pub struct Context { @@ -89,7 +91,9 @@ impl TrapFrame { pub extern "C" fn thread_trampoline() -> ! { unsafe { asm!( - "mov rsp, rbx; + "mov rax, 0; + mov cr8, rax; + mov rsp, rbx; pop rbp; pop rax; pop rbx; diff --git a/xernel/kernel/src/sched/scheduler.rs b/xernel/kernel/src/sched/scheduler.rs index 32eb0bf7..0036f4d7 100644 --- a/xernel/kernel/src/sched/scheduler.rs +++ b/xernel/kernel/src/sched/scheduler.rs @@ -1,18 +1,15 @@ use crate::arch::amd64::gdt::GDT_BSP; use crate::arch::amd64::switch_context; use crate::cpu::current_cpu; -use crate::timer::enqueue_timer; use crate::timer::timer_event::TimerEvent; use alloc::sync::Arc; use core::time::Duration; -use libxernel::ipl::get_ipl; use x86_64::registers::control::Cr3; use x86_64::registers::segmentation::{Segment, DS}; use super::thread::{Thread, ThreadStatus}; pub fn reschedule(_: ()) { - log!("reschedule {:?}", get_ipl()); let cpu = current_cpu(); let next_ref = cpu.run_queue.write().pop_front(); @@ -100,7 +97,6 @@ pub fn switch_threads(old: Arc, new: Arc) { } fn register_reschedule_event(millis: u64) { - log!("register reschedule {:?}", get_ipl()); let event = TimerEvent::new(reschedule, (), Duration::from_millis(millis), false); let cpu = current_cpu(); diff --git a/xernel/kernel/src/timer/mod.rs b/xernel/kernel/src/timer/mod.rs index 0ae53832..823e5886 100644 --- a/xernel/kernel/src/timer/mod.rs +++ b/xernel/kernel/src/timer/mod.rs @@ -35,7 +35,6 @@ pub fn init() { } pub fn timer_interrupt_handler(_frame: &mut TrapFrame) { - log!("timer_interrupt {:?}", get_ipl()); // if periodic, add again to queue // set timer to next event in queue @@ -45,13 +44,11 @@ pub fn timer_interrupt_handler(_frame: &mut TrapFrame) { //timer_queue.deadlines(); - //log!("calling event aka adding dpc to queue"); timer_queue.event_dispatch(); let next_event = timer_queue.events.front(); if let Some(event) = next_event { - debug!("{:?}", event.deadline); APIC.oneshot(*TIMER_VECTOR, &event.deadline); if event.periodic { diff --git a/xernel/kernel/src/timer/timer_queue.rs b/xernel/kernel/src/timer/timer_queue.rs index b557131f..c7cd8095 100644 --- a/xernel/kernel/src/timer/timer_queue.rs +++ b/xernel/kernel/src/timer/timer_queue.rs @@ -46,13 +46,11 @@ impl TimerQueue { pub fn enqueue(&mut self, event: TimerEvent) { if self.events.is_empty() { - debug!("setting apic {:#?}", event.deadline); APIC.oneshot(*TIMER_VECTOR, &event.deadline); self.events.push_front(event); } else { if event.deadline < self.events.front().unwrap().deadline { APIC.stop(); - debug!("stopping apic and setting new {:#?}", event.deadline); APIC.oneshot(*TIMER_VECTOR, &event.deadline); }