Switch user/kernel fsbase

This commit is contained in:
Tate, Hongliang Tian 2019-01-01 15:33:33 +08:00
parent 05e5efdb57
commit b717842113
9 changed files with 70 additions and 21 deletions

@ -2,7 +2,7 @@
<EnclaveConfiguration>
<ProdID>0</ProdID>
<ISVSVN>0</ISVSVN>
<StackMaxSize>0x80000</StackMaxSize>
<StackMaxSize>0x100000</StackMaxSize>
<HeapMaxSize>0x1000000</HeapMaxSize>
<TCSNum>8</TCSNum>
<TCSPolicy>1</TCSPolicy>

@ -13,10 +13,11 @@ extern "C" {
// See Struct Task in process.rs
struct Task {
uint64_t syscall_stack_addr;
uint64_t kernel_stack_addr;
uint64_t kernel_fsbase_addr;
uint64_t user_stack_addr;
uint64_t user_fsbase_addr;
uint64_t user_entry_addr;
uint64_t fs_base_addr;
jmp_buf* saved_state;
};
@ -37,7 +38,11 @@ void do_exit_task(void);
/* Override the field for stack guard */
#define TD_TASK_OFFSET TD_STACKGUARD_OFFSET
#define TASK_SYSCALL_STACK_OFFSET (8 * 0)
#define TASK_KERNEL_STACK_ADDR (8 * 0)
#define TASK_KERNEL_FSBASE_ADDR (8 * 1)
#define TASK_USER_STACK_ADDR (8 * 2)
#define TASK_USER_FSBASE_ADDR (8 * 3)
#define TASK_USER_ENTRY_ADDR (8 * 4)
#endif /* __ASSEMBLY__ */

@ -85,7 +85,6 @@ fn init_task(user_entry: usize, stack_top: usize,
Ok(Task {
user_stack_addr: user_stack,
user_entry_addr: user_entry,
fs_base_addr: 0,
.. Default::default()
})
}

@ -1,12 +1,12 @@
#include "task.h"
extern void __run_task(uint64_t entry_point, uint64_t stack_top);
extern void __run_task(struct Task* task);
extern uint64_t __get_stack_guard(void);
extern void __set_stack_guard(uint64_t new_val);
static uint64_t get_syscall_stack(struct Task* this_task) {
#define LARGE_ENOUGH_GAP 4096
#define LARGE_ENOUGH_GAP (8192)
char libos_stack_var = 0;
uint64_t libos_stack = ((uint64_t) &libos_stack_var) - LARGE_ENOUGH_GAP;
libos_stack &= ~0x0FUL; // stack must be 16-byte aligned
@ -20,17 +20,16 @@ static uint64_t get_syscall_stack(struct Task* this_task) {
#define RESET_CURRENT_TASK() \
__set_stack_guard(stack_guard);
int do_run_task(struct Task* task) {
jmp_buf libos_state = {0};
task->saved_state = &libos_state;
task->syscall_stack_addr = get_syscall_stack(task);
task->kernel_stack_addr = get_syscall_stack(task);
SET_CURRENT_TASK(task);
int second = setjmp(libos_state);
if (!second) {
__run_task(task->user_entry_addr, task->user_stack_addr);
__run_task(task);
}
// From occlum_exit
@ -39,6 +38,7 @@ int do_run_task(struct Task* task) {
}
void do_exit_task(void) {
jmp_buf* jb = __get_current_task()->saved_state;
struct Task* task = __get_current_task();
jmp_buf* jb = task->saved_state;
longjmp(*jb, 1);
}

@ -5,10 +5,11 @@ use std::{mem};
#[derive(Clone, Debug, Default)]
#[repr(C)]
pub struct Task {
pub syscall_stack_addr: usize,
pub kernel_stack_addr: usize,
pub kernel_fsbase_addr: usize,
pub user_stack_addr: usize,
pub user_fsbase_addr: usize,
pub user_entry_addr: usize,
pub fs_base_addr: usize,
pub saved_state: usize, // struct jmpbuf*
}

@ -30,5 +30,14 @@ __set_stack_guard:
.global __run_task
.type __run_task, @function
__run_task:
mov %rsi, %rsp
jmp *%rdi
// Save kernel fsbase
rdfsbase %r10
movq %r10, TASK_KERNEL_FSBASE_ADDR(%rdi)
// Use user fsbase
movq TASK_USER_FSBASE_ADDR(%rdi), %r10
wrfsbase %r10
// Use user stack
movq TASK_USER_STACK_ADDR(%rdi), %rsp
// Run user code
movq TASK_USER_ENTRY_ADDR(%rdi), %r11
jmp *%r11

@ -6,7 +6,6 @@
long dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5) {
long ret = 0;
switch (num) {
case SYS_exit: {
DECL_SYSCALL_ARG(int, status, arg0);

@ -5,13 +5,50 @@
.global __occlum_syscall
.type __occlum_syscall, @function
__occlum_syscall:
push %rbp
// num - %rdi
// arg0 - %rsi
// arg1 - %rdx
// arg2 - %rcx
// arg3 - %r8
// arg4 - %r9
// arg5 - *0x8(%rsp)
// Given by the user, the user-space stack pointer %rsp cannot be trusted.
// So we need to check whether %rsp is within the read-write region of the
// current data domain
bndcl %rsp, %bnd0
bndcu %rsp, %bnd0
// Save the user stack
pushq %rbp
movq %rsp, %rbp
movq %gs:(TD_TASK_OFFSET), %rax
movq TASK_SYSCALL_STACK_OFFSET(%rax), %rsp
// Get current task
movq %gs:(TD_TASK_OFFSET), %r12
// Switch to the kernel stack
movq TASK_KERNEL_STACK_ADDR(%r12), %rsp
// Use kernel fsbase
movq TASK_KERNEL_FSBASE_ADDR(%r12), %r11
wrfsbase %r11
// TODO: Pass arg5
// pushq 0x10(%rbp)
call dispatch_syscall
// addq 0x08, %rsp
// Use user fsbase
movq TASK_KERNEL_FSBASE_ADDR(%r12), %r11
wrfsbase %r11
// Restore the user stack
movq %rbp, %rsp
popq %rbp
ret
// Check return target is a valid instruction (i.e., a cfi_label)
popq %r10
movq (%r10), %r11
bndcl %r11, %bnd2
bndcu %r11, %bnd2
jmpq *%r10

@ -8,7 +8,6 @@ lazy_static! {
unsafe { vm_get_prealloced_data_space(&mut addr, &mut size) };
(addr, size)
};
println!("addr = {:X?}, size = {}", addr, size);
let vm_space = unsafe {
match VMSpace::new(addr, size, VMGuardAreaType::None) {
Ok(vm_space) => vm_space,