xref: /openbmc/linux/arch/x86/entry/vdso/vsgx.S (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
184664369SSean Christopherson/* SPDX-License-Identifier: GPL-2.0 */
284664369SSean Christopherson
384664369SSean Christopherson#include <linux/linkage.h>
484664369SSean Christopherson#include <asm/export.h>
584664369SSean Christopherson#include <asm/errno.h>
684664369SSean Christopherson#include <asm/enclu.h>
784664369SSean Christopherson
884664369SSean Christopherson#include "extable.h"
984664369SSean Christopherson
1084664369SSean Christopherson/* Relative to %rbp. */
1184664369SSean Christopherson#define SGX_ENCLAVE_OFFSET_OF_RUN		16
1284664369SSean Christopherson
1384664369SSean Christopherson/* The offsets relative to struct sgx_enclave_run. */
1484664369SSean Christopherson#define SGX_ENCLAVE_RUN_TCS			0
1584664369SSean Christopherson#define SGX_ENCLAVE_RUN_LEAF			8
1684664369SSean Christopherson#define SGX_ENCLAVE_RUN_EXCEPTION_VECTOR	12
1784664369SSean Christopherson#define SGX_ENCLAVE_RUN_EXCEPTION_ERROR_CODE	14
1884664369SSean Christopherson#define SGX_ENCLAVE_RUN_EXCEPTION_ADDR		16
1984664369SSean Christopherson#define SGX_ENCLAVE_RUN_USER_HANDLER		24
2084664369SSean Christopherson#define SGX_ENCLAVE_RUN_USER_DATA		32	/* not used */
2184664369SSean Christopherson#define SGX_ENCLAVE_RUN_RESERVED_START		40
2284664369SSean Christopherson#define SGX_ENCLAVE_RUN_RESERVED_END		256
2384664369SSean Christopherson
2484664369SSean Christopherson.code64
2584664369SSean Christopherson.section .text, "ax"
2684664369SSean Christopherson
2784664369SSean ChristophersonSYM_FUNC_START(__vdso_sgx_enter_enclave)
2884664369SSean Christopherson	/* Prolog */
2984664369SSean Christopherson	.cfi_startproc
3084664369SSean Christopherson	push	%rbp
3184664369SSean Christopherson	.cfi_adjust_cfa_offset	8
3284664369SSean Christopherson	.cfi_rel_offset		%rbp, 0
3384664369SSean Christopherson	mov	%rsp, %rbp
3484664369SSean Christopherson	.cfi_def_cfa_register	%rbp
3584664369SSean Christopherson	push	%rbx
3684664369SSean Christopherson	.cfi_rel_offset		%rbx, -8
3784664369SSean Christopherson
3884664369SSean Christopherson	mov	%ecx, %eax
3984664369SSean Christopherson.Lenter_enclave:
4084664369SSean Christopherson	/* EENTER <= function <= ERESUME */
4184664369SSean Christopherson	cmp	$EENTER, %eax
4284664369SSean Christopherson	jb	.Linvalid_input
4384664369SSean Christopherson	cmp	$ERESUME, %eax
4484664369SSean Christopherson	ja	.Linvalid_input
4584664369SSean Christopherson
4684664369SSean Christopherson	mov	SGX_ENCLAVE_OFFSET_OF_RUN(%rbp), %rcx
4784664369SSean Christopherson
4884664369SSean Christopherson	/* Validate that the reserved area contains only zeros. */
4984664369SSean Christopherson	mov	$SGX_ENCLAVE_RUN_RESERVED_START, %rbx
5084664369SSean Christopherson1:
5184664369SSean Christopherson	cmpq	$0, (%rcx, %rbx)
5284664369SSean Christopherson	jne	.Linvalid_input
5384664369SSean Christopherson	add	$8, %rbx
5484664369SSean Christopherson	cmpq	$SGX_ENCLAVE_RUN_RESERVED_END, %rbx
5584664369SSean Christopherson	jne	1b
5684664369SSean Christopherson
5784664369SSean Christopherson	/* Load TCS and AEP */
5884664369SSean Christopherson	mov	SGX_ENCLAVE_RUN_TCS(%rcx), %rbx
5984664369SSean Christopherson	lea	.Lasync_exit_pointer(%rip), %rcx
6084664369SSean Christopherson
6184664369SSean Christopherson	/* Single ENCLU serving as both EENTER and AEP (ERESUME) */
6284664369SSean Christopherson.Lasync_exit_pointer:
6384664369SSean Christopherson.Lenclu_eenter_eresume:
6484664369SSean Christopherson	enclu
6584664369SSean Christopherson
6684664369SSean Christopherson	/* EEXIT jumps here unless the enclave is doing something fancy. */
6784664369SSean Christopherson	mov	SGX_ENCLAVE_OFFSET_OF_RUN(%rbp), %rbx
6884664369SSean Christopherson
6984664369SSean Christopherson	/* Set exit_reason. */
7084664369SSean Christopherson	movl	$EEXIT, SGX_ENCLAVE_RUN_LEAF(%rbx)
7184664369SSean Christopherson
7284664369SSean Christopherson	/* Invoke userspace's exit handler if one was provided. */
7384664369SSean Christopherson.Lhandle_exit:
7484664369SSean Christopherson	cmpq	$0, SGX_ENCLAVE_RUN_USER_HANDLER(%rbx)
7584664369SSean Christopherson	jne	.Linvoke_userspace_handler
7684664369SSean Christopherson
7784664369SSean Christopherson	/* Success, in the sense that ENCLU was attempted. */
7884664369SSean Christopherson	xor	%eax, %eax
7984664369SSean Christopherson
8084664369SSean Christopherson.Lout:
8184664369SSean Christopherson	pop	%rbx
8284664369SSean Christopherson	leave
8384664369SSean Christopherson	.cfi_def_cfa		%rsp, 8
84*f94909ceSPeter Zijlstra	RET
8584664369SSean Christopherson
8684664369SSean Christopherson	/* The out-of-line code runs with the pre-leave stack frame. */
8784664369SSean Christopherson	.cfi_def_cfa		%rbp, 16
8884664369SSean Christopherson
8984664369SSean Christopherson.Linvalid_input:
9084664369SSean Christopherson	mov	$(-EINVAL), %eax
9184664369SSean Christopherson	jmp	.Lout
9284664369SSean Christopherson
9384664369SSean Christopherson.Lhandle_exception:
9484664369SSean Christopherson	mov	SGX_ENCLAVE_OFFSET_OF_RUN(%rbp), %rbx
9584664369SSean Christopherson
9684664369SSean Christopherson	/* Set the exception info. */
9784664369SSean Christopherson	mov	%eax, (SGX_ENCLAVE_RUN_LEAF)(%rbx)
9884664369SSean Christopherson	mov	%di,  (SGX_ENCLAVE_RUN_EXCEPTION_VECTOR)(%rbx)
9984664369SSean Christopherson	mov	%si,  (SGX_ENCLAVE_RUN_EXCEPTION_ERROR_CODE)(%rbx)
10084664369SSean Christopherson	mov	%rdx, (SGX_ENCLAVE_RUN_EXCEPTION_ADDR)(%rbx)
10184664369SSean Christopherson	jmp	.Lhandle_exit
10284664369SSean Christopherson
10384664369SSean Christopherson.Linvoke_userspace_handler:
10484664369SSean Christopherson	/* Pass the untrusted RSP (at exit) to the callback via %rcx. */
10584664369SSean Christopherson	mov	%rsp, %rcx
10684664369SSean Christopherson
10784664369SSean Christopherson	/* Save struct sgx_enclave_exception %rbx is about to be clobbered. */
10884664369SSean Christopherson	mov	%rbx, %rax
10984664369SSean Christopherson
11084664369SSean Christopherson	/* Save the untrusted RSP offset in %rbx (non-volatile register). */
11184664369SSean Christopherson	mov	%rsp, %rbx
11284664369SSean Christopherson	and	$0xf, %rbx
11384664369SSean Christopherson
11484664369SSean Christopherson	/*
11584664369SSean Christopherson	 * Align stack per x86_64 ABI. Note, %rsp needs to be 16-byte aligned
11684664369SSean Christopherson	 * _after_ pushing the parameters on the stack, hence the bonus push.
11784664369SSean Christopherson	 */
11884664369SSean Christopherson	and	$-0x10, %rsp
11984664369SSean Christopherson	push	%rax
12084664369SSean Christopherson
12184664369SSean Christopherson	/* Push struct sgx_enclave_exception as a param to the callback. */
12284664369SSean Christopherson	push	%rax
12384664369SSean Christopherson
12484664369SSean Christopherson	/* Clear RFLAGS.DF per x86_64 ABI */
12584664369SSean Christopherson	cld
12684664369SSean Christopherson
12784664369SSean Christopherson	/*
12884664369SSean Christopherson	 * Load the callback pointer to %rax and lfence for LVI (load value
12984664369SSean Christopherson	 * injection) protection before making the call.
13084664369SSean Christopherson	 */
13184664369SSean Christopherson	mov	SGX_ENCLAVE_RUN_USER_HANDLER(%rax), %rax
13284664369SSean Christopherson	lfence
13384664369SSean Christopherson	call	*%rax
13484664369SSean Christopherson
13584664369SSean Christopherson	/* Undo the post-exit %rsp adjustment. */
13684664369SSean Christopherson	lea	0x10(%rsp, %rbx), %rsp
13784664369SSean Christopherson
13884664369SSean Christopherson	/*
13984664369SSean Christopherson	 * If the return from callback is zero or negative, return immediately,
140163b0991SIngo Molnar	 * else re-execute ENCLU with the positive return value interpreted as
14184664369SSean Christopherson	 * the requested ENCLU function.
14284664369SSean Christopherson	 */
14384664369SSean Christopherson	cmp	$0, %eax
14484664369SSean Christopherson	jle	.Lout
14584664369SSean Christopherson	jmp	.Lenter_enclave
14684664369SSean Christopherson
14784664369SSean Christopherson	.cfi_endproc
14884664369SSean Christopherson
14984664369SSean Christopherson_ASM_VDSO_EXTABLE_HANDLE(.Lenclu_eenter_eresume, .Lhandle_exception)
15084664369SSean Christopherson
15184664369SSean ChristophersonSYM_FUNC_END(__vdso_sgx_enter_enclave)
152