OSDN Git Service

arm64: efi: Recover from synchronous exceptions occurring in firmware
[tomoyo/tomoyo-test1.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, #-112]!
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          * Preserve all callee saved registers and record the stack pointer
21          * value in a per-CPU variable so we can recover from synchronous
22          * exceptions occurring while running the firmware routines.
23          */
24         stp     x19, x20, [sp, #32]
25         stp     x21, x22, [sp, #48]
26         stp     x23, x24, [sp, #64]
27         stp     x25, x26, [sp, #80]
28         stp     x27, x28, [sp, #96]
29
30         adr_this_cpu    x8, __efi_rt_asm_recover_sp, x9
31         str             x29, [x8]
32
33         /*
34          * We are lucky enough that no EFI runtime services take more than
35          * 5 arguments, so all are passed in registers rather than via the
36          * stack.
37          */
38         mov     x8, x0
39         mov     x0, x2
40         mov     x1, x3
41         mov     x2, x4
42         mov     x3, x5
43         mov     x4, x6
44         blr     x8
45
46         ldp     x1, x2, [sp, #16]
47         cmp     x2, x18
48         ldp     x29, x30, [sp], #112
49         b.ne    0f
50         ret
51 0:
52         /*
53          * With CONFIG_SHADOW_CALL_STACK, the kernel uses x18 to store a
54          * shadow stack pointer, which we need to restore before returning to
55          * potentially instrumented code. This is safe because the wrapper is
56          * called with preemption disabled and a separate shadow stack is used
57          * for interrupts.
58          */
59         mov     x18, x2
60         b       efi_handle_corrupted_x18        // tail call
61 SYM_FUNC_END(__efi_rt_asm_wrapper)
62
63 SYM_FUNC_START(__efi_rt_asm_recover)
64         ldr_this_cpu    x8, __efi_rt_asm_recover_sp, x9
65         mov             sp, x8
66
67         ldp     x0,  x18, [sp, #16]
68         ldp     x19, x20, [sp, #32]
69         ldp     x21, x22, [sp, #48]
70         ldp     x23, x24, [sp, #64]
71         ldp     x25, x26, [sp, #80]
72         ldp     x27, x28, [sp, #96]
73         ldp     x29, x30, [sp], #112
74
75         b       efi_handle_runtime_exception
76 SYM_FUNC_END(__efi_rt_asm_recover)