[PATCH 3.13 115/187] MIPS: Remove BUG_ON(!is_fpu_owner()) in do_ade()

Kamal Mostafa kamal at canonical.com
Mon Sep 15 22:08:45 UTC 2014


3.13.11.7 -stable review patch.  If anyone has any objections, please let me know.

------------------

From: Huacai Chen <chenhc at lemote.com>

commit 2e5767a27337812f6850b3fa362419e2f085e5c3 upstream.

In do_ade(), is_fpu_owner() isn't preempt-safe. For example, when an
unaligned ldc1 is executed, do_cpu() is called and then FPU will be
enabled (and TIF_USEDFPU will be set for the current process). Then,
do_ade() is called because the access is unaligned.  If the current
process is preempted at this time, TIF_USEDFPU will be cleard.  So when
the process is scheduled again, BUG_ON(!is_fpu_owner()) is triggered.

This small program can trigger this BUG in a preemptible kernel:

int main (int argc, char *argv[])
{
        double u64[2];

        while (1) {
                asm volatile (
                        ".set push \n\t"
                        ".set noreorder \n\t"
                        "ldc1 $f3, 4(%0) \n\t"
                        ".set pop \n\t"
                        ::"r"(u64):
                );
        }

        return 0;
}

V2: Remove the BUG_ON() unconditionally due to Paul's suggestion.

Signed-off-by: Huacai Chen <chenhc at lemote.com>
Signed-off-by: Jie Chen <chenj at lemote.com>
Signed-off-by: Rui Wang <wangr at lemote.com>
Cc: John Crispin <john at phrozen.org>
Cc: Steven J. Hill <Steven.Hill at imgtec.com>
Cc: linux-mips at linux-mips.org
Cc: Fuxin Zhang <zhangfx at lemote.com>
Cc: Zhangjin Wu <wuzhangjin at gmail.com>
Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
 arch/mips/kernel/unaligned.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index c369a5d..b897dde 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -605,7 +605,6 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 	case sdc1_op:
 		die_if_kernel("Unaligned FP access in kernel code", regs);
 		BUG_ON(!used_math());
-		BUG_ON(!is_fpu_owner());
 
 		lose_fpu(1);	/* Save FPU state for the emulator. */
 		res = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
-- 
1.9.1





More information about the kernel-team mailing list