···11+// SPDX-License-Identifier: GPL-2.022+// Copyright (C) 2005-2017 Andes Technology Corporation33+44+#ifndef _ASMNDS32_SIGCONTEXT_H55+#define _ASMNDS32_SIGCONTEXT_H66+77+/*88+ * Signal context structure - contains all info to do with the state99+ * before the signal handler was invoked. Note: only add new entries1010+ * to the end of the structure.1111+ */1212+1313+struct zol_struct {1414+ unsigned long nds32_lc; /* $LC */1515+ unsigned long nds32_le; /* $LE */1616+ unsigned long nds32_lb; /* $LB */1717+};1818+1919+struct sigcontext {2020+ unsigned long trap_no;2121+ unsigned long error_code;2222+ unsigned long oldmask;2323+ unsigned long nds32_r0;2424+ unsigned long nds32_r1;2525+ unsigned long nds32_r2;2626+ unsigned long nds32_r3;2727+ unsigned long nds32_r4;2828+ unsigned long nds32_r5;2929+ unsigned long nds32_r6;3030+ unsigned long nds32_r7;3131+ unsigned long nds32_r8;3232+ unsigned long nds32_r9;3333+ unsigned long nds32_r10;3434+ unsigned long nds32_r11;3535+ unsigned long nds32_r12;3636+ unsigned long nds32_r13;3737+ unsigned long nds32_r14;3838+ unsigned long nds32_r15;3939+ unsigned long nds32_r16;4040+ unsigned long nds32_r17;4141+ unsigned long nds32_r18;4242+ unsigned long nds32_r19;4343+ unsigned long nds32_r20;4444+ unsigned long nds32_r21;4545+ unsigned long nds32_r22;4646+ unsigned long nds32_r23;4747+ unsigned long nds32_r24;4848+ unsigned long nds32_r25;4949+ unsigned long nds32_fp; /* $r28 */5050+ unsigned long nds32_gp; /* $r29 */5151+ unsigned long nds32_lp; /* $r30 */5252+ unsigned long nds32_sp; /* $r31 */5353+ unsigned long nds32_ipc;5454+ unsigned long fault_address;5555+ unsigned long used_math_flag;5656+ /* FPU Registers */5757+ struct zol_struct zol;5858+};5959+6060+#endif
+324
arch/nds32/kernel/signal.c
···11+// SPDX-License-Identifier: GPL-2.022+// Copyright (C) 2005-2017 Andes Technology Corporation33+44+#include <linux/errno.h>55+#include <linux/signal.h>66+#include <linux/ptrace.h>77+#include <linux/personality.h>88+#include <linux/freezer.h>99+#include <linux/tracehook.h>1010+#include <linux/uaccess.h>1111+1212+#include <asm/cacheflush.h>1313+#include <asm/ucontext.h>1414+#include <asm/unistd.h>1515+1616+#include <asm/ptrace.h>1717+#include <asm/vdso.h>1818+1919+struct rt_sigframe {2020+ struct siginfo info;2121+ struct ucontext uc;2222+};2323+2424+static int restore_sigframe(struct pt_regs *regs,2525+ struct rt_sigframe __user * sf)2626+{2727+ sigset_t set;2828+ int err;2929+3030+ err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));3131+ if (err == 0) {3232+ set_current_blocked(&set);3333+ }3434+3535+ __get_user_error(regs->uregs[0], &sf->uc.uc_mcontext.nds32_r0, err);3636+ __get_user_error(regs->uregs[1], &sf->uc.uc_mcontext.nds32_r1, err);3737+ __get_user_error(regs->uregs[2], &sf->uc.uc_mcontext.nds32_r2, err);3838+ __get_user_error(regs->uregs[3], &sf->uc.uc_mcontext.nds32_r3, err);3939+ __get_user_error(regs->uregs[4], &sf->uc.uc_mcontext.nds32_r4, err);4040+ __get_user_error(regs->uregs[5], &sf->uc.uc_mcontext.nds32_r5, err);4141+ __get_user_error(regs->uregs[6], &sf->uc.uc_mcontext.nds32_r6, err);4242+ __get_user_error(regs->uregs[7], &sf->uc.uc_mcontext.nds32_r7, err);4343+ __get_user_error(regs->uregs[8], &sf->uc.uc_mcontext.nds32_r8, err);4444+ __get_user_error(regs->uregs[9], &sf->uc.uc_mcontext.nds32_r9, err);4545+ __get_user_error(regs->uregs[10], &sf->uc.uc_mcontext.nds32_r10, err);4646+ __get_user_error(regs->uregs[11], &sf->uc.uc_mcontext.nds32_r11, err);4747+ __get_user_error(regs->uregs[12], &sf->uc.uc_mcontext.nds32_r12, err);4848+ __get_user_error(regs->uregs[13], &sf->uc.uc_mcontext.nds32_r13, err);4949+ __get_user_error(regs->uregs[14], &sf->uc.uc_mcontext.nds32_r14, err);5050+ __get_user_error(regs->uregs[15], &sf->uc.uc_mcontext.nds32_r15, err);5151+ __get_user_error(regs->uregs[16], &sf->uc.uc_mcontext.nds32_r16, err);5252+ __get_user_error(regs->uregs[17], &sf->uc.uc_mcontext.nds32_r17, err);5353+ __get_user_error(regs->uregs[18], &sf->uc.uc_mcontext.nds32_r18, err);5454+ __get_user_error(regs->uregs[19], &sf->uc.uc_mcontext.nds32_r19, err);5555+ __get_user_error(regs->uregs[20], &sf->uc.uc_mcontext.nds32_r20, err);5656+ __get_user_error(regs->uregs[21], &sf->uc.uc_mcontext.nds32_r21, err);5757+ __get_user_error(regs->uregs[22], &sf->uc.uc_mcontext.nds32_r22, err);5858+ __get_user_error(regs->uregs[23], &sf->uc.uc_mcontext.nds32_r23, err);5959+ __get_user_error(regs->uregs[24], &sf->uc.uc_mcontext.nds32_r24, err);6060+ __get_user_error(regs->uregs[25], &sf->uc.uc_mcontext.nds32_r25, err);6161+6262+ __get_user_error(regs->fp, &sf->uc.uc_mcontext.nds32_fp, err);6363+ __get_user_error(regs->gp, &sf->uc.uc_mcontext.nds32_gp, err);6464+ __get_user_error(regs->lp, &sf->uc.uc_mcontext.nds32_lp, err);6565+ __get_user_error(regs->sp, &sf->uc.uc_mcontext.nds32_sp, err);6666+ __get_user_error(regs->ipc, &sf->uc.uc_mcontext.nds32_ipc, err);6767+#if defined(CONFIG_HWZOL)6868+ __get_user_error(regs->lc, &sf->uc.uc_mcontext.zol.nds32_lc, err);6969+ __get_user_error(regs->le, &sf->uc.uc_mcontext.zol.nds32_le, err);7070+ __get_user_error(regs->lb, &sf->uc.uc_mcontext.zol.nds32_lb, err);7171+#endif7272+7373+ /*7474+ * Avoid sys_rt_sigreturn() restarting.7575+ */7676+ forget_syscall(regs);7777+ return err;7878+}7979+8080+asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)8181+{8282+ struct rt_sigframe __user *frame;8383+8484+ /* Always make any pending restarted system calls return -EINTR */8585+ current->restart_block.fn = do_no_restart_syscall;8686+8787+ /*8888+ * Since we stacked the signal on a 64-bit boundary,8989+ * then 'sp' should be two-word aligned here. If it's9090+ * not, then the user is trying to mess with us.9191+ */9292+ if (regs->sp & 7)9393+ goto badframe;9494+9595+ frame = (struct rt_sigframe __user *)regs->sp;9696+9797+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))9898+ goto badframe;9999+100100+ if (restore_sigframe(regs, frame))101101+ goto badframe;102102+103103+ if (restore_altstack(&frame->uc.uc_stack))104104+ goto badframe;105105+106106+ return regs->uregs[0];107107+108108+badframe:109109+ force_sig(SIGSEGV, current);110110+ return 0;111111+}112112+113113+static int114114+setup_sigframe(struct rt_sigframe __user * sf, struct pt_regs *regs,115115+ sigset_t * set)116116+{117117+ int err = 0;118118+119119+ __put_user_error(regs->uregs[0], &sf->uc.uc_mcontext.nds32_r0, err);120120+ __put_user_error(regs->uregs[1], &sf->uc.uc_mcontext.nds32_r1, err);121121+ __put_user_error(regs->uregs[2], &sf->uc.uc_mcontext.nds32_r2, err);122122+ __put_user_error(regs->uregs[3], &sf->uc.uc_mcontext.nds32_r3, err);123123+ __put_user_error(regs->uregs[4], &sf->uc.uc_mcontext.nds32_r4, err);124124+ __put_user_error(regs->uregs[5], &sf->uc.uc_mcontext.nds32_r5, err);125125+ __put_user_error(regs->uregs[6], &sf->uc.uc_mcontext.nds32_r6, err);126126+ __put_user_error(regs->uregs[7], &sf->uc.uc_mcontext.nds32_r7, err);127127+ __put_user_error(regs->uregs[8], &sf->uc.uc_mcontext.nds32_r8, err);128128+ __put_user_error(regs->uregs[9], &sf->uc.uc_mcontext.nds32_r9, err);129129+ __put_user_error(regs->uregs[10], &sf->uc.uc_mcontext.nds32_r10, err);130130+ __put_user_error(regs->uregs[11], &sf->uc.uc_mcontext.nds32_r11, err);131131+ __put_user_error(regs->uregs[12], &sf->uc.uc_mcontext.nds32_r12, err);132132+ __put_user_error(regs->uregs[13], &sf->uc.uc_mcontext.nds32_r13, err);133133+ __put_user_error(regs->uregs[14], &sf->uc.uc_mcontext.nds32_r14, err);134134+ __put_user_error(regs->uregs[15], &sf->uc.uc_mcontext.nds32_r15, err);135135+ __put_user_error(regs->uregs[16], &sf->uc.uc_mcontext.nds32_r16, err);136136+ __put_user_error(regs->uregs[17], &sf->uc.uc_mcontext.nds32_r17, err);137137+ __put_user_error(regs->uregs[18], &sf->uc.uc_mcontext.nds32_r18, err);138138+ __put_user_error(regs->uregs[19], &sf->uc.uc_mcontext.nds32_r19, err);139139+ __put_user_error(regs->uregs[20], &sf->uc.uc_mcontext.nds32_r20, err);140140+141141+ __put_user_error(regs->uregs[21], &sf->uc.uc_mcontext.nds32_r21, err);142142+ __put_user_error(regs->uregs[22], &sf->uc.uc_mcontext.nds32_r22, err);143143+ __put_user_error(regs->uregs[23], &sf->uc.uc_mcontext.nds32_r23, err);144144+ __put_user_error(regs->uregs[24], &sf->uc.uc_mcontext.nds32_r24, err);145145+ __put_user_error(regs->uregs[25], &sf->uc.uc_mcontext.nds32_r25, err);146146+ __put_user_error(regs->fp, &sf->uc.uc_mcontext.nds32_fp, err);147147+ __put_user_error(regs->gp, &sf->uc.uc_mcontext.nds32_gp, err);148148+ __put_user_error(regs->lp, &sf->uc.uc_mcontext.nds32_lp, err);149149+ __put_user_error(regs->sp, &sf->uc.uc_mcontext.nds32_sp, err);150150+ __put_user_error(regs->ipc, &sf->uc.uc_mcontext.nds32_ipc, err);151151+#if defined(CONFIG_HWZOL)152152+ __put_user_error(regs->lc, &sf->uc.uc_mcontext.zol.nds32_lc, err);153153+ __put_user_error(regs->le, &sf->uc.uc_mcontext.zol.nds32_le, err);154154+ __put_user_error(regs->lb, &sf->uc.uc_mcontext.zol.nds32_lb, err);155155+#endif156156+157157+ __put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no,158158+ err);159159+ __put_user_error(current->thread.error_code,160160+ &sf->uc.uc_mcontext.error_code, err);161161+ __put_user_error(current->thread.address,162162+ &sf->uc.uc_mcontext.fault_address, err);163163+ __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err);164164+165165+ err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));166166+167167+ return err;168168+}169169+170170+static inline void __user *get_sigframe(struct ksignal *ksig,171171+ struct pt_regs *regs, int framesize)172172+{173173+ unsigned long sp;174174+175175+ /* Default to using normal stack */176176+ sp = regs->sp;177177+178178+ /*179179+ * If we are on the alternate signal stack and would overflow it, don't.180180+ * Return an always-bogus address instead so we will die with SIGSEGV.181181+ */182182+ if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))183183+ return (void __user __force *)(-1UL);184184+185185+ /* This is the X/Open sanctioned signal stack switching. */186186+ sp = (sigsp(sp, ksig) - framesize);187187+188188+ /*189189+ * nds32 mandates 8-byte alignment190190+ */191191+ sp &= ~0x7UL;192192+193193+ return (void __user *)sp;194194+}195195+196196+static int197197+setup_return(struct pt_regs *regs, struct ksignal *ksig, void __user * frame)198198+{199199+ unsigned long handler = (unsigned long)ksig->ka.sa.sa_handler;200200+ unsigned long retcode;201201+202202+ retcode = VDSO_SYMBOL(current->mm->context.vdso, rt_sigtramp);203203+ regs->uregs[0] = ksig->sig;204204+ regs->sp = (unsigned long)frame;205205+ regs->lp = retcode;206206+ regs->ipc = handler;207207+208208+ return 0;209209+}210210+211211+static int212212+setup_rt_frame(struct ksignal *ksig, sigset_t * set, struct pt_regs *regs)213213+{214214+ struct rt_sigframe __user *frame =215215+ get_sigframe(ksig, regs, sizeof(*frame));216216+ int err = 0;217217+218218+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))219219+ return -EFAULT;220220+221221+ __put_user_error(0, &frame->uc.uc_flags, err);222222+ __put_user_error(NULL, &frame->uc.uc_link, err);223223+224224+ err |= __save_altstack(&frame->uc.uc_stack, regs->sp);225225+ err |= setup_sigframe(frame, regs, set);226226+ if (err == 0) {227227+ setup_return(regs, ksig, frame);228228+ if (ksig->ka.sa.sa_flags & SA_SIGINFO) {229229+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);230230+ regs->uregs[1] = (unsigned long)&frame->info;231231+ regs->uregs[2] = (unsigned long)&frame->uc;232232+ }233233+ }234234+ return err;235235+}236236+237237+/*238238+ * OK, we're invoking a handler239239+ */240240+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)241241+{242242+ int ret;243243+ sigset_t *oldset = sigmask_to_save();244244+245245+ if (in_syscall(regs)) {246246+ /* Avoid additional syscall restarting via ret_slow_syscall. */247247+ forget_syscall(regs);248248+249249+ switch (regs->uregs[0]) {250250+ case -ERESTART_RESTARTBLOCK:251251+ case -ERESTARTNOHAND:252252+ regs->uregs[0] = -EINTR;253253+ break;254254+ case -ERESTARTSYS:255255+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {256256+ regs->uregs[0] = -EINTR;257257+ break;258258+ }259259+ case -ERESTARTNOINTR:260260+ regs->uregs[0] = regs->orig_r0;261261+ regs->ipc -= 4;262262+ break;263263+ }264264+ }265265+ /*266266+ * Set up the stack frame267267+ */268268+ ret = setup_rt_frame(ksig, oldset, regs);269269+270270+ signal_setup_done(ret, ksig, 0);271271+}272272+273273+/*274274+ * Note that 'init' is a special process: it doesn't get signals it doesn't275275+ * want to handle. Thus you cannot kill init even with a SIGKILL even by276276+ * mistake.277277+ *278278+ * Note that we go through the signals twice: once to check the signals that279279+ * the kernel can handle, and then we build all the user-level signal handling280280+ * stack-frames in one go after that.281281+ */282282+static void do_signal(struct pt_regs *regs)283283+{284284+ struct ksignal ksig;285285+286286+ if (get_signal(&ksig)) {287287+ handle_signal(&ksig, regs);288288+ return;289289+ }290290+291291+ /*292292+ * If we were from a system call, check for system call restarting...293293+ */294294+ if (in_syscall(regs)) {295295+ /* Restart the system call - no handlers present */296296+297297+ /* Avoid additional syscall restarting via ret_slow_syscall. */298298+ forget_syscall(regs);299299+300300+ switch (regs->uregs[0]) {301301+ case -ERESTART_RESTARTBLOCK:302302+ regs->uregs[15] = __NR_restart_syscall;303303+ case -ERESTARTNOHAND:304304+ case -ERESTARTSYS:305305+ case -ERESTARTNOINTR:306306+ regs->uregs[0] = regs->orig_r0;307307+ regs->ipc -= 0x4;308308+ break;309309+ }310310+ }311311+ restore_saved_sigmask();312312+}313313+314314+asmlinkage void315315+do_notify_resume(struct pt_regs *regs, unsigned int thread_flags)316316+{317317+ if (thread_flags & _TIF_SIGPENDING)318318+ do_signal(regs);319319+320320+ if (thread_flags & _TIF_NOTIFY_RESUME) {321321+ clear_thread_flag(TIF_NOTIFY_RESUME);322322+ tracehook_notify_resume(regs);323323+ }324324+}