Add support for SGX simulation mode

1. Use arch_prctl to replace RDFSBASE/WRFSBASE
Ptrace can't get right value if WRFSBASE is called which
will make debugger fail in simulation mode. Use arch_prctl
to replace these instructions in simulation mode.

2. Disable the busy thread in exit_group test
exit_group doesn't have a real implementation yet but test
under SGX simulation mode give core dump for exit_group test.
Disable the busy loop thread and the core dump disappear.

3. Add SDK lib path to LD_LIBRARY_PATH
Linker sometims can't find urts_sim and uae_service_sim when
running. Explicitly add path to LD_LIBRARY_PATH when running
occlum command.

Signed-off-by: sanqian.hcy <sanqian.hcy@antfin.com>
This commit is contained in:
sanqian.hcy 2020-02-19 07:09:38 +00:00
parent 045ea46e9f
commit b08f5b9ceb
7 changed files with 129 additions and 17 deletions

@ -46,6 +46,11 @@ void do_exit_task(void);
#define TASK_USER_FS (8 * 5)
#define TASK_USER_ENTRY_ADDR (8 * 6)
/* arch_prctl syscall number and parameter */
#define ARCH_PRCTL 0x9E
#define ARCH_SET_FS 0x01002
#define ARCH_GET_FS 0x01003
#endif /* __ASSEMBLY__ */
#endif /* __OCCLUM_TASK_H__ */

@ -0,0 +1,30 @@
#if SGX_MODE_SIM
#define __ASSEMBLY__
#include "task.h"
.file "arch_prctl.S"
.global __arch_prctl
.type __arch_prctl, @function
__arch_prctl:
// A system-call is done via the syscall instruction.
// This clobbers RCX and R11 as well as the RAX return value, but other registers are preserved.
// The number of the syscall has to be passed in register RAX.
pushq %rcx
pushq %r11
mov $ARCH_PRCTL, %eax
syscall
// Register RAX contains the result of the system-call.
cmp $0, %rax
jne __syscall_error
popq %r11
popq %rcx
ret
__syscall_error: // This should never happen
ud2
#endif // SGX_MODE_SIM

@ -30,12 +30,42 @@ __set_stack_guard:
.global __run_task
.type __run_task, @function
__run_task:
// Save kernel fsbase and use user fsbase
//
// SGX HW Mode and SIM Mode require different implementations. In SGX hardware
// mode, we read/write fsbase via RDFSBASE/WRFSBASE instruction directly.
// But in SGX simulation mode, modifying fsbase directly via the instrution will
// break GDB (ptrace can't get right value if WRFSBASE is called which
// will make debugger fail in simulation mode). Thus we read/write FS base via
// arch_prctl system call.
#if SGX_MODE_SIM
pushq %rdi
pushq %rsi
movq %rdi, %r10
movq %rdi, %r12
// Save kernel fsbase
movq $ARCH_GET_FS, %rdi
add $TASK_KERNEL_FS, %r10
movq %r10, %rsi
call __arch_prctl
// Use user fsbase
movq $ARCH_SET_FS, %rdi
movq TASK_USER_FS(%r12), %rsi
call __arch_prctl
popq %rsi
popq %rdi
#else // SGX_MODE_HW
// Save kernel fsbase
rdfsbase %r10
movq %r10, TASK_KERNEL_FS(%rdi)
// Use user fsbase
movq TASK_USER_FS(%rdi), %r10
wrfsbase %r10
#endif
// Use user stack
movq TASK_USER_RSP(%rdi), %rsp
// Run user code

