• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
4 */
5
6#include <linux/linkage.h>
7#include <asm/assembler.h>
8
9SYM_FUNC_START(__efi_rt_asm_wrapper)
10	stp	x29, x30, [sp, #-32]!
11	mov	x29, sp
12
13	/*
14	 * Register x18 is designated as the 'platform' register by the AAPCS,
15	 * which means firmware running at the same exception level as the OS
16	 * (such as UEFI) should never touch it.
17	 */
18	stp	x1, x18, [sp, #16]
19
20	ldr_l	x16, efi_rt_stack_top
21	mov	sp, x16
22#ifdef CONFIG_SHADOW_CALL_STACK
23	str	x18, [sp, #-16]!
24#endif
25
26	/*
27	 * We are lucky enough that no EFI runtime services take more than
28	 * 5 arguments, so all are passed in registers rather than via the
29	 * stack.
30	 */
31	mov	x8, x0
32	mov	x0, x2
33	mov	x1, x3
34	mov	x2, x4
35	mov	x3, x5
36	mov	x4, x6
37	blr	x8
38
39	mov	sp, x29
40	ldp	x1, x2, [sp, #16]
41	cmp	x2, x18
42	ldp	x29, x30, [sp], #32
43	b.ne	0f
44	ret
450:
46	/*
47	 * With CONFIG_SHADOW_CALL_STACK, the kernel uses x18 to store a
48	 * shadow stack pointer, which we need to restore before returning to
49	 * potentially instrumented code. This is safe because the wrapper is
50	 * called with preemption disabled and a separate shadow stack is used
51	 * for interrupts.
52	 */
53#ifdef CONFIG_SHADOW_CALL_STACK
54	ldr_l	x18, efi_rt_stack_top
55	ldr	x18, [x18, #-16]
56#endif
57
58	b	efi_handle_corrupted_x18	// tail call
59SYM_FUNC_END(__efi_rt_asm_wrapper)
60