Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Aug 2014 15:15:59 +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-10@freebsd.org
Subject:   svn commit: r270573 - stable/10/sys/ia64/ia64
Message-ID:  <201408251515.s7PFFxPO054376@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marcel
Date: Mon Aug 25 15:15:59 2014
New Revision: 270573
URL: http://svnweb.freebsd.org/changeset/base/270573

Log:
  Make sure the psr field in the trapframe (which holds the value of cr.ipsr)
  is properly synthesized for the EPC syscall. Properly synthesized in this
  case means that the bank number (BN bitfield) is set to 1. This is needed
  because the move-from-PSR instruction does copy all bits! In this case
  the BN bitfield was not copied.
  
  While normally this is not a problem, because when we leave the kernel via
  the EPC syscall path again, we don't actually care about the BN bitfield.
  We restore PSR with a move-to-PSR instruction, which also doesn't cover
  the BN bitfield.
  
  There is however a scenario where we enter the kernel via the EPC syscall
  path and leave the kernel via the exception/interrupt path. That path
  uses the RFI (Return-From-Interrupt) instruction and it restores all bits.
  What happens in that case is that we don't properly switch to register
  bank 1 and any exception/interrupt that happens while running in bank 0
  clobbers the process' (or kernel's) banked registers. This is because the
  CPU switches to bank 0 on an exception/interrupt so that there are 16
  general registers available for constructing a trapframe and saving the
  context. Consequently: normal code should always use register bank 1.
  
  This bug has been present since 2003 (11 years) and has been the cause
  for many "unexplained" kernel panics. It says something about how often
  we hit this problem on the one hand and how tricky it was to find it.
  
  Many thanks to: clusteradm@ for enabling me to track this down!

Modified:
  stable/10/sys/ia64/ia64/syscall.S

Modified: stable/10/sys/ia64/ia64/syscall.S
==============================================================================
--- stable/10/sys/ia64/ia64/syscall.S	Mon Aug 25 14:58:36 2014	(r270572)
+++ stable/10/sys/ia64/ia64/syscall.S	Mon Aug 25 15:15:59 2014	(r270573)
@@ -296,7 +296,7 @@ ENTRY_NOPROFILE(epc_syscall, 8)
 {	.mmi
 	st8		[r30]=r19,16		// rnat
 	st8		[r31]=r0,16		// __spare
-	nop		0
+	dep		r11=-1,r11,44,1		// Set psr.bn=1
 	;;
 }
 {	.mmi



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