Skip to content

Commit a10059d

Browse files
committed
[interrupt-handlers] added GDT/GDTR
- added GdtEntry struct for GDT static mut global var, - added null, kernel code, and kernel data segments to GDT, - added code to load the GDT, and - added calls to init_idt, load_idt, and load_gdt to entrypoint. Signed-off-by: danbugs <[email protected]>
1 parent ef5fce8 commit a10059d

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

src/hyperlight_guest/src/entrypoint.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ use crate::{
3030
__security_cookie, HEAP_ALLOCATOR, MIN_STACK_ADDRESS, OS_PAGE_SIZE, OUTB_PTR,
3131
OUTB_PTR_WITH_CONTEXT, P_PEB, RUNNING_MODE,
3232
};
33+
use crate::gdt::load_gdt;
34+
use crate::idt::init_idt;
35+
use crate::idtr::load_idt;
3336

3437
#[inline(never)]
3538
pub fn halt() {
@@ -86,6 +89,14 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, ops: u64, max_log_
8689
let peb_ptr = P_PEB.unwrap();
8790
__security_cookie = peb_address ^ seed;
8891

92+
// Set up GDT/IDT
93+
load_gdt();
94+
init_idt();
95+
load_idt();
96+
97+
// Enable interrupts
98+
asm!("sti", options(nostack));
99+
89100
let srand_seed = ((peb_address << 8 ^ seed >> 4) >> 32) as u32;
90101

91102
// Set the seed for the random number generator for C code using rand;

src/hyperlight_guest/src/gdt.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
Copyright 2024 The Hyperlight Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
use core::arch::asm;
18+
use core::ptr::addr_of;
19+
20+
/// Entry in the Global Descriptor Table (GDT)
21+
/// For reference, see: https://wiki.osdev.org/Global_Descriptor_Table
22+
#[repr(C, align(8))]
23+
pub struct GdtEntry {
24+
limit_low: u16,
25+
base_low: u16,
26+
base_middle: u8,
27+
access: u8,
28+
flags_limit: u8,
29+
base_high: u8,
30+
}
31+
32+
impl GdtEntry {
33+
/// Creates a new GDT entry.
34+
pub const fn new(base: u32, limit: u32, access: u8, flags: u8) -> Self {
35+
Self {
36+
base_low: (base & 0xffff) as u16,
37+
base_middle: ((base >> 16) & 0xff) as u8,
38+
base_high: ((base >> 24) & 0xff) as u8,
39+
limit_low: (limit & 0xffff) as u16,
40+
flags_limit: (((limit >> 16) & 0x0f) as u8) | ((flags & 0x0f) << 4),
41+
access,
42+
}
43+
}
44+
}
45+
46+
// Global Descriptor Table (GDT)
47+
// For reference, see: https://wiki.osdev.org/GDT_Tutorial#What_to_Put_In_a_GDT
48+
static mut GDT: [GdtEntry; 3] = [
49+
// Null descriptor
50+
GdtEntry::new(0, 0, 0, 0),
51+
52+
// Kernel Code Segment (0x08)
53+
GdtEntry::new(0, 0, 0x9A, 0xA),
54+
55+
// Kernel Data Segment (0x10)
56+
GdtEntry::new(0, 0, 0x92, 0xC),
57+
];
58+
59+
/// GDTR (GDT pointer)
60+
#[repr(C, packed)]
61+
struct GdtPointer {
62+
size: u16,
63+
base: u64,
64+
}
65+
66+
/// Load the GDT
67+
pub unsafe fn load_gdt() {
68+
let gdt_ptr = GdtPointer {
69+
size: (core::mem::size_of::<[GdtEntry; 3]>() - 1) as u16,
70+
base: addr_of!(GDT) as *const _ as u64,
71+
};
72+
73+
asm!(
74+
"lgdt [{0}]",
75+
"mov ax, 0x10", // Load data segment registers
76+
"mov ds, ax",
77+
"mov es, ax",
78+
"mov fs, ax",
79+
"mov gs, ax",
80+
"mov ss, ax",
81+
"push 0x08", // Push CS (kernel code segment)
82+
"lea rax, [2f + rip]", // Load the next instruction's address
83+
"push rax", // Push address onto stack
84+
"retfq", // Far return to update CS
85+
"2:", // Label for continued execution
86+
in(reg) &gdt_ptr,
87+
options(nostack, preserves_flags)
88+
);
89+
}
90+

src/hyperlight_guest/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pub mod interrupt_entry;
5555
pub mod interrupt_handlers;
5656
pub mod idt;
5757
pub mod idtr;
58+
pub mod gdt;
5859

5960
// Unresolved symbols
6061
///cbindgen:ignore

0 commit comments

Comments
 (0)