parent
98b3b12c96
commit
9269a9856d
@ -0,0 +1,44 @@
|
|||||||
|
/// `syscall` instruction
|
||||||
|
|
||||||
|
use x86_64::registers::model_specific::*;
|
||||||
|
use core::mem::transmute;
|
||||||
|
use super::super::gdt;
|
||||||
|
use super::TrapFrame;
|
||||||
|
|
||||||
|
pub fn init() {
|
||||||
|
unsafe {
|
||||||
|
Efer::update(|flags| {
|
||||||
|
*flags |= EferFlags::SYSTEM_CALL_EXTENSIONS;
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut star = Msr::new(0xC0000081);
|
||||||
|
let mut lstar = Msr::new(0xC0000082);
|
||||||
|
let mut sfmask = Msr::new(0xC0000084);
|
||||||
|
|
||||||
|
// flags to clear on syscall
|
||||||
|
// copy from Linux 5.0
|
||||||
|
// TF|DF|IF|IOPL|AC|NT
|
||||||
|
let rflags_mask = 0x47700;
|
||||||
|
|
||||||
|
star.write(transmute(STAR));
|
||||||
|
lstar.write(syscall_entry as u64);
|
||||||
|
sfmask.write(rflags_mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern {
|
||||||
|
fn syscall_entry();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(packed)]
|
||||||
|
struct StarMsr {
|
||||||
|
eip: u32,
|
||||||
|
kernel_cs: u16,
|
||||||
|
user_cs: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
const STAR: StarMsr = StarMsr {
|
||||||
|
eip: 0, // ignored in 64 bit mode
|
||||||
|
kernel_cs: gdt::KCODE_SELECTOR.0,
|
||||||
|
user_cs: gdt::UCODE32_SELECTOR.0,
|
||||||
|
};
|
Loading…
Reference in new issue