Module Name:    src
Committed By:   martin
Date:           Wed Mar 22 19:00:47 UTC 2023

Modified Files:
        src/sys/arch/sparc/sparc [netbsd-10]: syscall.c vm_machdep.c
        src/tests/lib/libc/sys [netbsd-10]: t_ptrace_syscall_wait.h

Log Message:
Pull up following revision(s) (requested by hannken in ticket #124):

        tests/lib/libc/sys/t_ptrace_syscall_wait.h: revision 1.3
        sys/arch/sparc/sparc/syscall.c: revision 1.32
        sys/arch/sparc/sparc/vm_machdep.c: revision 1.108

Adjust pc/npc before syscall allowing EJUSTRETURN to return
to the next instruction.  Only ERESTART should return to
the same instruction.  Differences to sparc64 reduced.

Test t_ptrace_wait:syscallemu1 now passes on sparc.

Fixes PR kern/52166 "syscallemu does not work on sparc (32-bit)"

Ok: Martin Husemann


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.31.30.1 src/sys/arch/sparc/sparc/syscall.c
cvs rdiff -u -r1.107 -r1.107.70.1 src/sys/arch/sparc/sparc/vm_machdep.c
cvs rdiff -u -r1.2 -r1.2.2.1 src/tests/lib/libc/sys/t_ptrace_syscall_wait.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sparc/sparc/syscall.c
diff -u src/sys/arch/sparc/sparc/syscall.c:1.31 src/sys/arch/sparc/sparc/syscall.c:1.31.30.1
--- src/sys/arch/sparc/sparc/syscall.c:1.31	Sat Apr  6 11:54:20 2019
+++ src/sys/arch/sparc/sparc/syscall.c	Wed Mar 22 19:00:47 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: syscall.c,v 1.31 2019/04/06 11:54:20 kamil Exp $ */
+/*	$NetBSD: syscall.c,v 1.31.30.1 2023/03/22 19:00:47 martin Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -49,7 +49,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.31 2019/04/06 11:54:20 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.31.30.1 2023/03/22 19:00:47 martin Exp $");
 
 #include "opt_sparc_arch.h"
 #include "opt_multiprocessor.h"
@@ -106,6 +106,17 @@ handle_new(struct trapframe *tf, registe
 {
 	int new = *code & (SYSCALL_G7RFLAG|SYSCALL_G2RFLAG|SYSCALL_G5RFLAG);
 	*code &= ~(SYSCALL_G7RFLAG|SYSCALL_G2RFLAG|SYSCALL_G5RFLAG);
+	if (new) {
+		/* jmp %g5, (or %g2 or %g7, deprecated) on success */
+		if (__predict_true((new & SYSCALL_G5RFLAG) == SYSCALL_G5RFLAG))
+			tf->tf_pc = tf->tf_global[5];
+		else if (new & SYSCALL_G2RFLAG)
+			tf->tf_pc = tf->tf_global[2];
+		else
+			tf->tf_pc = tf->tf_global[7];
+	} else {
+		tf->tf_pc = tf->tf_npc;
+	}
 	return new;
 }
 
@@ -207,7 +218,7 @@ syscall(register_t code, struct trapfram
 	int error, new;
 	union args args;
 	union rval rval;
-	register_t i;
+	int opc, onpc;
 	u_quad_t sticks;
 
 	curcpu()->ci_data.cpu_nsyscall++;	/* XXXSMP */
@@ -221,8 +232,18 @@ syscall(register_t code, struct trapfram
 #ifdef FPU_DEBUG
 	save_fpu(tf);
 #endif
+
+	/*
+	 * save pc/npc in case of ERESTART
+	 * adjust pc/npc to new values
+	 */
+	opc = tf->tf_pc;
+	onpc = tf->tf_npc;
+
 	new = handle_new(tf, &code);
 
+	tf->tf_npc = tf->tf_pc + 4;
+
 	if ((error = getargs(p, tf, &code, &callp, &args)) != 0)
 		goto bad;
 
@@ -236,29 +257,17 @@ syscall(register_t code, struct trapfram
 		/* Note: fork() does not return here in the child */
 		tf->tf_out[0] = rval.o[0];
 		tf->tf_out[1] = rval.o[1];
-		if (new) {
-			/* jmp %g5, (or %g2 or %g7, deprecated) on success */
-			if (__predict_true((new & SYSCALL_G5RFLAG) ==
-					SYSCALL_G5RFLAG))
-				i = tf->tf_global[5];
-			else if (new & SYSCALL_G2RFLAG)
-				i = tf->tf_global[2];
-			else
-				i = tf->tf_global[7];
-			if (i & 3) {
-				error = EINVAL;
-				goto bad;
-			}
-		} else {
+		if (!new) {
 			/* old system call convention: clear C on success */
 			tf->tf_psr &= ~PSR_C;	/* success */
-			i = tf->tf_npc;
 		}
-		tf->tf_pc = i;
-		tf->tf_npc = i + 4;
 		break;
 
 	case ERESTART:
+		tf->tf_pc = opc;
+		tf->tf_npc = onpc;
+		break;
+
 	case EJUSTRETURN:
 		/* nothing to do */
 		break;
@@ -269,9 +278,8 @@ syscall(register_t code, struct trapfram
 			error = p->p_emul->e_errno[error];
 		tf->tf_out[0] = error;
 		tf->tf_psr |= PSR_C;	/* fail */
-		i = tf->tf_npc;
-		tf->tf_pc = i;
-		tf->tf_npc = i + 4;
+		tf->tf_pc = onpc;
+		tf->tf_npc = tf->tf_pc + 4;
 		break;
 	}
 

Index: src/sys/arch/sparc/sparc/vm_machdep.c
diff -u src/sys/arch/sparc/sparc/vm_machdep.c:1.107 src/sys/arch/sparc/sparc/vm_machdep.c:1.107.70.1
--- src/sys/arch/sparc/sparc/vm_machdep.c:1.107	Sun Feb 19 21:06:30 2012
+++ src/sys/arch/sparc/sparc/vm_machdep.c	Wed Mar 22 19:00:47 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_machdep.c,v 1.107 2012/02/19 21:06:30 rmind Exp $ */
+/*	$NetBSD: vm_machdep.c,v 1.107.70.1 2023/03/22 19:00:47 martin Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -49,7 +49,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.107 2012/02/19 21:06:30 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.107.70.1 2023/03/22 19:00:47 martin Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -268,8 +268,6 @@ cpu_lwp_fork(struct lwp *l1, struct lwp 
 	 * to user mode.
 	 */
 	/*tf2->tf_psr &= ~PSR_C;   -* success */
-	tf2->tf_pc = tf2->tf_npc;
-	tf2->tf_npc = tf2->tf_pc + 4;
 
 	/* Set return values in child mode */
 	tf2->tf_out[0] = 0;

Index: src/tests/lib/libc/sys/t_ptrace_syscall_wait.h
diff -u src/tests/lib/libc/sys/t_ptrace_syscall_wait.h:1.2 src/tests/lib/libc/sys/t_ptrace_syscall_wait.h:1.2.2.1
--- src/tests/lib/libc/sys/t_ptrace_syscall_wait.h:1.2	Thu Oct 21 17:02:37 2021
+++ src/tests/lib/libc/sys/t_ptrace_syscall_wait.h	Wed Mar 22 19:00:47 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_ptrace_syscall_wait.h,v 1.2 2021/10/21 17:02:37 gson Exp $	*/
+/*	$NetBSD: t_ptrace_syscall_wait.h,v 1.2.2.1 2023/03/22 19:00:47 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016, 2017, 2018, 2019, 2020 The NetBSD Foundation, Inc.
@@ -206,11 +206,6 @@ ATF_TC_BODY(syscallemu1, tc)
 	int status;
 #endif
 
-#if defined(__sparc__) && !defined(__sparc64__)
-	/* syscallemu does not work on sparc (32-bit) */
-	atf_tc_expect_fail("PR kern/52166");
-#endif
-
 	DPRINTF("Before forking process PID=%d\n", getpid());
 	SYSCALL_REQUIRE((child = fork()) != -1);
 	if (child == 0) {

Reply via email to