Switch user/kernel fsbase
This commit is contained in:
parent
05e5efdb57
commit
b717842113
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user