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