[klibc] [klibc:master] i386: use the vdso for system calls on i386

klibc-bot for H. Peter Anvin hpa at zytor.com
Fri Jan 24 20:36:04 PST 2014


Commit-ID:  c830ba8d7d4f1653b36321c103c02251528e47d6
Gitweb:     http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=c830ba8d7d4f1653b36321c103c02251528e47d6
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Fri, 24 Jan 2014 20:31:26 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Fri, 24 Jan 2014 20:31:26 -0800

[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 at zytor.com>

---
 usr/klibc/arch/i386/socketcall.S |  2 +-
 usr/klibc/arch/i386/syscall.S    | 16 +++++++++++++++-
 usr/klibc/arch/i386/vfork.S      |  7 +++++--
 usr/klibc/libc_init.c            |  9 +++++++++
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/usr/klibc/arch/i386/socketcall.S b/usr/klibc/arch/i386/socketcall.S
index a40cc02..44e2004 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 0dd363b..b7814e8 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, at 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 c98ba3a..d32b9b9 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 1087f95..1c6180b 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;


More information about the klibc mailing list