Skip to content

Commit 0e7cac7

Browse files
author
Dmitrii Kuvaiskii
committed
[PAL/Linux-SGX] Prepare AEX handler to call C code in release mode
Previously, the AEX handler only called C code (more specific to our use case, the code that works on the untrusted-thread stack) for SGX profiling logic and only when Gramine was built in debug mode. As a preparation for AEX Notify support, this commit modifies the AEX handler such that it can call C code when Gramine is built in release mode. Also, the AEX handler logic is not restricted to SGX profiling only, so the `_PROF`/`_prof` suffixes in related function and variable names are removed. This commit also adds two small prerequisites for AEX Notify: (1) `eenter_pointer` helper so that signal handling logic can learn whether an exception happened at EENTER instruction, and (2) dummy function `maybe_raise_pending_signal` that will be populated in a later commit. Signed-off-by: Dmitrii Kuvaiskii <[email protected]>
1 parent 988e6b8 commit 0e7cac7

File tree

6 files changed

+34
-22
lines changed

6 files changed

+34
-22
lines changed

pal/src/host/linux-sgx/enclave_framework.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,27 +63,19 @@ bool sgx_is_valid_untrusted_ptr(const void* _addr, size_t size, size_t alignment
6363
}
6464

6565
/*
66-
* When DEBUG is enabled, we run sgx_profile_sample() during asynchronous enclave exit (AEX), which
66+
* We run some functions (e.g. sgx_profile_sample()) during asynchronous enclave exit (AEX), which
6767
* uses the stack. Make sure to update URSP so that the AEX handler does not overwrite the part of
6868
* the stack that we just allocated.
6969
*
7070
* (Recall that URSP is an outside stack pointer, saved by EENTER and restored on AEX by the SGX
7171
* hardware itself.)
7272
*/
73-
#ifdef DEBUG
74-
7573
#define UPDATE_USTACK(_ustack) \
7674
do { \
7775
SET_ENCLAVE_TCB(ustack, _ustack); \
7876
GET_ENCLAVE_TCB(gpr)->ursp = (uint64_t)_ustack; \
7977
} while(0)
8078

