Fix i686 compilation.

This commit is contained in:
4lDO2
2024-03-05 10:26:57 +01:00
parent b35c9d1e62
commit d38d8b66bd
8 changed files with 52 additions and 71 deletions
+2 -26
View File
@@ -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}",
+1 -37
View File
@@ -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());
}
}
+1 -1
View File
@@ -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);
}