Lines Matching +full:rx +full:- +full:sched +full:- +full:sp
1 // SPDX-License-Identifier: GPL-2.0
3 * PA-RISC architecture-specific signal handling support.
5 * Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
7 * Copyright (C) 2000-2022 Helge Deller <deller@gmx.de>
13 #include <linux/sched.h>
14 #include <linux/sched/debug.h>
31 #include <asm/asm-offsets.h>
57 * Do a signal return - restore sigcontext.
65 err |= __copy_from_user(regs->gr, sc->sc_gr, sizeof(regs->gr)); in restore_sigcontext()
66 err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr)); in restore_sigcontext()
67 err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq)); in restore_sigcontext()
68 err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq)); in restore_sigcontext()
69 err |= __get_user(regs->sar, &sc->sc_sar); in restore_sigcontext()
71 __func__, regs->iaoq[0], regs->iaoq[1]); in restore_sigcontext()
72 DBG(2, "%s: r28 is %ld\n", __func__, regs->gr[28]); in restore_sigcontext()
81 unsigned long usp = (regs->gr[30] & ~(0x01UL)); in sys_rt_sigreturn()
90 current->restart_block.fn = do_no_restart_syscall; in sys_rt_sigreturn()
94 (usp - sigframe_size); in sys_rt_sigreturn()
97 regs->orig_r28 = 1; /* no restarts for sigreturn */ in sys_rt_sigreturn()
103 if (get_compat_sigset(&set, &compat_frame->uc.uc_sigmask)) in sys_rt_sigreturn()
108 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) in sys_rt_sigreturn()
117 DBG(1, "%s: compat_frame->uc.uc_mcontext 0x%p\n", in sys_rt_sigreturn()
118 __func__, &compat_frame->uc.uc_mcontext); in sys_rt_sigreturn()
120 if (restore_sigcontext32(&compat_frame->uc.uc_mcontext, in sys_rt_sigreturn()
121 &compat_frame->regs, regs)) in sys_rt_sigreturn()
124 __func__, usp, &compat_frame->uc.uc_stack); in sys_rt_sigreturn()
125 if (compat_restore_altstack(&compat_frame->uc.uc_stack)) in sys_rt_sigreturn()
130 DBG(1, "%s: frame->uc.uc_mcontext 0x%p\n", in sys_rt_sigreturn()
131 __func__, &frame->uc.uc_mcontext); in sys_rt_sigreturn()
132 if (restore_sigcontext(&frame->uc.uc_mcontext, regs)) in sys_rt_sigreturn()
135 __func__, usp, &frame->uc.uc_stack); in sys_rt_sigreturn()
136 if (restore_altstack(&frame->uc.uc_stack)) in sys_rt_sigreturn()
146 regs->gr[31] = regs->iaoq[0]; in sys_rt_sigreturn()
161 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) in get_sigframe() argument
166 DBG(1, "%s: ka = %#lx, sp = %#lx, frame_size = %zu\n", in get_sigframe()
167 __func__, (unsigned long)ka, sp, frame_size); in get_sigframe()
171 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) in get_sigframe()
172 sp = (current->sas_ss_sp + 0x7f) & ~0x3f; /* Stacks grow up! */ in get_sigframe()
174 DBG(1, "%s: Returning sp = %#lx\n", __func__, (unsigned long)sp); in get_sigframe()
175 return (void __user *) sp; /* Stacks grow up. Fun. */ in get_sigframe()
189 /* regs->iaoq is undefined in the syscall return path */ in setup_sigcontext()
190 err |= __put_user(regs->gr[31], &sc->sc_iaoq[0]); in setup_sigcontext()
191 err |= __put_user(regs->gr[31]+4, &sc->sc_iaoq[1]); in setup_sigcontext()
192 err |= __put_user(regs->sr[3], &sc->sc_iasq[0]); in setup_sigcontext()
193 err |= __put_user(regs->sr[3], &sc->sc_iasq[1]); in setup_sigcontext()
195 __func__, regs->gr[31], regs->gr[31]+4); in setup_sigcontext()
197 err |= __copy_to_user(sc->sc_iaoq, regs->iaoq, sizeof(regs->iaoq)); in setup_sigcontext()
198 err |= __copy_to_user(sc->sc_iasq, regs->iasq, sizeof(regs->iasq)); in setup_sigcontext()
200 __func__, regs->iaoq[0], regs->iaoq[1]); in setup_sigcontext()
203 err |= __put_user(flags, &sc->sc_flags); in setup_sigcontext()
204 err |= __copy_to_user(sc->sc_gr, regs->gr, sizeof(regs->gr)); in setup_sigcontext()
205 err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr)); in setup_sigcontext()
206 err |= __put_user(regs->sar, &sc->sc_sar); in setup_sigcontext()
207 DBG(1, "%s: r28 is %ld\n", __func__, regs->gr[28]); in setup_sigcontext()
225 usp = (regs->gr[30] & ~(0x01UL)); in setup_rt_frame()
229 /* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */ in setup_rt_frame()
234 frame = get_sigframe(&ksig->ka, usp, sigframe_size); in setup_rt_frame()
236 DBG(1, "%s: frame %p info %p\n", __func__, frame, &ksig->info); in setup_rt_frame()
239 if (start >= TASK_SIZE_MAX - sigframe_size) in setup_rt_frame()
240 return -EFAULT; in setup_rt_frame()
247 DBG(1, "%s: frame->info = 0x%p\n", __func__, &compat_frame->info); in setup_rt_frame()
248 err |= copy_siginfo_to_user32(&compat_frame->info, &ksig->info); in setup_rt_frame()
249 err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]); in setup_rt_frame()
250 DBG(1, "%s: frame->uc = 0x%p\n", __func__, &compat_frame->uc); in setup_rt_frame()
251 DBG(1, "%s: frame->uc.uc_mcontext = 0x%p\n", in setup_rt_frame()
252 __func__, &compat_frame->uc.uc_mcontext); in setup_rt_frame()
253 err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, in setup_rt_frame()
254 &compat_frame->regs, regs, in_syscall); in setup_rt_frame()
255 err |= put_compat_sigset(&compat_frame->uc.uc_sigmask, set, in setup_rt_frame()
260 DBG(1, "%s: frame->info = 0x%p\n", __func__, &frame->info); in setup_rt_frame()
261 err |= copy_siginfo_to_user(&frame->info, &ksig->info); in setup_rt_frame()
262 err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]); in setup_rt_frame()
263 DBG(1, "%s: frame->uc = 0x%p\n", __func__, &frame->uc); in setup_rt_frame()
264 DBG(1, "%s: frame->uc.uc_mcontext = 0x%p\n", in setup_rt_frame()
265 __func__, &frame->uc.uc_mcontext); in setup_rt_frame()
266 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall); in setup_rt_frame()
268 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); in setup_rt_frame()
272 return -EFAULT; in setup_rt_frame()
284 haddr = A(ksig->ka.sa.sa_handler); in setup_rt_frame()
296 return -EFAULT; in setup_rt_frame()
299 regs->gr[19] = fdesc.gp; in setup_rt_frame()
309 return -EFAULT; in setup_rt_frame()
312 regs->gr[19] = fdesc.gp; in setup_rt_frame()
314 __func__, haddr, regs->gr[19], in_syscall); in setup_rt_frame()
321 regs->gr[31] = haddr; in setup_rt_frame()
334 when we return to userspace. Note the semantics -- we in setup_rt_frame()
337 http://sources.redhat.com/ml/gdb/2004-11/msg00245.html in setup_rt_frame()
339 if (pa_psw(current)->r) { in setup_rt_frame()
340 pa_psw(current)->r = 0; in setup_rt_frame()
342 mtctl(-1, 0); in setup_rt_frame()
345 regs->gr[0] = psw; in setup_rt_frame()
346 regs->iaoq[0] = haddr | PRIV_USER; in setup_rt_frame()
347 regs->iaoq[1] = regs->iaoq[0] + 4; in setup_rt_frame()
350 regs->gr[2] = rp; /* userland return pointer */ in setup_rt_frame()
351 regs->gr[26] = ksig->sig; /* signal number */ in setup_rt_frame()
355 regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ in setup_rt_frame()
356 regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ in setup_rt_frame()
360 regs->gr[25] = A(&frame->info); /* siginfo pointer */ in setup_rt_frame()
361 regs->gr[24] = A(&frame->uc); /* ucontext pointer */ in setup_rt_frame()
365 regs->gr[30], sigframe_size, in setup_rt_frame()
366 regs->gr[30] + sigframe_size); in setup_rt_frame()
368 regs->gr[30] = (A(frame) + sigframe_size); in setup_rt_frame()
371 DBG(1, "%s: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n", in setup_rt_frame()
372 __func__, current->comm, current->pid, frame, regs->gr[30], in setup_rt_frame()
373 regs->iaoq[0], regs->iaoq[1], rp); in setup_rt_frame()
389 __func__, ksig->sig, &ksig->ka, &ksig->info, oldset, regs); in handle_signal()
397 DBG(1, "%s: Exit (success), regs->gr[28] = %ld\n", in handle_signal()
398 __func__, regs->gr[28]); in handle_signal()
415 * In some cases a register-to-register copy instruction might have in check_syscallno_in_delay_branch()
423 regs->gr[31] -= 8; /* delayed branching */ in check_syscallno_in_delay_branch()
426 uaddr = (u32 __user *) ((regs->gr[31] & ~3) + 4); in check_syscallno_in_delay_branch()
439 /* Check if delay branch uses "copy %rX,%r20" */ in check_syscallno_in_delay_branch()
442 regs->gr[source_reg] = regs->gr[20]; in check_syscallno_in_delay_branch()
447 current->comm, task_pid_nr(current), opcode); in check_syscallno_in_delay_branch()
453 if (regs->orig_r28) in syscall_restart()
455 regs->orig_r28 = 1; /* no more restarts */ in syscall_restart()
458 __func__, regs->orig_r28, task_pid_nr(current), regs->gr[20]); in syscall_restart()
461 switch (regs->gr[28]) { in syscall_restart()
462 case -ERESTART_RESTARTBLOCK: in syscall_restart()
463 case -ERESTARTNOHAND: in syscall_restart()
464 DBG(1, "%s: ERESTARTNOHAND: returning -EINTR\n", __func__); in syscall_restart()
465 regs->gr[28] = -EINTR; in syscall_restart()
467 case -ERESTARTSYS: in syscall_restart()
468 if (!(ka->sa.sa_flags & SA_RESTART)) { in syscall_restart()
469 DBG(1, "%s: ERESTARTSYS: putting -EINTR pid %d\n", in syscall_restart()
471 regs->gr[28] = -EINTR; in syscall_restart()
475 case -ERESTARTNOINTR: in syscall_restart()
476 DBG(1, "%s: %ld\n", __func__, regs->gr[28]); in syscall_restart()
485 if (regs->orig_r28) in insert_restart_trampoline()
487 regs->orig_r28 = 1; /* no more restarts */ in insert_restart_trampoline()
490 __func__, regs->gr[28], task_pid_nr(current)); in insert_restart_trampoline()
492 switch (regs->gr[28]) { in insert_restart_trampoline()
493 case -ERESTART_RESTARTBLOCK: { in insert_restart_trampoline()
494 /* Restart the system call - no handlers present */ in insert_restart_trampoline()
495 unsigned int *usp = (unsigned int *)regs->gr[30]; in insert_restart_trampoline()
500 if (A(&usp[0]) >= TASK_SIZE_MAX - 5 * sizeof(int)) in insert_restart_trampoline()
508 * 4: <2nd half for 64-bit> in insert_restart_trampoline()
512 err |= put_user(regs->gr[31] >> 32, &usp[0]); in insert_restart_trampoline()
513 err |= put_user(regs->gr[31] & 0xffffffff, &usp[1]); in insert_restart_trampoline()
518 err |= put_user(regs->gr[31], &usp[0]); in insert_restart_trampoline()
523 regs->gr[31] = rp; in insert_restart_trampoline()
527 case -EINTR: in insert_restart_trampoline()
530 case -ERESTARTNOHAND: in insert_restart_trampoline()
531 case -ERESTARTSYS: in insert_restart_trampoline()
532 case -ERESTARTNOINTR: in insert_restart_trampoline()
533 DBG(1, "%s: Type %ld\n", __func__, regs->gr[28]); in insert_restart_trampoline()
542 * We need to be able to restore the syscall arguments (r21-r26) to
544 * pt_regs structure (it's okay to do so since they are caller-save
575 DBG(1, "%s: Exit (not delivered), regs->gr[28] = %ld orig_r28 = %ld pid %d\n", in do_signal()
576 __func__, regs->gr[28], regs->orig_r28, task_pid_nr(current)); in do_signal()