diff options
author | Andreas Schwab <schwab@linux-m68k.org> | 2015-09-23 17:12:09 -0400 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2015-09-28 03:59:45 -0400 |
commit | 8474ba74193d302e8340dddd1e16c85cc4b98caf (patch) | |
tree | f95d6e941e2f940e32cc711c2784062fb4cb5466 /arch | |
parent | 7f843dab134b7ce8804b67cca2271267d3a0213d (diff) |
m68k: Define asmlinkage_protect
Make sure the compiler does not modify arguments of syscall functions.
This can happen if the compiler generates a tailcall to another
function. For example, without asmlinkage_protect sys_openat is compiled
into this function:
sys_openat:
clr.l %d0
move.w 18(%sp),%d0
move.l %d0,16(%sp)
jbra do_sys_open
Note how the fourth argument is modified in place, modifying the register
%d4 that gets restored from this stack slot when the function returns to
user-space. The caller may expect the register to be unmodified across
system calls.
Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: stable@vger.kernel.org
Diffstat (limited to 'arch')
-rw-r--r-- | arch/m68k/include/asm/linkage.h | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/arch/m68k/include/asm/linkage.h b/arch/m68k/include/asm/linkage.h index 5a822bb790f7..066e74f666ae 100644 --- a/arch/m68k/include/asm/linkage.h +++ b/arch/m68k/include/asm/linkage.h | |||
@@ -4,4 +4,34 @@ | |||
4 | #define __ALIGN .align 4 | 4 | #define __ALIGN .align 4 |
5 | #define __ALIGN_STR ".align 4" | 5 | #define __ALIGN_STR ".align 4" |
6 | 6 | ||
7 | /* | ||
8 | * Make sure the compiler doesn't do anything stupid with the | ||
9 | * arguments on the stack - they are owned by the *caller*, not | ||
10 | * the callee. This just fools gcc into not spilling into them, | ||
11 | * and keeps it from doing tailcall recursion and/or using the | ||
12 | * stack slots for temporaries, since they are live and "used" | ||
13 | * all the way to the end of the function. | ||
14 | */ | ||
15 | #define asmlinkage_protect(n, ret, args...) \ | ||
16 | __asmlinkage_protect##n(ret, ##args) | ||
17 | #define __asmlinkage_protect_n(ret, args...) \ | ||
18 | __asm__ __volatile__ ("" : "=r" (ret) : "0" (ret), ##args) | ||
19 | #define __asmlinkage_protect0(ret) \ | ||
20 | __asmlinkage_protect_n(ret) | ||
21 | #define __asmlinkage_protect1(ret, arg1) \ | ||
22 | __asmlinkage_protect_n(ret, "m" (arg1)) | ||
23 | #define __asmlinkage_protect2(ret, arg1, arg2) \ | ||
24 | __asmlinkage_protect_n(ret, "m" (arg1), "m" (arg2)) | ||
25 | #define __asmlinkage_protect3(ret, arg1, arg2, arg3) \ | ||
26 | __asmlinkage_protect_n(ret, "m" (arg1), "m" (arg2), "m" (arg3)) | ||
27 | #define __asmlinkage_protect4(ret, arg1, arg2, arg3, arg4) \ | ||
28 | __asmlinkage_protect_n(ret, "m" (arg1), "m" (arg2), "m" (arg3), \ | ||
29 | "m" (arg4)) | ||
30 | #define __asmlinkage_protect5(ret, arg1, arg2, arg3, arg4, arg5) \ | ||
31 | __asmlinkage_protect_n(ret, "m" (arg1), "m" (arg2), "m" (arg3), \ | ||
32 | "m" (arg4), "m" (arg5)) | ||
33 | #define __asmlinkage_protect6(ret, arg1, arg2, arg3, arg4, arg5, arg6) \ | ||
34 | __asmlinkage_protect_n(ret, "m" (arg1), "m" (arg2), "m" (arg3), \ | ||
35 | "m" (arg4), "m" (arg5), "m" (arg6)) | ||
36 | |||
7 | #endif | 37 | #endif |