81-
#else
82-
83-
#define UPDATE_USTACK(_ustack) SET_ENCLAVE_TCB(ustack, _ustack)
84-
85-
#endif
86-
8779
void* sgx_prepare_ustack(void) {
8880
void* old_ustack = GET_ENCLAVE_TCB(ustack);
8981

pal/src/host/linux-sgx/generated_offsets.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ const struct generated_offset generated_offsets[] = {
106106

107107
/* struct pal_host_tcb aka PAL_HOST_TCB */
108108
OFFSET(PAL_HOST_TCB_TCS, pal_host_tcb, tcs),
109-
OFFSET(PAL_HOST_TCB_IN_AEX_PROF, pal_host_tcb, is_in_aex_profiling),
109+
OFFSET(PAL_HOST_TCB_IN_AEX, pal_host_tcb, is_in_aex),
110110
OFFSET(PAL_HOST_TCB_EENTER_CNT, pal_host_tcb, eenter_cnt),
111111
OFFSET(PAL_HOST_TCB_EEXIT_CNT, pal_host_tcb, eexit_cnt),
112112
OFFSET(PAL_HOST_TCB_AEX_CNT, pal_host_tcb, aex_cnt),

pal/src/host/linux-sgx/host_entry.S

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@
1414

1515
#include "asm-offsets.h"
1616

17-
.extern tcs_base
18-
.extern g_in_aex_profiling
1917
.extern maybe_dump_and_reset_stats
18+
.extern maybe_raise_pending_signal
2019

2120
.global sgx_ecall
2221
.type sgx_ecall, @function
@@ -54,9 +53,14 @@ sgx_ecall:
5453
leaq async_exit_pointer(%rip), %rcx
5554

5655
movq $EENTER, %rax
56+
57+
.global eenter_pointer
58+
.type eenter_pointer, @function
59+
60+
eenter_pointer:
5761
enclu
5862

59-
# currently only ECALL_THREAD_RESET returns
63+
# currently only ECALL_THREAD_RESET ecall returns, as well as stage-1 signal handler
6064
.Lafter_resume:
6165
popq %r15
6266
.cfi_adjust_cfa_offset -8
@@ -80,12 +84,15 @@ async_exit_pointer:
8084
.cfi_startproc
8185
.cfi_undefined %rip
8286

87+
# Inform that we are in AEX code
88+
movb $1, %gs:PAL_HOST_TCB_IN_AEX
89+
8390
# increment per-thread AEX counter for stats
8491
lock incq %gs:PAL_HOST_TCB_AEX_CNT
8592

86-
#ifdef DEBUG
87-
# Inform that we are in AEX profiling code
88-
movb $1, %gs:PAL_HOST_TCB_IN_AEX_PROF
93+
subq $RED_ZONE_SIZE, %rsp
94+
.cfi_adjust_cfa_offset RED_ZONE_SIZE
95+
8996
# Save ERESUME parameters
9097
pushq %rax
9198
.cfi_adjust_cfa_offset 8
@@ -99,11 +106,15 @@ async_exit_pointer:
99106
.cfi_def_cfa_register %rbp
100107
andq $~0xF, %rsp
101108

109+
#ifdef DEBUG
102110
# Call sgx_profile_sample_aex with %rdi = TCS
103111
movq %rbx, %rdi
104112
call sgx_profile_sample_aex
105113

106114
call maybe_dump_and_reset_stats
115+
#endif
116+
117+
call maybe_raise_pending_signal
107118

108119
# Restore stack
109120
movq %rbp, %rsp
@@ -116,9 +127,11 @@ async_exit_pointer:
116127
.cfi_adjust_cfa_offset -8
117128
popq %rax
118129
.cfi_adjust_cfa_offset -8
119-
movb $0, %gs:PAL_HOST_TCB_IN_AEX_PROF
120-
#endif
121130

131+
addq $RED_ZONE_SIZE, %rsp
132+
.cfi_adjust_cfa_offset -RED_ZONE_SIZE
133+
134+
movb $0, %gs:PAL_HOST_TCB_IN_AEX
122135
.cfi_endproc
123136

124137
# fall-through to ERESUME

pal/src/host/linux-sgx/host_exception.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ static bool interrupted_in_enclave(struct ucontext* uc) {
8888
return rip >= (unsigned long)async_exit_pointer && rip < (unsigned long)async_exit_pointer_end;
8989
}
9090

91-
static bool interrupted_in_aex_profiling(void) {
92-
return pal_get_host_tcb()->is_in_aex_profiling != 0;
91+
static bool interrupted_in_aex(void) {
92+
return pal_get_host_tcb()->is_in_aex != 0;
9393
}
9494

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

156-
if (interrupted_in_enclave(uc) || interrupted_in_aex_profiling()) {
156+
if (interrupted_in_enclave(uc) || interrupted_in_aex()) {
157157
/* signal arrived while in app/LibOS/trusted PAL code or when handling another AEX, handle
158158
* signal inside enclave */
159159
pal_get_host_tcb()->async_signal_cnt++;
@@ -287,3 +287,7 @@ void maybe_dump_and_reset_stats(void) {
287287
}
288288
}
289289
#endif
290+
291+
void maybe_raise_pending_signal(void) {
292+
/* TODO: check if there is any sync or async pending signal and raise it */
293+
}

pal/src/host/linux-sgx/host_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ int sgx_ecall(long ecall_no, void* ms);
114114
int sgx_raise(int event);
115115

116116
void async_exit_pointer(void);
117+
void eenter_pointer(void);
117118
void eresume_pointer(void);
118119
void async_exit_pointer_end(void);
119120

pal/src/host/linux-sgx/pal_tcb.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ typedef struct pal_host_tcb {
9292
sgx_arch_tcs_t* tcs; /* TCS page of SGX corresponding to thread, for EENTER */
9393
void* stack; /* bottom of stack, for later freeing when thread exits */
9494
void* alt_stack; /* bottom of alt stack, for child thread to init alt stack */
95-
uint8_t is_in_aex_profiling; /* non-zero if thread is currently doing AEX profiling */
95+
uint8_t is_in_aex; /* non-zero if thread is currently running AEX code */
9696
atomic_ulong eenter_cnt; /* # of EENTERs, corresponds to # of ECALLs */
9797
atomic_ulong eexit_cnt; /* # of EEXITs, corresponds to # of OCALLs */
9898
atomic_ulong aex_cnt; /* # of AEXs, corresponds to # of interrupts/signals */
@@ -122,4 +122,6 @@ void collect_and_print_sgx_stats(void);
122122
void maybe_dump_and_reset_stats(void);
123123
#endif /* DEBUG */
124124

125+
void maybe_raise_pending_signal(void);
126+
125127
#endif /* IN_ENCLAVE */

0 commit comments

Comments
 (0)