The prevent_tail_call() macro works around the problem of the compiler
clobbering argument words on the stack, which for asmlinkage functions
is the caller's (user's) struct pt_regs. The tail/sibling-call
optimization is not the only way that the compiler can decide to use
stack argument words as scratch space, which we have to prevent.
Other optimizations can do it too.Until we have new compiler support to make "asmlinkage" binding on the
compiler's own use of the stack argument frame, we have work around all
the manifestations of this issue that crop up.More cases seem to be prevented by also keeping the incoming argument
variables live at the end of the function. This makes their original
stack slots attractive places to leave those variables, so the compiler
tends not clobber them for something else. It's still no guarantee, but
it handles some observed cases that prevent_tail_call() did not.Signed-off-by: Roland McGrath <roland@redhat.com>
---
arch/x86/kernel/tls.c | 4 ++--
fs/open.c | 8 ++++----
include/asm-x86/linkage.h | 24 +++++++++++++++++++++++-
include/linux/linkage.h | 4 ++--
kernel/exit.c | 4 ++--
kernel/uid16.c | 22 +++++++++++-----------
6 files changed, 44 insertions(+), 22 deletions(-)diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
index 022bcaa..ab6bf37 100644
--- a/arch/x86/kernel/tls.c
+++ b/arch/x86/kernel/tls.c
@@ -92,7 +92,7 @@ int do_set_thread_area(struct task_struct *p, int idx,
asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
{
int ret = do_set_thread_area(current, -1, u_info, 1);
- prevent_tail_call(ret);
+ asmlinkage_protect(1, ret, u_info);
return ret;
}@@ -142,7 +142,7 @@ int do_get_thread_area(struct task_struct *p, int idx,
asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
{
int ret = do_get_thread_area(current, -1, u_info);
- prevent_tail_call(ret);
+ asmlinkage_protect(1, ret, u_info);
...
From: Heiko Carstens <heiko.carstens@de.ibm.com>
git commit 54a015104136974262afa4b8ddd943ea70dec8a2
"asmlinkage_protect replaces prevent_tail_call" causes this build failure
on s390:AS arch/s390/kernel/entry64.o
In file included from arch/s390/kernel/entry64.S:14:
include/linux/linkage.h:34: error: syntax error in macro parameter list
make[1]: *** [arch/s390/kernel/entry64.o] Error 1
make: *** [arch/s390/kernel] Error 2So just surround the new define with an #ifndef __ASSEMBLY__ to prevent
any side effects on asm code.Cc: Roland McGrath <roland@redhat.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---
include/linux/linkage.h | 2 ++
1 file changed, 2 insertions(+)Index: linux-2.6/include/linux/linkage.h
===================================================================
--- linux-2.6.orig/include/linux/linkage.h
+++ linux-2.6/include/linux/linkage.h
@@ -30,9 +30,11 @@
* protection to work (ie no more work that the compiler might
* end up needing stack temporaries for).
*/
+#ifndef __ASSEMBLY__
#ifndef asmlinkage_protect
# define asmlinkage_protect(n, ret, args...) do { } while (0)
#endif
+#endif#ifndef __ALIGN
#define __ALIGN .align 4,0x90
--
There are no side effects on asm code. It just adds a #define that
obviously won't be used.Is the s390 assembler using some strange C pre-processor that is different
from the main C preprocessor and doesn't understand this pattern?I really think you should fix *that*, because otherwise you'll hit these
kinds of bugs occasionally. There aren't that many asm files, it's not
worth it optimizing them to use some faster-but-stupider preprocessor.Linus
--
FWIW, at least m68k and m32r cross-builds hit the same. I think I've a very
good guess about the reasons:
arch/m32r/kernel/Makefile:EXTRA_AFLAGS := -traditional
arch/m68k/fpsp040/Makefile:EXTRA_AFLAGS := -traditional
arch/m68k/ifpsp060/Makefile:EXTRA_AFLAGS := -traditional
arch/m68k/kernel/Makefile:EXTRA_AFLAGS := -traditional
arch/m68k/lib/Makefile:EXTRA_AFLAGS := -traditional
arch/m68k/math-emu/Makefile:EXTRA_AFLAGS := -traditional
arch/parisc/kernel/Makefile:AFLAGS_entry.o := -traditional
arch/parisc/kernel/Makefile:AFLAGS_pacache.o := -traditional
arch/s390/kernel/Makefile:EXTRA_AFLAGS := -traditional
arch/s390/lib/Makefile:EXTRA_AFLAGS := -traditional
arch/s390/math-emu/Makefile:EXTRA_AFLAGS := -traditionaland that gets us -traditional-cpp passed to cc1, with obvious resulting
unhappiness from vararg macro.
--
Yeah, I figured it out eventually.
I do think the architectures should try to avoid it, if only because x86
doesn't use -traditional (so they'll hit things like this unnecessarily
otherwise), but I'll apply Heiko's minimal patch in the meantime.Linus
--
Cool with me; I'll try to puzzle out why removing -traditional breaks on
those two specific files. Ugh, big cleanups likely.cheers, Kyle
--
So there is at least one architecture that really requires -traditional,
it is not an option to just remove them. For s390 the kernel compiles
fine without -traditional on the AFLAGS so we can as well remove them.
I'll queue the patch below. In the meantime Heikos patch will have to
do.--
blue skies,
Martin."Reality continues to ruin my life." - Calvin.
---
[PATCH] s390: remove -traditional from AFLAGSFrom: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 4d3e383..cfb6ccc 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#-EXTRA_AFLAGS := -traditional
+EXTRA_AFLAGS :=#
# Passing null pointers is ok for smp code, since we access the lowcore here.
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index 5208443..dd6f9f5 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -2,7 +2,7 @@
# Makefile for s390-specific library files..
#-EXTRA_AFLAGS := -traditional
+EXTRA_AFLAGS :=lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
obj-$(CONFIG_32BIT) += div64.o qrnnd.o
diff --git a/arch/s390/math-emu/Makefile b/arch/s390/math-emu/Makefile
index 73b3e72..42828d3 100644
--- a/arch/s390/math-emu/Makefile
+++ b/arch/s390/math-emu/Makefile
@@ -5,4 +5,4 @@
obj-$(CONFIG_MATHEMU) := math.oEXTRA_CFLAGS := -I$(src) -Iinclude/math-emu -w
-EXTRA_AFLAGS := -traditional
+EXTRA_AFLAGS :=--
You can simply ditch the line.
cu
Adrian--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed--
Not if (some) kernel assembly files are preprocessed with -traditional-cpp
or -traditional, which supports neither GNU style arg... nor
ISO C99 ... + __VA_ARGS__ vararg macros.Jakub
--
