]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.10.34/x86-fpu-check-tsk_used_math-in-kernel_fpu_end-for-eager-fpu.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.10.34 / x86-fpu-check-tsk_used_math-in-kernel_fpu_end-for-eager-fpu.patch
1 From 731bd6a93a6e9172094a2322bd0ee964bb1f4d63 Mon Sep 17 00:00:00 2001
2 From: Suresh Siddha <sbsiddha@gmail.com>
3 Date: Sun, 2 Feb 2014 22:56:23 -0800
4 Subject: x86, fpu: Check tsk_used_math() in kernel_fpu_end() for eager FPU
5
6 From: Suresh Siddha <sbsiddha@gmail.com>
7
8 commit 731bd6a93a6e9172094a2322bd0ee964bb1f4d63 upstream.
9
10 For non-eager fpu mode, thread's fpu state is allocated during the first
11 fpu usage (in the context of device not available exception). This
12 (math_state_restore()) can be a blocking call and hence we enable
13 interrupts (which were originally disabled when the exception happened),
14 allocate memory and disable interrupts etc.
15
16 But the eager-fpu mode, call's the same math_state_restore() from
17 kernel_fpu_end(). The assumption being that tsk_used_math() is always
18 set for the eager-fpu mode and thus avoid the code path of enabling
19 interrupts, allocating fpu state using blocking call and disable
20 interrupts etc.
21
22 But the below issue was noticed by Maarten Baert, Nate Eldredge and
23 few others:
24
25 If a user process dumps core on an ecrypt fs while aesni-intel is loaded,
26 we get a BUG() in __find_get_block() complaining that it was called with
27 interrupts disabled; then all further accesses to our ecrypt fs hang
28 and we have to reboot.
29
30 The aesni-intel code (encrypting the core file that we are writing) needs
31 the FPU and quite properly wraps its code in kernel_fpu_{begin,end}(),
32 the latter of which calls math_state_restore(). So after kernel_fpu_end(),
33 interrupts may be disabled, which nobody seems to expect, and they stay
34 that way until we eventually get to __find_get_block() which barfs.
35
36 For eager fpu, most the time, tsk_used_math() is true. At few instances
37 during thread exit, signal return handling etc, tsk_used_math() might
38 be false.
39
40 In kernel_fpu_end(), for eager-fpu, call math_state_restore()
41 only if tsk_used_math() is set. Otherwise, don't bother. Kernel code
42 path which cleared tsk_used_math() knows what needs to be done
43 with the fpu state.
44
45 Reported-by: Maarten Baert <maarten-baert@hotmail.com>
46 Reported-by: Nate Eldredge <nate@thatsmathematics.com>
47 Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
48 Signed-off-by: Suresh Siddha <sbsiddha@gmail.com>
49 Link: http://lkml.kernel.org/r/1391410583.3801.6.camel@europa
50 Cc: George Spelvin <linux@horizon.com>
51 Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
52 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
53
54 ---
55 arch/x86/kernel/i387.c | 15 ++++++++++++---
56 1 file changed, 12 insertions(+), 3 deletions(-)
57
58 --- a/arch/x86/kernel/i387.c
59 +++ b/arch/x86/kernel/i387.c
60 @@ -86,10 +86,19 @@ EXPORT_SYMBOL(__kernel_fpu_begin);
61
62 void __kernel_fpu_end(void)
63 {
64 - if (use_eager_fpu())
65 - math_state_restore();
66 - else
67 + if (use_eager_fpu()) {
68 + /*
69 + * For eager fpu, most the time, tsk_used_math() is true.
70 + * Restore the user math as we are done with the kernel usage.
71 + * At few instances during thread exit, signal handling etc,
72 + * tsk_used_math() is false. Those few places will take proper
73 + * actions, so we don't need to restore the math here.
74 + */
75 + if (likely(tsk_used_math(current)))
76 + math_state_restore();
77 + } else {
78 stts();
79 + }
80 }
81 EXPORT_SYMBOL(__kernel_fpu_end);
82