diff options
Diffstat (limited to 'arch/hexagon/kernel/signal.c')
-rw-r--r-- | arch/hexagon/kernel/signal.c | 45 |
1 files changed, 18 insertions, 27 deletions
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c index 60fa2ca3202b..d7c73874b515 100644 --- a/arch/hexagon/kernel/signal.c +++ b/arch/hexagon/kernel/signal.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Signal support for Hexagon processor | 2 | * Signal support for Hexagon processor |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 and | 7 | * it under the terms of the GNU General Public License version 2 and |
@@ -41,6 +41,10 @@ static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | |||
41 | { | 41 | { |
42 | unsigned long sp = regs->r29; | 42 | unsigned long sp = regs->r29; |
43 | 43 | ||
44 | /* check if we would overflow the alt stack */ | ||
45 | if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) | ||
46 | return (void __user __force *)-1UL; | ||
47 | |||
44 | /* Switch to signal stack if appropriate */ | 48 | /* Switch to signal stack if appropriate */ |
45 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) | 49 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) |
46 | sp = current->sas_ss_sp + current->sas_ss_size; | 50 | sp = current->sas_ss_sp + current->sas_ss_size; |
@@ -66,7 +70,10 @@ static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | |||
66 | err |= __put_user(regs->preds, &sc->sc_regs.p3_0); | 70 | err |= __put_user(regs->preds, &sc->sc_regs.p3_0); |
67 | err |= __put_user(regs->gp, &sc->sc_regs.gp); | 71 | err |= __put_user(regs->gp, &sc->sc_regs.gp); |
68 | err |= __put_user(regs->ugp, &sc->sc_regs.ugp); | 72 | err |= __put_user(regs->ugp, &sc->sc_regs.ugp); |
69 | 73 | #if CONFIG_HEXAGON_ARCH_VERSION >= 4 | |
74 | err |= __put_user(regs->cs0, &sc->sc_regs.cs0); | ||
75 | err |= __put_user(regs->cs1, &sc->sc_regs.cs1); | ||
76 | #endif | ||
70 | tmp = pt_elr(regs); err |= __put_user(tmp, &sc->sc_regs.pc); | 77 | tmp = pt_elr(regs); err |= __put_user(tmp, &sc->sc_regs.pc); |
71 | tmp = pt_cause(regs); err |= __put_user(tmp, &sc->sc_regs.cause); | 78 | tmp = pt_cause(regs); err |= __put_user(tmp, &sc->sc_regs.cause); |
72 | tmp = pt_badva(regs); err |= __put_user(tmp, &sc->sc_regs.badva); | 79 | tmp = pt_badva(regs); err |= __put_user(tmp, &sc->sc_regs.badva); |
@@ -93,7 +100,10 @@ static int restore_sigcontext(struct pt_regs *regs, | |||
93 | err |= __get_user(regs->preds, &sc->sc_regs.p3_0); | 100 | err |= __get_user(regs->preds, &sc->sc_regs.p3_0); |
94 | err |= __get_user(regs->gp, &sc->sc_regs.gp); | 101 | err |= __get_user(regs->gp, &sc->sc_regs.gp); |
95 | err |= __get_user(regs->ugp, &sc->sc_regs.ugp); | 102 | err |= __get_user(regs->ugp, &sc->sc_regs.ugp); |
96 | 103 | #if CONFIG_HEXAGON_ARCH_VERSION >= 4 | |
104 | err |= __get_user(regs->cs0, &sc->sc_regs.cs0); | ||
105 | err |= __get_user(regs->cs1, &sc->sc_regs.cs1); | ||
106 | #endif | ||
97 | err |= __get_user(tmp, &sc->sc_regs.pc); pt_set_elr(regs, tmp); | 107 | err |= __get_user(tmp, &sc->sc_regs.pc); pt_set_elr(regs, tmp); |
98 | 108 | ||
99 | return err; | 109 | return err; |
@@ -193,7 +203,7 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, | |||
193 | /* | 203 | /* |
194 | * Called from return-from-event code. | 204 | * Called from return-from-event code. |
195 | */ | 205 | */ |
196 | static void do_signal(struct pt_regs *regs) | 206 | void do_signal(struct pt_regs *regs) |
197 | { | 207 | { |
198 | struct k_sigaction sigact; | 208 | struct k_sigaction sigact; |
199 | siginfo_t info; | 209 | siginfo_t info; |
@@ -210,8 +220,9 @@ static void do_signal(struct pt_regs *regs) | |||
210 | } | 220 | } |
211 | 221 | ||
212 | /* | 222 | /* |
213 | * If we came from a system call, handle the restart. | 223 | * No (more) signals; if we came from a system call, handle the restart. |
214 | */ | 224 | */ |
225 | |||
215 | if (regs->syscall_nr >= 0) { | 226 | if (regs->syscall_nr >= 0) { |
216 | switch (regs->r00) { | 227 | switch (regs->r00) { |
217 | case -ERESTARTNOHAND: | 228 | case -ERESTARTNOHAND: |
@@ -234,17 +245,6 @@ no_restart: | |||
234 | restore_saved_sigmask(); | 245 | restore_saved_sigmask(); |
235 | } | 246 | } |
236 | 247 | ||
237 | void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) | ||
238 | { | ||
239 | if (thread_info_flags & _TIF_SIGPENDING) | ||
240 | do_signal(regs); | ||
241 | |||
242 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | ||
243 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
244 | tracehook_notify_resume(regs); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | /* | 248 | /* |
249 | * Architecture-specific wrappers for signal-related system calls | 249 | * Architecture-specific wrappers for signal-related system calls |
250 | */ | 250 | */ |
@@ -272,21 +272,12 @@ asmlinkage int sys_rt_sigreturn(void) | |||
272 | /* Restore the user's stack as well */ | 272 | /* Restore the user's stack as well */ |
273 | pt_psp(regs) = regs->r29; | 273 | pt_psp(regs) = regs->r29; |
274 | 274 | ||
275 | /* | 275 | regs->syscall_nr = -1; |
276 | * Leave a trace in the stack frame that this was a sigreturn. | ||
277 | * If the system call is to replay, we've already restored the | ||
278 | * number in the GPR slot and it will be regenerated on the | ||
279 | * new system call trap entry. Note that if restore_sigcontext() | ||
280 | * did something other than a bulk copy of the pt_regs struct, | ||
281 | * we could avoid this assignment by simply not overwriting | ||
282 | * regs->syscall_nr. | ||
283 | */ | ||
284 | regs->syscall_nr = __NR_rt_sigreturn; | ||
285 | 276 | ||
286 | if (restore_altstack(&frame->uc.uc_stack)) | 277 | if (restore_altstack(&frame->uc.uc_stack)) |
287 | goto badframe; | 278 | goto badframe; |
288 | 279 | ||
289 | return 0; | 280 | return regs->r00; |
290 | 281 | ||
291 | badframe: | 282 | badframe: |
292 | force_sig(SIGSEGV, current); | 283 | force_sig(SIGSEGV, current); |