svn commit: r227430 - head/sys/cddl/dev/dtrace/i386

Ryan Stone rstone at FreeBSD.org
Thu Nov 10 22:03:36 UTC 2011


Author: rstone
Date: Thu Nov 10 22:03:35 2011
New Revision: 227430
URL: http://svn.freebsd.org/changeset/base/227430

Log:
  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
  MFC after:	1 week

Modified:
  head/sys/cddl/dev/dtrace/i386/dtrace_asm.S

Modified: head/sys/cddl/dev/dtrace/i386/dtrace_asm.S
==============================================================================
--- head/sys/cddl/dev/dtrace/i386/dtrace_asm.S	Thu Nov 10 21:07:14 2011	(r227429)
+++ head/sys/cddl/dev/dtrace/i386/dtrace_asm.S	Thu Nov 10 22:03:35 2011	(r227430)
@@ -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:
 	/*


More information about the svn-src-all mailing list