mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-16 17:46:48 +00:00
Fix GDT issue when using EFI handover protocol
This commit is contained in:
parent
148695194f
commit
dd3aa8fe81
@ -21,10 +21,10 @@ use alloc::{boxed::Box, vec::Vec};
|
|||||||
use core::cell::SyncUnsafeCell;
|
use core::cell::SyncUnsafeCell;
|
||||||
|
|
||||||
use x86_64::{
|
use x86_64::{
|
||||||
instructions::tables::{lgdt, load_tss, sgdt},
|
instructions::tables::{lgdt, load_tss},
|
||||||
registers::{
|
registers::{
|
||||||
model_specific::Star,
|
model_specific::Star,
|
||||||
segmentation::{Segment64, GS},
|
segmentation::{Segment, Segment64, CS, GS},
|
||||||
},
|
},
|
||||||
structures::{
|
structures::{
|
||||||
gdt::{Descriptor, SegmentSelector},
|
gdt::{Descriptor, SegmentSelector},
|
||||||
@ -50,18 +50,13 @@ pub unsafe fn init(on_bsp: bool) {
|
|||||||
};
|
};
|
||||||
// FIXME: the segment limit assumed by x86_64 does not include the I/O port bitmap.
|
// FIXME: the segment limit assumed by x86_64 does not include the I/O port bitmap.
|
||||||
|
|
||||||
// Get current GDT.
|
// Allocate new GDT with 8 entries.
|
||||||
let gdtp = sgdt();
|
|
||||||
let entry_count = (gdtp.limit + 1) as usize / size_of::<u64>();
|
|
||||||
let old_gdt = core::slice::from_raw_parts(gdtp.base.as_ptr::<u64>(), entry_count);
|
|
||||||
|
|
||||||
// Allocate new GDT with 7 more entries.
|
|
||||||
//
|
//
|
||||||
// NOTICE: for fast syscall:
|
// NOTICE: for fast syscall:
|
||||||
// STAR[47:32] = K_CS = K_SS - 8
|
// STAR[47:32] = K_CS = K_SS - 8
|
||||||
// STAR[63:48] = U_CS32 = U_SS32 - 8 = U_CS - 16
|
// STAR[63:48] = U_CS32 = U_SS32 - 8 = U_CS - 16
|
||||||
let mut gdt = Vec::from(old_gdt);
|
let mut gdt = Vec::<u64>::new();
|
||||||
gdt.extend([tss0, tss1, KCODE64, KDATA64, UCODE32, UDATA32, UCODE64].iter());
|
gdt.extend([0, KCODE64, KDATA64, UCODE32, UDATA32, UCODE64, tss0, tss1].iter());
|
||||||
let gdt = Vec::leak(gdt);
|
let gdt = Vec::leak(gdt);
|
||||||
|
|
||||||
// Load new GDT and TSS.
|
// Load new GDT and TSS.
|
||||||
@ -69,13 +64,11 @@ pub unsafe fn init(on_bsp: bool) {
|
|||||||
limit: gdt.len() as u16 * 8 - 1,
|
limit: gdt.len() as u16 * 8 - 1,
|
||||||
base: VirtAddr::new(gdt.as_ptr() as _),
|
base: VirtAddr::new(gdt.as_ptr() as _),
|
||||||
});
|
});
|
||||||
load_tss(SegmentSelector::new(
|
load_tss(SegmentSelector::new(6, PrivilegeLevel::Ring0));
|
||||||
entry_count as u16,
|
CS::set_reg(SegmentSelector::new(1, PrivilegeLevel::Ring0));
|
||||||
PrivilegeLevel::Ring0,
|
|
||||||
));
|
|
||||||
|
|
||||||
let sysret = SegmentSelector::new(entry_count as u16 + 4, PrivilegeLevel::Ring3).0;
|
let sysret = SegmentSelector::new(3, PrivilegeLevel::Ring3).0;
|
||||||
let syscall = SegmentSelector::new(entry_count as u16 + 2, PrivilegeLevel::Ring0).0;
|
let syscall = SegmentSelector::new(1, PrivilegeLevel::Ring0).0;
|
||||||
Star::write_raw(sysret, syscall);
|
Star::write_raw(sysret, syscall);
|
||||||
|
|
||||||
USER_SS = sysret + 8;
|
USER_SS = sysret + 8;
|
||||||
@ -113,6 +106,7 @@ static mut USER_CS: u16 = 0;
|
|||||||
const KCODE64: u64 = 0x00209800_00000000; // EXECUTABLE | USER_SEGMENT | PRESENT | LONG_MODE
|
const KCODE64: u64 = 0x00209800_00000000; // EXECUTABLE | USER_SEGMENT | PRESENT | LONG_MODE
|
||||||
const UCODE64: u64 = 0x0020F800_00000000; // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT | LONG_MODE
|
const UCODE64: u64 = 0x0020F800_00000000; // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT | LONG_MODE
|
||||||
const KDATA64: u64 = 0x00009200_00000000; // DATA_WRITABLE | USER_SEGMENT | PRESENT
|
const KDATA64: u64 = 0x00009200_00000000; // DATA_WRITABLE | USER_SEGMENT | PRESENT
|
||||||
|
|
||||||
#[expect(dead_code)]
|
#[expect(dead_code)]
|
||||||
const UDATA64: u64 = 0x0000F200_00000000; // DATA_WRITABLE | USER_SEGMENT | USER_MODE | PRESENT
|
const UDATA64: u64 = 0x0000F200_00000000; // DATA_WRITABLE | USER_SEGMENT | USER_MODE | PRESENT
|
||||||
const UCODE32: u64 = 0x00cffa00_0000ffff; // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT
|
const UCODE32: u64 = 0x00cffa00_0000ffff; // EXECUTABLE | USER_SEGMENT | USER_MODE | PRESENT
|
||||||
|
Loading…
x
Reference in New Issue
Block a user