aboutsummaryrefslogtreecommitdiff
path: root/arch/um/kernel
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2005-12-18 17:50:39 +0100
committerLinus Torvalds <torvalds@g5.osdl.org>2005-12-18 11:19:44 -0800
commit5b7b15afee89d6940482259b54d0864b7b2302b0 (patch)
treea3294a2c1f14ff4ebc9d645189ad12070529a639 /arch/um/kernel
parent76c842d8f8096e2c98ff9ebe1db861363ff254e5 (diff)
[PATCH] uml skas0: stop gcc's insanity
With Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> UML skas0 stub has been miscompiling for many people (incidentally not the authors), depending on the used GCC versions. I think (and testing on some GCC versions shows) this patch avoids the fundamental issue which is behind this, namely gcc using the stack when we have just replaced it, behind gcc's back. The remapping and storage of the return value is hidden in a blob of asm, hopefully giving gcc no room for creativity. Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/skas/clone.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
index cb37ce9124a..47b812b3bca 100644
--- a/arch/um/kernel/skas/clone.c
+++ b/arch/um/kernel/skas/clone.c
@@ -18,11 +18,10 @@
* on some systems.
*/
-#define STUB_DATA(field) (((struct stub_data *) UML_CONFIG_STUB_DATA)->field)
-
void __attribute__ ((__section__ (".__syscall_stub")))
stub_clone_handler(void)
{
+ struct stub_data *data = (struct stub_data *) UML_CONFIG_STUB_DATA;
long err;
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
@@ -35,17 +34,21 @@ stub_clone_handler(void)
if(err)
goto out;
- err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL,
- (long) &STUB_DATA(timer), 0);
+ err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL,
+ (long) &data->timer, 0);
if(err)
goto out;
- err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA,
- UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
- MAP_FIXED | MAP_SHARED, STUB_DATA(fd),
- STUB_DATA(offset));
+ remap_stack(data->fd, data->offset);
+ goto done;
+
out:
- /* save current result. Parent: pid; child: retcode of mmap */
- STUB_DATA(err) = err;
+ /* save current result.
+ * Parent: pid;
+ * child: retcode of mmap already saved and it jumps around this
+ * assignment
+ */
+ data->err = err;
+ done:
trap_myself();
}