x86-64: Clean up 'save/restore_i387()' usage

Suresh Siddha wants to fix a possible FPU leakage in error conditions,
but the fact that save/restore_i387() are inlines in a header file makes
that harder to do than necessary. So start off with an obvious cleanup.

This just moves the x86-64 version of save/restore_i387() out of the
header file, and moves it to the only file that it is actually used in:
arch/x86/kernel/signal_64.c. So exposing it in a header file was wrong
to begin with.

[ Side note: I'd like to fix up some of the games we play with the
32-bit version of these functions too, but that's a separate
matter. The 32-bit versions are shared - under different names
at that! - by both the native x86-32 code and the x86-64 32-bit
compatibility code ]

Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

+53 -54
+53
arch/x86/kernel/signal_64.c
··· 53 53 return do_sigaltstack(uss, uoss, regs->sp); 54 54 } 55 55 56 + /* 57 + * Signal frame handlers. 58 + */ 59 + 60 + static inline int save_i387(struct _fpstate __user *buf) 61 + { 62 + struct task_struct *tsk = current; 63 + int err = 0; 64 + 65 + BUILD_BUG_ON(sizeof(struct user_i387_struct) != 66 + sizeof(tsk->thread.xstate->fxsave)); 67 + 68 + if ((unsigned long)buf % 16) 69 + printk("save_i387: bad fpstate %p\n", buf); 70 + 71 + if (!used_math()) 72 + return 0; 73 + clear_used_math(); /* trigger finit */ 74 + if (task_thread_info(tsk)->status & TS_USEDFPU) { 75 + err = save_i387_checking((struct i387_fxsave_struct __user *) 76 + buf); 77 + if (err) 78 + return err; 79 + task_thread_info(tsk)->status &= ~TS_USEDFPU; 80 + stts(); 81 + } else { 82 + if (__copy_to_user(buf, &tsk->thread.xstate->fxsave, 83 + sizeof(struct i387_fxsave_struct))) 84 + return -1; 85 + } 86 + return 1; 87 + } 88 + 89 + /* 90 + * This restores directly out of user space. Exceptions are handled. 91 + */ 92 + static inline int restore_i387(struct _fpstate __user *buf) 93 + { 94 + struct task_struct *tsk = current; 95 + int err; 96 + 97 + if (!used_math()) { 98 + err = init_fpu(tsk); 99 + if (err) 100 + return err; 101 + } 102 + 103 + if (!(task_thread_info(current)->status & TS_USEDFPU)) { 104 + clts(); 105 + task_thread_info(current)->status |= TS_USEDFPU; 106 + } 107 + return restore_fpu_checking((__force struct i387_fxsave_struct *)buf); 108 + } 56 109 57 110 /* 58 111 * Do a signal return; undo the signal stack.
-54
include/asm-x86/i387.h
··· 137 137 task_thread_info(tsk)->status &= ~TS_USEDFPU; 138 138 } 139 139 140 - /* 141 - * Signal frame handlers. 142 - */ 143 - 144 - static inline int save_i387(struct _fpstate __user *buf) 145 - { 146 - struct task_struct *tsk = current; 147 - int err = 0; 148 - 149 - BUILD_BUG_ON(sizeof(struct user_i387_struct) != 150 - sizeof(tsk->thread.xstate->fxsave)); 151 - 152 - if ((unsigned long)buf % 16) 153 - printk("save_i387: bad fpstate %p\n", buf); 154 - 155 - if (!used_math()) 156 - return 0; 157 - clear_used_math(); /* trigger finit */ 158 - if (task_thread_info(tsk)->status & TS_USEDFPU) { 159 - err = save_i387_checking((struct i387_fxsave_struct __user *) 160 - buf); 161 - if (err) 162 - return err; 163 - task_thread_info(tsk)->status &= ~TS_USEDFPU; 164 - stts(); 165 - } else { 166 - if (__copy_to_user(buf, &tsk->thread.xstate->fxsave, 167 - sizeof(struct i387_fxsave_struct))) 168 - return -1; 169 - } 170 - return 1; 171 - } 172 - 173 - /* 174 - * This restores directly out of user space. Exceptions are handled. 175 - */ 176 - static inline int restore_i387(struct _fpstate __user *buf) 177 - { 178 - struct task_struct *tsk = current; 179 - int err; 180 - 181 - if (!used_math()) { 182 - err = init_fpu(tsk); 183 - if (err) 184 - return err; 185 - } 186 - 187 - if (!(task_thread_info(current)->status & TS_USEDFPU)) { 188 - clts(); 189 - task_thread_info(current)->status |= TS_USEDFPU; 190 - } 191 - return restore_fpu_checking((__force struct i387_fxsave_struct *)buf); 192 - } 193 - 194 140 #else /* CONFIG_X86_32 */ 195 141 196 142 extern void finit(void);