Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Jun 2011 12:13:28 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r223254 - head/sys/amd64/ia32
Message-ID:  <201106181213.p5ICDSFu040577@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sat Jun 18 12:13:28 2011
New Revision: 223254
URL: http://svn.freebsd.org/changeset/base/223254

Log:
  Fix vfork. Add comments.

Modified:
  head/sys/amd64/ia32/ia32_sigtramp.S

Modified: head/sys/amd64/ia32/ia32_sigtramp.S
==============================================================================
--- head/sys/amd64/ia32/ia32_sigtramp.S	Sat Jun 18 12:13:27 2011	(r223253)
+++ head/sys/amd64/ia32/ia32_sigtramp.S	Sat Jun 18 12:13:28 2011	(r223254)
@@ -79,8 +79,20 @@ ia32_osigcode:
 	jmp	1b
 
 
+/*
+ * The lcall $7,$0 emulator cannot use the call gate that does an
+ * inter-privilege transition. The reason is that the call gate
+ * does not disable interrupts, and, before the swapgs is
+ * executed, we would have a window where the ring 0 code is
+ * executed with the wrong gsbase.
+ *
+ * Instead, reflect the lcall $7,$0 back to ring 3 trampoline
+ * which sets up the frame for int $0x80.
+ */
 	ALIGN_TEXT
 lcall_tramp:
+	cmpl	$SYS_vfork,%eax
+	je	2f
 	pushl	%ebp
 	movl	%esp,%ebp
 	pushl	0x24(%ebp) /* arg 6 */
@@ -91,8 +103,19 @@ lcall_tramp:
 	pushl	0x10(%ebp) /* arg 1 */
 	pushl	0xc(%ebp) /* gap */
 	int	$0x80
-	leave
+	leavel
+1:
 	lretl
+2:
+	/*
+	 * vfork handling is special and relies on the libc stub saving
+	 * the return ip in %ecx.  If vfork failed, then there is no
+	 * child which can corrupt the frame created by call gate.
+	 */
+	int	$0x80
+	jb	1b
+	addl	$8,%esp
+	jmpl	*%ecx
 #endif
 
 	ALIGN_TEXT



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106181213.p5ICDSFu040577>