Simplify x86_64 percpu and GSBASE calculation

This commit is contained in:
4lDO2
2023-07-10 14:13:12 +00:00
committed by Jeremy Soller
parent 5c99d73bbe
commit 3ded84c945
19 changed files with 334 additions and 635 deletions
+7 -5
View File
@@ -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 {
+3 -5
View File
@@ -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
-3
View File
@@ -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 {