common-user: Adjust system call return on FreeBSD

FreeBSD system calls return positive errno.  On the 4 hosts for
which we have support, error is indicated by the C bit set or clear.

Reviewed-by: Warner Losh <imp@bsdimp.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2021-11-23 15:18:49 +01:00
parent bbf15aaf7c
commit 5bfd125ec8
4 changed files with 44 additions and 1 deletions

View File

@ -60,17 +60,29 @@ safe_syscall_start:
cbnz w10, 2f cbnz w10, 2f
svc 0x0 svc 0x0
safe_syscall_end: safe_syscall_end:
/* code path for having successfully executed the syscall */ /* code path for having successfully executed the syscall */
#if defined(__linux__)
/* Linux kernel returns (small) negative errno. */
cmp x0, #-4096 cmp x0, #-4096
b.hi 0f b.hi 0f
#elif defined(__FreeBSD__)
/* FreeBSD kernel returns positive errno and C bit set. */
b.cs 1f
#else
#error "unsupported os"
#endif
ret ret
#if defined(__linux__)
/* code path setting errno */ /* code path setting errno */
0: neg w0, w0 0: neg w0, w0
b safe_syscall_set_errno_tail b safe_syscall_set_errno_tail
#endif
/* code path when we didn't execute the syscall */ /* code path when we didn't execute the syscall */
2: mov w0, #QEMU_ERESTARTSYS 2: mov w0, #QEMU_ERESTARTSYS
b safe_syscall_set_errno_tail 1: b safe_syscall_set_errno_tail
.cfi_endproc .cfi_endproc
.size safe_syscall_base, .-safe_syscall_base .size safe_syscall_base, .-safe_syscall_base

View File

@ -74,10 +74,19 @@ safe_syscall_start:
bne 2f bne 2f
swi 0 swi 0
safe_syscall_end: safe_syscall_end:
/* code path for having successfully executed the syscall */ /* code path for having successfully executed the syscall */
#if defined(__linux__)
/* Linux kernel returns (small) negative errno. */
cmp r0, #-4096 cmp r0, #-4096
neghi r0, r0 neghi r0, r0
bhi 1f bhi 1f
#elif defined(__FreeBSD__)
/* FreeBSD kernel returns positive errno and C bit set. */
bcs 1f
#else
#error "unsupported os"
#endif
pop { r4, r5, r6, r7, r8, pc } pop { r4, r5, r6, r7, r8, pc }
/* code path when we didn't execute the syscall */ /* code path when we didn't execute the syscall */

View File

@ -71,9 +71,18 @@ safe_syscall_start:
mov 8+16(%esp), %eax /* syscall number */ mov 8+16(%esp), %eax /* syscall number */
int $0x80 int $0x80
safe_syscall_end: safe_syscall_end:
/* code path for having successfully executed the syscall */ /* code path for having successfully executed the syscall */
#if defined(__linux__)
/* Linux kernel returns (small) negative errno. */
cmp $-4095, %eax cmp $-4095, %eax
jae 0f jae 0f
#elif defined(__FreeBSD__)
/* FreeBSD kernel returns positive errno and C bit set. */
jc 1f
#else
#error "unsupported os"
#endif
pop %ebx pop %ebx
.cfi_remember_state .cfi_remember_state
.cfi_adjust_cfa_offset -4 .cfi_adjust_cfa_offset -4
@ -90,8 +99,10 @@ safe_syscall_end:
ret ret
.cfi_restore_state .cfi_restore_state
#if defined(__linux__)
0: neg %eax 0: neg %eax
jmp 1f jmp 1f
#endif
/* code path when we didn't execute the syscall */ /* code path when we didn't execute the syscall */
2: mov $QEMU_ERESTARTSYS, %eax 2: mov $QEMU_ERESTARTSYS, %eax

View File

@ -68,9 +68,18 @@ safe_syscall_start:
jnz 2f jnz 2f
syscall syscall
safe_syscall_end: safe_syscall_end:
/* code path for having successfully executed the syscall */ /* code path for having successfully executed the syscall */
#if defined(__linux__)
/* Linux kernel returns (small) negative errno. */
cmp $-4095, %rax cmp $-4095, %rax
jae 0f jae 0f
#elif defined(__FreeBSD__)
/* FreeBSD kernel returns positive errno and C bit set. */
jc 1f
#else
#error "unsupported os"
#endif
pop %rbp pop %rbp
.cfi_remember_state .cfi_remember_state
.cfi_def_cfa_offset 8 .cfi_def_cfa_offset 8
@ -78,8 +87,10 @@ safe_syscall_end:
ret ret
.cfi_restore_state .cfi_restore_state
#if defined(__linux__)
0: neg %eax 0: neg %eax
jmp 1f jmp 1f
#endif
/* code path when we didn't execute the syscall */ /* code path when we didn't execute the syscall */
2: mov $QEMU_ERESTARTSYS, %eax 2: mov $QEMU_ERESTARTSYS, %eax