diff options
| -rw-r--r-- | arch/powerpc/include/asm/processor.h | 19 | ||||
| -rw-r--r-- | arch/powerpc/kernel/signal.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/kernel/signal.h | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/signal_32.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/kernel/signal_64.c | 2 |
5 files changed, 25 insertions, 6 deletions
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index d3466490104a..9eed29eee604 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
| @@ -313,6 +313,25 @@ static inline void prefetchw(const void *x) | |||
| 313 | #define HAVE_ARCH_PICK_MMAP_LAYOUT | 313 | #define HAVE_ARCH_PICK_MMAP_LAYOUT |
| 314 | #endif | 314 | #endif |
| 315 | 315 | ||
| 316 | #ifdef CONFIG_PPC64 | ||
| 317 | static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) | ||
| 318 | { | ||
| 319 | unsigned long sp; | ||
| 320 | |||
| 321 | if (is_32) | ||
| 322 | sp = regs->gpr[1] & 0x0ffffffffUL; | ||
| 323 | else | ||
| 324 | sp = regs->gpr[1]; | ||
| 325 | |||
| 326 | return sp; | ||
| 327 | } | ||
| 328 | #else | ||
| 329 | static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) | ||
| 330 | { | ||
| 331 | return regs->gpr[1]; | ||
| 332 | } | ||
| 333 | #endif | ||
| 334 | |||
| 316 | #endif /* __KERNEL__ */ | 335 | #endif /* __KERNEL__ */ |
| 317 | #endif /* __ASSEMBLY__ */ | 336 | #endif /* __ASSEMBLY__ */ |
| 318 | #endif /* _ASM_POWERPC_PROCESSOR_H */ | 337 | #endif /* _ASM_POWERPC_PROCESSOR_H */ |
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index a54405ebd7b0..00b5078da9a3 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c | |||
| @@ -26,12 +26,12 @@ int show_unhandled_signals = 0; | |||
| 26 | * Allocate space for the signal frame | 26 | * Allocate space for the signal frame |
| 27 | */ | 27 | */ |
| 28 | void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | 28 | void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, |
| 29 | size_t frame_size) | 29 | size_t frame_size, int is_32) |
| 30 | { | 30 | { |
| 31 | unsigned long oldsp, newsp; | 31 | unsigned long oldsp, newsp; |
| 32 | 32 | ||
| 33 | /* Default to using normal stack */ | 33 | /* Default to using normal stack */ |
| 34 | oldsp = regs->gpr[1]; | 34 | oldsp = get_clean_sp(regs, is_32); |
| 35 | 35 | ||
| 36 | /* Check for alt stack */ | 36 | /* Check for alt stack */ |
| 37 | if ((ka->sa.sa_flags & SA_ONSTACK) && | 37 | if ((ka->sa.sa_flags & SA_ONSTACK) && |
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index f1442d69d4ec..6c0ddfc0603e 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags); | 15 | extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags); |
| 16 | 16 | ||
| 17 | extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | 17 | extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, |
| 18 | size_t frame_size); | 18 | size_t frame_size, int is_32); |
| 19 | extern void restore_sigmask(sigset_t *set); | 19 | extern void restore_sigmask(sigset_t *set); |
| 20 | 20 | ||
| 21 | extern int handle_signal32(unsigned long sig, struct k_sigaction *ka, | 21 | extern int handle_signal32(unsigned long sig, struct k_sigaction *ka, |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index b13abf305996..d670429a1608 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
| @@ -836,7 +836,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, | |||
| 836 | 836 | ||
| 837 | /* Set up Signal Frame */ | 837 | /* Set up Signal Frame */ |
| 838 | /* Put a Real Time Context onto stack */ | 838 | /* Put a Real Time Context onto stack */ |
| 839 | rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf)); | 839 | rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1); |
| 840 | addr = rt_sf; | 840 | addr = rt_sf; |
| 841 | if (unlikely(rt_sf == NULL)) | 841 | if (unlikely(rt_sf == NULL)) |
| 842 | goto badframe; | 842 | goto badframe; |
| @@ -1182,7 +1182,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, | |||
| 1182 | unsigned long newsp = 0; | 1182 | unsigned long newsp = 0; |
| 1183 | 1183 | ||
| 1184 | /* Set up Signal Frame */ | 1184 | /* Set up Signal Frame */ |
| 1185 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 1185 | frame = get_sigframe(ka, regs, sizeof(*frame), 1); |
| 1186 | if (unlikely(frame == NULL)) | 1186 | if (unlikely(frame == NULL)) |
| 1187 | goto badframe; | 1187 | goto badframe; |
| 1188 | sc = (struct sigcontext __user *) &frame->sctx; | 1188 | sc = (struct sigcontext __user *) &frame->sctx; |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index e132891d3cea..2fe6fc64b614 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
| @@ -402,7 +402,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, | |||
| 402 | unsigned long newsp = 0; | 402 | unsigned long newsp = 0; |
| 403 | long err = 0; | 403 | long err = 0; |
| 404 | 404 | ||
| 405 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 405 | frame = get_sigframe(ka, regs, sizeof(*frame), 0); |
| 406 | if (unlikely(frame == NULL)) | 406 | if (unlikely(frame == NULL)) |
| 407 | goto badframe; | 407 | goto badframe; |
| 408 | 408 | ||
