Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PAL/Linux-SGX] Prepare AEX handler to call C code in release mode #2025

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions pal/src/host/linux-sgx/enclave_framework.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,19 @@ bool sgx_is_valid_untrusted_ptr(const void* _addr, size_t size, size_t alignment
}

/*
* When DEBUG is enabled, we run sgx_profile_sample() during asynchronous enclave exit (AEX), which
* We run some functions (e.g. sgx_profile_sample()) during asynchronous enclave exit (AEX), which
* uses the stack. Make sure to update URSP so that the AEX handler does not overwrite the part of
* the stack that we just allocated.
*
* (Recall that URSP is an outside stack pointer, saved by EENTER and restored on AEX by the SGX
* hardware itself.)
*/
#ifdef DEBUG

#define UPDATE_USTACK(_ustack) \
do { \
SET_ENCLAVE_TCB(ustack, _ustack); \
GET_ENCLAVE_TCB(gpr)->ursp = (uint64_t)_ustack; \
} while(0)

#else

#define UPDATE_USTACK(_ustack) SET_ENCLAVE_TCB(ustack, _ustack)

#endif

void* sgx_prepare_ustack(void) {
void* old_ustack = GET_ENCLAVE_TCB(ustack);

Expand Down
2 changes: 1 addition & 1 deletion pal/src/host/linux-sgx/generated_offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ const struct generated_offset generated_offsets[] = {

/* struct pal_host_tcb aka PAL_HOST_TCB */
OFFSET(PAL_HOST_TCB_TCS, pal_host_tcb, tcs),
OFFSET(PAL_HOST_TCB_IN_AEX_PROF, pal_host_tcb, is_in_aex_profiling),
OFFSET(PAL_HOST_TCB_IN_AEX, pal_host_tcb, is_in_aex),
OFFSET(PAL_HOST_TCB_EENTER_CNT, pal_host_tcb, eenter_cnt),
OFFSET(PAL_HOST_TCB_EEXIT_CNT, pal_host_tcb, eexit_cnt),
OFFSET(PAL_HOST_TCB_AEX_CNT, pal_host_tcb, aex_cnt),
Expand Down
29 changes: 21 additions & 8 deletions pal/src/host/linux-sgx/host_entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@

#include "asm-offsets.h"

.extern tcs_base
.extern g_in_aex_profiling
.extern maybe_dump_and_reset_stats
.extern maybe_raise_pending_signal

.global sgx_ecall
.type sgx_ecall, @function
Expand Down Expand Up @@ -54,9 +53,14 @@ sgx_ecall:
leaq async_exit_pointer(%rip), %rcx

movq $EENTER, %rax

.global eenter_pointer
.type eenter_pointer, @function

eenter_pointer:
enclu

# currently only ECALL_THREAD_RESET returns
# currently only ECALL_THREAD_RESET ecall returns, as well as stage-1 signal handler
.Lafter_resume:
popq %r15
.cfi_adjust_cfa_offset -8
Expand All @@ -80,12 +84,15 @@ async_exit_pointer:
.cfi_startproc
.cfi_undefined %rip

# Inform that we are in AEX code
movb $1, %gs:PAL_HOST_TCB_IN_AEX

# increment per-thread AEX counter for stats
lock incq %gs:PAL_HOST_TCB_AEX_CNT

#ifdef DEBUG
# Inform that we are in AEX profiling code
movb $1, %gs:PAL_HOST_TCB_IN_AEX_PROF
subq $RED_ZONE_SIZE, %rsp
.cfi_adjust_cfa_offset RED_ZONE_SIZE

# Save ERESUME parameters
pushq %rax
.cfi_adjust_cfa_offset 8
Expand All @@ -99,11 +106,15 @@ async_exit_pointer:
.cfi_def_cfa_register %rbp
andq $~0xF, %rsp

#ifdef DEBUG
# Call sgx_profile_sample_aex with %rdi = TCS
movq %rbx, %rdi
call sgx_profile_sample_aex

call maybe_dump_and_reset_stats
#endif

call maybe_raise_pending_signal

# Restore stack
movq %rbp, %rsp
Expand All @@ -116,9 +127,11 @@ async_exit_pointer:
.cfi_adjust_cfa_offset -8
popq %rax
.cfi_adjust_cfa_offset -8
movb $0, %gs:PAL_HOST_TCB_IN_AEX_PROF
#endif

addq $RED_ZONE_SIZE, %rsp
.cfi_adjust_cfa_offset -RED_ZONE_SIZE

movb $0, %gs:PAL_HOST_TCB_IN_AEX
.cfi_endproc

# fall-through to ERESUME
Expand Down
10 changes: 7 additions & 3 deletions pal/src/host/linux-sgx/host_exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ static bool interrupted_in_enclave(struct ucontext* uc) {
return rip >= (unsigned long)async_exit_pointer && rip < (unsigned long)async_exit_pointer_end;
}

static bool interrupted_in_aex_profiling(void) {
return pal_get_host_tcb()->is_in_aex_profiling != 0;
static bool interrupted_in_aex(void) {
return pal_get_host_tcb()->is_in_aex != 0;
}

static void handle_sync_signal(int signum, siginfo_t* info, struct ucontext* uc) {
Expand Down Expand Up @@ -153,7 +153,7 @@ static void handle_async_signal(int signum, siginfo_t* info, struct ucontext* uc
for (size_t i = 0; i < g_rpc_queue->rpc_threads_cnt; i++)
DO_SYSCALL(tkill, g_rpc_queue->rpc_threads[i], SIGUSR2);

if (interrupted_in_enclave(uc) || interrupted_in_aex_profiling()) {
if (interrupted_in_enclave(uc) || interrupted_in_aex()) {
/* signal arrived while in app/LibOS/trusted PAL code or when handling another AEX, handle
* signal inside enclave */
pal_get_host_tcb()->async_signal_cnt++;
Expand Down Expand Up @@ -287,3 +287,7 @@ void maybe_dump_and_reset_stats(void) {
}
}
#endif

void maybe_raise_pending_signal(void) {
/* TODO: check if there is any sync or async pending signal and raise it */
}
1 change: 1 addition & 0 deletions pal/src/host/linux-sgx/host_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ int sgx_ecall(long ecall_no, void* ms);
int sgx_raise(int event);

void async_exit_pointer(void);
void eenter_pointer(void);
void eresume_pointer(void);
void async_exit_pointer_end(void);

Expand Down
4 changes: 3 additions & 1 deletion pal/src/host/linux-sgx/pal_tcb.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ typedef struct pal_host_tcb {
sgx_arch_tcs_t* tcs; /* TCS page of SGX corresponding to thread, for EENTER */
void* stack; /* bottom of stack, for later freeing when thread exits */
void* alt_stack; /* bottom of alt stack, for child thread to init alt stack */
uint8_t is_in_aex_profiling; /* non-zero if thread is currently doing AEX profiling */
uint8_t is_in_aex; /* non-zero if thread is currently running AEX code */
atomic_ulong eenter_cnt; /* # of EENTERs, corresponds to # of ECALLs */
atomic_ulong eexit_cnt; /* # of EEXITs, corresponds to # of OCALLs */
atomic_ulong aex_cnt; /* # of AEXs, corresponds to # of interrupts/signals */
Expand Down Expand Up @@ -122,4 +122,6 @@ void collect_and_print_sgx_stats(void);
void maybe_dump_and_reset_stats(void);
#endif /* DEBUG */

void maybe_raise_pending_signal(void);

#endif /* IN_ENCLAVE */