diff options
| -rw-r--r-- | arch/avr32/kernel/signal.c | 43 |
1 files changed, 18 insertions, 25 deletions
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c index b80c0b3d2bab..dda150fe73bb 100644 --- a/arch/avr32/kernel/signal.c +++ b/arch/avr32/kernel/signal.c | |||
| @@ -138,13 +138,12 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize) | |||
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | static int | 140 | static int |
| 141 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 141 | setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) |
| 142 | sigset_t *set, struct pt_regs *regs) | ||
| 143 | { | 142 | { |
| 144 | struct rt_sigframe __user *frame; | 143 | struct rt_sigframe __user *frame; |
| 145 | int err = 0; | 144 | int err = 0; |
| 146 | 145 | ||
| 147 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 146 | frame = get_sigframe(&ksig->ka, regs, sizeof(*frame)); |
| 148 | err = -EFAULT; | 147 | err = -EFAULT; |
| 149 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 148 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
| 150 | goto out; | 149 | goto out; |
| @@ -164,7 +163,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 164 | err = __put_user(0x3008d733 | (__NR_rt_sigreturn << 20), | 163 | err = __put_user(0x3008d733 | (__NR_rt_sigreturn << 20), |
| 165 | &frame->retcode); | 164 | &frame->retcode); |
| 166 | 165 | ||
| 167 | err |= copy_siginfo_to_user(&frame->info, info); | 166 | err |= copy_siginfo_to_user(&frame->info, &ksig->info); |
| 168 | 167 | ||
| 169 | /* Set up the ucontext */ | 168 | /* Set up the ucontext */ |
| 170 | err |= __put_user(0, &frame->uc.uc_flags); | 169 | err |= __put_user(0, &frame->uc.uc_flags); |
| @@ -176,12 +175,12 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 176 | if (err) | 175 | if (err) |
| 177 | goto out; | 176 | goto out; |
| 178 | 177 | ||
| 179 | regs->r12 = sig; | 178 | regs->r12 = ksig->sig; |
| 180 | regs->r11 = (unsigned long) &frame->info; | 179 | regs->r11 = (unsigned long) &frame->info; |
| 181 | regs->r10 = (unsigned long) &frame->uc; | 180 | regs->r10 = (unsigned long) &frame->uc; |
| 182 | regs->sp = (unsigned long) frame; | 181 | regs->sp = (unsigned long) frame; |
| 183 | if (ka->sa.sa_flags & SA_RESTORER) | 182 | if (ksig->ka.sa.sa_flags & SA_RESTORER) |
| 184 | regs->lr = (unsigned long)ka->sa.sa_restorer; | 183 | regs->lr = (unsigned long)ksig->ka.sa.sa_restorer; |
| 185 | else { | 184 | else { |
| 186 | printk(KERN_NOTICE "[%s:%d] did not set SA_RESTORER\n", | 185 | printk(KERN_NOTICE "[%s:%d] did not set SA_RESTORER\n", |
| 187 | current->comm, current->pid); | 186 | current->comm, current->pid); |
| @@ -189,10 +188,10 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 189 | } | 188 | } |
| 190 | 189 | ||
| 191 | pr_debug("SIG deliver [%s:%d]: sig=%d sp=0x%lx pc=0x%lx->0x%p lr=0x%lx\n", | 190 | pr_debug("SIG deliver [%s:%d]: sig=%d sp=0x%lx pc=0x%lx->0x%p lr=0x%lx\n", |
| 192 | current->comm, current->pid, sig, regs->sp, | 191 | current->comm, current->pid, ksig->sig, regs->sp, |
| 193 | regs->pc, ka->sa.sa_handler, regs->lr); | 192 | regs->pc, ksig->ka.sa.sa_handler, regs->lr); |
| 194 | 193 | ||
| 195 | regs->pc = (unsigned long) ka->sa.sa_handler; | 194 | regs->pc = (unsigned long)ksig->ka.sa.sa_handler; |
| 196 | 195 | ||
| 197 | out: | 196 | out: |
| 198 | return err; | 197 | return err; |
| @@ -208,15 +207,14 @@ static inline void setup_syscall_restart(struct pt_regs *regs) | |||
| 208 | } | 207 | } |
| 209 | 208 | ||
| 210 | static inline void | 209 | static inline void |
| 211 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | 210 | handle_signal(struct ksignal *ksig, struct pt_regs *regs, int syscall) |
| 212 | struct pt_regs *regs, int syscall) | ||
| 213 | { | 211 | { |
| 214 | int ret; | 212 | int ret; |
| 215 | 213 | ||
| 216 | /* | 214 | /* |
| 217 | * Set up the stack frame | 215 | * Set up the stack frame |
| 218 | */ | 216 | */ |
| 219 | ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs); | 217 | ret = setup_rt_frame(ksig, sigmask_to_save(), regs); |
| 220 | 218 | ||
| 221 | /* | 219 | /* |
| 222 | * Check that the resulting registers are sane | 220 | * Check that the resulting registers are sane |
| @@ -226,10 +224,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 226 | /* | 224 | /* |
| 227 | * Block the signal if we were successful. | 225 | * Block the signal if we were successful. |
| 228 | */ | 226 | */ |
| 229 | if (ret != 0) | 227 | signal_setup_done(ret, ksig, 0); |
| 230 | force_sigsegv(sig, current); | ||
| 231 | else | ||
| 232 | signal_delivered(sig, info, ka, regs, 0); | ||
| 233 | } | 228 | } |
| 234 | 229 | ||
| 235 | /* | 230 | /* |
| @@ -239,9 +234,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 239 | */ | 234 | */ |
| 240 | static void do_signal(struct pt_regs *regs, int syscall) | 235 | static void do_signal(struct pt_regs *regs, int syscall) |
| 241 | { | 236 | { |
| 242 | siginfo_t info; | 237 | struct ksignal ksig; |
| 243 | int signr; | ||
| 244 | struct k_sigaction ka; | ||
| 245 | 238 | ||
| 246 | /* | 239 | /* |
| 247 | * We want the common case to go fast, which is why we may in | 240 | * We want the common case to go fast, which is why we may in |
| @@ -251,18 +244,18 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
| 251 | if (!user_mode(regs)) | 244 | if (!user_mode(regs)) |
| 252 | return; | 245 | return; |
| 253 | 246 | ||
| 254 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 247 | get_signal(&ksig); |
| 255 | if (syscall) { | 248 | if (syscall) { |
| 256 | switch (regs->r12) { | 249 | switch (regs->r12) { |
| 257 | case -ERESTART_RESTARTBLOCK: | 250 | case -ERESTART_RESTARTBLOCK: |
| 258 | case -ERESTARTNOHAND: | 251 | case -ERESTARTNOHAND: |
| 259 | if (signr > 0) { | 252 | if (ksig.sig > 0) { |
| 260 | regs->r12 = -EINTR; | 253 | regs->r12 = -EINTR; |
| 261 | break; | 254 | break; |
| 262 | } | 255 | } |
| 263 | /* fall through */ | 256 | /* fall through */ |
| 264 | case -ERESTARTSYS: | 257 | case -ERESTARTSYS: |
| 265 | if (signr > 0 && !(ka.sa.sa_flags & SA_RESTART)) { | 258 | if (ksig.sig > 0 && !(ksig.ka.sa.sa_flags & SA_RESTART)) { |
| 266 | regs->r12 = -EINTR; | 259 | regs->r12 = -EINTR; |
| 267 | break; | 260 | break; |
| 268 | } | 261 | } |
| @@ -272,13 +265,13 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
| 272 | } | 265 | } |
| 273 | } | 266 | } |
| 274 | 267 | ||
| 275 | if (signr == 0) { | 268 | if (!ksig.sig) { |
| 276 | /* No signal to deliver -- put the saved sigmask back */ | 269 | /* No signal to deliver -- put the saved sigmask back */ |
| 277 | restore_saved_sigmask(); | 270 | restore_saved_sigmask(); |
| 278 | return; | 271 | return; |
| 279 | } | 272 | } |
| 280 | 273 | ||
| 281 | handle_signal(signr, &ka, &info, regs, syscall); | 274 | handle_signal(&ksig, regs, syscall); |
| 282 | } | 275 | } |
| 283 | 276 | ||
| 284 | asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) | 277 | asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) |
