diff mbox series

riscv: uapi: Lie about having futex()

Message ID 20230119193924.21186-1-palmer@rivosinc.com (mailing list archive)
State Not Applicable
Headers show
Series riscv: uapi: Lie about having futex() | expand

Checks

Context Check Description
conchuod/cover_letter success Single patches do not need cover letters
conchuod/tree_selection success Guessed tree name to be for-next
conchuod/fixes_present success Fixes tag not required for -next series
conchuod/maintainers_pattern success MAINTAINERS pattern errors before the patch: 13 and now 13
conchuod/verify_signedoff success Signed-off-by tag matches author and committer
conchuod/kdoc success Errors and warnings before: 0 this patch: 0
conchuod/module_param success Was 0 now: 0
conchuod/build_rv64_gcc_allmodconfig success Errors and warnings before: 2025 this patch: 2025
conchuod/alphanumeric_selects success Out of order selects before the patch: 57 and now 57
conchuod/build_rv32_defconfig success Build OK
conchuod/dtb_warn_rv64 success Errors and warnings before: 2 this patch: 2
conchuod/header_inline success No static functions without inline keyword in header files
conchuod/checkpatch success total: 0 errors, 0 warnings, 0 checks, 11 lines checked
conchuod/source_inline success Was 0 now: 0
conchuod/build_rv64_nommu_k210_defconfig success Build OK
conchuod/verify_fixes success No Fixes tag
conchuod/build_rv64_nommu_virt_defconfig success Build OK

Commit Message

Palmer Dabbelt Jan. 19, 2023, 7:39 p.m. UTC
Without this libstdc++ correctly detects the lack of a futex() syscall
on rv32 and uses a fallback that doesn't work because it depends on
64-bit atomics.

Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>

---
I'm not exactly sure why this is triggering now, as it seems like all
the conditions have been there for a while, but I had to swizzle around
the toolchain tuples recently due to some glibc build system
improvements and I suspect it's related.

It looks viable to update libstdc++ to understand futex_time64, but
given how common SYS_futex is these days I'm guessing some other bits of
userspace will end up broken as well.   This certainly feels dirty, but
it's easy.
---
 arch/riscv/include/asm/unistd.h | 8 ++++++++
 1 file changed, 8 insertions(+)

Comments

Andreas Schwab Jan. 19, 2023, 8:16 p.m. UTC | #1
On Jan 19 2023, Palmer Dabbelt wrote:

> diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h
> index 221630bdbd07..26116686690a 100644
> --- a/arch/riscv/include/asm/unistd.h
> +++ b/arch/riscv/include/asm/unistd.h
> @@ -24,3 +24,11 @@
>  #include <uapi/asm/unistd.h>
>  
>  #define NR_syscalls (__NR_syscalls)
> +
> +/*
> + * Userspace (at least libstdc++) has come to expect SYS_futex, but we only
> + * have SYS_futex_time64 on rv32.  So just lie.
> + */
> +#ifndef __LP64__
> +#define __NR_futex __NR_futex_time64
> +#endif

This is not a uapi file, so why does this have any influence on
libstdc++?
Arnd Bergmann Jan. 20, 2023, 8:44 a.m. UTC | #2
On Thu, Jan 19, 2023, at 20:39, Palmer Dabbelt wrote:
> Without this libstdc++ correctly detects the lack of a futex() syscall
> on rv32 and uses a fallback that doesn't work because it depends on
> 64-bit atomics.
>
> Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
>
> ---
> I'm not exactly sure why this is triggering now, as it seems like all
> the conditions have been there for a while, but I had to swizzle around
> the toolchain tuples recently due to some glibc build system
> improvements and I suspect it's related.
>
> It looks viable to update libstdc++ to understand futex_time64, but
> given how common SYS_futex is these days I'm guessing some other bits of
> userspace will end up broken as well.   This certainly feels dirty, but
> it's easy.

Aside from what Andreas said, this is just wrong, riscv definitely
does not have a futex syscall and redirecting it to a different
syscall will lead to worse bugs because of mismatched arguments.

One possibility that we had discussed in the past is to actually
add support for a subset of futex() in configurations without
CONFIG_COMPAT_32BIT, which would include all rv32 kernels.

To avoid having to define an ABI with the incompatible 32-bit
timespec, this partial futex call would either have to reject
all commands that take a timeout (FUTEX_WAIT, FUTEX_LOCK_PI,
FUTEX_LOCK_PI2, FUTEX_WAIT_BITSET, FUTEX_WAIT_REQUEUE_PI) or
reject those calls that set a non-NULL timeout pointer.

I'm not convinced that this would actually be better than
what we have today though: right now any application that
tries to use futex_time32 but does not know futex_time64
will fail to build on riscv32.  If we provide a __NR_futex,
then all of these will build, but anything that actually
uses a timeout will receive -ENOSYS or similar and break
at runtime.

      Arnd
diff mbox series

Patch

diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h
index 221630bdbd07..26116686690a 100644
--- a/arch/riscv/include/asm/unistd.h
+++ b/arch/riscv/include/asm/unistd.h
@@ -24,3 +24,11 @@ 
 #include <uapi/asm/unistd.h>
 
 #define NR_syscalls (__NR_syscalls)
+
+/*
+ * Userspace (at least libstdc++) has come to expect SYS_futex, but we only
+ * have SYS_futex_time64 on rv32.  So just lie.
+ */
+#ifndef __LP64__
+#define __NR_futex __NR_futex_time64
+#endif