^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2003 Broadcom Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/cache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/abi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/compat-signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/sim.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/ucontext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/fpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/cpu-features.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/war.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "signal-common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define __NR_N32_restart_syscall 6214
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct ucontextn32 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u32 uc_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) s32 uc_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) compat_stack_t uc_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct sigcontext uc_mcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) compat_sigset_t uc_sigmask; /* mask last for extensibility */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct rt_sigframe_n32 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u32 rs_ass[4]; /* argument save space for o32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) u32 rs_pad[2]; /* Was: signal trampoline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct compat_siginfo rs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct ucontextn32 rs_uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) asmlinkage void sysn32_rt_sigreturn(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct rt_sigframe_n32 __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct pt_regs *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) sigset_t set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) regs = current_pt_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) frame = (struct rt_sigframe_n32 __user *)regs->regs[29];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (!access_ok(frame, sizeof(*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) set_current_blocked(&set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) sig = restore_sigcontext(regs, &frame->rs_uc.uc_mcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (sig < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) else if (sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) force_sig(sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (compat_restore_altstack(&frame->rs_uc.uc_stack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Don't let your children do this ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) __asm__ __volatile__(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) "move\t$29, %0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) "j\tsyscall_exit"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) : /* no outputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) : "r" (regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Unreached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) badframe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) force_sig(SIGSEGV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static int setup_rt_frame_n32(void *sig_return, struct ksignal *ksig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct pt_regs *regs, sigset_t *set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct rt_sigframe_n32 __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) frame = get_sigframe(ksig, regs, sizeof(*frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (!access_ok(frame, sizeof (*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* Create siginfo. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Create the ucontext. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) err |= __put_user(0, &frame->rs_uc.uc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) err |= __put_user(0, &frame->rs_uc.uc_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * Arguments to signal handler:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * a0 = signal number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * a1 = 0 (should be cause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * a2 = pointer to ucontext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * $25 and c0_epc point to the signal handler, $29 points to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * the struct rt_sigframe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) regs->regs[ 4] = ksig->sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) regs->regs[ 5] = (unsigned long) &frame->rs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) regs->regs[ 6] = (unsigned long) &frame->rs_uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) regs->regs[29] = (unsigned long) frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) regs->regs[31] = (unsigned long) sig_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) current->comm, current->pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) frame, regs->cp0_epc, regs->regs[31]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct mips_abi mips_abi_n32 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .setup_rt_frame = setup_rt_frame_n32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .restart = __NR_N32_restart_syscall,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .off_sc_fpregs = offsetof(struct sigcontext, sc_fpregs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .off_sc_fpc_csr = offsetof(struct sigcontext, sc_fpc_csr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .off_sc_used_math = offsetof(struct sigcontext, sc_used_math),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .vdso = &vdso_image_n32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) };