Simplify x86_64 percpu and GSBASE calculation
This commit is contained in:
@@ -4,7 +4,7 @@ use core::sync::atomic::AtomicBool;
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use crate::{push_scratch, pop_scratch};
|
||||
use crate::gdt::{GDT, GDT_USER_FS, GDT_USER_GS};
|
||||
use crate::gdt::{pcr, GDT_USER_FS, GDT_USER_GS};
|
||||
use crate::interrupt::handler::ScratchRegisters;
|
||||
use crate::paging::{RmmA, RmmArch, TableKind};
|
||||
use crate::syscall::FloatRegisters;
|
||||
@@ -137,10 +137,12 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) {
|
||||
);
|
||||
|
||||
{
|
||||
prev.arch.fsbase = GDT[GDT_USER_FS].offset() as usize;
|
||||
GDT[GDT_USER_FS].set_offset(next.arch.fsbase as u32);
|
||||
prev.arch.gsbase = GDT[GDT_USER_GS].offset() as usize;
|
||||
GDT[GDT_USER_GS].set_offset(next.arch.gsbase as u32);
|
||||
let gdt = &mut (&mut *pcr()).gdt;
|
||||
|
||||
prev.arch.fsbase = gdt[GDT_USER_FS].offset() as usize;
|
||||
gdt[GDT_USER_FS].set_offset(next.arch.fsbase as u32);
|
||||
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 {
|
||||
|
||||
@@ -154,17 +154,15 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) {
|
||||
wrgsbase(next.arch.gsbase as u64);
|
||||
swapgs();
|
||||
} else {
|
||||
prev.arch.fsbase = msr::rdmsr(msr::IA32_FS_BASE) as usize;
|
||||
msr::wrmsr(msr::IA32_FS_BASE, next.arch.fsbase as u64);
|
||||
prev.arch.gsbase = msr::rdmsr(msr::IA32_KERNEL_GSBASE) as usize;
|
||||
msr::wrmsr(msr::IA32_KERNEL_GSBASE, next.arch.gsbase as u64);
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
// Since Arc 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
|
||||
|
||||
@@ -960,9 +960,6 @@ pub fn setup_new_utable() -> Result<Table> {
|
||||
|
||||
// Copy physmap mapping
|
||||
copy_mapping(crate::PHYS_PML4);
|
||||
|
||||
// Copy kernel percpu (similar to TLS) mapping.
|
||||
copy_mapping(crate::KERNEL_PERCPU_PML4);
|
||||
}
|
||||
|
||||
Ok(Table {
|
||||
|
||||
Reference in New Issue
Block a user