]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.16.3/mips-remove-bug_on-is_fpu_owner-in-do_ade.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.16.3 / mips-remove-bug_on-is_fpu_owner-in-do_ade.patch
CommitLineData
c8fb49aa
GKH
1From 2e5767a27337812f6850b3fa362419e2f085e5c3 Mon Sep 17 00:00:00 2001
2From: Huacai Chen <chenhc@lemote.com>
3Date: Wed, 16 Jul 2014 09:19:16 +0800
4Subject: MIPS: Remove BUG_ON(!is_fpu_owner()) in do_ade()
5
6From: Huacai Chen <chenhc@lemote.com>
7
8commit 2e5767a27337812f6850b3fa362419e2f085e5c3 upstream.
9
10In do_ade(), is_fpu_owner() isn't preempt-safe. For example, when an
11unaligned ldc1 is executed, do_cpu() is called and then FPU will be
12enabled (and TIF_USEDFPU will be set for the current process). Then,
13do_ade() is called because the access is unaligned. If the current
14process is preempted at this time, TIF_USEDFPU will be cleard. So when
15the process is scheduled again, BUG_ON(!is_fpu_owner()) is triggered.
16
17This small program can trigger this BUG in a preemptible kernel:
18
19int main (int argc, char *argv[])
20{
21 double u64[2];
22
23 while (1) {
24 asm volatile (
25 ".set push \n\t"
26 ".set noreorder \n\t"
27 "ldc1 $f3, 4(%0) \n\t"
28 ".set pop \n\t"
29 ::"r"(u64):
30 );
31 }
32
33 return 0;
34}
35
36V2: Remove the BUG_ON() unconditionally due to Paul's suggestion.
37
38Signed-off-by: Huacai Chen <chenhc@lemote.com>
39Signed-off-by: Jie Chen <chenj@lemote.com>
40Signed-off-by: Rui Wang <wangr@lemote.com>
41Cc: John Crispin <john@phrozen.org>
42Cc: Steven J. Hill <Steven.Hill@imgtec.com>
43Cc: linux-mips@linux-mips.org
44Cc: Fuxin Zhang <zhangfx@lemote.com>
45Cc: Zhangjin Wu <wuzhangjin@gmail.com>
46Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
47Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
48
49---
50 arch/mips/kernel/unaligned.c | 1 -
51 1 file changed, 1 deletion(-)
52
53--- a/arch/mips/kernel/unaligned.c
54+++ b/arch/mips/kernel/unaligned.c
55@@ -690,7 +690,6 @@ static void emulate_load_store_insn(stru
56 case sdc1_op:
57 die_if_kernel("Unaligned FP access in kernel code", regs);
58 BUG_ON(!used_math());
59- BUG_ON(!is_fpu_owner());
60
61 lose_fpu(1); /* Save FPU state for the emulator. */
62 res = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,