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 8SYM_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 510: 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 61SYM_FUNC_END(__efi_rt_asm_wrapper) 62 63SYM_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 76SYM_FUNC_END(__efi_rt_asm_recover) 77