From d38d8b66bdf1b4f126b0635755a00a0232b250aa Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Tue, 5 Mar 2024 10:26:57 +0100 Subject: [PATCH] Fix i686 compilation. --- src/arch/x86/gdt.rs | 10 ++++++++-- src/arch/x86/rmm.rs | 2 +- src/arch/x86/start.rs | 2 +- src/context/arch/x86.rs | 28 ++-------------------------- src/context/arch/x86_64.rs | 38 +------------------------------------- src/context/switch.rs | 2 +- src/debugger.rs | 6 +++--- src/percpu.rs | 35 +++++++++++++++++++++++++++++++++++ 8 files changed, 52 insertions(+), 71 deletions(-) diff --git a/src/arch/x86/gdt.rs b/src/arch/x86/gdt.rs index 5fe9793996..5ee9b8ad50 100644 --- a/src/arch/x86/gdt.rs +++ b/src/arch/x86/gdt.rs @@ -1,8 +1,10 @@ //! Global descriptor table -use core::{convert::TryInto, mem, ptr::addr_of_mut}; +use core::ptr::addr_of_mut; +use core::{convert::TryInto, mem, cell::{Cell, RefCell}}; +use core::sync::atomic::AtomicBool; -use crate::LogicalCpuId; +use crate::cpu_set::LogicalCpuId; use x86::{ bits32::task::TaskStateSegment, @@ -214,7 +216,11 @@ pub unsafe fn init_paging(stack_offset: usize, cpu_id: LogicalCpuId) { pcr.percpu = crate::percpu::PercpuBlock { cpu_id, switch_internals: Default::default(), + current_addrsp: RefCell::new(None), + new_addrsp_tmp: Cell::new(None), + wants_tlb_shootdown: AtomicBool::new(false), }; + crate::percpu::init_tlb_shootdown(cpu_id, &mut pcr.percpu); } #[derive(Copy, Clone, Debug)] diff --git a/src/arch/x86/rmm.rs b/src/arch/x86/rmm.rs index 7afb8c6bb9..4e7d55f360 100644 --- a/src/arch/x86/rmm.rs +++ b/src/arch/x86/rmm.rs @@ -10,7 +10,7 @@ use rmm::{ }; use spin::Mutex; -use crate::LogicalCpuId; +use crate::cpu_set::LogicalCpuId; use super::CurrentRmmArch as RmmA; diff --git a/src/arch/x86/start.rs b/src/arch/x86/start.rs index 5c0155263c..6cfbcf8316 100644 --- a/src/arch/x86/start.rs +++ b/src/arch/x86/start.rs @@ -16,7 +16,7 @@ use crate::{ log::{self, info}, memory, paging::{self, KernelMapper, PhysicalAddress, RmmA, RmmArch, TableKind}, - LogicalCpuId, + cpu_set::LogicalCpuId, }; /// Test of zero values in BSS. diff --git a/src/context/arch/x86.rs b/src/context/arch/x86.rs index 4a67efe732..4257c3d5ba 100644 --- a/src/context/arch/x86.rs +++ b/src/context/arch/x86.rs @@ -6,6 +6,7 @@ use crate::{ gdt::{pcr, GDT_USER_FS, GDT_USER_GS}, interrupt::handler::ScratchRegisters, paging::{RmmA, RmmArch, TableKind}, + percpu::PercpuBlock, pop_scratch, push_scratch, syscall::FloatRegisters, }; @@ -148,32 +149,7 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) { prev.arch.gsbase = gdt[GDT_USER_GS].offset() as usize; gdt[GDT_USER_GS].set_offset(next.arch.gsbase as u32); } - - match next.addr_space { - // Since Arc is essentially just wraps a pointer, in this case a regular pointer (as - // opposed to dyn or slice fat pointers), and NonNull optimization exists, map_or will - // hopefully be optimized down to checking prev and next pointers, as next cannot be null. - Some(ref next_space) => { - if prev - .addr_space - .as_ref() - .map_or(true, |prev_space| !Arc::ptr_eq(&prev_space, &next_space)) - { - // Suppose we have two sibling threads A and B. A runs on CPU 0 and B on CPU 1. A - // recently called yield and is now here about to switch back. Meanwhile, B is - // currently creating a new mapping in their shared address space, for example a - // message on a channel. - // - // Unless we acquire this lock, it may be possible that the TLB will not contain new - // entries. While this can be caught and corrected in a page fault handler, this is not - // true when entries are removed from a page table! - next_space.read().table.utable.make_current(); - } - } - None => { - RmmA::set_table(TableKind::User, empty_cr3()); - } - } + PercpuBlock::current().new_addrsp_tmp.set(next.addr_space.clone()); core::arch::asm!( "call {inner}", diff --git a/src/context/arch/x86_64.rs b/src/context/arch/x86_64.rs index 1ad7968581..5eb34796ae 100644 --- a/src/context/arch/x86_64.rs +++ b/src/context/arch/x86_64.rs @@ -1,14 +1,11 @@ use core::{ mem, ptr::{addr_of, addr_of_mut}, - sync::atomic::AtomicBool, borrow::BorrowMut, + sync::atomic::AtomicBool, }; -use alloc::sync::Arc; - use crate::{ interrupt::handler::ScratchRegisters, - paging::{RmmA, RmmArch, TableKind}, pop_scratch, push_scratch, syscall::FloatRegisters, percpu::PercpuBlock, }; @@ -331,36 +328,3 @@ unsafe extern "C" fn signal_handler_wrapper() { options(noreturn) ); } -pub unsafe fn switch_arch_hook() { - let percpu = PercpuBlock::current(); - - let cur_addrsp = percpu.current_addrsp.borrow(); - let next_addrsp = percpu.new_addrsp_tmp.take(); - - let retain_pgtbl = match (&*cur_addrsp, &next_addrsp) { - (Some(ref p), Some(ref n)) => Arc::ptr_eq(p, n), - (Some(_), None) | (None, Some(_)) => false, - (None, None) => true, - }; - if retain_pgtbl { - // If we are not switching to a different address space, we can simply return early. - } - if let Some(ref prev_addrsp) = &*cur_addrsp { - prev_addrsp.acquire_read().used_by.atomic_clear(percpu.cpu_id); - } - - drop(cur_addrsp); - - // Tell future TLB shootdown handlers that old_addrsp_tmp is no longer the current address - // space. - *percpu.current_addrsp.borrow_mut() = next_addrsp; - - if let Some(next_addrsp) = &*percpu.current_addrsp.borrow() { - let next = next_addrsp.acquire_read(); - - next.used_by.atomic_set(percpu.cpu_id); - next.table.utable.make_current(); - } else { - RmmA::set_table(TableKind::User, empty_cr3()); - } -} diff --git a/src/context/switch.rs b/src/context/switch.rs index 340cc477fe..076568cd85 100644 --- a/src/context/switch.rs +++ b/src/context/switch.rs @@ -111,7 +111,7 @@ pub unsafe extern "C" fn switch_finish_hook() { // TODO: unreachable_unchecked()? crate::arch::stop::emergency_reset(); } - super::arch::switch_arch_hook(); + crate::percpu::switch_arch_hook(); arch::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst); } diff --git a/src/debugger.rs b/src/debugger.rs index c5fc9657c9..e51872e87b 100644 --- a/src/debugger.rs +++ b/src/debugger.rs @@ -132,7 +132,7 @@ pub unsafe fn debugger(target_id: Option) { // Switch to context page table to ensure syscall debug and stack dump will work if let Some(ref space) = context.addr_space { - RmmA::set_table(TableKind::User, space.read().table.utable.table().phys()); + RmmA::set_table(TableKind::User, space.acquire_read().table.utable.table().phys()); //TODO check_consistency(&mut space.write()); } @@ -147,7 +147,7 @@ pub unsafe fn debugger(target_id: Option) { ); } if let Some(ref addr_space) = context.addr_space { - let addr_space = addr_space.read(); + let addr_space = addr_space.acquire_read(); if !addr_space.grants.is_empty() { println!("grants:"); for (base, grant) in addr_space.grants.iter() { @@ -171,7 +171,7 @@ pub unsafe fn debugger(target_id: Option) { for _ in 0..64 { if context.addr_space.as_ref().map_or(false, |space| { space - .read() + .acquire_read() .table .utable .translate(crate::paging::VirtualAddress::new(sp)) diff --git a/src/percpu.rs b/src/percpu.rs index 1df0e1fff8..33f6b476c6 100644 --- a/src/percpu.rs +++ b/src/percpu.rs @@ -2,7 +2,9 @@ use core::cell::{Cell, RefCell}; use core::sync::atomic::{AtomicBool, AtomicPtr, Ordering}; use alloc::sync::Arc; +use rmm::Arch; +use crate::context::empty_cr3; use crate::context::memory::AddrSpaceWrapper; use crate::cpu_set::MAX_CPU_COUNT; use crate::{context::switch::ContextSwitchPercpu, cpu_set::LogicalCpuId}; @@ -80,3 +82,36 @@ impl PercpuBlock { } } } +pub unsafe fn switch_arch_hook() { + let percpu = PercpuBlock::current(); + + let cur_addrsp = percpu.current_addrsp.borrow(); + let next_addrsp = percpu.new_addrsp_tmp.take(); + + let retain_pgtbl = match (&*cur_addrsp, &next_addrsp) { + (Some(ref p), Some(ref n)) => Arc::ptr_eq(p, n), + (Some(_), None) | (None, Some(_)) => false, + (None, None) => true, + }; + if retain_pgtbl { + // If we are not switching to a different address space, we can simply return early. + } + if let Some(ref prev_addrsp) = &*cur_addrsp { + prev_addrsp.acquire_read().used_by.atomic_clear(percpu.cpu_id); + } + + drop(cur_addrsp); + + // Tell future TLB shootdown handlers that old_addrsp_tmp is no longer the current address + // space. + *percpu.current_addrsp.borrow_mut() = next_addrsp; + + if let Some(next_addrsp) = &*percpu.current_addrsp.borrow() { + let next = next_addrsp.acquire_read(); + + next.used_by.atomic_set(percpu.cpu_id); + next.table.utable.make_current(); + } else { + crate::paging::RmmA::set_table(rmm::TableKind::User, empty_cr3()); + } +}