Merge commit '81fd23e2b3ccf71c807e671444e8accaba98ca53' of https://git.pengutronix...
[linux-2.6-microblaze.git] / arch / arm64 / kernel / efi-rt-wrapper.S
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
8 SYM_FUNC_START(__efi_rt_asm_wrapper)
9         stp     x29, x30, [sp, #-32]!
10         mov     x29, sp
11
12         /*
13          * Register x18 is designated as the 'platform' register by the AAPCS,
14          * which means firmware running at the same exception level as the OS
15          * (such as UEFI) should never touch it.
16          */
17         stp     x1, x18, [sp, #16]
18
19         /*
20          * We are lucky enough that no EFI runtime services take more than
21          * 5 arguments, so all are passed in registers rather than via the
22          * stack.
23          */
24         mov     x8, x0
25         mov     x0, x2
26         mov     x1, x3
27         mov     x2, x4
28         mov     x3, x5
29         mov     x4, x6
30         blr     x8
31
32         ldp     x1, x2, [sp, #16]
33         cmp     x2, x18
34         ldp     x29, x30, [sp], #32
35         b.ne    0f
36         ret
37 0:
38         /*
39          * With CONFIG_SHADOW_CALL_STACK, the kernel uses x18 to store a
40          * shadow stack pointer, which we need to restore before returning to
41          * potentially instrumented code. This is safe because the wrapper is
42          * called with preemption disabled and a separate shadow stack is used
43          * for interrupts.
44          */
45         mov     x18, x2
46         b       efi_handle_corrupted_x18        // tail call
47 SYM_FUNC_END(__efi_rt_asm_wrapper)