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