MIPS: Fix for warning from FPU emulation code

The default implementation of 'cpu_has_fpu' macro calls
smp_processor_id() which causes this warning to be printed when
preemption is enabled:

[    4.664000] Algorithmics/MIPS FPU Emulator v1.5
[    4.676000] BUG: using smp_processor_id() in preemptible [00000000] code: ini
[    4.700000] caller is fpu_emulator_cop1Handler+0x434/0x27b8

This problem got introduced in November 2009 by
af1d2af877ef6c36990671bc86a5b9c5bb50b1da (lmo) [MIPS: Fix emulation of
64-bit FPU on 64-bit CPUs.] rsp.  da0bac3341
(kernel.org) [MIPS: Fix emulation of 64-bit FPU on FPU-less 64-bit CPUs.]
in 2.6.32.

Fixed by rewriting cop1_64bit() to return a constant whenever possible
but most importantly avoid the use pf cpu_has_fpu entirely.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Reported-by: Jayachandran C <jchandra@broadcom.com>
Initial-patch-by: Jayachandran C <jchandra@broadcom.com>
Patchwork: https://patchwork.linux-mips.org/patch/4225/
This commit is contained in:
Ralf Baechle 2012-08-15 19:42:19 +02:00
parent 051ff44a8b
commit 51d943f07d

View File

@ -171,16 +171,17 @@ static int isBranchInstr(mips_instruction * i)
* In the Linux kernel, we support selection of FPR format on the
* basis of the Status.FR bit. If an FPU is not present, the FR bit
* is hardwired to zero, which would imply a 32-bit FPU even for
* 64-bit CPUs. For 64-bit kernels with no FPU we use TIF_32BIT_REGS
* as a proxy for the FR bit so that a 64-bit FPU is emulated. In any
* case, for a 32-bit kernel which uses the O32 MIPS ABI, only the
* even FPRs are used (Status.FR = 0).
* 64-bit CPUs so we rather look at TIF_32BIT_REGS.
* FPU emu is slow and bulky and optimizing this function offers fairly
* sizeable benefits so we try to be clever and make this function return
* a constant whenever possible, that is on 64-bit kernels without O32
* compatibility enabled and on 32-bit kernels.
*/
static inline int cop1_64bit(struct pt_regs *xcp)
{
if (cpu_has_fpu)
return xcp->cp0_status & ST0_FR;
#ifdef CONFIG_64BIT
#if defined(CONFIG_64BIT) && !defined(CONFIG_MIPS32_O32)
return 1;
#elif defined(CONFIG_64BIT) && defined(CONFIG_MIPS32_O32)
return !test_thread_flag(TIF_32BIT_REGS);
#else
return 0;