diff --git a/src/libos/include/task.h b/src/libos/include/task.h index 36ae9a43..b11f2f0c 100644 --- a/src/libos/include/task.h +++ b/src/libos/include/task.h @@ -14,6 +14,8 @@ extern "C" { // See Struct Task in process.rs struct Task { uint64_t kernel_rsp; + uint64_t kernel_stack_base; + uint64_t kernel_stack_limit; uint64_t kernel_fs; uint64_t user_rsp; uint64_t user_stack_base; @@ -36,15 +38,21 @@ void do_exit_task(void); #else /* __ASSEMBLY__ */ /* See //common/inc/internal/thread_data.h */ +#define TD_STACK_BASE (8 * 2) +#define TD_STACK_LIMIT (8 * 3) #define TD_STACKGUARD_OFFSET (8 * 5) /* Override the field for stack guard */ #define TD_TASK_OFFSET TD_STACKGUARD_OFFSET #define TASK_KERNEL_RSP (8 * 0) -#define TASK_KERNEL_FS (8 * 1) -#define TASK_USER_RSP (8 * 2) -#define TASK_USER_FS (8 * 5) -#define TASK_USER_ENTRY_ADDR (8 * 6) +#define TASK_KERNEL_STACK_BASE (8 * 1) +#define TASK_KERNEL_STACK_LIMIT (8 * 2) +#define TASK_KERNEL_FS (8 * 3) +#define TASK_USER_RSP (8 * 4) +#define TASK_USER_STACK_BASE (8 * 5) +#define TASK_USER_STACK_LIMIT (8 * 6) +#define TASK_USER_FS (8 * 7) +#define TASK_USER_ENTRY_ADDR (8 * 8) /* arch_prctl syscall number and parameter */ #define ARCH_PRCTL 0x9E diff --git a/src/libos/src/process/task.c b/src/libos/src/process/task.c index 8a397d49..3bfd5afa 100644 --- a/src/libos/src/process/task.c +++ b/src/libos/src/process/task.c @@ -1,5 +1,18 @@ #include "task.h" +/* See //common/inc/internal/thread_data.h */ +typedef struct _thread_data_t +{ + uint64_t reserved1[2]; + uint64_t stack_base_addr; + uint64_t stack_limit_addr; + uint64_t reserved2[15]; + uint64_t stack_commit_addr; +} thread_data_t; + +extern thread_data_t *get_thread_data(void); + + extern void __run_task(struct Task* task); extern uint64_t __get_stack_guard(void); @@ -26,12 +39,19 @@ static uint64_t get_syscall_stack(struct Task* this_task) { int do_run_task(struct Task* task) { jmp_buf libos_state = {0}; + thread_data_t* td = get_thread_data(); task->saved_state = &libos_state; task->kernel_rsp = get_syscall_stack(task); + task->kernel_stack_base = td->stack_base_addr; + task->kernel_stack_limit = td->stack_limit_addr; + + //Do do not support stack expansion, need a new design on SGX2 platform. + //Set the stack_commit_addr to 0, as the result no stack expansion happens at any situations + __atomic_store_n(&td->stack_commit_addr, 0, __ATOMIC_RELAXED); + td->stack_base_addr = task->user_stack_base; + td->stack_limit_addr = task->user_stack_limit; + td->stack_commit_addr = task->user_stack_limit; - if (sgx_enable_user_stack(task->user_stack_base, task->user_stack_limit)) { - return -1; - } SET_CURRENT_TASK(task); int second = setjmp(libos_state); @@ -41,12 +61,19 @@ int do_run_task(struct Task* task) { // Jump from do_exit_task RESET_CURRENT_TASK(); - sgx_disable_user_stack(); return 0; } void do_exit_task(void) { struct Task* task = __get_current_task(); jmp_buf* jb = task->saved_state; + thread_data_t* td = get_thread_data(); + + //Do do not support stack expansion, need a new design on SGX2 platform. + //Set the stack_commit_addr to 0, as the result no stack expansion happens at any situations + __atomic_store_n(&td->stack_commit_addr, 0, __ATOMIC_RELAXED); + td->stack_base_addr = task->kernel_stack_base; + td->stack_limit_addr = task->kernel_stack_limit; + td->stack_commit_addr = task->kernel_stack_limit; longjmp(*jb, 1); } diff --git a/src/libos/src/process/task.rs b/src/libos/src/process/task.rs index ac6ffb04..042a61a7 100644 --- a/src/libos/src/process/task.rs +++ b/src/libos/src/process/task.rs @@ -7,6 +7,8 @@ use super::*; #[repr(C)] pub struct Task { kernel_rsp: usize, + kernel_stack_base: usize, + kernel_stack_limit: usize, kernel_fs: usize, user_rsp: usize, user_stack_base: usize, diff --git a/src/libos/src/syscall/syscall_entry_x86-64.S b/src/libos/src/syscall/syscall_entry_x86-64.S index c487f259..886215a9 100644 --- a/src/libos/src/syscall/syscall_entry_x86-64.S +++ b/src/libos/src/syscall/syscall_entry_x86-64.S @@ -46,6 +46,13 @@ __occlum_syscall: wrfsbase %r11 #endif + // Use kernel stack base and limit + movq TASK_KERNEL_STACK_BASE(%r12), %r11 + movq %r11, %gs:TD_STACK_BASE + + movq TASK_KERNEL_STACK_LIMIT(%r12), %r11 + movq %r11, %gs:TD_STACK_LIMIT + // Make %rsp 16-byte aligned before call sub $0x8, %rsp // Pass arg5 @@ -71,6 +78,13 @@ __occlum_syscall: wrfsbase %r11 #endif + // Use user stack base and limit + movq TASK_USER_STACK_BASE(%r12), %r11 + movq %r11, %gs:TD_STACK_BASE + + movq TASK_USER_STACK_LIMIT(%r12), %r11 + movq %r11, %gs:TD_STACK_LIMIT + // Switch to the user stack movq %rbp, %rsp // Restore callee-saved registers