]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/commit
Make sure the psr field in the trapframe (which holds the value of cr.ipsr)
authormarcel <marcel@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Mon, 25 Aug 2014 15:15:59 +0000 (15:15 +0000)
committermarcel <marcel@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Mon, 25 Aug 2014 15:15:59 +0000 (15:15 +0000)
commit26ef0d3eae58d32b3e2e0100214422c2d7d79fed
treece118c0ce4b16bb0bef534a9c34cbc342745dbd9
parentf7f0b62c6a62b2295ee4d13b914b2d12bc45f326
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!

git-svn-id: svn://svn.freebsd.org/base/stable/10@270573 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
sys/ia64/ia64/syscall.S