support 'syscall' instruction by handling invalid opcode exception
@@ -96,7 +96,8 @@ pub extern fn rust_trap(tf: &mut TrapFrame) {
SwitchToUser => to_user(tf),
Syscall => syscall(tf),
Syscall32 => syscall32(tf),
- DivideError | GeneralProtectionFault | InvalidOpcode => error(tf),
+ InvalidOpcode => invalid_opcode(tf),
+ DivideError | GeneralProtectionFault => error(tf),
_ => panic!("Unhandled interrupt {:x}", tf.trap_num),
}
}
@@ -172,6 +173,18 @@ fn syscall32(tf: &mut TrapFrame) {
tf.rax = ret as usize;
}
+/// Support `syscall` instruction
+fn invalid_opcode(tf: &mut TrapFrame) {
+ let opcode = unsafe { (tf.rip as *mut u16).read() };
+ const SYSCALL_OPCODE: u16 = 0x05_0f;
+ if opcode == SYSCALL_OPCODE {
+ syscall(tf);
+ tf.rip += 2;
+ } else {
+ crate::trap::error(tf);
+ }
+}
+
fn error(tf: &TrapFrame) {
crate::trap::error(tf);
}
