Skip to content

Commit

Permalink
[PAL/Linux-SGX] Remove no-XSAVE code paths (dead code)
Browse files Browse the repository at this point in the history
Commit "[PAL/Linux-SGX] Enforce AES-NI, XSAVE and RDRAND" enforced the
XSAVE CPU feature. The Linux-SGX PAL still had some code that use
no-XSAVE code paths, falling back to older FXSAVE. With that commit,
such code became dead code.

Also, this commit adds an additional enforcement: the OS must also
enable the XSAVE feature, which is reflected in CPUID.1:ECX.OSXSAVE.

Signed-off-by: Dmitrii Kuvaiskii <[email protected]>
  • Loading branch information
dimakuv committed Jun 19, 2023
1 parent 702ac42 commit a059331
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 45 deletions.
32 changes: 6 additions & 26 deletions pal/src/host/linux-sgx/enclave_entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,12 @@ enclave_entry:
popfq

# Clear "extended" state (FPU aka x87, SSE, AVX, ...).
# TODO: We currently clear only state covered by FXRSTOR but not by XRSTOR (e.g., no clearing of
# YMM/ZMM regs). This is because we didn't read the value of XFRM yet, so we don't know
# whether XRSTOR is safe at this point.
leaq g_xsave_reset_state(%rip), %rax
fxrstor (%rax)
movq %rdx, %rbx
mov $0xffffffff, %eax
mov %eax, %edx
xrstor64 g_xsave_reset_state(%rip)
xorq %rax, %rax
movq %rbx, %rdx

# register states need to be carefully checked, so we move handling to handle_ecall() in C code
callq handle_ecall
Expand Down Expand Up @@ -694,16 +694,10 @@ sgx_ocall:
#
# g_pal_linuxsgx_state.enclave_info.attributes.xfrm will always be zero before init_enclave has
# been called by pal_linux_main. So during early init nothing should use features not covered by
# fxrstor, like AVX.
cmpl $0, g_xsave_enabled(%rip)
jne 1f
fxrstor64 g_xsave_reset_state(%rip)
jmp 2f
1:
# xrstor, like AVX.
mov $0xffffffff, %eax
mov %eax, %edx
xrstor64 g_xsave_reset_state(%rip)
2:

#ifdef DEBUG
# Store pointer to context in RDX, for the SGX profiler.
Expand Down Expand Up @@ -873,10 +867,6 @@ _restore_sgx_context:
.type __save_xregs, @function
__save_xregs:
.cfi_startproc
movl g_xsave_enabled(%rip), %eax
cmpl $0, %eax
jz 1f

# clear XSAVE area header
movq $0, XSAVE_HEADER_OFFSET + 0 * 8(%rdi)
movq $0, XSAVE_HEADER_OFFSET + 1 * 8(%rdi)
Expand All @@ -891,9 +881,6 @@ __save_xregs:
movl $0xffffffff, %edx
xsave64 (%rdi)
jmp *%r11
1:
fxsave64 (%rdi)
jmp *%r11
.cfi_endproc


Expand All @@ -918,17 +905,10 @@ save_xregs:
.type __restore_xregs, @function
__restore_xregs:
.cfi_startproc
movl g_xsave_enabled(%rip), %eax
cmpl $0, %eax
jz 1f

movl $0xffffffff, %eax
movl $0xffffffff, %edx
xrstor64 (%rdi)
jmp *%r11
1:
fxrstor64 (%rdi)
jmp *%r11
.cfi_endproc


Expand Down
13 changes: 2 additions & 11 deletions pal/src/host/linux-sgx/enclave_xstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
#include "pal.h"
#include "pal_linux.h"

int g_xsave_enabled = 0;
uint64_t g_xsave_features = 0;
uint32_t g_xsave_size = 0;

Expand All @@ -62,8 +61,8 @@ const uint32_t g_cpu_extension_offsets[] = {
[AMX_TILECFG] = 2752, [AMX_TILEDATA] = 2816,
};

