From a737b66d012dda4b7bdf641d7f89b455c57ecced Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Sat, 24 Dec 2022 10:09:44 -0800 Subject: [PATCH] fix screwed up gdt/gdt pointer --- hal-x86_64/src/cpu/topology.rs | 7 ++---- hal-x86_64/src/segment.rs | 42 +++++++++++++-------------------- src/arch/x86_64/segmentation.rs | 2 +- 3 files changed, 19 insertions(+), 32 deletions(-) diff --git a/hal-x86_64/src/cpu/topology.rs b/hal-x86_64/src/cpu/topology.rs index e6bee52d2..54a8b39b2 100644 --- a/hal-x86_64/src/cpu/topology.rs +++ b/hal-x86_64/src/cpu/topology.rs @@ -127,16 +127,13 @@ impl Topology { }) } - pub fn init_boot_processor(&mut self, gdt: &mut segment::Gdt) { + pub fn init_boot_processor(&mut self, gdt: &mut segment::Gdt) { self.boot_processor.init_processor(gdt); } } impl Processor { - pub(crate) fn init_processor( - &mut self, - gdt: &mut segment::Gdt, - ) { + pub(crate) fn init_processor(&mut self, gdt: &mut segment::Gdt) { tracing::info!(self.id, "initializing processor"); assert!(!self.initialized, "processor already initialized"); diff --git a/hal-x86_64/src/segment.rs b/hal-x86_64/src/segment.rs index 9e9a097ec..e51ec7601 100644 --- a/hal-x86_64/src/segment.rs +++ b/hal-x86_64/src/segment.rs @@ -117,13 +117,12 @@ bits::bitfield! { // it to `usize` in the array, but this requires unstable const generics // features and i didn't want to mess with it... #[derive(Clone)] +#[repr(C)] // rustfmt eats default parameters in const generics for some reason (probably a // bug...) #[rustfmt::skip] -pub struct Gdt { - entries: [Descriptor; SIZE], - tss_descrs: [SystemDescriptor; crate::cpu::topology::MAX_CPUS], - push_tss_at: usize, +pub struct Gdt { + entries: [u64; Self::SIZE as usize], push_at: usize, } @@ -334,10 +333,8 @@ impl Selector { // === impl Gdt === -impl Gdt { - /// The total size of the GDT, including both the normal GDT descriptors and - /// system (TSS) descriptors. - const TOTAL_SIZE: usize = SIZE + (crate::cpu::topology::MAX_CPUS * 2); +impl Gdt { + const SIZE: u16 = 8 + (crate::cpu::topology::MAX_CPUS as u16 * 2); /// Sets `self` as the current GDT. /// @@ -372,12 +369,7 @@ impl Gdt { /// /// `self` must point to a GDT that is valid for the `'static` lifetime. unsafe fn load_unchecked(&self) { - // Create the descriptor table pointer with *just* the actual table, so - // that the next push index isn't considered a segment descriptor! - let limit: u16 = ((Self::TOTAL_SIZE - 1) * mem::size_of::()) - .try_into() - .expect("GDT size would exceed a u16"); - let ptr = cpu::DtablePtr::new_raw(self as *const _ as *const (), limit); + let ptr = cpu::DtablePtr::new_unchecked(&self.entries); tracing::trace!(?ptr, "loading GDT"); cpu::intrinsics::lgdt(ptr); tracing::trace!("loaded GDT!"); @@ -385,12 +377,9 @@ impl Gdt { /// Returns a new `Gdt` with all entries zeroed. pub const fn new() -> Self { - assert!(Self::TOTAL_SIZE <= 65535); Gdt { - entries: [Descriptor::new(); SIZE], - tss_descrs: [SystemDescriptor::null(); crate::cpu::topology::MAX_CPUS], + entries: [Descriptor::new().bits(); Self::SIZE as usize], push_at: 1, - push_tss_at: 1, } } @@ -417,26 +406,27 @@ impl Gdt { const fn push(&mut self, entry: Descriptor) -> u16 { let idx = self.push_at; - self.entries[idx] = entry; + self.entries[idx] = entry.bits(); self.push_at += 1; idx as u16 } const fn push_tss(&mut self, entry: SystemDescriptor) -> u16 { - let idx = self.push_tss_at; - self.tss_descrs[idx] = entry; - self.push_tss_at += 1; + let idx = self.push_at; + self.entries[idx] = entry.low; + self.entries[idx + 1] = entry.high; + self.push_at += 2; idx as u16 } } -impl fmt::Debug for Gdt { +impl fmt::Debug for Gdt { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Gdt") - .field("capacity", &SIZE) + .field("capacity", &Self::SIZE) .field("len", &(self.push_at - 1)) - .field("entries", &&self.entries[..self.push_at]) - .field("tss_descrs", &&self.tss_descrs[..self.push_tss_at]) + // .field("entries", &&self.entries[..self.push_at]) + // .field("tss_descrs", &&self.tss_descrs[..self.push_tss_at]) .finish() } } diff --git a/src/arch/x86_64/segmentation.rs b/src/arch/x86_64/segmentation.rs index 1e249bb0e..1bbe14dd3 100644 --- a/src/arch/x86_64/segmentation.rs +++ b/src/arch/x86_64/segmentation.rs @@ -10,7 +10,7 @@ use mycelium_util::{ sync::{self, spin}, }; -pub(super) static GDT: spin::Mutex> = spin::Mutex::new(Gdt::new()); +pub(super) static GDT: spin::Mutex = spin::Mutex::new(Gdt::new()); #[tracing::instrument(level = tracing::Level::DEBUG)] pub(super) fn init_gdt() {