Skip to content

Commit 1bd70e1

Browse files
committed
[interrupt-handlers] added interrupt handler entry stubs and exception handler
- interrupt handler entry stubs = -- added macros to save/restore register context -- added defintions for different exceptions (_do_excp0-20+30), which save context, set params per SysV ABI, call handler, restore context, then iretq via macros. - added an exception handler that are used by the _do_excp* fxns. Note: this code is specific for x86_64 Signed-off-by: danbugs <[email protected]>
1 parent 4b3bd98 commit 1bd70e1

File tree

3 files changed

+274
-0
lines changed

3 files changed

+274
-0
lines changed
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
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+
// Note: this code takes reference from
18+
// https://github.com/nanvix/nanvix/tree/dev/src/kernel/src/hal/arch/x86
19+
20+
use core::arch::global_asm;
21+
22+
use crate::interrupt_handlers::hl_exception_handler;
23+
24+
extern "sysv64" {
25+
// Exception handlers
26+
pub(crate) fn _do_excp0();
27+
pub(crate) fn _do_excp1();
28+
pub(crate) fn _do_excp2();
29+
pub(crate) fn _do_excp3();
30+
pub(crate) fn _do_excp4();
31+
pub(crate) fn _do_excp5();
32+
pub(crate) fn _do_excp6();
33+
pub(crate) fn _do_excp7();
34+
// TODO: uncomment when pagefault is implemented
35+
// pub(crate) fn _do_excp8();
36+
pub(crate) fn _do_excp9();
37+
pub(crate) fn _do_excp10();
38+
pub(crate) fn _do_excp11();
39+
pub(crate) fn _do_excp12();
40+
pub(crate) fn _do_excp13();
41+
// TODO: uncomment when pagefault is implemented
42+
// pub(crate) fn _do_excp14();
43+
pub(crate) fn _do_excp15();
44+
pub(crate) fn _do_excp16();
45+
pub(crate) fn _do_excp17();
46+
pub(crate) fn _do_excp18();
47+
pub(crate) fn _do_excp19();
48+
pub(crate) fn _do_excp20();
49+
pub(crate) fn _do_excp30();
50+
}
51+
52+
// Defines `context_save` and `context_restore`
53+
macro_rules! context_save {
54+
() => {
55+
concat!(
56+
// Save general-purpose registers
57+
" push rax\n",
58+
" push rbx\n",
59+
" push rcx\n",
60+
" push rdx\n",
61+
" push rsi\n",
62+
" push rdi\n",
63+
" push rbp\n",
64+
" push r8\n",
65+
" push r9\n",
66+
" push r10\n",
67+
" push r11\n",
68+
" push r12\n",
69+
" push r13\n",
70+
" push r14\n",
71+
" push r15\n",
72+
// Save segment registers
73+
" mov rax, ds\n",
74+
" push rax\n",
75+
" mov rax, es\n",
76+
" push rax\n",
77+
" mov rax, fs\n",
78+
" push rax\n",
79+
" mov rax, gs\n",
80+
" push rax\n",
81+
)
82+
};
83+
}
84+
85+
macro_rules! context_restore {
86+
() => {
87+
concat!(
88+
// Restore segment registers
89+
" pop rax\n",
90+
" mov gs, rax\n",
91+
" pop rax\n",
92+
" mov fs, rax\n",
93+
" pop rax\n",
94+
" mov es, rax\n",
95+
" pop rax\n",
96+
" mov ds, rax\n",
97+
// Restore general-purpose registers
98+
" pop r15\n",
99+
" pop r14\n",
100+
" pop r13\n",
101+
" pop r12\n",
102+
" pop r11\n",
103+
" pop r10\n",
104+
" pop r9\n",
105+
" pop r8\n",
106+
" pop rbp\n",
107+
" pop rdi\n",
108+
" pop rsi\n",
109+
" pop rdx\n",
110+
" pop rcx\n",
111+
" pop rbx\n",
112+
" pop rax\n",
113+
)
114+
};
115+
}
116+
117+
// Generates exception handlers
118+
macro_rules! generate_exceptions {
119+
() => {
120+
concat!(
121+
// Common exception handler
122+
".global _do_excp_common\n",
123+
"_do_excp_common:\n",
124+
// In SysV ABI, the first argument is passed in rdi
125+
// rdi is the stack pointer.
126+
" mov rdi, rsp\n",
127+
" call {hl_exception_handler}\n",
128+
context_restore!(),
129+
" iretq\n", // iretq is used to return from exception in x86_64
130+
generate_excp!(0, pusherrcode),
131+
generate_excp!(1, pusherrcode),
132+
generate_excp!(2, pusherrcode),
133+
generate_excp!(3, pusherrcode),
134+
generate_excp!(4, pusherrcode),
135+
generate_excp!(5, pusherrcode),
136+
generate_excp!(6, pusherrcode),
137+
generate_excp!(7, pusherrcode),
138+
generate_excp!(8),
139+
generate_excp!(9, pusherrcode),
140+
generate_excp!(10),
141+
generate_excp!(11),
142+
generate_excp!(12),
143+
generate_excp!(13),
144+
// generate_excp!(14, pagefault),
145+
generate_excp!(15, pusherrcode),
146+
generate_excp!(16, pusherrcode),
147+
generate_excp!(17),
148+
generate_excp!(18, pusherrcode),
149+
generate_excp!(19, pusherrcode),
150+
generate_excp!(20, pusherrcode),
151+
generate_excp!(30),
152+
)
153+
};
154+
}
155+
156+
// Macro to generate exception handlers
157+
// that satisfy the `extern`s at the top of the file.
158+
//
159+
// - Example output from this macro for generate_excp!(0) call:
160+
// ```assembly
161+
// .global _do_excp0
162+
// _do_excp0:
163+
// context_save!()
164+
// mov rsi, 0
165+
// mov rdx, 0
166+
// jmp _do_excp_common
167+
// ```
168+
macro_rules! generate_excp {
169+
($num:expr) => {
170+
concat!(
171+
".global _do_excp",
172+
stringify!($num),
173+
"\n",
174+
"_do_excp",
175+
stringify!($num),
176+
":\n",
177+
context_save!(),
178+
// In SysV ABI, the second argument is passed in rsi
179+
// rsi is the exception number.
180+
" mov rsi, ",
181+
stringify!($num),
182+
"\n",
183+
// In SysV ABI, the third argument is passed in rdx
184+
// rdx is only used for pagefault exception and
185+
// contains the address that caused the pagefault.
186+
" mov rdx, 0\n",
187+
" jmp _do_excp_common\n"
188+
)
189+
};
190+
($num:expr, pusherrcode) => {
191+
concat!(
192+
".global _do_excp",
193+
stringify!($num),
194+
"\n",
195+
"_do_excp",
196+
stringify!($num),
197+
":\n",
198+
// Some exceptions push an error code onto the stack.
199+
// For the ones that don't, we push a 0 to keep the
200+
// stack aligned.
201+
" push 0\n",
202+
context_save!(),
203+
// In SysV ABI, the second argument is passed in rsi
204+
// rsi is the exception number.
205+
" mov rsi, ",
206+
stringify!($num),
207+
"\n",
208+
// In SysV ABI, the third argument is passed in rdx
209+
// rdx is only used for pagefault exception and
210+
// contains the address that caused the pagefault.
211+
" mov rdx, 0\n",
212+
" jmp _do_excp_common\n"
213+
)
214+
};
215+
($num:expr, pagefault) => {
216+
concat!(
217+
".global _do_excp",
218+
stringify!($num),
219+
"\n",
220+
"_do_excp",
221+
stringify!($num),
222+
":\n",
223+
context_save!(),
224+
" mov rsi, ",
225+
stringify!($num),
226+
"\n",
227+
// In a page fault exception, the cr2 register
228+
// contains the address that caused the page fault.
229+
" mov rdx, cr2\n",
230+
" jmp _do_excp_common\n"
231+
)
232+
};
233+
}
234+
235+
// Output the assembly code
236+
global_asm!(
237+
generate_exceptions!(),
238+
hl_exception_handler = sym hl_exception_handler,
239+
);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
// Note: this code takes reference from
18+
// https://github.com/nanvix/nanvix/tree/dev/src/kernel/src/hal/arch/x86
19+
20+
/// Exception handler
21+
#[no_mangle]
22+
pub extern "sysv64" fn hl_exception_handler(
23+
stack_pointer: u64,
24+
exception_number: u64,
25+
page_fault_address: u64,
26+
) {
27+
panic!(
28+
"EXCEPTION: {:#x}\n\
29+
Page Fault Address: {:#x}\n\
30+
Stack Pointer: {:#x}",
31+
exception_number, page_fault_address, stack_pointer
32+
);
33+
}

src/hyperlight_guest/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ pub mod setjmp;
5151
pub mod chkstk;
5252
pub mod error;
5353
pub mod logging;
54+
pub mod interrupt_entry;
55+
pub mod interrupt_handlers;
5456

5557
// Unresolved symbols
5658
///cbindgen:ignore

0 commit comments

Comments
 (0)