Fix i686 compilation.
This commit is contained in:
+8
-2
@@ -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)]
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ use rmm::{
|
||||
};
|
||||
use spin::Mutex;
|
||||
|
||||
use crate::LogicalCpuId;
|
||||
use crate::cpu_set::LogicalCpuId;
|
||||
|
||||
use super::CurrentRmmArch as RmmA;
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
+2
-26
@@ -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,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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -132,7 +132,7 @@ pub unsafe fn debugger(target_id: Option<crate::context::ContextId>) {
|
||||
|
||||
// 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<crate::context::ContextId>) {
|
||||
);
|
||||
}
|
||||
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<crate::context::ContextId>) {
|
||||
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))
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user