Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 27 May 2012 00:38:36 +0000 (UTC)
From:      Ryan Stone <rstone@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r236133 - stable/8/sys/cddl/dev/dtrace/i386
Message-ID:  <201205270038.q4R0ca68016269@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rstone
Date: Sun May 27 00:38:36 2012
New Revision: 236133
URL: http://svn.freebsd.org/changeset/base/236133

Log:
  MFC 227430
  
   On i386, fbt probes are implemented by writing an invalid opcode over
   certain instructions in a function prologue or epilogue.  DTrace has a
   hook into the invalid opcode fault handler that checks whether the fault
   was due to an probe and if so, runs the DTrace magic.
  
   Upon returning from an invalid opcode fault caused by a probe, DTrace must
   emulate the instruction that was replaced with the invalid opcode and then
   return control to the instruction following the invalid opcode.
  
   There were a pair of related bugs in the emulation for the leave
   instruction.  The leave instruction is used to pop off a stack frame prior
   to returning from a function.  The emulation for this instruction must
   move the trap frame for the invalid opcode fault down the stack to the
   bottom of the stack frame that is being removed, and then execute an iret.
  
   At two points in this process, the emulation code was storing values above
   the current value of the stack pointer.  This opened up a window in which
   if we were two take an interrupt, the trap frame for the interrupt would
   overwrite the values stored on the stack, causing the system to panic
   later.
  
   The first bug was that at one point the emulation code saves the new value
   for $esp above the current stack pointer value.  The fix is to save this
   value instead inside of the original trap frame.  At this point we do
   not need the original trap frame so this is safe.
  
   The second bug is that when the emulate code loads $esp from the stack, it
   points part-way through the new trap frame instead of at its beginning.
   The emulation code adjusts the stack pointer to the correct value
   immediately afterwards, but this still leaves a one instruction window in
   which an interrupt would corrupt this trap frame.  Fix this by adjusting
   the stack frame value before loading it into $esp.
  
   This fixes panics in invop_leave on i386 when using fbt return probes.
  
   Reviewed by:  rpaulo, attilio

Modified:
  stable/8/sys/cddl/dev/dtrace/i386/dtrace_asm.S
Directory Properties:
  stable/8/sys/   (props changed)

Modified: stable/8/sys/cddl/dev/dtrace/i386/dtrace_asm.S
==============================================================================
--- stable/8/sys/cddl/dev/dtrace/i386/dtrace_asm.S	Sun May 27 00:34:56 2012	(r236132)
+++ stable/8/sys/cddl/dev/dtrace/i386/dtrace_asm.S	Sun May 27 00:38:36 2012	(r236133)
@@ -125,11 +125,11 @@ invop_leave:
 	movl	8(%esp), %eax		/* load calling EIP */
 	incl	%eax			/* increment over LOCK prefix */
 	movl	%eax, -8(%ebx)		/* store calling EIP */
-	movl	%ebx, -4(%esp)		/* temporarily store new %esp */
+	subl	$8, %ebx		/* adjust for three pushes, one pop */
+	movl	%ebx, 8(%esp)		/* temporarily store new %esp */
 	popl	%ebx			/* pop off temp */
 	popl	%eax			/* pop off temp */
-	movl	-12(%esp), %esp		/* set stack pointer */
-	subl	$8, %esp		/* adjust for three pushes, one pop */
+	movl	(%esp), %esp		/* set stack pointer */
 	iret				/* return from interrupt */
 invop_nop:
 	/*



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