diff options
Diffstat (limited to 'arch/x86/kernel/traps_64.c')
-rw-r--r-- | arch/x86/kernel/traps_64.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index dc0cb497eec3..adff76ea97c4 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c | |||
@@ -1124,10 +1124,23 @@ asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void) | |||
1124 | asmlinkage void math_state_restore(void) | 1124 | asmlinkage void math_state_restore(void) |
1125 | { | 1125 | { |
1126 | struct task_struct *me = current; | 1126 | struct task_struct *me = current; |
1127 | clts(); /* Allow maths ops (or we recurse) */ | ||
1128 | 1127 | ||
1129 | if (!used_math()) | 1128 | if (!used_math()) { |
1130 | init_fpu(me); | 1129 | local_irq_enable(); |
1130 | /* | ||
1131 | * does a slab alloc which can sleep | ||
1132 | */ | ||
1133 | if (init_fpu(me)) { | ||
1134 | /* | ||
1135 | * ran out of memory! | ||
1136 | */ | ||
1137 | do_group_exit(SIGKILL); | ||
1138 | return; | ||
1139 | } | ||
1140 | local_irq_disable(); | ||
1141 | } | ||
1142 | |||
1143 | clts(); /* Allow maths ops (or we recurse) */ | ||
1131 | restore_fpu_checking(&me->thread.xstate->fxsave); | 1144 | restore_fpu_checking(&me->thread.xstate->fxsave); |
1132 | task_thread_info(me)->status |= TS_USEDFPU; | 1145 | task_thread_info(me)->status |= TS_USEDFPU; |
1133 | me->fpu_counter++; | 1146 | me->fpu_counter++; |