From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 13 May 2024 10:30:14 +0000 Subject: [PATCH] modify sin led gpio --- kernel/arch/xtensa/kernel/signal.c | 55 +++++++++++++++++++++++++++++++++---------------------- 1 files changed, 33 insertions(+), 22 deletions(-) diff --git a/kernel/arch/xtensa/kernel/signal.c b/kernel/arch/xtensa/kernel/signal.c index f88e7a0..f2b00f4 100644 --- a/kernel/arch/xtensa/kernel/signal.c +++ b/kernel/arch/xtensa/kernel/signal.c @@ -185,13 +185,13 @@ COPY(sar); #undef COPY - /* All registers were flushed to stack. Start with a prestine frame. */ + /* All registers were flushed to stack. Start with a pristine frame. */ regs->wmask = 1; regs->windowbase = 0; regs->windowstart = 1; - regs->syscall = -1; /* disable syscall checks */ + regs->syscall = NO_SYSCALL; /* disable syscall checks */ /* For PS, restore only PS.CALLINC. * Assume that all other bits are either the same as for the signal @@ -236,9 +236,9 @@ * Do a signal return; undo the signal stack. */ -asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3, - long a4, long a5, struct pt_regs *regs) +asmlinkage long xtensa_rt_sigreturn(void) { + struct pt_regs *regs = current_pt_regs(); struct rt_sigframe __user *frame; sigset_t set; int ret; @@ -251,7 +251,7 @@ frame = (struct rt_sigframe __user *) regs->areg[1]; - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + if (!access_ok(frame, sizeof(*frame))) goto badframe; if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) @@ -270,7 +270,7 @@ return ret; badframe: - force_sig(SIGSEGV, current); + force_sig(SIGSEGV); return 0; } @@ -335,7 +335,8 @@ { struct rt_sigframe *frame; int err = 0, sig = ksig->sig; - unsigned long sp, ra, tp; + unsigned long sp, ra, tp, ps; + unsigned int base; sp = regs->areg[1]; @@ -348,7 +349,7 @@ if (regs->depc > 64) panic ("Double exception sys_sigreturn\n"); - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) { + if (!access_ok(frame, sizeof(*frame))) { return -EFAULT; } @@ -385,17 +386,26 @@ /* Set up registers for signal handler; preserve the threadptr */ tp = regs->threadptr; + ps = regs->ps; start_thread(regs, (unsigned long) ksig->ka.sa.sa_handler, (unsigned long) frame); - /* Set up a stack frame for a call4 - * Note: PS.CALLINC is set to one by start_thread - */ - regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000; - regs->areg[6] = (unsigned long) sig; - regs->areg[7] = (unsigned long) &frame->info; - regs->areg[8] = (unsigned long) &frame->uc; + /* Set up a stack frame for a call4 if userspace uses windowed ABI */ + if (ps & PS_WOE_MASK) { + base = 4; + regs->areg[base] = + (((unsigned long) ra) & 0x3fffffff) | 0x40000000; + ps = (ps & ~(PS_CALLINC_MASK | PS_OWB_MASK)) | + (1 << PS_CALLINC_SHIFT); + } else { + base = 0; + regs->areg[base] = (unsigned long) ra; + } + regs->areg[base + 2] = (unsigned long) sig; + regs->areg[base + 3] = (unsigned long) &frame->info; + regs->areg[base + 4] = (unsigned long) &frame->uc; regs->threadptr = tp; + regs->ps = ps; pr_debug("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08lx\n", current->comm, current->pid, sig, frame, regs->pc); @@ -423,7 +433,7 @@ /* Are we from a system call? */ - if ((signed)regs->syscall >= 0) { + if (regs->syscall != NO_SYSCALL) { /* If so, check system call restarting.. */ @@ -438,7 +448,7 @@ regs->areg[2] = -EINTR; break; } - /* fallthrough */ + fallthrough; case -ERESTARTNOINTR: regs->areg[2] = regs->syscall; regs->pc -= 3; @@ -455,14 +465,14 @@ /* Set up the stack frame */ ret = setup_frame(&ksig, sigmask_to_save(), regs); signal_setup_done(ret, &ksig, 0); - if (current->ptrace & PT_SINGLESTEP) + if (test_thread_flag(TIF_SINGLESTEP)) task_pt_regs(current)->icountlevel = 1; return; } /* Did we come from a system call? */ - if ((signed) regs->syscall >= 0) { + if (regs->syscall != NO_SYSCALL) { /* Restart the system call - no handlers present */ switch (regs->areg[2]) { case -ERESTARTNOHAND: @@ -481,16 +491,17 @@ /* If there's no signal to deliver, we just restore the saved mask. */ restore_saved_sigmask(); - if (current->ptrace & PT_SINGLESTEP) + if (test_thread_flag(TIF_SINGLESTEP)) task_pt_regs(current)->icountlevel = 1; return; } void do_notify_resume(struct pt_regs *regs) { - if (test_thread_flag(TIF_SIGPENDING)) + if (test_thread_flag(TIF_SIGPENDING) || + test_thread_flag(TIF_NOTIFY_SIGNAL)) do_signal(regs); - if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) + if (test_thread_flag(TIF_NOTIFY_RESUME)) tracehook_notify_resume(regs); } -- Gitblit v1.6.2