Message ID | 20211116110256.365484-9-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | linux-user: simplify safe signal handling | expand |
On Tue, Nov 16, 2021 at 4:03 AM Richard Henderson < richard.henderson@linaro.org> wrote: > From: Warner Losh <imp@bsdimp.com> > > 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. > > Signed-off-by: Warner Losh <imp@bsdimp.com> > [rth: Rebase on new safe_syscall_base api; add #error check.] > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > common-user/host/aarch64/safe-syscall.inc.S | 12 +++++++++++- > common-user/host/arm/safe-syscall.inc.S | 11 +++++++++++ > common-user/host/i386/safe-syscall.inc.S | 10 ++++++++++ > common-user/host/x86_64/safe-syscall.inc.S | 10 ++++++++++ > 4 files changed, 42 insertions(+), 1 deletion(-) > > diff --git a/common-user/host/aarch64/safe-syscall.inc.S > b/common-user/host/aarch64/safe-syscall.inc.S > index 95c60d8609..d3f065cdef 100644 > --- a/common-user/host/aarch64/safe-syscall.inc.S > +++ b/common-user/host/aarch64/safe-syscall.inc.S > @@ -65,12 +65,22 @@ safe_syscall_start: > safe_syscall_end: > > /* code path for having successfully executed the syscall */ > - cmn x0, #4095 > +#if defined(__linux__) > + /* Linux kernel returns (small) negative errno. */ > + cmn x0, #4096 > + b.hi 0f > +#elif defined(__FreeBSD__) > + /* FreeBSD kernel returns positive errno and C bit set. */ > b.cs 1f > +#else > +#error "unsupported os" > +#endif > ret > > /* code path setting errno */ > +#ifdef __linux__ > 0: neg w0, w0 /* create positive errno */ > +#endif > 1: str w0, [x11] /* store errno */ > mov x0, #-1 > ret > diff --git a/common-user/host/arm/safe-syscall.inc.S > b/common-user/host/arm/safe-syscall.inc.S > index 17839c6486..328299021d 100644 > --- a/common-user/host/arm/safe-syscall.inc.S > +++ b/common-user/host/arm/safe-syscall.inc.S > @@ -82,12 +82,23 @@ safe_syscall_start: > safe_syscall_end: > > /* code path for having successfully executed the syscall */ > +#if defined(__linux__) > + /* Linux kernel returns (small) negative errno. */ > cmp r0, #-4096 > bhi 0f > +#elif defined(__FreeBSD__) > + /* FreeBSD kernel returns positive errno and C bit set. */ > + bcs 1f > +#else > +#error "unsupported os" > +#endif > + > 9: pop { r4, r5, r6, r7, r8, r9, r10, pc } > > /* code path setting errno */ > +#ifdef __linux__ > 0: neg r0, r0 /* create positive errno */ > +#endif > 1: str r0, [r9] /* store errno */ > mov r0, #-1 > b 9b > diff --git a/common-user/host/i386/safe-syscall.inc.S > b/common-user/host/i386/safe-syscall.inc.S > index ad89521783..a9382f777e 100644 > --- a/common-user/host/i386/safe-syscall.inc.S > +++ b/common-user/host/i386/safe-syscall.inc.S > @@ -76,8 +76,16 @@ safe_syscall_start: > safe_syscall_end: > > /* code path for having successfully executed the syscall */ > +#if defined(__linux__) > + /* Linux kernel returns (small) negative errno. */ > cmp $-4095, %eax > jae 0f > +#elif defined(__FreeBSD__) > + /* FreeBSD kernel returns positive errno and C bit set. */ > + jcs 1f > I needed to change this to 'jc' and that's all google found for Intel. +#else > +#error "unsupported os" > +#endif > > 9: pop %ebx > .cfi_remember_state > @@ -97,7 +105,9 @@ safe_syscall_end: > .cfi_restore_state > > /* code path setting errno */ > +#ifdef __linux__ > 0: neg %eax /* create positive errno */ > +#endif > 1: mov 8+16(%esp), %ebx /* load errno pointer */ > mov %eax, (%ebx) /* store errno */ > mov $-1, %eax > diff --git a/common-user/host/x86_64/safe-syscall.inc.S > b/common-user/host/x86_64/safe-syscall.inc.S > index 9a0c4c93b4..36b7efe2ca 100644 > --- a/common-user/host/x86_64/safe-syscall.inc.S > +++ b/common-user/host/x86_64/safe-syscall.inc.S > @@ -75,8 +75,16 @@ safe_syscall_start: > safe_syscall_end: > > /* code path for having successfully executed the syscall */ > +#if defined(__linux__) > + /* Linux kernel returns (small) negative errno. */ > cmp $-4095, %rax > jae 0f > +#elif defined(__FreeBSD__) > + /* FreeBSD kernel returns positive errno and C bit set. */ > + jcs 1f > Likewise. > +#else > +#error "unsupported os" > +#endif > > 9: pop %rbp > .cfi_remember_state > @@ -86,7 +94,9 @@ safe_syscall_end: > .cfi_restore_state > > /* code path setting errno */ > +#ifdef __linux__ > 0: neg %eax /* create positive errno */ > +#endif > 1: mov %eax, (%rbp) /* store errno */ > mov $-1, %rax > jmp 9b > I've not yet tested this on my arm/aarch64 systems, but I think it will work there. Warner
On 11/16/21 9:58 PM, Warner Losh wrote: > +#elif defined(__FreeBSD__) > + /* FreeBSD kernel returns positive errno and C bit set. */ > + jcs 1f > > > I needed to change this to 'jc' and that's all google found for Intel. Yep, that's me jumping between too many arches in one day. It's jc/jnc for intel. r~
On 11/16/21 12:02, Richard Henderson wrote: > From: Warner Losh <imp@bsdimp.com> > > 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. > > Signed-off-by: Warner Losh <imp@bsdimp.com> > [rth: Rebase on new safe_syscall_base api; add #error check.] > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > common-user/host/aarch64/safe-syscall.inc.S | 12 +++++++++++- > common-user/host/arm/safe-syscall.inc.S | 11 +++++++++++ Can we split this in 2 patches? > common-user/host/i386/safe-syscall.inc.S | 10 ++++++++++ > common-user/host/x86_64/safe-syscall.inc.S | 10 ++++++++++ > 4 files changed, 42 insertions(+), 1 deletion(-)
On 11/17/21 9:23 AM, Philippe Mathieu-Daudé wrote: > On 11/16/21 12:02, Richard Henderson wrote: >> From: Warner Losh <imp@bsdimp.com> >> >> 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. >> >> Signed-off-by: Warner Losh <imp@bsdimp.com> >> [rth: Rebase on new safe_syscall_base api; add #error check.] >> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> >> --- >> common-user/host/aarch64/safe-syscall.inc.S | 12 +++++++++++- >> common-user/host/arm/safe-syscall.inc.S | 11 +++++++++++ > > Can we split this in 2 patches? > >> common-user/host/i386/safe-syscall.inc.S | 10 ++++++++++ >> common-user/host/x86_64/safe-syscall.inc.S | 10 ++++++++++ >> 4 files changed, 42 insertions(+), 1 deletion(-) Why 2? They're small enough that I think having them all together is fine, but otherwise why wouldn't I split to 4? r~
On 11/17/21 09:32, Richard Henderson wrote: > On 11/17/21 9:23 AM, Philippe Mathieu-Daudé wrote: >> On 11/16/21 12:02, Richard Henderson wrote: >>> From: Warner Losh <imp@bsdimp.com> >>> >>> 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. >>> >>> Signed-off-by: Warner Losh <imp@bsdimp.com> >>> [rth: Rebase on new safe_syscall_base api; add #error check.] >>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> >>> --- >>> common-user/host/aarch64/safe-syscall.inc.S | 12 +++++++++++- >>> common-user/host/arm/safe-syscall.inc.S | 11 +++++++++++ >> >> Can we split this in 2 patches? >> >>> common-user/host/i386/safe-syscall.inc.S | 10 ++++++++++ >>> common-user/host/x86_64/safe-syscall.inc.S | 10 ++++++++++ >>> 4 files changed, 42 insertions(+), 1 deletion(-) > > Why 2? Personal brain limitation, it is easier to me when I focus on one base arch at a time. Previous mips/sparc64 changes are in different patches. > They're small enough that I think having them all together is fine, but > otherwise why wouldn't I split to 4? 4 is even better for my brain, but I think I could force my brain to focus in 1 hunk at a time in a single patch :)
diff --git a/common-user/host/aarch64/safe-syscall.inc.S b/common-user/host/aarch64/safe-syscall.inc.S index 95c60d8609..d3f065cdef 100644 --- a/common-user/host/aarch64/safe-syscall.inc.S +++ b/common-user/host/aarch64/safe-syscall.inc.S @@ -65,12 +65,22 @@ safe_syscall_start: safe_syscall_end: /* code path for having successfully executed the syscall */ - cmn x0, #4095 +#if defined(__linux__) + /* Linux kernel returns (small) negative errno. */ + cmn x0, #4096 + b.hi 0f +#elif defined(__FreeBSD__) + /* FreeBSD kernel returns positive errno and C bit set. */ b.cs 1f +#else +#error "unsupported os" +#endif ret /* code path setting errno */ +#ifdef __linux__ 0: neg w0, w0 /* create positive errno */ +#endif 1: str w0, [x11] /* store errno */ mov x0, #-1 ret diff --git a/common-user/host/arm/safe-syscall.inc.S b/common-user/host/arm/safe-syscall.inc.S index 17839c6486..328299021d 100644 --- a/common-user/host/arm/safe-syscall.inc.S +++ b/common-user/host/arm/safe-syscall.inc.S @@ -82,12 +82,23 @@ safe_syscall_start: safe_syscall_end: /* code path for having successfully executed the syscall */ +#if defined(__linux__) + /* Linux kernel returns (small) negative errno. */ cmp r0, #-4096 bhi 0f +#elif defined(__FreeBSD__) + /* FreeBSD kernel returns positive errno and C bit set. */ + bcs 1f +#else +#error "unsupported os" +#endif + 9: pop { r4, r5, r6, r7, r8, r9, r10, pc } /* code path setting errno */ +#ifdef __linux__ 0: neg r0, r0 /* create positive errno */ +#endif 1: str r0, [r9] /* store errno */ mov r0, #-1 b 9b diff --git a/common-user/host/i386/safe-syscall.inc.S b/common-user/host/i386/safe-syscall.inc.S index ad89521783..a9382f777e 100644 --- a/common-user/host/i386/safe-syscall.inc.S +++ b/common-user/host/i386/safe-syscall.inc.S @@ -76,8 +76,16 @@ safe_syscall_start: safe_syscall_end: /* code path for having successfully executed the syscall */ +#if defined(__linux__) + /* Linux kernel returns (small) negative errno. */ cmp $-4095, %eax jae 0f +#elif defined(__FreeBSD__) + /* FreeBSD kernel returns positive errno and C bit set. */ + jcs 1f +#else +#error "unsupported os" +#endif 9: pop %ebx .cfi_remember_state @@ -97,7 +105,9 @@ safe_syscall_end: .cfi_restore_state /* code path setting errno */ +#ifdef __linux__ 0: neg %eax /* create positive errno */ +#endif 1: mov 8+16(%esp), %ebx /* load errno pointer */ mov %eax, (%ebx) /* store errno */ mov $-1, %eax diff --git a/common-user/host/x86_64/safe-syscall.inc.S b/common-user/host/x86_64/safe-syscall.inc.S index 9a0c4c93b4..36b7efe2ca 100644 --- a/common-user/host/x86_64/safe-syscall.inc.S +++ b/common-user/host/x86_64/safe-syscall.inc.S @@ -75,8 +75,16 @@ safe_syscall_start: safe_syscall_end: /* code path for having successfully executed the syscall */ +#if defined(__linux__) + /* Linux kernel returns (small) negative errno. */ cmp $-4095, %rax jae 0f +#elif defined(__FreeBSD__) + /* FreeBSD kernel returns positive errno and C bit set. */ + jcs 1f +#else +#error "unsupported os" +#endif 9: pop %rbp .cfi_remember_state @@ -86,7 +94,9 @@ safe_syscall_end: .cfi_restore_state /* code path setting errno */ +#ifdef __linux__ 0: neg %eax /* create positive errno */ +#endif 1: mov %eax, (%rbp) /* store errno */ mov $-1, %rax jmp 9b