Support user manage stack
Go/Java/JIT code manage their own stack So we need to help them to handle exception
This commit is contained in:
parent
aed572064b
commit
eca27408be
@ -38,8 +38,6 @@ void do_exit_task(void);
|
|||||||
#else /* __ASSEMBLY__ */
|
#else /* __ASSEMBLY__ */
|
||||||
|
|
||||||
/* See /<path-to-linux-sgx>/common/inc/internal/thread_data.h */
|
/* See /<path-to-linux-sgx>/common/inc/internal/thread_data.h */
|
||||||
#define TD_STACK_BASE (8 * 2)
|
|
||||||
#define TD_STACK_LIMIT (8 * 3)
|
|
||||||
#define TD_STACKGUARD_OFFSET (8 * 5)
|
#define TD_STACKGUARD_OFFSET (8 * 5)
|
||||||
/* 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
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <assert.h>
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/* See /<path-to-linux-sgx>/common/inc/internal/thread_data.h */
|
/* See /<path-to-linux-sgx>/common/inc/internal/thread_data.h */
|
||||||
@ -22,6 +23,8 @@ extern void __set_stack_guard(uint64_t new_val);
|
|||||||
int sgx_enable_user_stack(size_t stack_base, size_t stack_limit);
|
int sgx_enable_user_stack(size_t stack_base, size_t stack_limit);
|
||||||
void sgx_disable_user_stack(void);
|
void sgx_disable_user_stack(void);
|
||||||
|
|
||||||
|
#define OCCLUM_PAGE_SIZE 4096
|
||||||
|
|
||||||
static uint64_t get_syscall_stack(struct Task* this_task) {
|
static uint64_t get_syscall_stack(struct Task* this_task) {
|
||||||
#define LARGE_ENOUGH_GAP (8192)
|
#define LARGE_ENOUGH_GAP (8192)
|
||||||
char libos_stack_var = 0;
|
char libos_stack_var = 0;
|
||||||
@ -37,28 +40,6 @@ 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);
|
||||||
|
|
||||||
void switch_td_to_kernel(const struct Task* task) {
|
|
||||||
thread_data_t* td = get_thread_data();
|
|
||||||
|
|
||||||
// TODO: 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void switch_td_to_user(const struct Task* task) {
|
|
||||||
thread_data_t* td = get_thread_data();
|
|
||||||
|
|
||||||
// TODO: 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int do_exec_task(struct Task* task) {
|
int do_exec_task(struct Task* task) {
|
||||||
jmp_buf libos_state = {0};
|
jmp_buf libos_state = {0};
|
||||||
thread_data_t* td = get_thread_data();
|
thread_data_t* td = get_thread_data();
|
||||||
@ -67,7 +48,10 @@ int do_exec_task(struct Task* task) {
|
|||||||
task->kernel_stack_base = td->stack_base_addr;
|
task->kernel_stack_base = td->stack_base_addr;
|
||||||
task->kernel_stack_limit = td->stack_limit_addr;
|
task->kernel_stack_limit = td->stack_limit_addr;
|
||||||
|
|
||||||
switch_td_to_user(task);
|
//Reserve two pages stack for exception handler
|
||||||
|
//The SGX SDK exception handler depends on the two pages as stack to handle exceptions in user's code
|
||||||
|
//TODO:Add a check in the sysreturn logic to confirm the stack is not corrupted
|
||||||
|
assert(task->kernel_stack_limit+OCCLUM_PAGE_SIZE*2 <= task->kernel_rsp);
|
||||||
|
|
||||||
SET_CURRENT_TASK(task);
|
SET_CURRENT_TASK(task);
|
||||||
|
|
||||||
@ -84,7 +68,5 @@ int do_exec_task(struct Task* task) {
|
|||||||
void do_exit_task(void) {
|
void do_exit_task(void) {
|
||||||
struct Task* task = __get_current_task();
|
struct Task* task = __get_current_task();
|
||||||
jmp_buf* jb = task->saved_state;
|
jmp_buf* jb = task->saved_state;
|
||||||
|
|
||||||
switch_td_to_kernel(task);
|
|
||||||
longjmp(*jb, 1);
|
longjmp(*jb, 1);
|
||||||
}
|
}
|
@ -66,11 +66,6 @@ __occlum_syscall_linux_abi:
|
|||||||
movq TASK_KERNEL_FS(%r12), %r11
|
movq TASK_KERNEL_FS(%r12), %r11
|
||||||
wrfsbase %r11
|
wrfsbase %r11
|
||||||
#endif
|
#endif
|
||||||
// Switch to 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
|
|
||||||
|
|
||||||
call occlum_syscall
|
call occlum_syscall
|
||||||
|
|
||||||
@ -116,12 +111,6 @@ __occlum_sysret:
|
|||||||
movq TASK_USER_FS(%r12), %r11
|
movq TASK_USER_FS(%r12), %r11
|
||||||
wrfsbase %r11
|
wrfsbase %r11
|
||||||
#endif
|
#endif
|
||||||
// Switch to 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
|
|
||||||
|
|
||||||
// Restore flags first
|
// Restore flags first
|
||||||
leaq (17*8)(%rdi), %rsp
|
leaq (17*8)(%rdi), %rsp
|
||||||
popfq
|
popfq
|
||||||
|
Loading…
Reference in New Issue
Block a user