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