forked from Minki/linux
MIPS: Fix MIPS64 FP save/restore on 32-bit kernels
32-bit kernels can be configured to support MIPS64, in which case neither CONFIG_64BIT or CONFIG_CPU_MIPS32_R* will be set. This causes the CP0_Status.FR checks at the point of floating point register save and restore to be compiled out, which results in odd FP registers not being saved or restored to the task or signal context even when CP0_Status.FR is set. Fix the ifdefs to use CONFIG_CPU_MIPSR2 and CONFIG_CPU_MIPSR6, which are enabled for the relevant revisions of either MIPS32 or MIPS64, along with some other CPUs such as Octeon (r2), Loongson1 (r2), XLP (r2), Loongson 3A R2. The suspect code originates from commit597ce1723e
("MIPS: Support for 64-bit FP with O32 binaries") in v3.14, however the code in __enable_fpu() was consistent and refused to set FR=1, falling back to software FPU emulation. This was suboptimal but should be functionally correct. Commitfcc53b5f6c
("MIPS: fpu.h: Allow 64-bit FPU on a 64-bit MIPS R6 CPU") in v4.2 (and stable tagged back to 4.0) later introduced the bug by updating __enable_fpu() to set FR=1 but failing to update the other similar ifdefs to enable FR=1 state handling. Fixes:fcc53b5f6c
("MIPS: fpu.h: Allow 64-bit FPU on a 64-bit MIPS R6 CPU") Signed-off-by: James Hogan <jhogan@kernel.org> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Paul Burton <paul.burton@imgtec.com> Cc: linux-mips@linux-mips.org Cc: <stable@vger.kernel.org> # 4.0+ Patchwork: https://patchwork.linux-mips.org/patch/16739/
This commit is contained in:
parent
37d15948eb
commit
22b8ba765a
@ -126,8 +126,8 @@
|
||||
.endm
|
||||
|
||||
.macro fpu_save_double thread status tmp
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
|
||||
defined(CONFIG_CPU_MIPS32_R6)
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
|
||||
defined(CONFIG_CPU_MIPSR6)
|
||||
sll \tmp, \status, 5
|
||||
bgez \tmp, 10f
|
||||
fpu_save_16odd \thread
|
||||
@ -184,8 +184,8 @@
|
||||
.endm
|
||||
|
||||
.macro fpu_restore_double thread status tmp
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
|
||||
defined(CONFIG_CPU_MIPS32_R6)
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
|
||||
defined(CONFIG_CPU_MIPSR6)
|
||||
sll \tmp, \status, 5
|
||||
bgez \tmp, 10f # 16 register mode?
|
||||
|
||||
|
@ -40,8 +40,8 @@
|
||||
*/
|
||||
LEAF(_save_fp)
|
||||
EXPORT_SYMBOL(_save_fp)
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
|
||||
defined(CONFIG_CPU_MIPS32_R6)
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
|
||||
defined(CONFIG_CPU_MIPSR6)
|
||||
mfc0 t0, CP0_STATUS
|
||||
#endif
|
||||
fpu_save_double a0 t0 t1 # clobbers t1
|
||||
@ -52,8 +52,8 @@ EXPORT_SYMBOL(_save_fp)
|
||||
* Restore a thread's fp context.
|
||||
*/
|
||||
LEAF(_restore_fp)
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
|
||||
defined(CONFIG_CPU_MIPS32_R6)
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
|
||||
defined(CONFIG_CPU_MIPSR6)
|
||||
mfc0 t0, CP0_STATUS
|
||||
#endif
|
||||
fpu_restore_double a0 t0 t1 # clobbers t1
|
||||
@ -246,11 +246,11 @@ LEAF(_save_fp_context)
|
||||
cfc1 t1, fcr31
|
||||
.set pop
|
||||
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
|
||||
defined(CONFIG_CPU_MIPS32_R6)
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
|
||||
defined(CONFIG_CPU_MIPSR6)
|
||||
.set push
|
||||
SET_HARDFLOAT
|
||||
#ifdef CONFIG_CPU_MIPS32_R2
|
||||
#ifdef CONFIG_CPU_MIPSR2
|
||||
.set mips32r2
|
||||
.set fp=64
|
||||
mfc0 t0, CP0_STATUS
|
||||
@ -314,11 +314,11 @@ LEAF(_save_fp_context)
|
||||
LEAF(_restore_fp_context)
|
||||
EX lw t1, 0(a1)
|
||||
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
|
||||
defined(CONFIG_CPU_MIPS32_R6)
|
||||
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
|
||||
defined(CONFIG_CPU_MIPSR6)
|
||||
.set push
|
||||
SET_HARDFLOAT
|
||||
#ifdef CONFIG_CPU_MIPS32_R2
|
||||
#ifdef CONFIG_CPU_MIPSR2
|
||||
.set mips32r2
|
||||
.set fp=64
|
||||
mfc0 t0, CP0_STATUS
|
||||
|
Loading…
Reference in New Issue
Block a user