ARC: fp: set FPU_STATUS.FWE to enable FPU_STATUS update on context switch
authorVineet Gupta <vgupta@synopsys.com>
Fri, 9 Jul 2021 00:13:48 +0000 (17:13 -0700)
committerVineet Gupta <vgupta@synopsys.com>
Wed, 4 Aug 2021 01:58:33 +0000 (18:58 -0700)
commit3a715e80400f452b247caa55344f4f60250ffbcf
tree4ed421bc57f72cde68bf116ab5dcc9ab4178ca64
parentbf79167fd86f3b97390fe2e70231d383526bd9cc
ARC: fp: set FPU_STATUS.FWE to enable FPU_STATUS update on context switch

FPU_STATUS register contains FP exception flags bits which are updated
by core as side-effect of FP instructions but can also be manually
wiggled such as by glibc C99 functions fe{raise,clear,test}except() etc.
To effect the update, the programming model requires OR'ing FWE
bit (31). This bit is write-only and RAZ, meaning it is effectively
auto-cleared after write and thus needs to be set everytime: which
is how glibc implements this.

However there's another usecase of FPU_STATUS update, at the time of
Linux task switch when incoming task value needs to be programmed into
the register. This was added as part of f45ba2bd6da0dc ("ARCv2:
fpu: preserve userspace fpu state") which missed OR'ing FWE bit,
meaning the new value is effectively not being written at all.
This patch remedies that.

Interestingly, this snafu was not caught in interm glibc testing as the
race window which relies on a specific exception bit to be set/clear is
really small specially when it nvolves context switch.
Fortunately this was caught by glibc's math/test-fenv-tls test which
repeatedly set/clear exception flags in a big loop, concurrently in main
program and also in a thread.

Fixes: https://github.com/foss-for-synopsys-dwc-arc-processors/linux/issues/54
Fixes: f45ba2bd6da0dc ("ARCv2: fpu: preserve userspace fpu state")
Cc: stable@vger.kernel.org #5.6+
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/kernel/fpu.c