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
This commit is contained in:
Edward Tomasz Napierala 2020-09-15 16:41:21 +00:00
parent 160ea95362
commit c26391f4dd
9 changed files with 47 additions and 8 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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,

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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,

View File

@ -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;
}