diff --git a/hal-x86_64/src/cpu.rs b/hal-x86_64/src/cpu.rs index f63d6e84..0e55ede7 100644 --- a/hal-x86_64/src/cpu.rs +++ b/hal-x86_64/src/cpu.rs @@ -243,7 +243,10 @@ impl DtablePtr { pub(crate) unsafe fn new_unchecked(t: &T) -> Self { let limit = (mem::size_of::() - 1) as u16; let base = t as *const _ as *const (); + Self { limit, base } + } + pub(crate) unsafe fn new_raw(base: *const (), limit: u16) -> Self { Self { limit, base } } } diff --git a/hal-x86_64/src/segment.rs b/hal-x86_64/src/segment.rs index 5ef524cc..9e9a097e 100644 --- a/hal-x86_64/src/segment.rs +++ b/hal-x86_64/src/segment.rs @@ -1,6 +1,6 @@ /// x86 memory segmentation structures. use crate::{cpu, task}; -use core::{arch::asm, mem}; +use core::{arch::asm, convert::TryInto, mem}; use mycelium_util::{ bits::{self, Pack64, Packing64, Pair64}, fmt, @@ -335,6 +335,10 @@ 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); + /// Sets `self` as the current GDT. /// /// This method is safe, because the `'static` bound on `self` ensures that @@ -370,7 +374,10 @@ impl Gdt { 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 ptr = cpu::DtablePtr::new_unchecked(&self.entries); + 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); tracing::trace!(?ptr, "loading GDT"); cpu::intrinsics::lgdt(ptr); tracing::trace!("loaded GDT!"); @@ -378,7 +385,7 @@ impl Gdt { /// Returns a new `Gdt` with all entries zeroed. pub const fn new() -> Self { - assert!(SIZE + (crate::cpu::topology::MAX_CPUS * 2) <= 65535); + assert!(Self::TOTAL_SIZE <= 65535); Gdt { entries: [Descriptor::new(); SIZE], tss_descrs: [SystemDescriptor::null(); crate::cpu::topology::MAX_CPUS],