aboutsummaryrefslogtreecommitdiffstats
path: root/arch/hexagon/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/hexagon/kernel/signal.c')
-rw-r--r--arch/hexagon/kernel/signal.c45
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 */
196static void do_signal(struct pt_regs *regs) 206void 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
237void 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
291badframe: 282badframe:
292 force_sig(SIGSEGV, current); 283 force_sig(SIGSEGV, current);