/* FXRSTOR only cares about the first 512 bytes, while XRSTOR in compacted mode will ignore
* the first 512 bytes. */
/* FXRSTOR-compatible reset state. We use it just for sanity, even though XRSTOR in compacted mode
* ignores the first 512 bytes. */
const uint32_t g_xsave_reset_state[XSAVE_RESET_STATE_SIZE / sizeof(uint32_t)] __attribute__((
aligned(PAL_XSTATE_ALIGN))) = {
0x037F, 0, 0, 0, 0, 0, 0x1F80, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Expand Down Expand Up @@ -98,16 +97,8 @@ void init_xsave_size(uint64_t xfrm) {
};
assert(xsave_size_table[ARRAY_SIZE(xsave_size_table) - 1].size == SSA_XSAVE_SIZE_MAX);

/* fxsave/fxrstore as fallback */
g_xsave_enabled = 0;
g_xsave_features = PAL_XFEATURE_MASK_FPSSE;
g_xsave_size = 512 + 64;
if (!xfrm || (xfrm & SGX_XFRM_RESERVED)) {
log_debug("xsave is disabled, xfrm 0x%lx", xfrm);
return;
}

g_xsave_enabled = (xfrm == SGX_XFRM_LEGACY) ? 0 : 1;
for (size_t i = 0; i < ARRAY_SIZE(xsave_size_table); i++) {
if ((xfrm & xsave_size_table[i].bits) == xsave_size_table[i].bits) {
g_xsave_features = xfrm;
Expand Down
7 changes: 7 additions & 0 deletions pal/src/host/linux-sgx/host_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,13 @@ static int verify_hw_requirements(char* envp[]) {
"Please upgrade your hardware.", missing);
return -EINVAL;
}

if (!(values[CPUID_WORD_ECX] & (1 << 27))) {
log_error("Gramine with Linux-SGX backend requires XSAVE support in OS (OSXSAVE). "
"Please use an OS with XSAVE support.");
return -EINVAL;
}

return 0;
}

Expand Down
9 changes: 2 additions & 7 deletions pal/src/host/linux-sgx/pal_exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,8 @@ static void save_pal_context(PAL_CONTEXT* ctx, sgx_cpu_context_t* uc,
fpx_sw->extended_size = g_xsave_size;
fpx_sw->xfeatures = g_xsave_features;
memset(fpx_sw->padding, 0, sizeof(fpx_sw->padding));
if (g_xsave_enabled) {
fpx_sw->xstate_size = g_xsave_size + PAL_FP_XSTATE_MAGIC2_SIZE;
*(__typeof__(PAL_FP_XSTATE_MAGIC2)*)((void*)xregs_state + g_xsave_size) =
PAL_FP_XSTATE_MAGIC2;
} else {
fpx_sw->xstate_size = g_xsave_size;
}
fpx_sw->xstate_size = g_xsave_size + PAL_FP_XSTATE_MAGIC2_SIZE;
*(__typeof__(PAL_FP_XSTATE_MAGIC2)*)((void*)xregs_state + g_xsave_size) = PAL_FP_XSTATE_MAGIC2;
}

static void emulate_rdtsc_and_print_warning(sgx_cpu_context_t* uc) {
Expand Down
1 change: 0 additions & 1 deletion pal/src/host/linux-sgx/pal_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ extern char __text_start, __text_end, __data_start, __data_end;
extern const uint32_t g_cpu_extension_sizes[];
extern const uint32_t g_cpu_extension_offsets[];

extern int g_xsave_enabled;
extern uint64_t g_xsave_features;
extern uint32_t g_xsave_size;
#define XSAVE_RESET_STATE_SIZE (512 + 64) // 512 for legacy regs, 64 for xsave header
Expand Down

0 comments on commit a059331

Please sign in to comment.