aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Tomasz Napierala <trasz@FreeBSD.org>2020-09-15 16:41:21 +0000
committerEdward Tomasz Napierala <trasz@FreeBSD.org>2020-09-15 16:41:21 +0000
commitc26391f4dd0de02dd777ee2b38c28a04464bc075 (patch)
treee6830e596f9ce8a2cd610e84b6cee4bf21f7a5e0
parent160ea95362644c14ab81535ec140def91c701d62 (diff)
downloadsrc-c26391f4dd0de02dd777ee2b38c28a04464bc075.tar.gz
src-c26391f4dd0de02dd777ee2b38c28a04464bc075.zip
Move SV_ABI_ERRNO translation into linux-specific code, to simplify
the syscall path and declutter it a bit. No functional changes intended. Reviewed by: kib (earlier version) MFC after: 2 weeks Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D26378
Notes
Notes: svn path=/head/; revision=365755
-rw-r--r--sys/amd64/amd64/vm_machdep.c2
-rw-r--r--sys/amd64/linux/linux_sysvec.c5
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c16
-rw-r--r--sys/arm/arm/vm_machdep.c2
-rw-r--r--sys/arm64/arm64/vm_machdep.c2
-rw-r--r--sys/arm64/linux/linux_sysvec.c7
-rw-r--r--sys/i386/i386/vm_machdep.c2
-rw-r--r--sys/i386/linux/linux_sysvec.c17
-rw-r--r--sys/powerpc/powerpc/exec_machdep.c2
9 files changed, 47 insertions, 8 deletions
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index b4513f1b751b..1d9eacd8a8b8 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -543,7 +543,7 @@ cpu_set_syscall_retval(struct thread *td, int error)
break;
default:
- frame->tf_rax = SV_ABI_ERRNO(td->td_proc, error);
+ frame->tf_rax = error;
frame->tf_rflags |= PSL_C;
break;
}
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
index bb80f324868c..112b17f35f9a 100644
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -219,6 +219,11 @@ linux_set_syscall_retval(struct thread *td, int error)
cpu_set_syscall_retval(td, error);
+ if (__predict_false(error != 0)) {
+ if (error != ERESTART && error != EJUSTRETURN)
+ frame->tf_rax = SV_ABI_ERRNO(td->td_proc, error);
+ }
+
/* Restore all registers. */
set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
}
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index d04d5878836c..937387fd6555 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -112,6 +112,7 @@ static void linux32_fixlimit(struct rlimit *rl, int which);
static bool linux32_trans_osrel(const Elf_Note *note, int32_t *osrel);
static void linux_vdso_install(void *param);
static void linux_vdso_deinstall(void *param);
+static void linux32_set_syscall_retval(struct thread *td, int error);
#define LINUX_T_UNKNOWN 255
static int _bsd_to_linux_trapcode[] = {
@@ -669,6 +670,19 @@ linux32_fetch_syscall_args(struct thread *td)
return (0);
}
+static void
+linux32_set_syscall_retval(struct thread *td, int error)
+{
+ struct trapframe *frame = td->td_frame;
+
+ cpu_set_syscall_retval(td, error);
+
+ if (__predict_false(error != 0)) {
+ if (error != ERESTART && error != EJUSTRETURN)
+ frame->tf_rax = SV_ABI_ERRNO(td->td_proc, error);
+ }
+}
+
/*
* Clear registers on exec
* XXX copied from ia32_signal.c.
@@ -906,7 +920,7 @@ struct sysentvec elf_linux_sysvec = {
.sv_fixlimit = linux32_fixlimit,
.sv_maxssiz = &linux32_maxssiz,
.sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_IA32 | SV_SHP,
- .sv_set_syscall_retval = cpu_set_syscall_retval,
+ .sv_set_syscall_retval = linux32_set_syscall_retval,
.sv_fetch_syscall_args = linux32_fetch_syscall_args,
.sv_syscallnames = NULL,
.sv_shared_page_base = LINUX32_SHAREDPAGE,
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index e13c8f01b0f2..16597ba8269b 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -219,7 +219,7 @@ cpu_set_syscall_retval(struct thread *td, int error)
/* nothing to do */
break;
default:
- frame->tf_r0 = SV_ABI_ERRNO(td->td_proc, error);
+ frame->tf_r0 = error;
frame->tf_spsr |= PSR_C; /* carry bit */
break;
}
diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c
index 3b928ad7cabf..b4a3e596f9ef 100644
--- a/sys/arm64/arm64/vm_machdep.c
+++ b/sys/arm64/arm64/vm_machdep.c
@@ -153,7 +153,7 @@ cpu_set_syscall_retval(struct thread *td, int error)
break;
default:
frame->tf_spsr |= PSR_C; /* carry bit */
- frame->tf_x[0] = SV_ABI_ERRNO(td->td_proc, error);
+ frame->tf_x[0] = error;
break;
}
}
diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c
index 5b33b63fba92..8619535c57e9 100644
--- a/sys/arm64/linux/linux_sysvec.c
+++ b/sys/arm64/linux/linux_sysvec.c
@@ -141,6 +141,13 @@ linux_set_syscall_retval(struct thread *td, int error)
td->td_retval[1] = td->td_frame->tf_x[1];
cpu_set_syscall_retval(td, error);
+
+ if (__predict_false(error != 0)) {
+ if (error != ERESTART && error != EJUSTRETURN) {
+ td->td_frame->tf_x[0] =
+ SV_ABI_ERRNO(td->td_proc, error);
+ }
+ }
}
static int
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index eaf0f8dd0135..d3182cb224bf 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -407,7 +407,7 @@ cpu_set_syscall_retval(struct thread *td, int error)
break;
default:
- td->td_frame->tf_eax = SV_ABI_ERRNO(td->td_proc, error);
+ td->td_frame->tf_eax = error;
td->td_frame->tf_eflags |= PSL_C;
break;
}
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 10560ac501d3..69d9ca97c526 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -792,6 +792,19 @@ linux_fetch_syscall_args(struct thread *td)
return (0);
}
+static void
+linux_set_syscall_retval(struct thread *td, int error)
+{
+ struct trapframe *frame = td->td_frame;
+
+ cpu_set_syscall_retval(td, error);
+
+ if (__predict_false(error != 0)) {
+ if (error != ERESTART && error != EJUSTRETURN)
+ frame->tf_eax = SV_ABI_ERRNO(td->td_proc, error);
+ }
+}
+
/*
* exec_setregs may initialize some registers differently than Linux
* does, thus potentially confusing Linux binaries. If necessary, we
@@ -855,7 +868,7 @@ struct sysentvec linux_sysvec = {
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_LINUX | SV_AOUT | SV_IA32 | SV_ILP32,
- .sv_set_syscall_retval = cpu_set_syscall_retval,
+ .sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = NULL,
.sv_shared_page_base = LINUX_SHAREDPAGE,
@@ -891,7 +904,7 @@ struct sysentvec elf_linux_sysvec = {
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_LINUX | SV_IA32 | SV_ILP32 | SV_SHP,
- .sv_set_syscall_retval = cpu_set_syscall_retval,
+ .sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = NULL,
.sv_shared_page_base = LINUX_SHAREDPAGE,
diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c
index d4ec621f7630..5df7f38aa3d0 100644
--- a/sys/powerpc/powerpc/exec_machdep.c
+++ b/sys/powerpc/powerpc/exec_machdep.c
@@ -955,7 +955,7 @@ cpu_set_syscall_retval(struct thread *td, int error)
tf->srr0 -= 4;
break;
default:
- tf->fixreg[FIRSTARG] = SV_ABI_ERRNO(p, error);
+ tf->fixreg[FIRSTARG] = error;
tf->cr |= 0x10000000; /* Set summary overflow */
break;
}