Skip to content

Commit 91b7de6

Browse files
committed
[interrupt-handlers] added IDT
- added IdtEntry structure, - created IDT static mut array, and - made fxns to init_idt and set_idt_entry. Signed-off-by: danbugs <[email protected]>
1 parent da58023 commit 91b7de6

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

src/hyperlight_guest/src/idt.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 crate::interrupt_entry::{
18+
_do_excp0, _do_excp1, _do_excp2, _do_excp3, _do_excp4, _do_excp5, _do_excp6, _do_excp7,
19+
_do_excp8, _do_excp9, _do_excp10, _do_excp11, _do_excp12, _do_excp13, _do_excp14, _do_excp15,
20+
_do_excp16, _do_excp17, _do_excp18, _do_excp19, _do_excp20, _do_excp30};
21+
22+
// An entry in the Interrupt Descriptor Table (IDT)
23+
// For reference, see: https://wiki.osdev.org/Interrupt_Descriptor_Table#Structure_on_x86-64
24+
#[repr(C, align(16))]
25+
pub(crate) struct IdtEntry {
26+
offset_low: u16, // Lower 16 bits of handler address
27+
selector: u16, // code segment selector in GDT
28+
ist: u8, // Interrupt Stack Table offset
29+
type_attr: u8, // Gate type and flags
30+
offset_mid: u16, // Middle 16 bits of handler address
31+
offset_high: u32, // High 32 bits of handler address
32+
zero: u32, // Reserved (always 0)
33+
}
34+
35+
impl IdtEntry {
36+
fn new(handler: u64) -> Self {
37+
Self {
38+
offset_low: (handler & 0xFFFF) as u16,
39+
selector: 0x08, // Kernel Code Segment
40+
ist: 0, // No IST used
41+
type_attr: 0x8E,
42+
// 0x8E = 10001110b
43+
// 1 00 0 1110
44+
// 1 = Present
45+
// 00 = Descriptor Privilege Level (0)
46+
// 0 = Storage Segment (0)
47+
// 1110 = Gate Type (0b1110 = 14 = 0xE)
48+
// 0xE means it's an interrupt gate
49+
offset_mid: ((handler >> 16) & 0xFFFF) as u16,
50+
offset_high: ((handler >> 32) & 0xFFFFFFFF) as u32,
51+
zero: 0,
52+
}
53+
}
54+
}
55+
56+
57+
// The IDT is an array of 256 IDT entries
58+
// (for reference, see: https://wiki.osdev.org/Interrupt_Descriptor_Table#Structure_on_x86-64)
59+
pub(crate) static mut IDT: [IdtEntry; 256] = unsafe { core::mem::zeroed() };
60+
61+
pub(crate) fn init_idt() {
62+
set_idt_entry(0, _do_excp0); // Divide by zero
63+
set_idt_entry(1, _do_excp1); // Debug
64+
set_idt_entry(2, _do_excp2); // Non-maskable interrupt
65+
set_idt_entry(3, _do_excp3); // Breakpoint
66+
set_idt_entry(4, _do_excp4); // Overflow
67+
set_idt_entry(5, _do_excp5); // Bound Range Exceeded
68+
set_idt_entry(6, _do_excp6); // Invalid Opcode
69+
set_idt_entry(7, _do_excp7); // Device Not Available
70+
set_idt_entry(8, _do_excp8); // Double Fault
71+
set_idt_entry(9, _do_excp9); // Coprocessor Segment Overrun
72+
set_idt_entry(10, _do_excp10); // Invalid TSS
73+
set_idt_entry(11, _do_excp11); // Segment Not Present
74+
set_idt_entry(12, _do_excp12); // Stack-Segment Fault
75+
set_idt_entry(13, _do_excp13); // General Protection Fault
76+
set_idt_entry(14, _do_excp14); // Page Fault
77+
set_idt_entry(15, _do_excp15); // Reserved
78+
set_idt_entry(16, _do_excp16); // x87 Floating-Point Exception
79+
set_idt_entry(17, _do_excp17); // Alignment Check
80+
set_idt_entry(18, _do_excp18); // Machine Check
81+
set_idt_entry(19, _do_excp19); // SIMD Floating-Point Exception
82+
set_idt_entry(20, _do_excp20); // Virtualization Exception
83+
set_idt_entry(30, _do_excp30); // Security Exception
84+
}
85+
86+
fn set_idt_entry(index: usize, handler: unsafe extern "sysv64" fn()) {
87+
let handler_addr = handler as *const () as u64;
88+
unsafe { IDT[index] = IdtEntry::new(handler_addr); }
89+
}
90+

src/hyperlight_guest/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub mod error;
5353
pub mod logging;
5454
pub mod interrupt_entry;
5555
pub mod interrupt_handlers;
56+
pub mod idt;
5657

5758
// Unresolved symbols
5859
///cbindgen:ignore

0 commit comments

Comments
 (0)