From 93b90712c64ca2db4b39fcb2e7dffcf0d478468d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 22 Apr 2015 12:50:13 +0200 Subject: x86/fpu: Move math_state_restore() to fpu/core.c It's another piece of FPU internals that is better off close to the other FPU internals. Reviewed-by: Borislav Petkov Cc: Andy Lutomirski Cc: Dave Hansen Cc: Fenghua Yu Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index 787bf57..7add2fb 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -227,6 +227,48 @@ static int fpu__unlazy_stopped(struct task_struct *child) return 0; } +/* + * 'math_state_restore()' saves the current math information in the + * old math state array, and gets the new ones from the current task + * + * Careful.. There are problems with IBM-designed IRQ13 behaviour. + * Don't touch unless you *really* know how it works. + * + * Must be called with kernel preemption disabled (eg with local + * local interrupts as in the case of do_device_not_available). + */ +void math_state_restore(void) +{ + struct task_struct *tsk = current; + + if (!tsk_used_math(tsk)) { + local_irq_enable(); + /* + * does a slab alloc which can sleep + */ + if (fpstate_alloc_init(tsk)) { + /* + * ran out of memory! + */ + do_group_exit(SIGKILL); + return; + } + local_irq_disable(); + } + + /* Avoid __kernel_fpu_begin() right after __thread_fpu_begin() */ + kernel_fpu_disable(); + __thread_fpu_begin(tsk); + if (unlikely(restore_fpu_checking(tsk))) { + fpu_reset_state(tsk); + force_sig_info(SIGSEGV, SEND_SIG_PRIV, tsk); + } else { + tsk->thread.fpu.counter++; + } + kernel_fpu_enable(); +} +EXPORT_SYMBOL_GPL(math_state_restore); + void fpu__flush_thread(struct task_struct *tsk) { if (!use_eager_fpu()) { diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 465b335..63c7fc3 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -826,48 +826,6 @@ asmlinkage __visible void __attribute__((weak)) smp_threshold_interrupt(void) { } -/* - * 'math_state_restore()' saves the current math information in the - * old math state array, and gets the new ones from the current task - * - * Careful.. There are problems with IBM-designed IRQ13 behaviour. - * Don't touch unless you *really* know how it works. - * - * Must be called with kernel preemption disabled (eg with local - * local interrupts as in the case of do_device_not_available). - */ -void math_state_restore(void) -{ - struct task_struct *tsk = current; - - if (!tsk_used_math(tsk)) { - local_irq_enable(); - /* - * does a slab alloc which can sleep - */ - if (fpstate_alloc_init(tsk)) { - /* - * ran out of memory! - */ - do_group_exit(SIGKILL); - return; - } - local_irq_disable(); - } - - /* Avoid __kernel_fpu_begin() right after __thread_fpu_begin() */ - kernel_fpu_disable(); - __thread_fpu_begin(tsk); - if (unlikely(restore_fpu_checking(tsk))) { - fpu_reset_state(tsk); - force_sig_info(SIGSEGV, SEND_SIG_PRIV, tsk); - } else { - tsk->thread.fpu.counter++; - } - kernel_fpu_enable(); -} -EXPORT_SYMBOL_GPL(math_state_restore); - dotraplinkage void do_device_not_available(struct pt_regs *regs, long error_code) { -- cgit v0.10.2