[libos] Retain red zone area and FLAGS unmodified across syscall

1. The previous implementation of __occlum_syret usse the red zone to
save the register temporarily, which may overwrite the red zone area.
This change avoids using the red zone when handling syscall.

2. Save and restore the FLAGS register before and after the operations
on PKRU to keep the FLAGS unmodified.
This commit is contained in:
zhubojun 2023-03-20 21:46:38 -04:00 committed by volcano
parent 5a03deb6b9
commit 6cb368fbbe

@ -6,6 +6,11 @@
.global __occlum_syscall_linux_pku_abi .global __occlum_syscall_linux_pku_abi
.type __occlum_syscall_linux_pku_abi, @function .type __occlum_syscall_linux_pku_abi, @function
__occlum_syscall_linux_pku_abi: __occlum_syscall_linux_pku_abi:
// Skip the red zone aera (128 bytes according to x86_64 System V ABI)
// Use `lea` here since it does not modify FLAGS
lea -128(%rsp), %rsp
pushfq
pushq %rcx pushq %rcx
pushq %rdx pushq %rdx
pushq %rax pushq %rax
@ -18,6 +23,9 @@ __occlum_syscall_linux_pku_abi:
popq %rax popq %rax
popq %rdx popq %rdx
popq %rcx popq %rcx
popfq
lea 128(%rsp), %rsp
.global __occlum_syscall_linux_abi .global __occlum_syscall_linux_abi
.type __occlum_syscall_linux_abi, @function .type __occlum_syscall_linux_abi, @function
@ -145,6 +153,10 @@ __occlum_sysret:
pop %rcx pop %rcx
pop %rsp pop %rsp
// Skip the red zone aera (128 bytes according to x86_64 System V ABI)
// Use `lea` here since it does not modify FLAGS
lea -128(%rsp), %rsp
// Store RFLAGS since `cmp` operation may overwrite it // Store RFLAGS since `cmp` operation may overwrite it
pushfq pushfq
push %rax push %rax
@ -156,30 +168,36 @@ __occlum_sysret:
pop %rax pop %rax
popfq popfq
lea 128(%rsp), %rsp
jmp *%gs:(TD_SYSCALL_RET_ADDR_OFFSET) jmp *%gs:(TD_SYSCALL_RET_ADDR_OFFSET)
// This should never happen // This should never happen
ud2 ud2
update_pkru_in_sysret: update_pkru_in_sysret:
pop %rax // Prepare temporary stack area for saving the %rdx, %rdx and return address
popfq lea -3*8(%rsp), %rsp
mov %rdx, (%rsp)
sub $0x20, %rsp mov %rcx, 8(%rsp)
mov %rax, (%rsp)
mov %rdx, 0x8(%rsp)
mov %rcx, 0x10(%rsp)
mov %gs:(TD_SYSCALL_RET_ADDR_OFFSET), %rcx mov %gs:(TD_SYSCALL_RET_ADDR_OFFSET), %rcx
mov %rcx, 0x18(%rsp) mov %rcx, 2*8(%rsp)
xor %ecx, %ecx xor %ecx, %ecx
xor %edx, %edx xor %edx, %edx
mov $PKRU_USER, %eax mov $PKRU_USER, %eax
wrpkru wrpkru
pop %rax
pop %rdx pop %rdx
pop %rcx pop %rcx
ret // Skip the return address
lea 8(%rsp), %rsp
pop %rax
popfq
lea 128(%rsp), %rsp // Restore the %rsp
jmp *(-128-3*8)(%rsp)
// This should never happen
ud2
.global __occlum_syscall_c_abi .global __occlum_syscall_c_abi
.type __occlum_syscall_c_abi, @function .type __occlum_syscall_c_abi, @function