diff options
author | Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> | 2009-02-27 13:29:57 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-02-28 03:17:30 -0500 |
commit | 75779f05264b9968d7ae7ecb4ca5127b08785692 (patch) | |
tree | 7c82dd08542be74c324a59a68f4f53feac927c4c /arch/x86/kernel/signal.c | |
parent | 36a4526583ad61fe7cb7432f53bce52ea198813a (diff) |
x86: signal: unify get_sigframe()
Impact: cleanup
Unify get_sigframe().
Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/signal.c')
-rw-r--r-- | arch/x86/kernel/signal.c | 97 |
1 files changed, 41 insertions, 56 deletions
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 89ef90df985f..53425c681f2b 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -187,28 +187,6 @@ setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate, | |||
187 | /* | 187 | /* |
188 | * Set up a signal frame. | 188 | * Set up a signal frame. |
189 | */ | 189 | */ |
190 | #ifdef CONFIG_X86_32 | ||
191 | static const struct { | ||
192 | u16 poplmovl; | ||
193 | u32 val; | ||
194 | u16 int80; | ||
195 | } __attribute__((packed)) retcode = { | ||
196 | 0xb858, /* popl %eax; movl $..., %eax */ | ||
197 | __NR_sigreturn, | ||
198 | 0x80cd, /* int $0x80 */ | ||
199 | }; | ||
200 | |||
201 | static const struct { | ||
202 | u8 movl; | ||
203 | u32 val; | ||
204 | u16 int80; | ||
205 | u8 pad; | ||
206 | } __attribute__((packed)) rt_retcode = { | ||
207 | 0xb8, /* movl $..., %eax */ | ||
208 | __NR_rt_sigreturn, | ||
209 | 0x80cd, /* int $0x80 */ | ||
210 | 0 | ||
211 | }; | ||
212 | 190 | ||
213 | /* | 191 | /* |
214 | * Determine which stack to use.. | 192 | * Determine which stack to use.. |
@@ -217,10 +195,13 @@ static inline void __user * | |||
217 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, | 195 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, |
218 | void __user **fpstate) | 196 | void __user **fpstate) |
219 | { | 197 | { |
220 | unsigned long sp; | ||
221 | |||
222 | /* Default to using normal stack */ | 198 | /* Default to using normal stack */ |
223 | sp = regs->sp; | 199 | unsigned long sp = regs->sp; |
200 | |||
201 | #ifdef CONFIG_X86_64 | ||
202 | /* redzone */ | ||
203 | sp -= 128; | ||
204 | #endif /* CONFIG_X86_64 */ | ||
224 | 205 | ||
225 | /* | 206 | /* |
226 | * If we are on the alternate signal stack and would overflow it, don't. | 207 | * If we are on the alternate signal stack and would overflow it, don't. |
@@ -234,30 +215,64 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, | |||
234 | if (sas_ss_flags(sp) == 0) | 215 | if (sas_ss_flags(sp) == 0) |
235 | sp = current->sas_ss_sp + current->sas_ss_size; | 216 | sp = current->sas_ss_sp + current->sas_ss_size; |
236 | } else { | 217 | } else { |
218 | #ifdef CONFIG_X86_32 | ||
237 | /* This is the legacy signal stack switching. */ | 219 | /* This is the legacy signal stack switching. */ |
238 | if ((regs->ss & 0xffff) != __USER_DS && | 220 | if ((regs->ss & 0xffff) != __USER_DS && |
239 | !(ka->sa.sa_flags & SA_RESTORER) && | 221 | !(ka->sa.sa_flags & SA_RESTORER) && |
240 | ka->sa.sa_restorer) | 222 | ka->sa.sa_restorer) |
241 | sp = (unsigned long) ka->sa.sa_restorer; | 223 | sp = (unsigned long) ka->sa.sa_restorer; |
224 | #endif /* CONFIG_X86_32 */ | ||
242 | } | 225 | } |
243 | 226 | ||
244 | if (used_math()) { | 227 | if (used_math()) { |
245 | sp = sp - sig_xstate_size; | 228 | sp -= sig_xstate_size; |
229 | #ifdef CONFIG_X86_32 | ||
246 | *fpstate = (void __user *) sp; | 230 | *fpstate = (void __user *) sp; |
231 | #else /* !CONFIG_X86_32 */ | ||
232 | *fpstate = (void __user *)round_down(sp, 64); | ||
233 | #endif /* CONFIG_X86_32 */ | ||
234 | |||
247 | if (save_i387_xstate(*fpstate) < 0) | 235 | if (save_i387_xstate(*fpstate) < 0) |
248 | return (void __user *)-1L; | 236 | return (void __user *)-1L; |
249 | } | 237 | } |
250 | 238 | ||
251 | sp -= frame_size; | 239 | sp -= frame_size; |
240 | #ifdef CONFIG_X86_32 | ||
252 | /* | 241 | /* |
253 | * Align the stack pointer according to the i386 ABI, | 242 | * Align the stack pointer according to the i386 ABI, |
254 | * i.e. so that on function entry ((sp + 4) & 15) == 0. | 243 | * i.e. so that on function entry ((sp + 4) & 15) == 0. |
255 | */ | 244 | */ |
256 | sp = ((sp + 4) & -16ul) - 4; | 245 | sp = ((sp + 4) & -16ul) - 4; |
246 | #else /* !CONFIG_X86_32 */ | ||
247 | sp = round_down(sp, 16) - 8; | ||
248 | #endif | ||
257 | 249 | ||
258 | return (void __user *) sp; | 250 | return (void __user *) sp; |
259 | } | 251 | } |
260 | 252 | ||
253 | #ifdef CONFIG_X86_32 | ||
254 | static const struct { | ||
255 | u16 poplmovl; | ||
256 | u32 val; | ||
257 | u16 int80; | ||
258 | } __attribute__((packed)) retcode = { | ||
259 | 0xb858, /* popl %eax; movl $..., %eax */ | ||
260 | __NR_sigreturn, | ||
261 | 0x80cd, /* int $0x80 */ | ||
262 | }; | ||
263 | |||
264 | static const struct { | ||
265 | u8 movl; | ||
266 | u32 val; | ||
267 | u16 int80; | ||
268 | u8 pad; | ||
269 | } __attribute__((packed)) rt_retcode = { | ||
270 | 0xb8, /* movl $..., %eax */ | ||
271 | __NR_rt_sigreturn, | ||
272 | 0x80cd, /* int $0x80 */ | ||
273 | 0 | ||
274 | }; | ||
275 | |||
261 | static int | 276 | static int |
262 | __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | 277 | __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, |
263 | struct pt_regs *regs) | 278 | struct pt_regs *regs) |
@@ -388,36 +403,6 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
388 | return 0; | 403 | return 0; |
389 | } | 404 | } |
390 | #else /* !CONFIG_X86_32 */ | 405 | #else /* !CONFIG_X86_32 */ |
391 | /* | ||
392 | * Determine which stack to use.. | ||
393 | */ | ||
394 | static void __user * | ||
395 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, | ||
396 | void __user **fpstate) | ||
397 | { | ||
398 | unsigned long sp; | ||
399 | |||
400 | /* Default to using normal stack - redzone */ | ||
401 | sp = regs->sp - 128; | ||
402 | |||
403 | /* This is the X/Open sanctioned signal stack switching. */ | ||
404 | if (ka->sa.sa_flags & SA_ONSTACK) { | ||
405 | if (sas_ss_flags(sp) == 0) | ||
406 | sp = current->sas_ss_sp + current->sas_ss_size; | ||
407 | } | ||
408 | |||
409 | if (used_math()) { | ||
410 | sp -= sig_xstate_size; | ||
411 | *fpstate = (void __user *)round_down(sp, 64); | ||
412 | |||
413 | if (save_i387_xstate(*fpstate) < 0) | ||
414 | return (void __user *) -1L; | ||
415 | } | ||
416 | |||
417 | sp -= frame_size; | ||
418 | return (void __user *)round_down(sp, 16) - 8; | ||
419 | } | ||
420 | |||
421 | static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 406 | static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
422 | sigset_t *set, struct pt_regs *regs) | 407 | sigset_t *set, struct pt_regs *regs) |
423 | { | 408 | { |