aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 18:43:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 19:12:40 -0400
commitb30f3ae50cd03ef2ff433a5030fbf88dd8323528 (patch)
treeec140aa507d73eb5f4dfb8d46ccbd9dd80ca84e7
parentb5684b83b1e1579bbbc80e703e990c0cccf5892c (diff)
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>
-rw-r--r--arch/x86/kernel/signal_64.c53
-rw-r--r--include/asm-x86/i387.h54
2 files changed, 53 insertions, 54 deletions
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 47c3d249e638..b45ef8ddd651 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -53,6 +53,59 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
53 return do_sigaltstack(uss, uoss, regs->sp); 53 return do_sigaltstack(uss, uoss, regs->sp);
54} 54}
55 55
56/*
57 * Signal frame handlers.
58 */
59
60static 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 */
92static 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 * Do a signal return; undo the signal stack. 111 * Do a signal return; undo the signal stack.
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h
index 37672f79dcc8..96fa8449ff11 100644
--- a/include/asm-x86/i387.h
+++ b/include/asm-x86/i387.h
@@ -137,60 +137,6 @@ static inline void __save_init_fpu(struct task_struct *tsk)
137 task_thread_info(tsk)->status &= ~TS_USEDFPU; 137 task_thread_info(tsk)->status &= ~TS_USEDFPU;
138} 138}
139 139
140/*
141 * Signal frame handlers.
142 */
143
144static 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 */
176static 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#else /* CONFIG_X86_32 */ 140#else /* CONFIG_X86_32 */
195 141
196extern void finit(void); 142extern void finit(void);