aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/kernel/signal.c')
-rw-r--r--arch/arm64/kernel/signal.c58
1 files changed, 22 insertions, 36 deletions
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 6357b9c6c90e..6fa792137eda 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -209,19 +209,13 @@ static int setup_sigframe(struct rt_sigframe __user *sf,
209 return err; 209 return err;
210} 210}
211 211
212static struct rt_sigframe __user *get_sigframe(struct k_sigaction *ka, 212static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig,
213 struct pt_regs *regs) 213 struct pt_regs *regs)
214{ 214{
215 unsigned long sp, sp_top; 215 unsigned long sp, sp_top;
216 struct rt_sigframe __user *frame; 216 struct rt_sigframe __user *frame;
217 217
218 sp = sp_top = regs->sp; 218 sp = sp_top = sigsp(regs->sp, ksig);
219
220 /*
221 * This is the X/Open sanctioned signal stack switching.
222 */
223 if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
224 sp = sp_top = current->sas_ss_sp + current->sas_ss_size;
225 219
226 sp = (sp - sizeof(struct rt_sigframe)) & ~15; 220 sp = (sp - sizeof(struct rt_sigframe)) & ~15;
227 frame = (struct rt_sigframe __user *)sp; 221 frame = (struct rt_sigframe __user *)sp;
@@ -253,13 +247,13 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
253 regs->regs[30] = (unsigned long)sigtramp; 247 regs->regs[30] = (unsigned long)sigtramp;
254} 248}
255 249
256static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, 250static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
257 sigset_t *set, struct pt_regs *regs) 251 struct pt_regs *regs)
258{ 252{
259 struct rt_sigframe __user *frame; 253 struct rt_sigframe __user *frame;
260 int err = 0; 254 int err = 0;
261 255
262 frame = get_sigframe(ka, regs); 256 frame = get_sigframe(ksig, regs);
263 if (!frame) 257 if (!frame)
264 return 1; 258 return 1;
265 259
@@ -269,9 +263,9 @@ static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
269 err |= __save_altstack(&frame->uc.uc_stack, regs->sp); 263 err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
270 err |= setup_sigframe(frame, regs, set); 264 err |= setup_sigframe(frame, regs, set);
271 if (err == 0) { 265 if (err == 0) {
272 setup_return(regs, ka, frame, usig); 266 setup_return(regs, &ksig->ka, frame, usig);
273 if (ka->sa.sa_flags & SA_SIGINFO) { 267 if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
274 err |= copy_siginfo_to_user(&frame->info, info); 268 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
275 regs->regs[1] = (unsigned long)&frame->info; 269 regs->regs[1] = (unsigned long)&frame->info;
276 regs->regs[2] = (unsigned long)&frame->uc; 270 regs->regs[2] = (unsigned long)&frame->uc;
277 } 271 }
@@ -291,13 +285,12 @@ static void setup_restart_syscall(struct pt_regs *regs)
291/* 285/*
292 * OK, we're invoking a handler 286 * OK, we're invoking a handler
293 */ 287 */
294static void handle_signal(unsigned long sig, struct k_sigaction *ka, 288static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
295 siginfo_t *info, struct pt_regs *regs)
296{ 289{
297 struct thread_info *thread = current_thread_info(); 290 struct thread_info *thread = current_thread_info();
298 struct task_struct *tsk = current; 291 struct task_struct *tsk = current;
299 sigset_t *oldset = sigmask_to_save(); 292 sigset_t *oldset = sigmask_to_save();
300 int usig = sig; 293 int usig = ksig->sig;
301 int ret; 294 int ret;
302 295
303 /* 296 /*
@@ -310,13 +303,12 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
310 * Set up the stack frame 303 * Set up the stack frame
311 */ 304 */
312 if (is_compat_task()) { 305 if (is_compat_task()) {
313 if (ka->sa.sa_flags & SA_SIGINFO) 306 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
314 ret = compat_setup_rt_frame(usig, ka, info, oldset, 307 ret = compat_setup_rt_frame(usig, ksig, oldset, regs);
315 regs);
316 else 308 else
317 ret = compat_setup_frame(usig, ka, oldset, regs); 309 ret = compat_setup_frame(usig, ksig, oldset, regs);
318 } else { 310 } else {
319 ret = setup_rt_frame(usig, ka, info, oldset, regs); 311 ret = setup_rt_frame(usig, ksig, oldset, regs);
320 } 312 }
321 313
322 /* 314 /*
@@ -324,18 +316,14 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
324 */ 316 */
325 ret |= !valid_user_regs(&regs->user_regs); 317 ret |= !valid_user_regs(&regs->user_regs);
326 318
327 if (ret != 0) {
328 force_sigsegv(sig, tsk);
329 return;
330 }
331
332 /* 319 /*
333 * Fast forward the stepping logic so we step into the signal 320 * Fast forward the stepping logic so we step into the signal
334 * handler. 321 * handler.
335 */ 322 */
336 user_fastforward_single_step(tsk); 323 if (!ret)
324 user_fastforward_single_step(tsk);
337 325
338 signal_delivered(sig, info, ka, regs, 0); 326 signal_setup_done(ret, ksig, 0);
339} 327}
340 328
341/* 329/*
@@ -350,10 +338,9 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
350static void do_signal(struct pt_regs *regs) 338static void do_signal(struct pt_regs *regs)
351{ 339{
352 unsigned long continue_addr = 0, restart_addr = 0; 340 unsigned long continue_addr = 0, restart_addr = 0;
353 struct k_sigaction ka; 341 int retval = 0;
354 siginfo_t info;
355 int signr, retval = 0;
356 int syscall = (int)regs->syscallno; 342 int syscall = (int)regs->syscallno;
343 struct ksignal ksig;
357 344
358 /* 345 /*
359 * If we were from a system call, check for system call restarting... 346 * If we were from a system call, check for system call restarting...
@@ -387,8 +374,7 @@ static void do_signal(struct pt_regs *regs)
387 * Get the signal to deliver. When running under ptrace, at this point 374 * Get the signal to deliver. When running under ptrace, at this point
388 * the debugger may change all of our registers. 375 * the debugger may change all of our registers.
389 */ 376 */
390 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 377 if (get_signal(&ksig)) {
391 if (signr > 0) {
392 /* 378 /*
393 * Depending on the signal settings, we may need to revert the 379 * Depending on the signal settings, we may need to revert the
394 * decision to restart the system call, but skip this if a 380 * decision to restart the system call, but skip this if a
@@ -398,12 +384,12 @@ static void do_signal(struct pt_regs *regs)
398 (retval == -ERESTARTNOHAND || 384 (retval == -ERESTARTNOHAND ||
399 retval == -ERESTART_RESTARTBLOCK || 385 retval == -ERESTART_RESTARTBLOCK ||
400 (retval == -ERESTARTSYS && 386 (retval == -ERESTARTSYS &&
401 !(ka.sa.sa_flags & SA_RESTART)))) { 387 !(ksig.ka.sa.sa_flags & SA_RESTART)))) {
402 regs->regs[0] = -EINTR; 388 regs->regs[0] = -EINTR;
403 regs->pc = continue_addr; 389 regs->pc = continue_addr;
404 } 390 }
405 391
406 handle_signal(signr, &ka, &info, regs); 392 handle_signal(&ksig, regs);
407 return; 393 return;
408 } 394 }
409 395