Module Name: src
Committed By: hannken
Date: Mon Mar 20 11:19:30 UTC 2023
Modified Files:
src/sys/arch/sparc/sparc: syscall.c vm_machdep.c
src/tests/lib/libc/sys: t_ptrace_syscall_wait.h
Log Message:
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.32 src/sys/arch/sparc/sparc/syscall.c
cvs rdiff -u -r1.107 -r1.108 src/sys/arch/sparc/sparc/vm_machdep.c
cvs rdiff -u -r1.2 -r1.3 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.32
--- src/sys/arch/sparc/sparc/syscall.c:1.31 Sat Apr 6 11:54:20 2019
+++ src/sys/arch/sparc/sparc/syscall.c Mon Mar 20 11:19:29 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: syscall.c,v 1.31 2019/04/06 11:54:20 kamil Exp $ */
+/* $NetBSD: syscall.c,v 1.32 2023/03/20 11:19:29 hannken 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.32 2023/03/20 11:19:29 hannken 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.108
--- 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 Mon Mar 20 11:19:29 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.108 2023/03/20 11:19:29 hannken 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.108 2023/03/20 11:19:29 hannken 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.3
--- 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 Mon Mar 20 11:19:30 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.3 2023/03/20 11:19:30 hannken 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) {