Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Adjust pc/npc before syscall allowing EJUSTRETURN to return
details: https://anonhg.NetBSD.org/src/rev/f5579bbc8be3
branches: trunk
changeset: 373921:f5579bbc8be3
user: hannken <hannken%NetBSD.org@localhost>
date: Mon Mar 20 11:19:29 2023 +0000
description:
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
diffstat:
sys/arch/sparc/sparc/syscall.c | 54 +++++++++++++++++------------
sys/arch/sparc/sparc/vm_machdep.c | 6 +--
tests/lib/libc/sys/t_ptrace_syscall_wait.h | 7 +---
3 files changed, 34 insertions(+), 33 deletions(-)
diffs (159 lines):
diff -r e26d88ee9b3e -r f5579bbc8be3 sys/arch/sparc/sparc/syscall.c
--- a/sys/arch/sparc/sparc/syscall.c Mon Mar 20 11:07:33 2023 +0000
+++ b/sys/arch/sparc/sparc/syscall.c Mon Mar 20 11:19:29 2023 +0000
@@ -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 @@
{
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 @@
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 @@
#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 @@
/* 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 @@
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;
}
diff -r e26d88ee9b3e -r f5579bbc8be3 sys/arch/sparc/sparc/vm_machdep.c
--- a/sys/arch/sparc/sparc/vm_machdep.c Mon Mar 20 11:07:33 2023 +0000
+++ b/sys/arch/sparc/sparc/vm_machdep.c Mon Mar 20 11:19:29 2023 +0000
@@ -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 @@
* 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;
diff -r e26d88ee9b3e -r f5579bbc8be3 tests/lib/libc/sys/t_ptrace_syscall_wait.h
--- a/tests/lib/libc/sys/t_ptrace_syscall_wait.h Mon Mar 20 11:07:33 2023 +0000
+++ b/tests/lib/libc/sys/t_ptrace_syscall_wait.h Mon Mar 20 11:19:29 2023 +0000
@@ -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 @@
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) {
Home |
Main Index |
Thread Index |
Old Index