ARM: 9075/1: kernel: Fix interrupted SMC calls
[linux-2.6-microblaze.git] / arch / arm / kernel / smccc-call.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2015, Linaro Limited
4  */
5 #include <linux/linkage.h>
6 #include <linux/arm-smccc.h>
7
8 #include <asm/asm-offsets.h>
9 #include <asm/opcodes-sec.h>
10 #include <asm/opcodes-virt.h>
11 #include <asm/unwind.h>
12
13         /*
14          * Wrap c macros in asm macros to delay expansion until after the
15          * SMCCC asm macro is expanded.
16          */
17         .macro SMCCC_SMC
18         __SMC(0)
19         .endm
20
21         .macro SMCCC_HVC
22         __HVC(0)
23         .endm
24
25         .macro SMCCC instr
26 UNWIND( .fnstart)
27         mov     r12, sp
28         push    {r4-r7}
29 UNWIND( .save   {r4-r7})
30         ldm     r12, {r4-r7}
31         \instr
32         ldr     r4, [sp, #36]
33         cmp     r4, #0
34         beq     1f                      // No quirk structure
35         ldr     r5, [r4, #ARM_SMCCC_QUIRK_ID_OFFS]
36         cmp     r5, #ARM_SMCCC_QUIRK_QCOM_A6
37         bne     1f                      // No quirk present
38         str     r6, [r4, #ARM_SMCCC_QUIRK_STATE_OFFS]
39 1:      pop     {r4-r7}
40         ldr     r12, [sp, #(4 * 4)]
41         stm     r12, {r0-r3}
42         bx      lr
43 UNWIND( .fnend)
44         .endm
45
46 /*
47  * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
48  *                unsigned long a3, unsigned long a4, unsigned long a5,
49  *                unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
50  *                struct arm_smccc_quirk *quirk)
51  */
52 ENTRY(__arm_smccc_smc)
53         SMCCC SMCCC_SMC
54 ENDPROC(__arm_smccc_smc)
55
56 /*
57  * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
58  *                unsigned long a3, unsigned long a4, unsigned long a5,
59  *                unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
60  *                struct arm_smccc_quirk *quirk)
61  */
62 ENTRY(__arm_smccc_hvc)
63         SMCCC SMCCC_HVC
64 ENDPROC(__arm_smccc_hvc)