arm64: nofpsimd: Handle TIF_FOREIGN_FPSTATE flag cleanly
commit 52f73c383b2418f2d31b798e765ae7d596c35021 upstream We detect the absence of FP/SIMD after an incapable CPU is brought up, and by then we have kernel threads running already with TIF_FOREIGN_FPSTATE set which could be set for early userspace applications (e.g, modprobe triggered from initramfs) and init. This could cause the applications to loop forever in do_nofity_resume() as we never clear the TIF flag, once we now know that we don't support FP. Fix this by making sure that we clear the TIF_FOREIGN_FPSTATE flag for tasks which may have them set, as we would have done in the normal case, but avoiding touching the hardware state (since we don't support any). Cc: stable@vger.kernel.org # v4.14 Cc: Will Deacon <will@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
06fb1c6d23
commit
afe95b7f56
@ -206,8 +206,19 @@ void fpsimd_preserve_current_state(void)
|
||||
*/
|
||||
void fpsimd_restore_current_state(void)
|
||||
{
|
||||
if (!system_supports_fpsimd())
|
||||
/*
|
||||
* For the tasks that were created before we detected the absence of
|
||||
* FP/SIMD, the TIF_FOREIGN_FPSTATE could be set via fpsimd_thread_switch(),
|
||||
* e.g, init. This could be then inherited by the children processes.
|
||||
* If we later detect that the system doesn't support FP/SIMD,
|
||||
* we must clear the flag for all the tasks to indicate that the
|
||||
* FPSTATE is clean (as we can't have one) to avoid looping for ever in
|
||||
* do_notify_resume().
|
||||
*/
|
||||
if (!system_supports_fpsimd()) {
|
||||
clear_thread_flag(TIF_FOREIGN_FPSTATE);
|
||||
return;
|
||||
}
|
||||
|
||||
local_bh_disable();
|
||||
|
||||
@ -229,7 +240,7 @@ void fpsimd_restore_current_state(void)
|
||||
*/
|
||||
void fpsimd_update_current_state(struct fpsimd_state *state)
|
||||
{
|
||||
if (!system_supports_fpsimd())
|
||||
if (WARN_ON(!system_supports_fpsimd()))
|
||||
return;
|
||||
|
||||
local_bh_disable();
|
||||
|
Loading…
x
Reference in New Issue
Block a user