aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2014-01-24 20:31:26 -0800
committerH. Peter Anvin <hpa@zytor.com>2014-01-24 20:31:26 -0800
commitc830ba8d7d4f1653b36321c103c02251528e47d6 (patch)
tree3181eba42b614c70bb13980d4c4963243ece8700
parent45e09deb6a0a4fcb3a56efb7e18807b2800e358f (diff)
downloadklibc-c830ba8d7d4f1653b36321c103c02251528e47d6.tar.gz
[klibc] i386: use the vdso for system calls on i386
Use the system call entry point in the vdso for system calls on i386. The vdso can provide either int $0x80, sysenter or syscall depending on the CPU. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--usr/klibc/arch/i386/socketcall.S2
-rw-r--r--usr/klibc/arch/i386/syscall.S16
-rw-r--r--usr/klibc/arch/i386/vfork.S7
-rw-r--r--usr/klibc/libc_init.c9
4 files changed, 30 insertions, 4 deletions
diff --git a/usr/klibc/arch/i386/socketcall.S b/usr/klibc/arch/i386/socketcall.S
index a40cc02c0e1b98..44e2004d872658 100644
--- a/usr/klibc/arch/i386/socketcall.S
+++ b/usr/klibc/arch/i386/socketcall.S
@@ -32,7 +32,7 @@ __socketcall_common:
#endif
movl $__NR_socketcall,%eax
- int $0x80
+ call *__syscall_entry
#ifdef _REGPARM
addl $6*4, %esp
diff --git a/usr/klibc/arch/i386/syscall.S b/usr/klibc/arch/i386/syscall.S
index 0dd363b6857ff4..b7814e8f655d8d 100644
--- a/usr/klibc/arch/i386/syscall.S
+++ b/usr/klibc/arch/i386/syscall.S
@@ -37,7 +37,7 @@ __syscall_common:
#endif
.globl __syscall_common_tail
__syscall_common_tail:
- int $0x80
+ call *__syscall_entry
cmpl $-4095,%eax
@@ -66,3 +66,17 @@ __syscall_common_tail:
__syscall_varadic = __syscall_common
#endif
+
+ .align 4
+__syscall_int80:
+ int $0x80
+ ret
+ .type __syscall_int80,@function
+ .size __syscall_int80,.-__syscall_int80
+
+ .data
+ .align 4
+ .globl __syscall_entry
+__syscall_entry:
+ .long __syscall_int80
+ .size __syscall_entry,.-__syscall_entry
diff --git a/usr/klibc/arch/i386/vfork.S b/usr/klibc/arch/i386/vfork.S
index c98ba3a8a75355..d32b9b93dffafd 100644
--- a/usr/klibc/arch/i386/vfork.S
+++ b/usr/klibc/arch/i386/vfork.S
@@ -4,7 +4,10 @@
# vfork is nasty - there must be nothing at all on the stack above
# the stack frame of the enclosing function.
#
-
+# We *MUST* use int $0x80, because calling the vdso would screw up
+# our stack handling.
+#
+
#include <asm/unistd.h>
.text
@@ -14,7 +17,7 @@
vfork:
popl %edx /* Return address */
movl $__NR_vfork, %eax
- int $0x80
+ int $0x80 /* DO NOT call the vdso here! */
pushl %edx
cmpl $-4095, %eax
jae 1f
diff --git a/usr/klibc/libc_init.c b/usr/klibc/libc_init.c
index 1087f9532edf1c..1c6180b77680be 100644
--- a/usr/klibc/libc_init.c
+++ b/usr/klibc/libc_init.c
@@ -90,6 +90,15 @@ __noreturn __libc_init(uintptr_t * elfdata, void (*onexit) (void))
__page_size = page_size = __auxval[AT_PAGESZ];
+#ifdef __i386__
+ {
+ extern void (*__syscall_entry)(int, ...);
+ if (__auxval[AT_SYSINFO])
+ __syscall_entry = (void (*)(int, ...))
+ __auxval[AT_SYSINFO];
+ }
+#endif
+
#if __GNUC__ >= 4
/* unsigned int is 32 bits on all our architectures */
page_shift = __builtin_clz(page_size) ^ 31;