Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Mar 2012 05:45:22 +0000 (UTC)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r233076 - in stable/9/sys: cddl/dev/dtrace/i386 i386/conf
Message-ID:  <201203170545.q2H5jM1N052695@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marcel
Date: Sat Mar 17 05:45:21 2012
New Revision: 233076
URL: http://svn.freebsd.org/changeset/base/233076

Log:
  MFC r227430:
  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.
  
  Ok'd by: rstone

Modified:
  stable/9/sys/cddl/dev/dtrace/i386/dtrace_asm.S
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/amd64/include/xen/   (props changed)
  stable/9/sys/boot/   (props changed)
  stable/9/sys/boot/i386/efi/   (props changed)
  stable/9/sys/boot/ia64/efi/   (props changed)
  stable/9/sys/boot/ia64/ski/   (props changed)
  stable/9/sys/boot/powerpc/boot1.chrp/   (props changed)
  stable/9/sys/boot/powerpc/ofw/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)
  stable/9/sys/conf/   (props changed)
  stable/9/sys/contrib/dev/acpica/   (props changed)
  stable/9/sys/contrib/octeon-sdk/   (props changed)
  stable/9/sys/contrib/pf/   (props changed)
  stable/9/sys/contrib/x86emu/   (props changed)
  stable/9/sys/fs/ntfs/   (props changed)
  stable/9/sys/i386/conf/XENHVM   (props changed)

Modified: stable/9/sys/cddl/dev/dtrace/i386/dtrace_asm.S
==============================================================================
--- stable/9/sys/cddl/dev/dtrace/i386/dtrace_asm.S	Sat Mar 17 03:31:11 2012	(r233075)
+++ stable/9/sys/cddl/dev/dtrace/i386/dtrace_asm.S	Sat Mar 17 05:45:21 2012	(r233076)
@@ -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?201203170545.q2H5jM1N052695>