aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2013-10-06 16:35:03 -0400
committerJonas Bonn <jonas@southpole.se>2014-01-09 04:57:21 -0500
commit548dafe880ad84d0accc0a5596c26e3348b103e1 (patch)
tree82be25fcf98bfe606bf9be0707c9122c614a27c5
parent10f67dbf6add97751050f294d4c8e0cc1e5c2c23 (diff)
openrisc: Use get_signal() signal_setup_done()
Use the more generic functions get_signal() signal_setup_done() for signal delivery. Signed-off-by: Richard Weinberger <richard@nod.at> Signed-off-by: Jonas Bonn <jonas@southpole.se>
-rw-r--r--arch/openrisc/kernel/signal.c59
1 files changed, 22 insertions, 37 deletions
diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c
index c277ec82783d..66775bc07a8e 100644
--- a/arch/openrisc/kernel/signal.c
+++ b/arch/openrisc/kernel/signal.c
@@ -166,20 +166,21 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
166 * trampoline which performs the syscall sigreturn, or a provided 166 * trampoline which performs the syscall sigreturn, or a provided
167 * user-mode trampoline. 167 * user-mode trampoline.
168 */ 168 */
169static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 169static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
170 sigset_t *set, struct pt_regs *regs) 170 struct pt_regs *regs)
171{ 171{
172 struct rt_sigframe *frame; 172 struct rt_sigframe *frame;
173 unsigned long return_ip; 173 unsigned long return_ip;
174 int err = 0; 174 int err = 0;
175 175
176 frame = get_sigframe(ka, regs, sizeof(*frame)); 176 frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
177
177 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 178 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
178 goto give_sigsegv; 179 return -EFAULT;
179 180
180 /* Create siginfo. */ 181 /* Create siginfo. */
181 if (ka->sa.sa_flags & SA_SIGINFO) 182 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
182 err |= copy_siginfo_to_user(&frame->info, info); 183 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
183 184
184 /* Create the ucontext. */ 185 /* Create the ucontext. */
185 err |= __put_user(0, &frame->uc.uc_flags); 186 err |= __put_user(0, &frame->uc.uc_flags);
@@ -190,7 +191,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
190 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 191 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
191 192
192 if (err) 193 if (err)
193 goto give_sigsegv; 194 return -EFAULT;
194 195
195 /* trampoline - the desired return ip is the retcode itself */ 196 /* trampoline - the desired return ip is the retcode itself */
196 return_ip = (unsigned long)&frame->retcode; 197 return_ip = (unsigned long)&frame->retcode;
@@ -204,14 +205,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
204 err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8)); 205 err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
205 206
206 if (err) 207 if (err)
207 goto give_sigsegv; 208 return -EFAULT;
208 209
209 /* TODO what is the current->exec_domain stuff and invmap ? */ 210 /* TODO what is the current->exec_domain stuff and invmap ? */
210 211
211 /* Set up registers for signal handler */ 212 /* Set up registers for signal handler */
212 regs->pc = (unsigned long)ka->sa.sa_handler; /* what we enter NOW */ 213 regs->pc = (unsigned long)ksig->ka.sa.sa_handler; /* what we enter NOW */
213 regs->gpr[9] = (unsigned long)return_ip; /* what we enter LATER */ 214 regs->gpr[9] = (unsigned long)return_ip; /* what we enter LATER */
214 regs->gpr[3] = (unsigned long)sig; /* arg 1: signo */ 215 regs->gpr[3] = (unsigned long)ksig->sig; /* arg 1: signo */
215 regs->gpr[4] = (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */ 216 regs->gpr[4] = (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */
216 regs->gpr[5] = (unsigned long)&frame->uc; /* arg 3: ucontext */ 217 regs->gpr[5] = (unsigned long)&frame->uc; /* arg 3: ucontext */
217 218
@@ -219,25 +220,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
219 regs->sp = (unsigned long)frame; 220 regs->sp = (unsigned long)frame;
220 221
221 return 0; 222 return 0;
222
223give_sigsegv:
224 force_sigsegv(sig, current);
225 return -EFAULT;
226} 223}
227 224
228static inline void 225static inline void
229handle_signal(unsigned long sig, 226handle_signal(struct ksignal *ksig, struct pt_regs *regs)
230 siginfo_t *info, struct k_sigaction *ka,
231 struct pt_regs *regs)
232{ 227{
233 int ret; 228 int ret;
234 229
235 ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs); 230 ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
236 if (ret)
237 return;
238 231
239 signal_delivered(sig, info, ka, regs, 232 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
240 test_thread_flag(TIF_SINGLESTEP));
241} 233}
242 234
243/* 235/*
@@ -254,9 +246,7 @@ handle_signal(unsigned long sig,
254 246
255int do_signal(struct pt_regs *regs, int syscall) 247int do_signal(struct pt_regs *regs, int syscall)
256{ 248{
257 siginfo_t info; 249 struct ksignal ksig;
258 int signr;
259 struct k_sigaction ka;
260 unsigned long continue_addr = 0; 250 unsigned long continue_addr = 0;
261 unsigned long restart_addr = 0; 251 unsigned long restart_addr = 0;
262 unsigned long retval = 0; 252 unsigned long retval = 0;
@@ -286,28 +276,23 @@ int do_signal(struct pt_regs *regs, int syscall)
286 } 276 }
287 277
288 /* 278 /*
289 * Get the signal to deliver. When running under ptrace, at this 279 * Get the signal to deliver. During the call to get_signal the
290 * point the debugger may change all our registers ... 280 * debugger may change all our registers so we may need to revert
281 * the decision to restart the syscall; specifically, if the PC is
282 * changed, don't restart the syscall.
291 */ 283 */
292 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 284 if (get_signal(&ksig)) {
293 /*
294 * Depending on the signal settings we may need to revert the
295 * decision to restart the system call. But skip this if a
296 * debugger has chosen to restart at a different PC.
297 */
298 if (signr > 0) {
299 if (unlikely(restart) && regs->pc == restart_addr) { 285 if (unlikely(restart) && regs->pc == restart_addr) {
300 if (retval == -ERESTARTNOHAND || 286 if (retval == -ERESTARTNOHAND ||
301 retval == -ERESTART_RESTARTBLOCK 287 retval == -ERESTART_RESTARTBLOCK
302 || (retval == -ERESTARTSYS 288 || (retval == -ERESTARTSYS
303 && !(ka.sa.sa_flags & SA_RESTART))) { 289 && !(ksig.ka.sa.sa_flags & SA_RESTART))) {
304 /* No automatic restart */ 290 /* No automatic restart */
305 regs->gpr[11] = -EINTR; 291 regs->gpr[11] = -EINTR;
306 regs->pc = continue_addr; 292 regs->pc = continue_addr;
307 } 293 }
308 } 294 }
309 295 handle_signal(&ksig, regs);
310 handle_signal(signr, &info, &ka, regs);
311 } else { 296 } else {
312 /* no handler */ 297 /* no handler */
313 restore_saved_sigmask(); 298 restore_saved_sigmask();