aboutsummaryrefslogtreecommitdiff
path: root/sys/riscv
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2016-02-12 12:38:04 +0000
committerAndrew Turner <andrew@FreeBSD.org>2016-02-12 12:38:04 +0000
commit770fd1c976d93312b58c2017cf51685ea8946b5a (patch)
tree95a1a95950225bb3b8d447662016224986ce3ccb /sys/riscv
parentc85285a96b1a6de70557d2953267b927ebf3cc08 (diff)
downloadsrc-770fd1c976d93312b58c2017cf51685ea8946b5a.tar.gz
src-770fd1c976d93312b58c2017cf51685ea8946b5a.zip
Only update curthread and curpcb after we have finished using the old
values. If switching from a thread that used floating-point registers to a thread that is still running, but holding the blocked_lock lock we would switch the curthread to the new (running) thread, then call critical_enter. This will non-atomically increment td_critnest, and later call critical_exit to non-atomically decrement this value. This can happen at the same time as the new thread is still running on the old core, also calling these functions. In this case there will be a race between these non-atomic operations. This can be an issue as we could loose one of these operations leading to the value to not return to zero. If, later on, we then hit a data abort we check if the td_critnest is zero. If this check fails we will panic the kernel. This has been observed when running pcmstat on a Cavium ThunderX. The pcm thread will use the blocked_lock lock and there is a high chance userspace will use the floating-point registers. When, later on, pmcstat triggers a data abort we will hit this panic. The fix is to update these values after storing the floating-point state. This means we use the correct curthread while storing the state so it will not be an issue that the changes to td_critnest are non-atomic. Sponsored by: ABT Systems Ltd
Notes
Notes: svn path=/head/; revision=295563
Diffstat (limited to 'sys/riscv')
0 files changed, 0 insertions, 0 deletions