Commit a6550341 authored by Jeremy Soller's avatar Jeremy Soller

Add trampolines for PTI support

parent 670d7b00
......@@ -26,7 +26,8 @@ version = "0.7"
default-features = false
[features]
default = []
default = ["pti"]
doc = []
live = []
multi_core = []
pti = []
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;
\ No newline at end of file
pub mod stop;
#[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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment