]>
Commit | Line | Data |
---|---|---|
e925bffa GKH |
1 | From foo@baz Tue Dec 4 11:34:44 CET 2018 |
2 | From: Stefan Agner <stefan@agner.ch> | |
3 | Date: Sun, 25 Mar 2018 20:09:56 +0200 | |
4 | Subject: ARM: trusted_foundations: do not use naked function | |
5 | ||
6 | From: Stefan Agner <stefan@agner.ch> | |
7 | ||
8 | (commit 4ea7bdc6b5b33427bbd3f41c333e21c1825462a3 upstream) | |
9 | ||
10 | As documented in GCC naked functions should only use basic ASM | |
11 | syntax. The extended ASM or mixture of basic ASM and "C" code is | |
12 | not guaranteed. Currently this works because it was hard coded | |
13 | to follow and check GCC behavior for arguments and register | |
14 | placement. | |
15 | ||
16 | Furthermore with clang using parameters in Extended asm in a | |
17 | naked function is not supported: | |
18 | arch/arm/firmware/trusted_foundations.c:47:10: error: parameter | |
19 | references not allowed in naked functions | |
20 | : "r" (type), "r" (arg1), "r" (arg2) | |
21 | ^ | |
22 | ||
23 | Use a regular function to be more portable. This aligns also with | |
24 | the other SMC call implementations e.g. in qcom_scm-32.c and | |
25 | bcm_kona_smc.c. | |
26 | ||
27 | Cc: Dmitry Osipenko <digetx@gmail.com> | |
28 | Cc: Stephen Warren <swarren@nvidia.com> | |
29 | Cc: Thierry Reding <treding@nvidia.com> | |
30 | Signed-off-by: Stefan Agner <stefan@agner.ch> | |
31 | Signed-off-by: Thierry Reding <treding@nvidia.com> | |
32 | Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> | |
33 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
34 | --- | |
35 | arch/arm/firmware/trusted_foundations.c | 14 +++++++++----- | |
36 | 1 file changed, 9 insertions(+), 5 deletions(-) | |
37 | ||
38 | --- a/arch/arm/firmware/trusted_foundations.c | |
39 | +++ b/arch/arm/firmware/trusted_foundations.c | |
40 | @@ -31,21 +31,25 @@ | |
41 | ||
42 | static unsigned long cpu_boot_addr; | |
43 | ||
44 | -static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2) | |
45 | +static void tf_generic_smc(u32 type, u32 arg1, u32 arg2) | |
46 | { | |
47 | + register u32 r0 asm("r0") = type; | |
48 | + register u32 r1 asm("r1") = arg1; | |
49 | + register u32 r2 asm("r2") = arg2; | |
50 | + | |
51 | asm volatile( | |
52 | ".arch_extension sec\n\t" | |
53 | - "stmfd sp!, {r4 - r11, lr}\n\t" | |
54 | + "stmfd sp!, {r4 - r11}\n\t" | |
55 | __asmeq("%0", "r0") | |
56 | __asmeq("%1", "r1") | |
57 | __asmeq("%2", "r2") | |
58 | "mov r3, #0\n\t" | |
59 | "mov r4, #0\n\t" | |
60 | "smc #0\n\t" | |
61 | - "ldmfd sp!, {r4 - r11, pc}" | |
62 | + "ldmfd sp!, {r4 - r11}\n\t" | |
63 | : | |
64 | - : "r" (type), "r" (arg1), "r" (arg2) | |
65 | - : "memory"); | |
66 | + : "r" (r0), "r" (r1), "r" (r2) | |
67 | + : "memory", "r3", "r12", "lr"); | |
68 | } | |
69 | ||
70 | static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr) |