Skip to content

Commit cd85bc6

Browse files
xvancAndy-Python-Programmer
authored andcommitted
catch the #UD exception for sysenter on AMD
1 parent 7c3d3f1 commit cd85bc6

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

src/aero_kernel/src/arch/x86_64/interrupts/exceptions.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ interrupt_exception!(fn debug() => "Debug");
5050
interrupt_exception!(fn non_maskable() => "Non Maskable");
5151
interrupt_exception!(fn overflow() => "Stack Overflow");
5252
interrupt_exception!(fn bound_range() => "Out of Bounds");
53-
interrupt_exception!(fn invalid_opcode() => "Invalid Opcode");
5453
interrupt_exception!(fn device_not_available() => "Device not Avaliable");
5554
interrupt_exception!(fn double_fault() => "Double Fault");
5655
interrupt_exception!(fn invalid_tss() => "Invalid TSS");
@@ -64,6 +63,38 @@ interrupt_exception!(fn simd() => "SIMD floating point fault");
6463
interrupt_exception!(fn virtualization() => "Virtualization fault");
6564
interrupt_exception!(fn security() => "Security exception");
6665

66+
pub fn invalid_opcode(stack: &mut InterruptErrorStack) {
67+
// Catch SYSENTER on AMD CPUs.
68+
//
69+
// The RIP on the stack for #UD points to the instruction which generated the exception.
70+
// The return RIP and RSP need to be changed to the user-provided values in RCX and R11.
71+
const SYSENTER_OPCODE: [u8; 2] = [0x0f, 0x34];
72+
73+
let opcode = unsafe { *(stack.stack.iret.rip as *const [u8; 2]) };
74+
if opcode == SYSENTER_OPCODE {
75+
stack.stack.iret.rip = stack.stack.scratch.rcx;
76+
stack.stack.iret.rsp = stack.stack.scratch.r11;
77+
78+
super::super::syscall::x86_64_do_syscall(stack);
79+
return;
80+
}
81+
82+
// Otherwise handle the exception as normal.
83+
84+
unwind::prepare_panic();
85+
86+
log::error!("EXCEPTION: Invalid Opcode");
87+
log::error!("Stack: {:#x?}", stack);
88+
89+
unwind::unwind_stack_trace();
90+
91+
unsafe {
92+
loop {
93+
super::halt();
94+
}
95+
}
96+
}
97+
6798
pub fn breakpoint(stack: &mut InterruptErrorStack) {
6899
// We will need to prevent RIP from going out of sync with
69100
// instructions.

0 commit comments

Comments
 (0)