Add trampolines for PTI support
This commit is contained in:
@@ -26,7 +26,8 @@ version = "0.7"
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
default = []
|
||||
default = ["pti"]
|
||||
doc = []
|
||||
live = []
|
||||
multi_core = []
|
||||
pti = []
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
use arch::x86_64::pti;
|
||||
use syscall;
|
||||
|
||||
#[naked]
|
||||
pub unsafe extern fn syscall() {
|
||||
#[inline(never)]
|
||||
unsafe fn inner(stack: &mut SyscallStack) {
|
||||
extern {
|
||||
fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, rbp: usize, stack: &mut SyscallStack) -> usize;
|
||||
}
|
||||
|
||||
let mut a;
|
||||
{
|
||||
let b;
|
||||
let rbp;
|
||||
asm!("" : "={rax}"(a), "={rbx}"(b), "={rbp}"(rbp)
|
||||
let b;
|
||||
let rbp;
|
||||
asm!("" : "={rax}"(a), "={rbx}"(b), "={rbp}"(rbp)
|
||||
: : : "intel", "volatile");
|
||||
|
||||
a = syscall(a, b, stack.rcx, stack.rdx, stack.rsi, stack.rdi, rbp, stack);
|
||||
}
|
||||
// Map kernel
|
||||
pti::map();
|
||||
|
||||
a = syscall::syscall(a, b, stack.rcx, stack.rdx, stack.rsi, stack.rdi, rbp, stack);
|
||||
|
||||
// Unmap kernel
|
||||
pti::unmap();
|
||||
|
||||
asm!("" : : "{rax}"(a) : : "intel", "volatile");
|
||||
}
|
||||
|
||||
@@ -166,7 +166,13 @@ macro_rules! interrupt {
|
||||
pub unsafe extern fn $name () {
|
||||
#[inline(never)]
|
||||
unsafe fn inner() {
|
||||
// Map kernel
|
||||
$crate::arch::x86_64::pti::map();
|
||||
|
||||
$func
|
||||
|
||||
// Unmap kernel
|
||||
$crate::arch::x86_64::pti::unmap();
|
||||
}
|
||||
|
||||
// Push scratch registers
|
||||
@@ -207,7 +213,13 @@ macro_rules! interrupt_stack {
|
||||
pub unsafe extern fn $name () {
|
||||
#[inline(never)]
|
||||
unsafe fn inner($stack: &mut $crate::arch::x86_64::macros::InterruptStack) {
|
||||
// Map kernel
|
||||
$crate::arch::x86_64::pti::map();
|
||||
|
||||
$func
|
||||
|
||||
// Unmap kernel
|
||||
$crate::arch::x86_64::pti::unmap();
|
||||
}
|
||||
|
||||
// Push scratch registers
|
||||
@@ -254,7 +266,13 @@ macro_rules! interrupt_error {
|
||||
pub unsafe extern fn $name () {
|
||||
#[inline(never)]
|
||||
unsafe fn inner($stack: &$crate::arch::x86_64::macros::InterruptErrorStack) {
|
||||
// Map kernel
|
||||
$crate::arch::x86_64::pti::map();
|
||||
|
||||
$func
|
||||
|
||||
// Unmap kernel
|
||||
$crate::arch::x86_64::pti::unmap();
|
||||
}
|
||||
|
||||
// Push scratch registers
|
||||
@@ -302,7 +320,13 @@ macro_rules! interrupt_stack_p {
|
||||
pub unsafe extern fn $name () {
|
||||
#[inline(never)]
|
||||
unsafe fn inner($stack: &mut $crate::arch::x86_64::macros::InterruptStackP) {
|
||||
// Map kernel
|
||||
$crate::arch::x86_64::pti::map();
|
||||
|
||||
$func
|
||||
|
||||
// Unmap kernel
|
||||
$crate::arch::x86_64::pti::unmap();
|
||||
}
|
||||
|
||||
// Push scratch registers
|
||||
@@ -353,7 +377,13 @@ macro_rules! interrupt_error_p {
|
||||
pub unsafe extern fn $name () {
|
||||
#[inline(never)]
|
||||
unsafe fn inner($stack: &$crate::arch::x86_64::macros::InterruptErrorStackP) {
|
||||
// Map kernel
|
||||
$crate::arch::x86_64::pti::map();
|
||||
|
||||
$func
|
||||
|
||||
// Unmap kernel
|
||||
$crate::arch::x86_64::pti::unmap();
|
||||
}
|
||||
|
||||
// Push scratch registers
|
||||
|
||||
@@ -16,8 +16,11 @@ pub mod interrupt;
|
||||
/// Paging
|
||||
pub mod paging;
|
||||
|
||||
/// Page table isolation
|
||||
pub mod pti;
|
||||
|
||||
/// Initialization and start function
|
||||
pub mod start;
|
||||
|
||||
/// Stop function
|
||||
pub mod stop;
|
||||
pub mod stop;
|
||||
|
||||
25
src/arch/x86_64/pti.rs
Normal file
25
src/arch/x86_64/pti.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
#[cfg(feature = "pti")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn map() {
|
||||
let _cr3: usize;
|
||||
asm!("mov $0, cr3
|
||||
mov cr3, $0"
|
||||
: "=r"(_cr3) : : "memory" : "intel", "volatile");
|
||||
}
|
||||
|
||||
#[cfg(feature = "pti")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn unmap() {
|
||||
let _cr3: usize;
|
||||
asm!("mov $0, cr3
|
||||
mov cr3, $0"
|
||||
: "=r"(_cr3) : : "memory" : "intel", "volatile");
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "pti"))]
|
||||
#[inline(always)]
|
||||
pub unsafe fn map() {}
|
||||
|
||||
#[cfg(not(feature = "pti"))]
|
||||
#[inline(always)]
|
||||
pub unsafe fn unmap() {}
|
||||
@@ -8,6 +8,7 @@ use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, AtomicUsize, ATOMIC_USIZE
|
||||
|
||||
use acpi;
|
||||
use allocator;
|
||||
use arch::x86_64::pti;
|
||||
use device;
|
||||
use gdt;
|
||||
use idt;
|
||||
@@ -190,6 +191,9 @@ pub unsafe extern fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! {
|
||||
}
|
||||
|
||||
pub unsafe fn usermode(ip: usize, sp: usize, arg: usize) -> ! {
|
||||
// Unmap kernel
|
||||
pti::unmap();
|
||||
|
||||
// Go to usermode
|
||||
asm!("mov ds, r10d
|
||||
mov es, r10d
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
pub const KERNEL_PML4: usize = (KERNEL_OFFSET & PML4_MASK)/PML4_SIZE;
|
||||
|
||||
/// Offset to kernel heap
|
||||
pub const KERNEL_HEAP_OFFSET: usize = KERNEL_OFFSET + PML4_SIZE/2;
|
||||
pub const KERNEL_HEAP_OFFSET: usize = KERNEL_OFFSET - PML4_SIZE;
|
||||
pub const KERNEL_HEAP_PML4: usize = (KERNEL_HEAP_OFFSET & PML4_MASK)/PML4_SIZE;
|
||||
/// Size of kernel heap
|
||||
pub const KERNEL_HEAP_SIZE: usize = 256 * 1024 * 1024; // 256 MB
|
||||
|
||||
|
||||
@@ -44,12 +44,7 @@ pub mod time;
|
||||
/// Validate input
|
||||
pub mod validate;
|
||||
|
||||
//mod print_call;
|
||||
//use self::print_call::print_call;
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: usize, stack: &mut SyscallStack) -> usize {
|
||||
pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: usize, stack: &mut SyscallStack) -> usize {
|
||||
#[inline(always)]
|
||||
fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: usize, stack: &mut SyscallStack) -> Result<usize> {
|
||||
match a & SYS_CLASS {
|
||||
|
||||
@@ -355,15 +355,24 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
|
||||
|
||||
context.arch.set_page_table(unsafe { new_table.address() });
|
||||
|
||||
// Copy kernel mapping
|
||||
// Copy kernel image mapping
|
||||
{
|
||||
let frame = active_table.p4()[::KERNEL_PML4].pointed_frame().expect("kernel table not mapped");
|
||||
let frame = active_table.p4()[::KERNEL_PML4].pointed_frame().expect("kernel image not mapped");
|
||||
let flags = active_table.p4()[::KERNEL_PML4].flags();
|
||||
active_table.with(&mut new_table, &mut temporary_page, |mapper| {
|
||||
mapper.p4_mut()[::KERNEL_PML4].set(frame, flags);
|
||||
});
|
||||
}
|
||||
|
||||
// Copy kernel heap mapping
|
||||
{
|
||||
let frame = active_table.p4()[::KERNEL_HEAP_PML4].pointed_frame().expect("kernel heap not mapped");
|
||||
let flags = active_table.p4()[::KERNEL_HEAP_PML4].flags();
|
||||
active_table.with(&mut new_table, &mut temporary_page, |mapper| {
|
||||
mapper.p4_mut()[::KERNEL_HEAP_PML4].set(frame, flags);
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(fx) = kfx_option.take() {
|
||||
context.arch.set_fx(fx.as_ptr() as usize);
|
||||
context.kfx = Some(fx);
|
||||
|
||||
Reference in New Issue
Block a user