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 | |
| 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>
| -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 | { |