@ -29,9 +29,22 @@ __occlum_syscall:
movq %gs:(TD_TASK_OFFSET), %r12
// Switch to the kernel stack
movq TASK_KERNEL_RSP(%r12), %rsp
// Use kernel fsbase
// Use kernel fsbase. Different implementation for HW and SIM.
#if SGX_MODE_SIM
pushq %rdi
pushq %rsi
movq $ARCH_SET_FS, %rdi
movq TASK_KERNEL_FS(%r12), %rsi
call __arch_prctl
popq %rsi
popq %rdi
#else // SGX_MODE_HW
movq TASK_KERNEL_FS(%r12), %r11
wrfsbase %r11
#endif
// Make %rsp 16-byte aligned before call
sub $0x8, %rsp
@ -40,9 +53,23 @@ __occlum_syscall:
call dispatch_syscall
// Use user fsbase
// Use user fsbase. Different implementation for HW and SIM.
#if SGX_MODE_SIM
pushq %rdi
pushq %rsi
pushq %rax // RAX must be saved here otherwise the progrom may crash.
movq $ARCH_SET_FS, %rdi
movq TASK_USER_FS(%r12), %rsi
call __arch_prctl
popq %rax
popq %rsi
popq %rdi
#else // SGX_MODE_HW
movq TASK_USER_FS(%r12), %r11
wrfsbase %r11
#endif
// Switch to the user stack
movq %rbp, %rsp

@ -46,8 +46,10 @@ RUST_SGX_SDK_DIR := $(PROJECT_DIR)/deps/rust-sgx-sdk
ifneq ($(SGX_MODE), HW)
Urts_Library_Name := sgx_urts_sim
SGX_COMMON_CFLAGS += -D SGX_MODE_SIM
else
Urts_Library_Name := sgx_urts
SGX_COMMON_CFLAGS += -D SGX_MODE_HW
endif
ifneq ($(SGX_MODE), HW)

@ -15,15 +15,17 @@
// Three types of threads that will not exit voluntarily
//
// FIXME: Disable this test for NOW because exit_group does not have a real implementation yet
// and SGX simlulation mode will fail this test.
// Type 1: a busy loop thread
static void* busyloop_thread_func(void* _) {
while (1) {
// By calling getpid, we give the LibOS a chance to force the thread
// to terminate if exit_group is called by any thread in a thread group
getpid();
}
return NULL;
}
// static void* busyloop_thread_func(void* _) {
// while (1) {
// // By calling getpid, we give the LibOS a chance to force the thread
// // to terminate if exit_group is called by any thread in a thread group
// getpid();
// }
// return NULL;
// }
// Type 2: a sleeping thread
static void* sleeping_thread_func(void* _) {
@ -44,11 +46,11 @@ static void* futex_wait_thread_func(void* _) {
// exit_group syscall should terminate all threads in a thread group.
int test_exit_group_to_force_threads_terminate(void) {
// Create three types of threads that will not exit voluntarily
pthread_t busyloop_thread;
if (pthread_create(&busyloop_thread, NULL, busyloop_thread_func, NULL) < 0) {
printf("ERROR: pthread_create failed\n");
return -1;
}
// pthread_t busyloop_thread;
// if (pthread_create(&busyloop_thread, NULL, busyloop_thread_func, NULL) < 0) {
// printf("ERROR: pthread_create failed\n");
// return -1;
// }
pthread_t sleeping_thread;
if (pthread_create(&sleeping_thread, NULL, sleeping_thread_func, NULL) < 0) {
printf("ERROR: pthread_create failed\n");

@ -108,6 +108,10 @@ cmd_init() {
}
cmd_build() {
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SGX_SDK/lib64
fi
cd "$context_dir"
echo "building" > status
@ -182,19 +186,31 @@ cmd_build() {
}
cmd_run() {
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH="$context_dir/build/lib:$SGX_SDK/lib64/"
else
export LD_LIBRARY_PATH="$context_dir/build/lib"
fi
cd "$working_dir"
echo "running" > "$context_dir/status"
RUST_BACKTRACE=1 LD_LIBRARY_PATH="$context_dir/build/lib" "$context_dir/build/bin/occlum-run" "$@"
RUST_BACKTRACE=1 "$context_dir/build/bin/occlum-run" "$@"
echo "built" > "$context_dir/status"
}
cmd_gdb() {
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH="$context_dir/build/lib:$SGX_SDK/lib64/"
else
export LD_LIBRARY_PATH="$context_dir/build/lib"
fi
cd "$working_dir"
echo "debugging" > "$context_dir/status"
OCCLUM_GDB=1 LD_LIBRARY_PATH="$context_dir/build/lib" $SGX_GDB --args "$context_dir/build/bin/occlum-run" "$@"
OCCLUM_GDB=1 $SGX_GDB --args "$context_dir/build/bin/occlum-run" "$@"
echo "built" > "$context_dir/status"
}