diff options
| -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 d7c73874b515..6525358630d4 100644 --- a/arch/hexagon/kernel/signal.c +++ b/arch/hexagon/kernel/signal.c | |||
| @@ -112,20 +112,20 @@ static int restore_sigcontext(struct pt_regs *regs, | |||
| 112 | /* | 112 | /* |
| 113 | * Setup signal stack frame with siginfo structure | 113 | * Setup signal stack frame with siginfo structure |
| 114 | */ | 114 | */ |
| 115 | static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, | 115 | static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, |
| 116 | sigset_t *set, struct pt_regs *regs) | 116 | struct pt_regs *regs) |
| 117 | { | 117 | { |
| 118 | int err = 0; | 118 | int err = 0; |
| 119 | struct rt_sigframe __user *frame; | 119 | struct rt_sigframe __user *frame; |
| 120 | struct hexagon_vdso *vdso = current->mm->context.vdso; | 120 | struct hexagon_vdso *vdso = current->mm->context.vdso; |
| 121 | 121 | ||
| 122 | frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe)); | 122 | frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe)); |
| 123 | 123 | ||
| 124 | if (!access_ok(VERIFY_WRITE, frame, sizeof(struct rt_sigframe))) | 124 | if (!access_ok(VERIFY_WRITE, frame, sizeof(struct rt_sigframe))) |
| 125 | goto sigsegv; | 125 | return -EFAULT; |
| 126 | 126 | ||
| 127 | if (copy_siginfo_to_user(&frame->info, info)) | 127 | if (copy_siginfo_to_user(&frame->info, &ksig->info)) |
| 128 | goto sigsegv; | 128 | return -EFAULT; |
| 129 | 129 | ||
| 130 | /* The on-stack signal trampoline is no longer executed; | 130 | /* The on-stack signal trampoline is no longer executed; |
| 131 | * however, the libgcc signal frame unwinding code checks for | 131 | * however, the libgcc signal frame unwinding code checks for |
| @@ -137,29 +137,26 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, | |||
| 137 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | 137 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
| 138 | err |= __save_altstack(&frame->uc.uc_stack, user_stack_pointer(regs)); | 138 | err |= __save_altstack(&frame->uc.uc_stack, user_stack_pointer(regs)); |
| 139 | if (err) | 139 | if (err) |
| 140 | goto sigsegv; | 140 | return -EFAULT; |
| 141 | 141 | ||
| 142 | /* Load r0/r1 pair with signumber/siginfo pointer... */ | 142 | /* Load r0/r1 pair with signumber/siginfo pointer... */ |
| 143 | regs->r0100 = ((unsigned long long)((unsigned long)&frame->info) << 32) | 143 | regs->r0100 = ((unsigned long long)((unsigned long)&frame->info) << 32) |
| 144 | | (unsigned long long)signr; | 144 | | (unsigned long long)ksig->sig; |
| 145 | regs->r02 = (unsigned long) &frame->uc; | 145 | regs->r02 = (unsigned long) &frame->uc; |
| 146 | regs->r31 = (unsigned long) vdso->rt_signal_trampoline; | 146 | regs->r31 = (unsigned long) vdso->rt_signal_trampoline; |
| 147 | pt_psp(regs) = (unsigned long) frame; | 147 | pt_psp(regs) = (unsigned long) frame; |
| 148 | pt_set_elr(regs, (unsigned long)ka->sa.sa_handler); | 148 | pt_set_elr(regs, (unsigned long)ksig->ka.sa.sa_handler); |
| 149 | 149 | ||
| 150 | return 0; | 150 | return 0; |
| 151 | |||
| 152 | sigsegv: | ||
| 153 | force_sigsegv(signr, current); | ||
| 154 | return -EFAULT; | ||
| 155 | } | 151 | } |
| 156 | 152 | ||
| 157 | /* | 153 | /* |
| 158 | * Setup invocation of signal handler | 154 | * Setup invocation of signal handler |
| 159 | */ | 155 | */ |
| 160 | static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, | 156 | static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) |
| 161 | struct pt_regs *regs) | ||
| 162 | { | 157 | { |
| 158 | int ret; | ||
| 159 | |||
| 163 | /* | 160 | /* |
| 164 | * If we're handling a signal that aborted a system call, | 161 | * If we're handling a signal that aborted a system call, |
| 165 | * set up the error return value before adding the signal | 162 | * set up the error return value before adding the signal |
| @@ -173,7 +170,7 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, | |||
| 173 | regs->r00 = -EINTR; | 170 | regs->r00 = -EINTR; |
| 174 | break; | 171 | break; |
| 175 | case -ERESTARTSYS: | 172 | case -ERESTARTSYS: |
| 176 | if (!(ka->sa.sa_flags & SA_RESTART)) { | 173 | if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { |
| 177 | regs->r00 = -EINTR; | 174 | regs->r00 = -EINTR; |
| 178 | break; | 175 | break; |
| 179 | } | 176 | } |
| @@ -193,11 +190,9 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, | |||
| 193 | * only set up the rt_frame flavor. | 190 | * only set up the rt_frame flavor. |
| 194 | */ | 191 | */ |
| 195 | /* If there was an error on setup, no signal was delivered. */ | 192 | /* If there was an error on setup, no signal was delivered. */ |
| 196 | if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0) | 193 | ret = setup_rt_frame(ksig, sigmask_to_save(), regs); |
| 197 | return; | ||
| 198 | 194 | ||
| 199 | signal_delivered(sig, info, ka, regs, | 195 | signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); |
| 200 | test_thread_flag(TIF_SINGLESTEP)); | ||
| 201 | } | 196 | } |
| 202 | 197 | ||
| 203 | /* | 198 | /* |
| @@ -205,17 +200,13 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, | |||
| 205 | */ | 200 | */ |
| 206 | void do_signal(struct pt_regs *regs) | 201 | void do_signal(struct pt_regs *regs) |
| 207 | { | 202 | { |
| 208 | struct k_sigaction sigact; | 203 | struct ksignal ksig; |
| 209 | siginfo_t info; | ||
| 210 | int signo; | ||
| 211 | 204 | ||
| 212 | if (!user_mode(regs)) | 205 | if (!user_mode(regs)) |
| 213 | return; | 206 | return; |
| 214 | 207 | ||
| 215 | signo = get_signal_to_deliver(&info, &sigact, regs, NULL); | 208 | if (get_signal(&ksig)) { |
| 216 | 209 | handle_signal(&ksig, regs); | |
| 217 | if (signo > 0) { | ||
| 218 | handle_signal(signo, &info, &sigact, regs); | ||
| 219 | return; | 210 | return; |
| 220 | } | 211 | } |
| 221 | 212 | ||
