Switch user/kernel fsbase
This commit is contained in:
parent
05e5efdb57
commit
b717842113
@ -2,7 +2,7 @@
|
|||||||
<EnclaveConfiguration>
|
<EnclaveConfiguration>
|
||||||
<ProdID>0</ProdID>
|
<ProdID>0</ProdID>
|
||||||
<ISVSVN>0</ISVSVN>
|
<ISVSVN>0</ISVSVN>
|
||||||
<StackMaxSize>0x80000</StackMaxSize>
|
<StackMaxSize>0x100000</StackMaxSize>
|
||||||
<HeapMaxSize>0x1000000</HeapMaxSize>
|
<HeapMaxSize>0x1000000</HeapMaxSize>
|
||||||
<TCSNum>8</TCSNum>
|
<TCSNum>8</TCSNum>
|
||||||
<TCSPolicy>1</TCSPolicy>
|
<TCSPolicy>1</TCSPolicy>
|
||||||
|
@ -13,10 +13,11 @@ extern "C" {
|
|||||||
|
|
||||||
// See Struct Task in process.rs
|
// See Struct Task in process.rs
|
||||||
struct Task {
|
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_stack_addr;
|
||||||
|
uint64_t user_fsbase_addr;
|
||||||
uint64_t user_entry_addr;
|
uint64_t user_entry_addr;
|
||||||
uint64_t fs_base_addr;
|
|
||||||
jmp_buf* saved_state;
|
jmp_buf* saved_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -37,7 +38,11 @@ void do_exit_task(void);
|
|||||||
/* Override the field for stack guard */
|
/* Override the field for stack guard */
|
||||||
#define TD_TASK_OFFSET TD_STACKGUARD_OFFSET
|
#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__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
@ -85,7 +85,6 @@ fn init_task(user_entry: usize, stack_top: usize,
|
|||||||
Ok(Task {
|
Ok(Task {
|
||||||
user_stack_addr: user_stack,
|
user_stack_addr: user_stack,
|
||||||
user_entry_addr: user_entry,
|
user_entry_addr: user_entry,
|
||||||
fs_base_addr: 0,
|
|
||||||
.. Default::default()
|
.. Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#include "task.h"
|
#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 uint64_t __get_stack_guard(void);
|
||||||
extern void __set_stack_guard(uint64_t new_val);
|
extern void __set_stack_guard(uint64_t new_val);
|
||||||
|
|
||||||
static uint64_t get_syscall_stack(struct Task* this_task) {
|
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;
|
char libos_stack_var = 0;
|
||||||
uint64_t libos_stack = ((uint64_t) &libos_stack_var) - LARGE_ENOUGH_GAP;
|
uint64_t libos_stack = ((uint64_t) &libos_stack_var) - LARGE_ENOUGH_GAP;
|
||||||
libos_stack &= ~0x0FUL; // stack must be 16-byte aligned
|
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() \
|
#define RESET_CURRENT_TASK() \
|
||||||
__set_stack_guard(stack_guard);
|
__set_stack_guard(stack_guard);
|
||||||
|
|
||||||
|
|
||||||
int do_run_task(struct Task* task) {
|
int do_run_task(struct Task* task) {
|
||||||
jmp_buf libos_state = {0};
|
jmp_buf libos_state = {0};
|
||||||
task->saved_state = &libos_state;
|
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);
|
SET_CURRENT_TASK(task);
|
||||||
|
|
||||||
int second = setjmp(libos_state);
|
int second = setjmp(libos_state);
|
||||||
if (!second) {
|
if (!second) {
|
||||||
__run_task(task->user_entry_addr, task->user_stack_addr);
|
__run_task(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
// From occlum_exit
|
// From occlum_exit
|
||||||
@ -39,6 +38,7 @@ int do_run_task(struct Task* task) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void do_exit_task(void) {
|
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);
|
longjmp(*jb, 1);
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,11 @@ use std::{mem};
|
|||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Task {
|
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_stack_addr: usize,
|
||||||
|
pub user_fsbase_addr: usize,
|
||||||
pub user_entry_addr: usize,
|
pub user_entry_addr: usize,
|
||||||
pub fs_base_addr: usize,
|
|
||||||
pub saved_state: usize, // struct jmpbuf*
|
pub saved_state: usize, // struct jmpbuf*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,5 +30,14 @@ __set_stack_guard:
|
|||||||
.global __run_task
|
.global __run_task
|
||||||
.type __run_task, @function
|
.type __run_task, @function
|
||||||
__run_task:
|
__run_task:
|
||||||
mov %rsi, %rsp
|
// Save kernel fsbase
|
||||||
jmp *%rdi
|
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 dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5) {
|
||||||
long ret = 0;
|
long ret = 0;
|
||||||
|
|
||||||
switch (num) {
|
switch (num) {
|
||||||
case SYS_exit: {
|
case SYS_exit: {
|
||||||
DECL_SYSCALL_ARG(int, status, arg0);
|
DECL_SYSCALL_ARG(int, status, arg0);
|
||||||
|
@ -5,13 +5,50 @@
|
|||||||
.global __occlum_syscall
|
.global __occlum_syscall
|
||||||
.type __occlum_syscall, @function
|
.type __occlum_syscall, @function
|
||||||
__occlum_syscall:
|
__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 %rsp, %rbp
|
||||||
|
|
||||||
movq %gs:(TD_TASK_OFFSET), %rax
|
// Get current task
|
||||||
movq TASK_SYSCALL_STACK_OFFSET(%rax), %rsp
|
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
|
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
|
movq %rbp, %rsp
|
||||||
popq %rbp
|
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) };
|
unsafe { vm_get_prealloced_data_space(&mut addr, &mut size) };
|
||||||
(addr, size)
|
(addr, size)
|
||||||
};
|
};
|
||||||
println!("addr = {:X?}, size = {}", addr, size);
|
|
||||||
let vm_space = unsafe {
|
let vm_space = unsafe {
|
||||||
match VMSpace::new(addr, size, VMGuardAreaType::None) {
|
match VMSpace::new(addr, size, VMGuardAreaType::None) {
|
||||||
Ok(vm_space) => vm_space,
|
Ok(vm_space) => vm_space,
|
||||||
|
Loading…
Reference in New Issue
Block a user