* [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
@ 2026-09-25 21:46 Nathan Chancellor
2026-09-25 21:53 ` Nick Desaulniers
2026-09-26 9:39 ` Andreas Schwab
0 siblings, 2 replies; 14+ messages in thread
From: Nathan Chancellor @ 2026-09-25 21:46 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Theodore Ts'o, Jason A. Donenfeld
Cc: Vincenzo Frascino, Nick Desaulniers, Bill Wendling, Justin Stitt,
Catalin Marinas, Will Deacon, Mark Rutland, Huacai Chen,
WANG Xuerui, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP),
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm, Nathan Chancellor
After a recent change in LLVM [1], builds with the random vDSO
implementation, such as PowerPC and RISC-V, fail when checking the vDSO:
arch/powerpc/kernel/vdso/vdso32.so.dbg: dynamic relocations are not supported
arch/riscv/kernel/vdso/vdso.so.dbg: dynamic relocations are not supported
memset() is now generated when zeroing params->reserved for some builds
because LLVM has an optimization (now run in more instances) that can
recognize at compile time when it is assigning a static value to a
contiguous area of memory and turn that into a call to memset(). Both
clang and GCC assume memset() is always available [2].
clang provides a builtin, __builtin_memset_inline [3][4], that can be
used to ensure an external function call is not generated when zeroing
this memory. Use it when it is available.
While GCC has no issues with the current code, it has generated memset()
before, as seen in commit b7bad082e113 ("random: vDSO: avoid call to out
of line memset()"). GCC 14 provides '-finline-stringops=memset' [5][6]
with a similar guarantee to the clang builtin, so use it and
__builtin_memset() when available.
If no option is available, provide a simple memset_inline() like the one
from lib/string.c to avoid adding an ugly ifdef.
Link: https://github.com/llvm/llvm-project/commit/90cebef1411617fc3eedd359bdf00cb44b1c2439 [1]
Link: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/gcc/Standards.html#index-ffreestanding [2]
Link: https://github.com/llvm/llvm-project/commit/38637ee477541370a90b37f149069d8e5c0c2efd [3]
Link: https://clang.llvm.org/docs/LanguageExtensions.html#guaranteed-inlined-memset [4]
Link: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=1ff6d9f7428b0668cd8ab0b3e3ab94f1d733124d [5]
Link: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-finline-stringops [6]
Suggested-by: "Jason A. Donenfeld" <Jason@zx2c4.com>
Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
---
Changes in v2:
- Switch approach entirely (Jason, Nick)
- clang: use __builtin_memset_inline() to avoid external call
- GCC 14+: use __builtin_memset + -finline-stringops=memset (hence the
massive CC list increase)
- GCC < 14: no issues currently but avoid ifdef with simple memset
implementation
- Link to v1: https://patch.msgid.link/20260916-vdso-getrandom-avoid-memset-llvm-24-v1-1-80a92f2e225a@kernel.org
---
arch/arm64/kernel/vdso/Makefile | 2 +-
arch/loongarch/vdso/Makefile | 1 +
arch/powerpc/kernel/vdso/Makefile | 1 +
arch/riscv/kernel/vdso/Makefile | 1 +
arch/s390/kernel/vdso/Makefile | 1 +
arch/x86/entry/vdso/vdso64/Makefile | 2 +-
init/Kconfig | 7 +++++++
lib/vdso/getrandom.c | 19 +++++++++++++++++--
8 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index 7dec05dd33b7..f6619e1cb2ce 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -41,7 +41,7 @@ CC_FLAGS_REMOVE_VDSO := $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \
$(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
-Wmissing-prototypes -Wmissing-declarations
-CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
+CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables $(CONFIG_CC_OPT_INLINE_MEMSET)
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)
diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
index 9c9181bb4071..0b84892d084b 100644
--- a/arch/loongarch/vdso/Makefile
+++ b/arch/loongarch/vdso/Makefile
@@ -16,6 +16,7 @@ ccflags-vdso := \
$(filter -m64,$(KBUILD_CFLAGS)) \
$(filter -march=%,$(KBUILD_CFLAGS)) \
$(filter -m%-float,$(KBUILD_CFLAGS)) \
+ $(CONFIG_CC_OPT_INLINE_MEMSET) \
$(CLANG_FLAGS) \
-D__VDSO__
diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile
index 368759f81708..0d1a49529885 100644
--- a/arch/powerpc/kernel/vdso/Makefile
+++ b/arch/powerpc/kernel/vdso/Makefile
@@ -43,6 +43,7 @@ ccflags-y := -fno-common -fno-builtin -DBUILD_VDSO
ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN)
ccflags-y += $(call cc-option, -fno-stack-protector)
ccflags-y += -DDISABLE_BRANCH_PROFILING
+ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
ccflags-y += -ffreestanding -fasynchronous-unwind-tables
ccflags-remove-y := $(CC_FLAGS_FTRACE)
ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)
diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
index 8dbf2532a573..c023046a3fd7 100644
--- a/arch/riscv/kernel/vdso/Makefile
+++ b/arch/riscv/kernel/vdso/Makefile
@@ -36,6 +36,7 @@ endif
ccflags-y := -fno-stack-protector
ccflags-y += -DDISABLE_BRANCH_PROFILING
ccflags-y += -fno-builtin
+ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
ccflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
ccflags-y += $(CFI_FULL)
asflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
diff --git a/arch/s390/kernel/vdso/Makefile b/arch/s390/kernel/vdso/Makefile
index 35c834b895ec..54bcf2984ca1 100644
--- a/arch/s390/kernel/vdso/Makefile
+++ b/arch/s390/kernel/vdso/Makefile
@@ -29,6 +29,7 @@ KBUILD_CFLAGS_VDSO := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_VDSO))
KBUILD_CFLAGS_VDSO := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_VDSO))
KBUILD_CFLAGS_VDSO += -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
KBUILD_CFLAGS_VDSO += -fno-stack-protector $(DISABLE_KSTACK_ERASE)
+KBUILD_CFLAGS_VDSO += $(CONFIG_CC_OPT_INLINE_MEMSET)
ldflags-y := -shared -soname=linux-vdso.so.1 \
--hash-style=both --build-id=sha1 \
$(call ld-option, --eh-frame-hdr) -T
diff --git a/arch/x86/entry/vdso/vdso64/Makefile b/arch/x86/entry/vdso/vdso64/Makefile
index 7c0790065b5e..c2353a065279 100644
--- a/arch/x86/entry/vdso/vdso64/Makefile
+++ b/arch/x86/entry/vdso/vdso64/Makefile
@@ -14,7 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o
vobjs-$(CONFIG_FUTEX_ROBUST_UNLOCK) += vfutex.o
# Compilation flags
-flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
+flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small $(CONFIG_CC_OPT_INLINE_MEMSET)
# The location of this include matters!
include $(src)/../common/Makefile.include
diff --git a/init/Kconfig b/init/Kconfig
index 8583d9f06c52..ff3f8475dd2f 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -173,6 +173,13 @@ config CC_HAS_ALLOC_TOKEN
config CC_HAS_MULTIDIMENSIONAL_NONSTRING
def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
+config CC_HAS_OPT_INLINE_MEMSET
+ def_bool $(cc-option,-finline-stringops=memset)
+
+config CC_OPT_INLINE_MEMSET
+ string
+ default "-finline-stringops=memset" if CC_HAS_OPT_INLINE_MEMSET
+
config LD_CAN_USE_KEEP_IN_OVERLAY
# ld.lld prior to 21.0.0 did not support KEEP within an overlay description
# https://github.com/llvm/llvm-project/pull/130661
diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c
index 2851afa9154f..f5cad5641985 100644
--- a/lib/vdso/getrandom.c
+++ b/lib/vdso/getrandom.c
@@ -29,6 +29,22 @@
} \
} while (0)
+#if __has_builtin(__builtin_memset_inline)
+#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
+#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
+#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
+#else
+static inline void *memset_inline(void *dst, int value, size_t size)
+{
+ char *d = dst;
+
+ while (size--)
+ *d++ = value;
+
+ return d;
+}
+#endif
+
static void memcpy_and_zero_src(void *dst, void *src, size_t len)
{
if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
@@ -83,8 +99,7 @@ __cvdso_getrandom_data(const struct vdso_rng_data *rng_info, void *buffer, size_
params->size_of_opaque_state = sizeof(*state);
params->mmap_prot = PROT_READ | PROT_WRITE;
params->mmap_flags = MAP_DROPPABLE | MAP_ANONYMOUS;
- for (size_t i = 0; i < ARRAY_SIZE(params->reserved); ++i)
- params->reserved[i] = 0;
+ memset_inline(params->reserved, 0, sizeof(params->reserved));
return 0;
}
---
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
change-id: 20260916-vdso-getrandom-avoid-memset-llvm-24-74d45fa6031e
Best regards,
--
Cheers,
Nathan
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-25 21:46 [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data() Nathan Chancellor
@ 2026-09-25 21:53 ` Nick Desaulniers
2026-09-25 21:56 ` Nick Desaulniers
2026-09-26 9:39 ` Andreas Schwab
1 sibling, 1 reply; 14+ messages in thread
From: Nick Desaulniers @ 2026-09-25 21:53 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Andy Lutomirski, Thomas Gleixner, Theodore Ts'o,
Jason A. Donenfeld, Vincenzo Frascino, Bill Wendling,
Justin Stitt, Catalin Marinas, Will Deacon, Mark Rutland,
Huacai Chen, WANG Xuerui, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP),
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
On Fri, Sep 25, 2026 at 2:46 PM Nathan Chancellor <nathan@kernel.org> wrote:
>
> After a recent change in LLVM [1], builds with the random vDSO
> implementation, such as PowerPC and RISC-V, fail when checking the vDSO:
>
> arch/powerpc/kernel/vdso/vdso32.so.dbg: dynamic relocations are not supported
> arch/riscv/kernel/vdso/vdso.so.dbg: dynamic relocations are not supported
>
> memset() is now generated when zeroing params->reserved for some builds
> because LLVM has an optimization (now run in more instances) that can
> recognize at compile time when it is assigning a static value to a
> contiguous area of memory and turn that into a call to memset(). Both
> clang and GCC assume memset() is always available [2].
>
> clang provides a builtin, __builtin_memset_inline [3][4], that can be
> used to ensure an external function call is not generated when zeroing
> this memory. Use it when it is available.
>
> While GCC has no issues with the current code, it has generated memset()
> before, as seen in commit b7bad082e113 ("random: vDSO: avoid call to out
> of line memset()"). GCC 14 provides '-finline-stringops=memset' [5][6]
> with a similar guarantee to the clang builtin, so use it and
> __builtin_memset() when available.
>
> If no option is available, provide a simple memset_inline() like the one
> from lib/string.c to avoid adding an ugly ifdef.
>
> Link: https://github.com/llvm/llvm-project/commit/90cebef1411617fc3eedd359bdf00cb44b1c2439 [1]
> Link: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/gcc/Standards.html#index-ffreestanding [2]
> Link: https://github.com/llvm/llvm-project/commit/38637ee477541370a90b37f149069d8e5c0c2efd [3]
> Link: https://clang.llvm.org/docs/LanguageExtensions.html#guaranteed-inlined-memset [4]
> Link: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=1ff6d9f7428b0668cd8ab0b3e3ab94f1d733124d [5]
> Link: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-finline-stringops [6]
> Suggested-by: "Jason A. Donenfeld" <Jason@zx2c4.com>
> Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
> Signed-off-by: Nathan Chancellor <nathan@kernel.org>
> ---
> Changes in v2:
> - Switch approach entirely (Jason, Nick)
> - clang: use __builtin_memset_inline() to avoid external call
> - GCC 14+: use __builtin_memset + -finline-stringops=memset (hence the
> massive CC list increase)
> - GCC < 14: no issues currently but avoid ifdef with simple memset
> implementation
> - Link to v1: https://patch.msgid.link/20260916-vdso-getrandom-avoid-memset-llvm-24-v1-1-80a92f2e225a@kernel.org
> ---
> arch/arm64/kernel/vdso/Makefile | 2 +-
> arch/loongarch/vdso/Makefile | 1 +
> arch/powerpc/kernel/vdso/Makefile | 1 +
> arch/riscv/kernel/vdso/Makefile | 1 +
> arch/s390/kernel/vdso/Makefile | 1 +
> arch/x86/entry/vdso/vdso64/Makefile | 2 +-
> init/Kconfig | 7 +++++++
> lib/vdso/getrandom.c | 19 +++++++++++++++++--
> 8 files changed, 30 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
> index 7dec05dd33b7..f6619e1cb2ce 100644
> --- a/arch/arm64/kernel/vdso/Makefile
> +++ b/arch/arm64/kernel/vdso/Makefile
> @@ -41,7 +41,7 @@ CC_FLAGS_REMOVE_VDSO := $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \
> $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
> -Wmissing-prototypes -Wmissing-declarations
>
> -CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
> +CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables $(CONFIG_CC_OPT_INLINE_MEMSET)
>
> CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
> CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)
> diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
> index 9c9181bb4071..0b84892d084b 100644
> --- a/arch/loongarch/vdso/Makefile
> +++ b/arch/loongarch/vdso/Makefile
> @@ -16,6 +16,7 @@ ccflags-vdso := \
> $(filter -m64,$(KBUILD_CFLAGS)) \
> $(filter -march=%,$(KBUILD_CFLAGS)) \
> $(filter -m%-float,$(KBUILD_CFLAGS)) \
> + $(CONFIG_CC_OPT_INLINE_MEMSET) \
> $(CLANG_FLAGS) \
> -D__VDSO__
>
> diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile
> index 368759f81708..0d1a49529885 100644
> --- a/arch/powerpc/kernel/vdso/Makefile
> +++ b/arch/powerpc/kernel/vdso/Makefile
> @@ -43,6 +43,7 @@ ccflags-y := -fno-common -fno-builtin -DBUILD_VDSO
> ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN)
> ccflags-y += $(call cc-option, -fno-stack-protector)
> ccflags-y += -DDISABLE_BRANCH_PROFILING
> +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
> ccflags-y += -ffreestanding -fasynchronous-unwind-tables
> ccflags-remove-y := $(CC_FLAGS_FTRACE)
> ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)
> diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
> index 8dbf2532a573..c023046a3fd7 100644
> --- a/arch/riscv/kernel/vdso/Makefile
> +++ b/arch/riscv/kernel/vdso/Makefile
> @@ -36,6 +36,7 @@ endif
> ccflags-y := -fno-stack-protector
> ccflags-y += -DDISABLE_BRANCH_PROFILING
> ccflags-y += -fno-builtin
> +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
> ccflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
> ccflags-y += $(CFI_FULL)
> asflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
> diff --git a/arch/s390/kernel/vdso/Makefile b/arch/s390/kernel/vdso/Makefile
> index 35c834b895ec..54bcf2984ca1 100644
> --- a/arch/s390/kernel/vdso/Makefile
> +++ b/arch/s390/kernel/vdso/Makefile
> @@ -29,6 +29,7 @@ KBUILD_CFLAGS_VDSO := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_VDSO))
> KBUILD_CFLAGS_VDSO := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_VDSO))
> KBUILD_CFLAGS_VDSO += -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
> KBUILD_CFLAGS_VDSO += -fno-stack-protector $(DISABLE_KSTACK_ERASE)
> +KBUILD_CFLAGS_VDSO += $(CONFIG_CC_OPT_INLINE_MEMSET)
> ldflags-y := -shared -soname=linux-vdso.so.1 \
> --hash-style=both --build-id=sha1 \
> $(call ld-option, --eh-frame-hdr) -T
> diff --git a/arch/x86/entry/vdso/vdso64/Makefile b/arch/x86/entry/vdso/vdso64/Makefile
> index 7c0790065b5e..c2353a065279 100644
> --- a/arch/x86/entry/vdso/vdso64/Makefile
> +++ b/arch/x86/entry/vdso/vdso64/Makefile
> @@ -14,7 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o
> vobjs-$(CONFIG_FUTEX_ROBUST_UNLOCK) += vfutex.o
>
> # Compilation flags
> -flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
> +flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small $(CONFIG_CC_OPT_INLINE_MEMSET)
>
> # The location of this include matters!
> include $(src)/../common/Makefile.include
> diff --git a/init/Kconfig b/init/Kconfig
> index 8583d9f06c52..ff3f8475dd2f 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -173,6 +173,13 @@ config CC_HAS_ALLOC_TOKEN
> config CC_HAS_MULTIDIMENSIONAL_NONSTRING
> def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
>
> +config CC_HAS_OPT_INLINE_MEMSET
> + def_bool $(cc-option,-finline-stringops=memset)
> +
> +config CC_OPT_INLINE_MEMSET
> + string
> + default "-finline-stringops=memset" if CC_HAS_OPT_INLINE_MEMSET
> +
> config LD_CAN_USE_KEEP_IN_OVERLAY
> # ld.lld prior to 21.0.0 did not support KEEP within an overlay description
> # https://github.com/llvm/llvm-project/pull/130661
> diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c
> index 2851afa9154f..f5cad5641985 100644
> --- a/lib/vdso/getrandom.c
> +++ b/lib/vdso/getrandom.c
> @@ -29,6 +29,22 @@
> } \
> } while (0)
>
> +#if __has_builtin(__builtin_memset_inline)
> +#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
> +#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
> +#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
> +#else
> +static inline void *memset_inline(void *dst, int value, size_t size)
> +{
> + char *d = dst;
> +
> + while (size--)
> + *d++ = value;
> +
> + return d;
> +}
> +#endif
Does this work?
https://godbolt.org/z/Tx6EaGMfb
(Sorry, I _should_ have replied to Jason on V1. I'm not ignoring him,
just way behind on my code reviews. Sorry!)
> +
> static void memcpy_and_zero_src(void *dst, void *src, size_t len)
> {
> if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
> @@ -83,8 +99,7 @@ __cvdso_getrandom_data(const struct vdso_rng_data *rng_info, void *buffer, size_
> params->size_of_opaque_state = sizeof(*state);
> params->mmap_prot = PROT_READ | PROT_WRITE;
> params->mmap_flags = MAP_DROPPABLE | MAP_ANONYMOUS;
> - for (size_t i = 0; i < ARRAY_SIZE(params->reserved); ++i)
> - params->reserved[i] = 0;
> + memset_inline(params->reserved, 0, sizeof(params->reserved));
> return 0;
> }
>
>
> ---
> base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
> change-id: 20260916-vdso-getrandom-avoid-memset-llvm-24-74d45fa6031e
>
> Best regards,
> --
> Cheers,
> Nathan
>
--
Thanks,
~Nick Desaulniers
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-25 21:53 ` Nick Desaulniers
@ 2026-09-25 21:56 ` Nick Desaulniers
2026-09-25 22:00 ` Nick Desaulniers
0 siblings, 1 reply; 14+ messages in thread
From: Nick Desaulniers @ 2026-09-25 21:56 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Andy Lutomirski, Thomas Gleixner, Theodore Ts'o,
Jason A. Donenfeld, Vincenzo Frascino, Bill Wendling,
Justin Stitt, Catalin Marinas, Will Deacon, Mark Rutland,
Huacai Chen, WANG Xuerui, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP),
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
On Fri, Sep 25, 2026 at 2:53 PM Nick Desaulniers
<ndesaulniers@google.com> wrote:
>
> On Fri, Sep 25, 2026 at 2:46 PM Nathan Chancellor <nathan@kernel.org> wrote:
> >
> > After a recent change in LLVM [1], builds with the random vDSO
> > implementation, such as PowerPC and RISC-V, fail when checking the vDSO:
> >
> > arch/powerpc/kernel/vdso/vdso32.so.dbg: dynamic relocations are not supported
> > arch/riscv/kernel/vdso/vdso.so.dbg: dynamic relocations are not supported
> >
> > memset() is now generated when zeroing params->reserved for some builds
> > because LLVM has an optimization (now run in more instances) that can
> > recognize at compile time when it is assigning a static value to a
> > contiguous area of memory and turn that into a call to memset(). Both
> > clang and GCC assume memset() is always available [2].
> >
> > clang provides a builtin, __builtin_memset_inline [3][4], that can be
> > used to ensure an external function call is not generated when zeroing
> > this memory. Use it when it is available.
> >
> > While GCC has no issues with the current code, it has generated memset()
> > before, as seen in commit b7bad082e113 ("random: vDSO: avoid call to out
> > of line memset()"). GCC 14 provides '-finline-stringops=memset' [5][6]
> > with a similar guarantee to the clang builtin, so use it and
> > __builtin_memset() when available.
> >
> > If no option is available, provide a simple memset_inline() like the one
> > from lib/string.c to avoid adding an ugly ifdef.
> >
> > Link: https://github.com/llvm/llvm-project/commit/90cebef1411617fc3eedd359bdf00cb44b1c2439 [1]
> > Link: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/gcc/Standards.html#index-ffreestanding [2]
> > Link: https://github.com/llvm/llvm-project/commit/38637ee477541370a90b37f149069d8e5c0c2efd [3]
> > Link: https://clang.llvm.org/docs/LanguageExtensions.html#guaranteed-inlined-memset [4]
> > Link: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=1ff6d9f7428b0668cd8ab0b3e3ab94f1d733124d [5]
> > Link: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-finline-stringops [6]
> > Suggested-by: "Jason A. Donenfeld" <Jason@zx2c4.com>
> > Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
> > Signed-off-by: Nathan Chancellor <nathan@kernel.org>
> > ---
> > Changes in v2:
> > - Switch approach entirely (Jason, Nick)
> > - clang: use __builtin_memset_inline() to avoid external call
> > - GCC 14+: use __builtin_memset + -finline-stringops=memset (hence the
> > massive CC list increase)
> > - GCC < 14: no issues currently but avoid ifdef with simple memset
> > implementation
> > - Link to v1: https://patch.msgid.link/20260916-vdso-getrandom-avoid-memset-llvm-24-v1-1-80a92f2e225a@kernel.org
> > ---
> > arch/arm64/kernel/vdso/Makefile | 2 +-
> > arch/loongarch/vdso/Makefile | 1 +
> > arch/powerpc/kernel/vdso/Makefile | 1 +
> > arch/riscv/kernel/vdso/Makefile | 1 +
> > arch/s390/kernel/vdso/Makefile | 1 +
> > arch/x86/entry/vdso/vdso64/Makefile | 2 +-
> > init/Kconfig | 7 +++++++
> > lib/vdso/getrandom.c | 19 +++++++++++++++++--
> > 8 files changed, 30 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
> > index 7dec05dd33b7..f6619e1cb2ce 100644
> > --- a/arch/arm64/kernel/vdso/Makefile
> > +++ b/arch/arm64/kernel/vdso/Makefile
> > @@ -41,7 +41,7 @@ CC_FLAGS_REMOVE_VDSO := $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \
> > $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
> > -Wmissing-prototypes -Wmissing-declarations
> >
> > -CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
> > +CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables $(CONFIG_CC_OPT_INLINE_MEMSET)
> >
> > CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
> > CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)
> > diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
> > index 9c9181bb4071..0b84892d084b 100644
> > --- a/arch/loongarch/vdso/Makefile
> > +++ b/arch/loongarch/vdso/Makefile
> > @@ -16,6 +16,7 @@ ccflags-vdso := \
> > $(filter -m64,$(KBUILD_CFLAGS)) \
> > $(filter -march=%,$(KBUILD_CFLAGS)) \
> > $(filter -m%-float,$(KBUILD_CFLAGS)) \
> > + $(CONFIG_CC_OPT_INLINE_MEMSET) \
> > $(CLANG_FLAGS) \
> > -D__VDSO__
> >
> > diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile
> > index 368759f81708..0d1a49529885 100644
> > --- a/arch/powerpc/kernel/vdso/Makefile
> > +++ b/arch/powerpc/kernel/vdso/Makefile
> > @@ -43,6 +43,7 @@ ccflags-y := -fno-common -fno-builtin -DBUILD_VDSO
> > ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN)
> > ccflags-y += $(call cc-option, -fno-stack-protector)
> > ccflags-y += -DDISABLE_BRANCH_PROFILING
> > +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
> > ccflags-y += -ffreestanding -fasynchronous-unwind-tables
> > ccflags-remove-y := $(CC_FLAGS_FTRACE)
> > ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)
> > diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
> > index 8dbf2532a573..c023046a3fd7 100644
> > --- a/arch/riscv/kernel/vdso/Makefile
> > +++ b/arch/riscv/kernel/vdso/Makefile
> > @@ -36,6 +36,7 @@ endif
> > ccflags-y := -fno-stack-protector
> > ccflags-y += -DDISABLE_BRANCH_PROFILING
> > ccflags-y += -fno-builtin
> > +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
> > ccflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
> > ccflags-y += $(CFI_FULL)
> > asflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
> > diff --git a/arch/s390/kernel/vdso/Makefile b/arch/s390/kernel/vdso/Makefile
> > index 35c834b895ec..54bcf2984ca1 100644
> > --- a/arch/s390/kernel/vdso/Makefile
> > +++ b/arch/s390/kernel/vdso/Makefile
> > @@ -29,6 +29,7 @@ KBUILD_CFLAGS_VDSO := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_VDSO))
> > KBUILD_CFLAGS_VDSO := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_VDSO))
> > KBUILD_CFLAGS_VDSO += -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
> > KBUILD_CFLAGS_VDSO += -fno-stack-protector $(DISABLE_KSTACK_ERASE)
> > +KBUILD_CFLAGS_VDSO += $(CONFIG_CC_OPT_INLINE_MEMSET)
> > ldflags-y := -shared -soname=linux-vdso.so.1 \
> > --hash-style=both --build-id=sha1 \
> > $(call ld-option, --eh-frame-hdr) -T
> > diff --git a/arch/x86/entry/vdso/vdso64/Makefile b/arch/x86/entry/vdso/vdso64/Makefile
> > index 7c0790065b5e..c2353a065279 100644
> > --- a/arch/x86/entry/vdso/vdso64/Makefile
> > +++ b/arch/x86/entry/vdso/vdso64/Makefile
> > @@ -14,7 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o
> > vobjs-$(CONFIG_FUTEX_ROBUST_UNLOCK) += vfutex.o
> >
> > # Compilation flags
> > -flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
> > +flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small $(CONFIG_CC_OPT_INLINE_MEMSET)
> >
> > # The location of this include matters!
> > include $(src)/../common/Makefile.include
> > diff --git a/init/Kconfig b/init/Kconfig
> > index 8583d9f06c52..ff3f8475dd2f 100644
> > --- a/init/Kconfig
> > +++ b/init/Kconfig
> > @@ -173,6 +173,13 @@ config CC_HAS_ALLOC_TOKEN
> > config CC_HAS_MULTIDIMENSIONAL_NONSTRING
> > def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
> >
> > +config CC_HAS_OPT_INLINE_MEMSET
> > + def_bool $(cc-option,-finline-stringops=memset)
> > +
> > +config CC_OPT_INLINE_MEMSET
> > + string
> > + default "-finline-stringops=memset" if CC_HAS_OPT_INLINE_MEMSET
> > +
> > config LD_CAN_USE_KEEP_IN_OVERLAY
> > # ld.lld prior to 21.0.0 did not support KEEP within an overlay description
> > # https://github.com/llvm/llvm-project/pull/130661
> > diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c
> > index 2851afa9154f..f5cad5641985 100644
> > --- a/lib/vdso/getrandom.c
> > +++ b/lib/vdso/getrandom.c
> > @@ -29,6 +29,22 @@
> > } \
> > } while (0)
> >
> > +#if __has_builtin(__builtin_memset_inline)
> > +#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
> > +#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
> > +#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
> > +#else
> > +static inline void *memset_inline(void *dst, int value, size_t size)
> > +{
> > + char *d = dst;
> > +
> > + while (size--)
> > + *d++ = value;
> > +
> > + return d;
> > +}
> > +#endif
>
> Does this work?
> https://godbolt.org/z/Tx6EaGMfb
Hmmm...possibly.
https://godbolt.org/z/ec9rzd9Yf
I don't get it...
>
> (Sorry, I _should_ have replied to Jason on V1. I'm not ignoring him,
> just way behind on my code reviews. Sorry!)
>
> > +
> > static void memcpy_and_zero_src(void *dst, void *src, size_t len)
> > {
> > if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
> > @@ -83,8 +99,7 @@ __cvdso_getrandom_data(const struct vdso_rng_data *rng_info, void *buffer, size_
> > params->size_of_opaque_state = sizeof(*state);
> > params->mmap_prot = PROT_READ | PROT_WRITE;
> > params->mmap_flags = MAP_DROPPABLE | MAP_ANONYMOUS;
> > - for (size_t i = 0; i < ARRAY_SIZE(params->reserved); ++i)
> > - params->reserved[i] = 0;
> > + memset_inline(params->reserved, 0, sizeof(params->reserved));
> > return 0;
> > }
> >
> >
> > ---
> > base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
> > change-id: 20260916-vdso-getrandom-avoid-memset-llvm-24-74d45fa6031e
> >
> > Best regards,
> > --
> > Cheers,
> > Nathan
> >
>
>
> --
> Thanks,
> ~Nick Desaulniers
--
Thanks,
~Nick Desaulniers
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-25 21:56 ` Nick Desaulniers
@ 2026-09-25 22:00 ` Nick Desaulniers
2026-09-25 22:19 ` Nathan Chancellor
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Nick Desaulniers @ 2026-09-25 22:00 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Andy Lutomirski, Thomas Gleixner, Theodore Ts'o,
Jason A. Donenfeld, Vincenzo Frascino, Bill Wendling,
Justin Stitt, Catalin Marinas, Will Deacon, Mark Rutland,
Huacai Chen, WANG Xuerui, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP),
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
On Fri, Sep 25, 2026 at 2:56 PM Nick Desaulniers
<ndesaulniers@google.com> wrote:
>
> On Fri, Sep 25, 2026 at 2:53 PM Nick Desaulniers
> <ndesaulniers@google.com> wrote:
> >
> > On Fri, Sep 25, 2026 at 2:46 PM Nathan Chancellor <nathan@kernel.org> wrote:
> > >
> > > After a recent change in LLVM [1], builds with the random vDSO
> > > implementation, such as PowerPC and RISC-V, fail when checking the vDSO:
> > >
> > > arch/powerpc/kernel/vdso/vdso32.so.dbg: dynamic relocations are not supported
> > > arch/riscv/kernel/vdso/vdso.so.dbg: dynamic relocations are not supported
> > >
> > > memset() is now generated when zeroing params->reserved for some builds
> > > because LLVM has an optimization (now run in more instances) that can
> > > recognize at compile time when it is assigning a static value to a
> > > contiguous area of memory and turn that into a call to memset(). Both
> > > clang and GCC assume memset() is always available [2].
> > >
> > > clang provides a builtin, __builtin_memset_inline [3][4], that can be
> > > used to ensure an external function call is not generated when zeroing
> > > this memory. Use it when it is available.
> > >
> > > While GCC has no issues with the current code, it has generated memset()
> > > before, as seen in commit b7bad082e113 ("random: vDSO: avoid call to out
> > > of line memset()"). GCC 14 provides '-finline-stringops=memset' [5][6]
> > > with a similar guarantee to the clang builtin, so use it and
> > > __builtin_memset() when available.
> > >
> > > If no option is available, provide a simple memset_inline() like the one
> > > from lib/string.c to avoid adding an ugly ifdef.
> > >
> > > Link: https://github.com/llvm/llvm-project/commit/90cebef1411617fc3eedd359bdf00cb44b1c2439 [1]
> > > Link: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/gcc/Standards.html#index-ffreestanding [2]
> > > Link: https://github.com/llvm/llvm-project/commit/38637ee477541370a90b37f149069d8e5c0c2efd [3]
> > > Link: https://clang.llvm.org/docs/LanguageExtensions.html#guaranteed-inlined-memset [4]
> > > Link: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=1ff6d9f7428b0668cd8ab0b3e3ab94f1d733124d [5]
> > > Link: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-finline-stringops [6]
> > > Suggested-by: "Jason A. Donenfeld" <Jason@zx2c4.com>
> > > Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
> > > Signed-off-by: Nathan Chancellor <nathan@kernel.org>
> > > ---
> > > Changes in v2:
> > > - Switch approach entirely (Jason, Nick)
> > > - clang: use __builtin_memset_inline() to avoid external call
> > > - GCC 14+: use __builtin_memset + -finline-stringops=memset (hence the
> > > massive CC list increase)
> > > - GCC < 14: no issues currently but avoid ifdef with simple memset
> > > implementation
> > > - Link to v1: https://patch.msgid.link/20260916-vdso-getrandom-avoid-memset-llvm-24-v1-1-80a92f2e225a@kernel.org
> > > ---
> > > arch/arm64/kernel/vdso/Makefile | 2 +-
> > > arch/loongarch/vdso/Makefile | 1 +
> > > arch/powerpc/kernel/vdso/Makefile | 1 +
> > > arch/riscv/kernel/vdso/Makefile | 1 +
> > > arch/s390/kernel/vdso/Makefile | 1 +
> > > arch/x86/entry/vdso/vdso64/Makefile | 2 +-
> > > init/Kconfig | 7 +++++++
> > > lib/vdso/getrandom.c | 19 +++++++++++++++++--
> > > 8 files changed, 30 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
> > > index 7dec05dd33b7..f6619e1cb2ce 100644
> > > --- a/arch/arm64/kernel/vdso/Makefile
> > > +++ b/arch/arm64/kernel/vdso/Makefile
> > > @@ -41,7 +41,7 @@ CC_FLAGS_REMOVE_VDSO := $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \
> > > $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
> > > -Wmissing-prototypes -Wmissing-declarations
> > >
> > > -CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
> > > +CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables $(CONFIG_CC_OPT_INLINE_MEMSET)
> > >
> > > CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
> > > CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)
> > > diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
> > > index 9c9181bb4071..0b84892d084b 100644
> > > --- a/arch/loongarch/vdso/Makefile
> > > +++ b/arch/loongarch/vdso/Makefile
> > > @@ -16,6 +16,7 @@ ccflags-vdso := \
> > > $(filter -m64,$(KBUILD_CFLAGS)) \
> > > $(filter -march=%,$(KBUILD_CFLAGS)) \
> > > $(filter -m%-float,$(KBUILD_CFLAGS)) \
> > > + $(CONFIG_CC_OPT_INLINE_MEMSET) \
> > > $(CLANG_FLAGS) \
> > > -D__VDSO__
> > >
> > > diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile
> > > index 368759f81708..0d1a49529885 100644
> > > --- a/arch/powerpc/kernel/vdso/Makefile
> > > +++ b/arch/powerpc/kernel/vdso/Makefile
> > > @@ -43,6 +43,7 @@ ccflags-y := -fno-common -fno-builtin -DBUILD_VDSO
> > > ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN)
> > > ccflags-y += $(call cc-option, -fno-stack-protector)
> > > ccflags-y += -DDISABLE_BRANCH_PROFILING
> > > +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
> > > ccflags-y += -ffreestanding -fasynchronous-unwind-tables
> > > ccflags-remove-y := $(CC_FLAGS_FTRACE)
> > > ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)
> > > diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
> > > index 8dbf2532a573..c023046a3fd7 100644
> > > --- a/arch/riscv/kernel/vdso/Makefile
> > > +++ b/arch/riscv/kernel/vdso/Makefile
> > > @@ -36,6 +36,7 @@ endif
> > > ccflags-y := -fno-stack-protector
> > > ccflags-y += -DDISABLE_BRANCH_PROFILING
> > > ccflags-y += -fno-builtin
> > > +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
> > > ccflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
> > > ccflags-y += $(CFI_FULL)
> > > asflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
> > > diff --git a/arch/s390/kernel/vdso/Makefile b/arch/s390/kernel/vdso/Makefile
> > > index 35c834b895ec..54bcf2984ca1 100644
> > > --- a/arch/s390/kernel/vdso/Makefile
> > > +++ b/arch/s390/kernel/vdso/Makefile
> > > @@ -29,6 +29,7 @@ KBUILD_CFLAGS_VDSO := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_VDSO))
> > > KBUILD_CFLAGS_VDSO := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_VDSO))
> > > KBUILD_CFLAGS_VDSO += -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
> > > KBUILD_CFLAGS_VDSO += -fno-stack-protector $(DISABLE_KSTACK_ERASE)
> > > +KBUILD_CFLAGS_VDSO += $(CONFIG_CC_OPT_INLINE_MEMSET)
> > > ldflags-y := -shared -soname=linux-vdso.so.1 \
> > > --hash-style=both --build-id=sha1 \
> > > $(call ld-option, --eh-frame-hdr) -T
> > > diff --git a/arch/x86/entry/vdso/vdso64/Makefile b/arch/x86/entry/vdso/vdso64/Makefile
> > > index 7c0790065b5e..c2353a065279 100644
> > > --- a/arch/x86/entry/vdso/vdso64/Makefile
> > > +++ b/arch/x86/entry/vdso/vdso64/Makefile
> > > @@ -14,7 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o
> > > vobjs-$(CONFIG_FUTEX_ROBUST_UNLOCK) += vfutex.o
> > >
> > > # Compilation flags
> > > -flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
> > > +flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small $(CONFIG_CC_OPT_INLINE_MEMSET)
> > >
> > > # The location of this include matters!
> > > include $(src)/../common/Makefile.include
> > > diff --git a/init/Kconfig b/init/Kconfig
> > > index 8583d9f06c52..ff3f8475dd2f 100644
> > > --- a/init/Kconfig
> > > +++ b/init/Kconfig
> > > @@ -173,6 +173,13 @@ config CC_HAS_ALLOC_TOKEN
> > > config CC_HAS_MULTIDIMENSIONAL_NONSTRING
> > > def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
> > >
> > > +config CC_HAS_OPT_INLINE_MEMSET
> > > + def_bool $(cc-option,-finline-stringops=memset)
> > > +
> > > +config CC_OPT_INLINE_MEMSET
> > > + string
> > > + default "-finline-stringops=memset" if CC_HAS_OPT_INLINE_MEMSET
> > > +
> > > config LD_CAN_USE_KEEP_IN_OVERLAY
> > > # ld.lld prior to 21.0.0 did not support KEEP within an overlay description
> > > # https://github.com/llvm/llvm-project/pull/130661
> > > diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c
> > > index 2851afa9154f..f5cad5641985 100644
> > > --- a/lib/vdso/getrandom.c
> > > +++ b/lib/vdso/getrandom.c
> > > @@ -29,6 +29,22 @@
> > > } \
> > > } while (0)
> > >
> > > +#if __has_builtin(__builtin_memset_inline)
> > > +#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
> > > +#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
> > > +#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
> > > +#else
> > > +static inline void *memset_inline(void *dst, int value, size_t size)
> > > +{
> > > + char *d = dst;
> > > +
> > > + while (size--)
> > > + *d++ = value;
> > > +
> > > + return d;
> > > +}
> > > +#endif
> >
> > Does this work?
> > https://godbolt.org/z/Tx6EaGMfb
>
> Hmmm...possibly.
> https://godbolt.org/z/ec9rzd9Yf
> I don't get it...
Just keep it under 2 pages, it will be fine:
https://godbolt.org/z/qqoMqfxev
>
> >
> > (Sorry, I _should_ have replied to Jason on V1. I'm not ignoring him,
> > just way behind on my code reviews. Sorry!)
> >
> > > +
> > > static void memcpy_and_zero_src(void *dst, void *src, size_t len)
> > > {
> > > if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
> > > @@ -83,8 +99,7 @@ __cvdso_getrandom_data(const struct vdso_rng_data *rng_info, void *buffer, size_
> > > params->size_of_opaque_state = sizeof(*state);
> > > params->mmap_prot = PROT_READ | PROT_WRITE;
> > > params->mmap_flags = MAP_DROPPABLE | MAP_ANONYMOUS;
> > > - for (size_t i = 0; i < ARRAY_SIZE(params->reserved); ++i)
> > > - params->reserved[i] = 0;
> > > + memset_inline(params->reserved, 0, sizeof(params->reserved));
> > > return 0;
> > > }
> > >
> > >
> > > ---
> > > base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
> > > change-id: 20260916-vdso-getrandom-avoid-memset-llvm-24-74d45fa6031e
> > >
> > > Best regards,
> > > --
> > > Cheers,
> > > Nathan
> > >
> >
> >
> > --
> > Thanks,
> > ~Nick Desaulniers
>
>
>
> --
> Thanks,
> ~Nick Desaulniers
--
Thanks,
~Nick Desaulniers
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-25 22:00 ` Nick Desaulniers
@ 2026-09-25 22:19 ` Nathan Chancellor
2026-09-26 6:34 ` Christophe Leroy (CS GROUP)
2026-09-26 10:02 ` Jason A. Donenfeld
2 siblings, 0 replies; 14+ messages in thread
From: Nathan Chancellor @ 2026-09-25 22:19 UTC (permalink / raw)
To: Nick Desaulniers
Cc: Andy Lutomirski, Thomas Gleixner, Theodore Ts'o,
Jason A. Donenfeld, Vincenzo Frascino, Bill Wendling,
Justin Stitt, Catalin Marinas, Will Deacon, Mark Rutland,
Huacai Chen, WANG Xuerui, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP),
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
On Fri, Sep 25, 2026 at 03:00:46PM -0700, Nick Desaulniers wrote:
> > > > +static inline void *memset_inline(void *dst, int value, size_t size)
> > > > +{
> > > > + char *d = dst;
> > > > +
> > > > + while (size--)
> > > > + *d++ = value;
> > > > +
> > > > + return d;
> > > > +}
> > >
> > > Does this work?
> > > https://godbolt.org/z/Tx6EaGMfb
> >
> > Hmmm...possibly.
> > https://godbolt.org/z/ec9rzd9Yf
> > I don't get it...
>
> Just keep it under 2 pages, it will be fine:
> https://godbolt.org/z/qqoMqfxev
Yeah, it might be worth a comment that this is only safe for small
values of size so it should not be blindly copied elsewhere (although I
guess if it is, the outlined version exists in the majority of other
places).
--
Cheers,
Nathan
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-25 22:00 ` Nick Desaulniers
2026-09-25 22:19 ` Nathan Chancellor
@ 2026-09-26 6:34 ` Christophe Leroy (CS GROUP)
2026-09-26 10:02 ` Jason A. Donenfeld
2 siblings, 0 replies; 14+ messages in thread
From: Christophe Leroy (CS GROUP) @ 2026-09-26 6:34 UTC (permalink / raw)
To: Nick Desaulniers, Nathan Chancellor
Cc: Andy Lutomirski, Thomas Gleixner, Theodore Ts'o,
Jason A. Donenfeld, Vincenzo Frascino, Bill Wendling,
Justin Stitt, Catalin Marinas, Will Deacon, Mark Rutland,
Huacai Chen, WANG Xuerui, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
Le 26/09/2026 à 00:00, Nick Desaulniers a écrit :
> On Fri, Sep 25, 2026 at 2:56 PM Nick Desaulniers
> <ndesaulniers@google.com> wrote:
>>
>> On Fri, Sep 25, 2026 at 2:53 PM Nick Desaulniers
>> <ndesaulniers@google.com> wrote:
>>>
>>> On Fri, Sep 25, 2026 at 2:46 PM Nathan Chancellor <nathan@kernel.org> wrote:
>>>>
>>>> After a recent change in LLVM [1], builds with the random vDSO
>>>> implementation, such as PowerPC and RISC-V, fail when checking the vDSO:
>>>>
>>>> arch/powerpc/kernel/vdso/vdso32.so.dbg: dynamic relocations are not supported
>>>> arch/riscv/kernel/vdso/vdso.so.dbg: dynamic relocations are not supported
>>>>
>>>> memset() is now generated when zeroing params->reserved for some builds
>>>> because LLVM has an optimization (now run in more instances) that can
>>>> recognize at compile time when it is assigning a static value to a
>>>> contiguous area of memory and turn that into a call to memset(). Both
>>>> clang and GCC assume memset() is always available [2].
>>>>
>>>> clang provides a builtin, __builtin_memset_inline [3][4], that can be
>>>> used to ensure an external function call is not generated when zeroing
>>>> this memory. Use it when it is available.
>>>>
>>>> While GCC has no issues with the current code, it has generated memset()
>>>> before, as seen in commit b7bad082e113 ("random: vDSO: avoid call to out
>>>> of line memset()"). GCC 14 provides '-finline-stringops=memset' [5][6]
>>>> with a similar guarantee to the clang builtin, so use it and
>>>> __builtin_memset() when available.
>>>>
>>>> If no option is available, provide a simple memset_inline() like the one
>>>> from lib/string.c to avoid adding an ugly ifdef.
>>>>
>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fllvm%2Fllvm-project%2Fcommit%2F90cebef1411617fc3eedd359bdf00cb44b1c2439&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C8130be3fe7304659b8e308df1b507f25%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639259704683663121%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=TzFmsIf6K0ZNffmwZjFRWcrFHJ4akhMw%2FxcWeHR4hFY%3D&reserved=0 [1]
>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc-16.2.0%2Fgcc%2FStandards.html%23index-ffreestanding&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C8130be3fe7304659b8e308df1b507f25%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639259704683681786%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=A6PdZfaF0MvKQ0TEuJEnFWmXpMKD5CPz6Ko2fWh9ZGY%3D&reserved=0 [2]
>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fllvm%2Fllvm-project%2Fcommit%2F38637ee477541370a90b37f149069d8e5c0c2efd&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C8130be3fe7304659b8e308df1b507f25%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639259704683693796%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=ordMFwd99jKGsM6%2F5jqb6T%2FCzJZ%2BccJTNL6Zyyz38S4%3D&reserved=0 [3]
>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fclang.llvm.org%2Fdocs%2FLanguageExtensions.html%23guaranteed-inlined-memset&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C8130be3fe7304659b8e308df1b507f25%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639259704683704121%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=mqgeAxJp0cTsBD1qngk%2BliTUC1kID648Z81H6hiKYDI%3D&reserved=0 [4]
>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fgit%2F%3Fp%3Dgcc.git%3Ba%3Dcommit%3Bh%3D1ff6d9f7428b0668cd8ab0b3e3ab94f1d733124d&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C8130be3fe7304659b8e308df1b507f25%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639259704683713563%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=hNiJSMBbn6k7Pq4uBYQ5Bi6fO8ttW8KXVK6hPLEfJCM%3D&reserved=0 [5]
>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FOptimize-Options.html%23index-finline-stringops&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C8130be3fe7304659b8e308df1b507f25%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639259704683722844%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=BwB1lUSynGcGGLwkspnlVbkBAkdeRo4ItXk19ffMU44%3D&reserved=0 [6]
>>>> Suggested-by: "Jason A. Donenfeld" <Jason@zx2c4.com>
>>>> Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
>>>> Signed-off-by: Nathan Chancellor <nathan@kernel.org>
>>>> ---
>>>> Changes in v2:
>>>> - Switch approach entirely (Jason, Nick)
>>>> - clang: use __builtin_memset_inline() to avoid external call
>>>> - GCC 14+: use __builtin_memset + -finline-stringops=memset (hence the
>>>> massive CC list increase)
>>>> - GCC < 14: no issues currently but avoid ifdef with simple memset
>>>> implementation
>>>> - Link to v1: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatch.msgid.link%2F20260916-vdso-getrandom-avoid-memset-llvm-24-v1-1-80a92f2e225a%40kernel.org&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C8130be3fe7304659b8e308df1b507f25%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639259704683731836%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=Z1w8wFKZCVjlUIwkIjffeIBIPkDhRRln3l7xot3daRc%3D&reserved=0
>>>> ---
>>>> arch/arm64/kernel/vdso/Makefile | 2 +-
>>>> arch/loongarch/vdso/Makefile | 1 +
>>>> arch/powerpc/kernel/vdso/Makefile | 1 +
>>>> arch/riscv/kernel/vdso/Makefile | 1 +
>>>> arch/s390/kernel/vdso/Makefile | 1 +
>>>> arch/x86/entry/vdso/vdso64/Makefile | 2 +-
>>>> init/Kconfig | 7 +++++++
>>>> lib/vdso/getrandom.c | 19 +++++++++++++++++--
>>>> 8 files changed, 30 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
>>>> index 7dec05dd33b7..f6619e1cb2ce 100644
>>>> --- a/arch/arm64/kernel/vdso/Makefile
>>>> +++ b/arch/arm64/kernel/vdso/Makefile
>>>> @@ -41,7 +41,7 @@ CC_FLAGS_REMOVE_VDSO := $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \
>>>> $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
>>>> -Wmissing-prototypes -Wmissing-declarations
>>>>
>>>> -CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
>>>> +CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables $(CONFIG_CC_OPT_INLINE_MEMSET)
>>>>
>>>> CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
>>>> CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)
>>>> diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
>>>> index 9c9181bb4071..0b84892d084b 100644
>>>> --- a/arch/loongarch/vdso/Makefile
>>>> +++ b/arch/loongarch/vdso/Makefile
>>>> @@ -16,6 +16,7 @@ ccflags-vdso := \
>>>> $(filter -m64,$(KBUILD_CFLAGS)) \
>>>> $(filter -march=%,$(KBUILD_CFLAGS)) \
>>>> $(filter -m%-float,$(KBUILD_CFLAGS)) \
>>>> + $(CONFIG_CC_OPT_INLINE_MEMSET) \
>>>> $(CLANG_FLAGS) \
>>>> -D__VDSO__
>>>>
>>>> diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile
>>>> index 368759f81708..0d1a49529885 100644
>>>> --- a/arch/powerpc/kernel/vdso/Makefile
>>>> +++ b/arch/powerpc/kernel/vdso/Makefile
>>>> @@ -43,6 +43,7 @@ ccflags-y := -fno-common -fno-builtin -DBUILD_VDSO
>>>> ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN)
>>>> ccflags-y += $(call cc-option, -fno-stack-protector)
>>>> ccflags-y += -DDISABLE_BRANCH_PROFILING
>>>> +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
>>>> ccflags-y += -ffreestanding -fasynchronous-unwind-tables
>>>> ccflags-remove-y := $(CC_FLAGS_FTRACE)
>>>> ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)
>>>> diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
>>>> index 8dbf2532a573..c023046a3fd7 100644
>>>> --- a/arch/riscv/kernel/vdso/Makefile
>>>> +++ b/arch/riscv/kernel/vdso/Makefile
>>>> @@ -36,6 +36,7 @@ endif
>>>> ccflags-y := -fno-stack-protector
>>>> ccflags-y += -DDISABLE_BRANCH_PROFILING
>>>> ccflags-y += -fno-builtin
>>>> +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
>>>> ccflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
>>>> ccflags-y += $(CFI_FULL)
>>>> asflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
>>>> diff --git a/arch/s390/kernel/vdso/Makefile b/arch/s390/kernel/vdso/Makefile
>>>> index 35c834b895ec..54bcf2984ca1 100644
>>>> --- a/arch/s390/kernel/vdso/Makefile
>>>> +++ b/arch/s390/kernel/vdso/Makefile
>>>> @@ -29,6 +29,7 @@ KBUILD_CFLAGS_VDSO := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_VDSO))
>>>> KBUILD_CFLAGS_VDSO := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_VDSO))
>>>> KBUILD_CFLAGS_VDSO += -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
>>>> KBUILD_CFLAGS_VDSO += -fno-stack-protector $(DISABLE_KSTACK_ERASE)
>>>> +KBUILD_CFLAGS_VDSO += $(CONFIG_CC_OPT_INLINE_MEMSET)
>>>> ldflags-y := -shared -soname=linux-vdso.so.1 \
>>>> --hash-style=both --build-id=sha1 \
>>>> $(call ld-option, --eh-frame-hdr) -T
>>>> diff --git a/arch/x86/entry/vdso/vdso64/Makefile b/arch/x86/entry/vdso/vdso64/Makefile
>>>> index 7c0790065b5e..c2353a065279 100644
>>>> --- a/arch/x86/entry/vdso/vdso64/Makefile
>>>> +++ b/arch/x86/entry/vdso/vdso64/Makefile
>>>> @@ -14,7 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o
>>>> vobjs-$(CONFIG_FUTEX_ROBUST_UNLOCK) += vfutex.o
>>>>
>>>> # Compilation flags
>>>> -flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
>>>> +flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small $(CONFIG_CC_OPT_INLINE_MEMSET)
>>>>
>>>> # The location of this include matters!
>>>> include $(src)/../common/Makefile.include
>>>> diff --git a/init/Kconfig b/init/Kconfig
>>>> index 8583d9f06c52..ff3f8475dd2f 100644
>>>> --- a/init/Kconfig
>>>> +++ b/init/Kconfig
>>>> @@ -173,6 +173,13 @@ config CC_HAS_ALLOC_TOKEN
>>>> config CC_HAS_MULTIDIMENSIONAL_NONSTRING
>>>> def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
>>>>
>>>> +config CC_HAS_OPT_INLINE_MEMSET
>>>> + def_bool $(cc-option,-finline-stringops=memset)
>>>> +
>>>> +config CC_OPT_INLINE_MEMSET
>>>> + string
>>>> + default "-finline-stringops=memset" if CC_HAS_OPT_INLINE_MEMSET
>>>> +
>>>> config LD_CAN_USE_KEEP_IN_OVERLAY
>>>> # ld.lld prior to 21.0.0 did not support KEEP within an overlay description
>>>> # https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fllvm%2Fllvm-project%2Fpull%2F130661&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C8130be3fe7304659b8e308df1b507f25%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639259704683740883%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=JlYxG81FQsC5sm3aLe4M6uUIaU5QNmdbupcy3LuGPGQ%3D&reserved=0
>>>> diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c
>>>> index 2851afa9154f..f5cad5641985 100644
>>>> --- a/lib/vdso/getrandom.c
>>>> +++ b/lib/vdso/getrandom.c
>>>> @@ -29,6 +29,22 @@
>>>> } \
>>>> } while (0)
>>>>
>>>> +#if __has_builtin(__builtin_memset_inline)
>>>> +#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
>>>> +#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
>>>> +#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
>>>> +#else
>>>> +static inline void *memset_inline(void *dst, int value, size_t size)
>>>> +{
>>>> + char *d = dst;
>>>> +
>>>> + while (size--)
>>>> + *d++ = value;
>>>> +
>>>> + return d;
>>>> +}
>>>> +#endif
>>>
>>> Does this work?
>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2FTx6EaGMfb&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C8130be3fe7304659b8e308df1b507f25%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639259704683749874%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=3MCx7IwcEz2ieYYZzQ2dLdrxFTjJiUqH0c1qiOXeLlo%3D&reserved=0
>>
>> Hmmm...possibly.
>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2Fec9rzd9Yf&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C8130be3fe7304659b8e308df1b507f25%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639259704683758681%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=5T4oq%2B4AfVJBqvBNA19kzNq19kRYM9u8YzYcP%2B8P7Mw%3D&reserved=0
>> I don't get it...
>
> Just keep it under 2 pages, it will be fine:
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2FqqoMqfxev&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C8130be3fe7304659b8e308df1b507f25%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639259704683768107%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=FrwGHnEXsSp8scH8GtL%2BlqjymHfVokSrtaOqhp2iZPg%3D&reserved=0
>
Doesn't work on powerpc (gcc 13.4):
foo:
li 5,8192
li 4,0
b memset
foo2:
li 5,8193
li 4,0
b memset
But that's the reason why vdso Makefile has option -fno-builtin, that
option gives instead:
foo:
li 10,2048
li 9,0
addi 3,3,-1
mtctr 10
.L2:
stb 9,1(3)
stb 9,2(3)
stb 9,3(3)
stbu 9,4(3)
bdnz .L2
blr
foo2:
li 9,0
li 10,2048
stb 9,0(3)
mtctr 10
.L10:
stb 9,1(3)
stb 9,2(3)
stb 9,3(3)
stbu 9,4(3)
bdnz .L10
blr
Christophe
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-25 21:46 [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data() Nathan Chancellor
2026-09-25 21:53 ` Nick Desaulniers
@ 2026-09-26 9:39 ` Andreas Schwab
2026-09-26 12:19 ` Nathan Chancellor
1 sibling, 1 reply; 14+ messages in thread
From: Andreas Schwab @ 2026-09-26 9:39 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Andy Lutomirski, Thomas Gleixner, Theodore Ts'o,
Jason A. Donenfeld, Vincenzo Frascino, Nick Desaulniers,
Bill Wendling, Justin Stitt, Catalin Marinas, Will Deacon,
Mark Rutland, Huacai Chen, WANG Xuerui, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy (CS GROUP),
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
On Sep 25 2026, Nathan Chancellor wrote:
> +#if __has_builtin(__builtin_memset_inline)
> +#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
> +#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
> +#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
> +#else
> +static inline void *memset_inline(void *dst, int value, size_t size)
> +{
> + char *d = dst;
> +
> + while (size--)
> + *d++ = value;
> +
> + return d;
> +}
> +#endif
> +
memset actually returns the original pointer, not the incremented one.
Nothing uses the return value of memset_inline here, but it is
confusing.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1
"And now for something completely different."
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-25 22:00 ` Nick Desaulniers
2026-09-25 22:19 ` Nathan Chancellor
2026-09-26 6:34 ` Christophe Leroy (CS GROUP)
@ 2026-09-26 10:02 ` Jason A. Donenfeld
2026-09-26 10:55 ` Christophe Leroy (CS GROUP)
2 siblings, 1 reply; 14+ messages in thread
From: Jason A. Donenfeld @ 2026-09-26 10:02 UTC (permalink / raw)
To: Nick Desaulniers
Cc: Nathan Chancellor, Andy Lutomirski, Thomas Gleixner,
Theodore Ts'o, Vincenzo Frascino, Bill Wendling,
Justin Stitt, Catalin Marinas, Will Deacon, Mark Rutland,
Huacai Chen, WANG Xuerui, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP),
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
On Fri, Sep 25, 2026 at 03:00:46PM -0700, Nick Desaulniers wrote:
> On Fri, Sep 25, 2026 at 2:56 PM Nick Desaulniers
> <ndesaulniers@google.com> wrote:
> >
> > On Fri, Sep 25, 2026 at 2:53 PM Nick Desaulniers
> > <ndesaulniers@google.com> wrote:
> > >
> > > On Fri, Sep 25, 2026 at 2:46 PM Nathan Chancellor <nathan@kernel.org> wrote:
> > > >
> > > > After a recent change in LLVM [1], builds with the random vDSO
> > > > implementation, such as PowerPC and RISC-V, fail when checking the vDSO:
> > > >
> > > > arch/powerpc/kernel/vdso/vdso32.so.dbg: dynamic relocations are not supported
> > > > arch/riscv/kernel/vdso/vdso.so.dbg: dynamic relocations are not supported
> > > >
> > > > memset() is now generated when zeroing params->reserved for some builds
> > > > because LLVM has an optimization (now run in more instances) that can
> > > > recognize at compile time when it is assigning a static value to a
> > > > contiguous area of memory and turn that into a call to memset(). Both
> > > > clang and GCC assume memset() is always available [2].
> > > >
> > > > clang provides a builtin, __builtin_memset_inline [3][4], that can be
> > > > used to ensure an external function call is not generated when zeroing
> > > > this memory. Use it when it is available.
> > > >
> > > > While GCC has no issues with the current code, it has generated memset()
> > > > before, as seen in commit b7bad082e113 ("random: vDSO: avoid call to out
> > > > of line memset()"). GCC 14 provides '-finline-stringops=memset' [5][6]
> > > > with a similar guarantee to the clang builtin, so use it and
> > > > __builtin_memset() when available.
> > > >
> > > > If no option is available, provide a simple memset_inline() like the one
> > > > from lib/string.c to avoid adding an ugly ifdef.
> > > >
> > > > Link: https://github.com/llvm/llvm-project/commit/90cebef1411617fc3eedd359bdf00cb44b1c2439 [1]
> > > > Link: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/gcc/Standards.html#index-ffreestanding [2]
> > > > Link: https://github.com/llvm/llvm-project/commit/38637ee477541370a90b37f149069d8e5c0c2efd [3]
> > > > Link: https://clang.llvm.org/docs/LanguageExtensions.html#guaranteed-inlined-memset [4]
> > > > Link: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=1ff6d9f7428b0668cd8ab0b3e3ab94f1d733124d [5]
> > > > Link: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-finline-stringops [6]
> > > > Suggested-by: "Jason A. Donenfeld" <Jason@zx2c4.com>
> > > > Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
> > > > Signed-off-by: Nathan Chancellor <nathan@kernel.org>
> > > > ---
> > > > Changes in v2:
> > > > - Switch approach entirely (Jason, Nick)
> > > > - clang: use __builtin_memset_inline() to avoid external call
> > > > - GCC 14+: use __builtin_memset + -finline-stringops=memset (hence the
> > > > massive CC list increase)
> > > > - GCC < 14: no issues currently but avoid ifdef with simple memset
> > > > implementation
> > > > - Link to v1: https://patch.msgid.link/20260916-vdso-getrandom-avoid-memset-llvm-24-v1-1-80a92f2e225a@kernel.org
> > > > ---
> > > > arch/arm64/kernel/vdso/Makefile | 2 +-
> > > > arch/loongarch/vdso/Makefile | 1 +
> > > > arch/powerpc/kernel/vdso/Makefile | 1 +
> > > > arch/riscv/kernel/vdso/Makefile | 1 +
> > > > arch/s390/kernel/vdso/Makefile | 1 +
> > > > arch/x86/entry/vdso/vdso64/Makefile | 2 +-
> > > > init/Kconfig | 7 +++++++
> > > > lib/vdso/getrandom.c | 19 +++++++++++++++++--
> > > > 8 files changed, 30 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
> > > > index 7dec05dd33b7..f6619e1cb2ce 100644
> > > > --- a/arch/arm64/kernel/vdso/Makefile
> > > > +++ b/arch/arm64/kernel/vdso/Makefile
> > > > @@ -41,7 +41,7 @@ CC_FLAGS_REMOVE_VDSO := $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \
> > > > $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
> > > > -Wmissing-prototypes -Wmissing-declarations
> > > >
> > > > -CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
> > > > +CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables $(CONFIG_CC_OPT_INLINE_MEMSET)
> > > >
> > > > CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
> > > > CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)
> > > > diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
> > > > index 9c9181bb4071..0b84892d084b 100644
> > > > --- a/arch/loongarch/vdso/Makefile
> > > > +++ b/arch/loongarch/vdso/Makefile
> > > > @@ -16,6 +16,7 @@ ccflags-vdso := \
> > > > $(filter -m64,$(KBUILD_CFLAGS)) \
> > > > $(filter -march=%,$(KBUILD_CFLAGS)) \
> > > > $(filter -m%-float,$(KBUILD_CFLAGS)) \
> > > > + $(CONFIG_CC_OPT_INLINE_MEMSET) \
> > > > $(CLANG_FLAGS) \
> > > > -D__VDSO__
> > > >
> > > > diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile
> > > > index 368759f81708..0d1a49529885 100644
> > > > --- a/arch/powerpc/kernel/vdso/Makefile
> > > > +++ b/arch/powerpc/kernel/vdso/Makefile
> > > > @@ -43,6 +43,7 @@ ccflags-y := -fno-common -fno-builtin -DBUILD_VDSO
> > > > ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN)
> > > > ccflags-y += $(call cc-option, -fno-stack-protector)
> > > > ccflags-y += -DDISABLE_BRANCH_PROFILING
> > > > +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
> > > > ccflags-y += -ffreestanding -fasynchronous-unwind-tables
> > > > ccflags-remove-y := $(CC_FLAGS_FTRACE)
> > > > ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)
> > > > diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
> > > > index 8dbf2532a573..c023046a3fd7 100644
> > > > --- a/arch/riscv/kernel/vdso/Makefile
> > > > +++ b/arch/riscv/kernel/vdso/Makefile
> > > > @@ -36,6 +36,7 @@ endif
> > > > ccflags-y := -fno-stack-protector
> > > > ccflags-y += -DDISABLE_BRANCH_PROFILING
> > > > ccflags-y += -fno-builtin
> > > > +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
> > > > ccflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
> > > > ccflags-y += $(CFI_FULL)
> > > > asflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
> > > > diff --git a/arch/s390/kernel/vdso/Makefile b/arch/s390/kernel/vdso/Makefile
> > > > index 35c834b895ec..54bcf2984ca1 100644
> > > > --- a/arch/s390/kernel/vdso/Makefile
> > > > +++ b/arch/s390/kernel/vdso/Makefile
> > > > @@ -29,6 +29,7 @@ KBUILD_CFLAGS_VDSO := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_VDSO))
> > > > KBUILD_CFLAGS_VDSO := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_VDSO))
> > > > KBUILD_CFLAGS_VDSO += -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
> > > > KBUILD_CFLAGS_VDSO += -fno-stack-protector $(DISABLE_KSTACK_ERASE)
> > > > +KBUILD_CFLAGS_VDSO += $(CONFIG_CC_OPT_INLINE_MEMSET)
> > > > ldflags-y := -shared -soname=linux-vdso.so.1 \
> > > > --hash-style=both --build-id=sha1 \
> > > > $(call ld-option, --eh-frame-hdr) -T
> > > > diff --git a/arch/x86/entry/vdso/vdso64/Makefile b/arch/x86/entry/vdso/vdso64/Makefile
> > > > index 7c0790065b5e..c2353a065279 100644
> > > > --- a/arch/x86/entry/vdso/vdso64/Makefile
> > > > +++ b/arch/x86/entry/vdso/vdso64/Makefile
> > > > @@ -14,7 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o
> > > > vobjs-$(CONFIG_FUTEX_ROBUST_UNLOCK) += vfutex.o
> > > >
> > > > # Compilation flags
> > > > -flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
> > > > +flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small $(CONFIG_CC_OPT_INLINE_MEMSET)
> > > >
> > > > # The location of this include matters!
> > > > include $(src)/../common/Makefile.include
> > > > diff --git a/init/Kconfig b/init/Kconfig
> > > > index 8583d9f06c52..ff3f8475dd2f 100644
> > > > --- a/init/Kconfig
> > > > +++ b/init/Kconfig
> > > > @@ -173,6 +173,13 @@ config CC_HAS_ALLOC_TOKEN
> > > > config CC_HAS_MULTIDIMENSIONAL_NONSTRING
> > > > def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
> > > >
> > > > +config CC_HAS_OPT_INLINE_MEMSET
> > > > + def_bool $(cc-option,-finline-stringops=memset)
> > > > +
> > > > +config CC_OPT_INLINE_MEMSET
> > > > + string
> > > > + default "-finline-stringops=memset" if CC_HAS_OPT_INLINE_MEMSET
> > > > +
> > > > config LD_CAN_USE_KEEP_IN_OVERLAY
> > > > # ld.lld prior to 21.0.0 did not support KEEP within an overlay description
> > > > # https://github.com/llvm/llvm-project/pull/130661
> > > > diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c
> > > > index 2851afa9154f..f5cad5641985 100644
> > > > --- a/lib/vdso/getrandom.c
> > > > +++ b/lib/vdso/getrandom.c
> > > > @@ -29,6 +29,22 @@
> > > > } \
> > > > } while (0)
> > > >
> > > > +#if __has_builtin(__builtin_memset_inline)
> > > > +#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
> > > > +#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
> > > > +#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
> > > > +#else
> > > > +static inline void *memset_inline(void *dst, int value, size_t size)
> > > > +{
> > > > + char *d = dst;
> > > > +
> > > > + while (size--)
> > > > + *d++ = value;
> > > > +
> > > > + return d;
> > > > +}
> > > > +#endif
> > >
> > > Does this work?
> > > https://godbolt.org/z/Tx6EaGMfb
> >
> > Hmmm...possibly.
> > https://godbolt.org/z/ec9rzd9Yf
> > I don't get it...
>
> Just keep it under 2 pages, it will be fine:
> https://godbolt.org/z/qqoMqfxev
https://godbolt.org/z/9W9f5a7Wx
Apparently not on RISCV, which is what prompted this patch in the first
place. So I suspect Nathan's v2 here is the way to go.
Jason
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-26 10:02 ` Jason A. Donenfeld
@ 2026-09-26 10:55 ` Christophe Leroy (CS GROUP)
2026-09-26 12:29 ` Jason A. Donenfeld
2026-09-26 12:39 ` Nathan Chancellor
0 siblings, 2 replies; 14+ messages in thread
From: Christophe Leroy (CS GROUP) @ 2026-09-26 10:55 UTC (permalink / raw)
To: Jason A. Donenfeld, Nick Desaulniers
Cc: Nathan Chancellor, Andy Lutomirski, Thomas Gleixner,
Theodore Ts'o, Vincenzo Frascino, Bill Wendling,
Justin Stitt, Catalin Marinas, Will Deacon, Mark Rutland,
Huacai Chen, WANG Xuerui, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
Hi Jason,
Le 26/09/2026 à 12:02, Jason A. Donenfeld a écrit :
> On Fri, Sep 25, 2026 at 03:00:46PM -0700, Nick Desaulniers wrote:
>> On Fri, Sep 25, 2026 at 2:56 PM Nick Desaulniers
>> <ndesaulniers@google.com> wrote:
>>>
>>> On Fri, Sep 25, 2026 at 2:53 PM Nick Desaulniers
>>> <ndesaulniers@google.com> wrote:
>>>>
>>>> On Fri, Sep 25, 2026 at 2:46 PM Nathan Chancellor <nathan@kernel.org> wrote:
>>>>>
>>>>> After a recent change in LLVM [1], builds with the random vDSO
>>>>> implementation, such as PowerPC and RISC-V, fail when checking the vDSO:
>>>>>
>>>>> arch/powerpc/kernel/vdso/vdso32.so.dbg: dynamic relocations are not supported
>>>>> arch/riscv/kernel/vdso/vdso.so.dbg: dynamic relocations are not supported
>>>>>
>>>>> memset() is now generated when zeroing params->reserved for some builds
>>>>> because LLVM has an optimization (now run in more instances) that can
>>>>> recognize at compile time when it is assigning a static value to a
>>>>> contiguous area of memory and turn that into a call to memset(). Both
>>>>> clang and GCC assume memset() is always available [2].
>>>>>
>>>>> clang provides a builtin, __builtin_memset_inline [3][4], that can be
>>>>> used to ensure an external function call is not generated when zeroing
>>>>> this memory. Use it when it is available.
>>>>>
>>>>> While GCC has no issues with the current code, it has generated memset()
>>>>> before, as seen in commit b7bad082e113 ("random: vDSO: avoid call to out
>>>>> of line memset()"). GCC 14 provides '-finline-stringops=memset' [5][6]
>>>>> with a similar guarantee to the clang builtin, so use it and
>>>>> __builtin_memset() when available.
>>>>>
>>>>> If no option is available, provide a simple memset_inline() like the one
>>>>> from lib/string.c to avoid adding an ugly ifdef.
>>>>>
>>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fllvm%2Fllvm-project%2Fcommit%2F90cebef1411617fc3eedd359bdf00cb44b1c2439&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659627802%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=ku4l8Ol5OJ2qi%2BcSblspxxUKOA6rNpiUO3ZvGSoAb1s%3D&reserved=0 [1]
>>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc-16.2.0%2Fgcc%2FStandards.html%23index-ffreestanding&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659651194%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=jQa1eTDLk3cPNTa3GEBwVEohHh67ukShaRHMZvA%2FHDg%3D&reserved=0 [2]
>>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fllvm%2Fllvm-project%2Fcommit%2F38637ee477541370a90b37f149069d8e5c0c2efd&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659668579%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=zY7Kr9ZZNNZR%2FVsnwYRlubPRpbMaKe9QtMD2snd8ZvA%3D&reserved=0 [3]
>>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fclang.llvm.org%2Fdocs%2FLanguageExtensions.html%23guaranteed-inlined-memset&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659678360%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=vUU2fhCVcUWsbQD3IsRaUzSO8KVSpxwSpgr9San4aq0%3D&reserved=0 [4]
>>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fgit%2F%3Fp%3Dgcc.git%3Ba%3Dcommit%3Bh%3D1ff6d9f7428b0668cd8ab0b3e3ab94f1d733124d&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659687815%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=qHRqxAO252imwH1W93yHlp6jdcFGkFOr2Y2hXbG2MLU%3D&reserved=0 [5]
>>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FOptimize-Options.html%23index-finline-stringops&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659698298%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=0ecc%2BXd6o3nozh3N71aq%2F98Xam%2Fdol7GUHmC637Iv7I%3D&reserved=0 [6]
>>>>> Suggested-by: "Jason A. Donenfeld" <Jason@zx2c4.com>
>>>>> Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
>>>>> Signed-off-by: Nathan Chancellor <nathan@kernel.org>
>>>>> ---
>>>>> Changes in v2:
>>>>> - Switch approach entirely (Jason, Nick)
>>>>> - clang: use __builtin_memset_inline() to avoid external call
>>>>> - GCC 14+: use __builtin_memset + -finline-stringops=memset (hence the
>>>>> massive CC list increase)
>>>>> - GCC < 14: no issues currently but avoid ifdef with simple memset
>>>>> implementation
>>>>> - Link to v1: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatch.msgid.link%2F20260916-vdso-getrandom-avoid-memset-llvm-24-v1-1-80a92f2e225a%40kernel.org&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659712983%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=%2Ftq3tUHqDmbXesqB69w6umXAuaTsfzOIhk54Jy76cwo%3D&reserved=0
>>>>> ---
>>>>> arch/arm64/kernel/vdso/Makefile | 2 +-
>>>>> arch/loongarch/vdso/Makefile | 1 +
>>>>> arch/powerpc/kernel/vdso/Makefile | 1 +
>>>>> arch/riscv/kernel/vdso/Makefile | 1 +
>>>>> arch/s390/kernel/vdso/Makefile | 1 +
>>>>> arch/x86/entry/vdso/vdso64/Makefile | 2 +-
>>>>> init/Kconfig | 7 +++++++
>>>>> lib/vdso/getrandom.c | 19 +++++++++++++++++--
>>>>> 8 files changed, 30 insertions(+), 4 deletions(-)
>>>>>
>>>>> diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
>>>>> index 7dec05dd33b7..f6619e1cb2ce 100644
>>>>> --- a/arch/arm64/kernel/vdso/Makefile
>>>>> +++ b/arch/arm64/kernel/vdso/Makefile
>>>>> @@ -41,7 +41,7 @@ CC_FLAGS_REMOVE_VDSO := $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \
>>>>> $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
>>>>> -Wmissing-prototypes -Wmissing-declarations
>>>>>
>>>>> -CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
>>>>> +CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables $(CONFIG_CC_OPT_INLINE_MEMSET)
>>>>>
>>>>> CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
>>>>> CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)
>>>>> diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
>>>>> index 9c9181bb4071..0b84892d084b 100644
>>>>> --- a/arch/loongarch/vdso/Makefile
>>>>> +++ b/arch/loongarch/vdso/Makefile
>>>>> @@ -16,6 +16,7 @@ ccflags-vdso := \
>>>>> $(filter -m64,$(KBUILD_CFLAGS)) \
>>>>> $(filter -march=%,$(KBUILD_CFLAGS)) \
>>>>> $(filter -m%-float,$(KBUILD_CFLAGS)) \
>>>>> + $(CONFIG_CC_OPT_INLINE_MEMSET) \
>>>>> $(CLANG_FLAGS) \
>>>>> -D__VDSO__
>>>>>
>>>>> diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile
>>>>> index 368759f81708..0d1a49529885 100644
>>>>> --- a/arch/powerpc/kernel/vdso/Makefile
>>>>> +++ b/arch/powerpc/kernel/vdso/Makefile
>>>>> @@ -43,6 +43,7 @@ ccflags-y := -fno-common -fno-builtin -DBUILD_VDSO
>>>>> ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN)
>>>>> ccflags-y += $(call cc-option, -fno-stack-protector)
>>>>> ccflags-y += -DDISABLE_BRANCH_PROFILING
>>>>> +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
>>>>> ccflags-y += -ffreestanding -fasynchronous-unwind-tables
>>>>> ccflags-remove-y := $(CC_FLAGS_FTRACE)
>>>>> ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)
>>>>> diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
>>>>> index 8dbf2532a573..c023046a3fd7 100644
>>>>> --- a/arch/riscv/kernel/vdso/Makefile
>>>>> +++ b/arch/riscv/kernel/vdso/Makefile
>>>>> @@ -36,6 +36,7 @@ endif
>>>>> ccflags-y := -fno-stack-protector
>>>>> ccflags-y += -DDISABLE_BRANCH_PROFILING
>>>>> ccflags-y += -fno-builtin
>>>>> +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
>>>>> ccflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
>>>>> ccflags-y += $(CFI_FULL)
>>>>> asflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
>>>>> diff --git a/arch/s390/kernel/vdso/Makefile b/arch/s390/kernel/vdso/Makefile
>>>>> index 35c834b895ec..54bcf2984ca1 100644
>>>>> --- a/arch/s390/kernel/vdso/Makefile
>>>>> +++ b/arch/s390/kernel/vdso/Makefile
>>>>> @@ -29,6 +29,7 @@ KBUILD_CFLAGS_VDSO := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_VDSO))
>>>>> KBUILD_CFLAGS_VDSO := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_VDSO))
>>>>> KBUILD_CFLAGS_VDSO += -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
>>>>> KBUILD_CFLAGS_VDSO += -fno-stack-protector $(DISABLE_KSTACK_ERASE)
>>>>> +KBUILD_CFLAGS_VDSO += $(CONFIG_CC_OPT_INLINE_MEMSET)
>>>>> ldflags-y := -shared -soname=linux-vdso.so.1 \
>>>>> --hash-style=both --build-id=sha1 \
>>>>> $(call ld-option, --eh-frame-hdr) -T
>>>>> diff --git a/arch/x86/entry/vdso/vdso64/Makefile b/arch/x86/entry/vdso/vdso64/Makefile
>>>>> index 7c0790065b5e..c2353a065279 100644
>>>>> --- a/arch/x86/entry/vdso/vdso64/Makefile
>>>>> +++ b/arch/x86/entry/vdso/vdso64/Makefile
>>>>> @@ -14,7 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o
>>>>> vobjs-$(CONFIG_FUTEX_ROBUST_UNLOCK) += vfutex.o
>>>>>
>>>>> # Compilation flags
>>>>> -flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
>>>>> +flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small $(CONFIG_CC_OPT_INLINE_MEMSET)
>>>>>
>>>>> # The location of this include matters!
>>>>> include $(src)/../common/Makefile.include
>>>>> diff --git a/init/Kconfig b/init/Kconfig
>>>>> index 8583d9f06c52..ff3f8475dd2f 100644
>>>>> --- a/init/Kconfig
>>>>> +++ b/init/Kconfig
>>>>> @@ -173,6 +173,13 @@ config CC_HAS_ALLOC_TOKEN
>>>>> config CC_HAS_MULTIDIMENSIONAL_NONSTRING
>>>>> def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
>>>>>
>>>>> +config CC_HAS_OPT_INLINE_MEMSET
>>>>> + def_bool $(cc-option,-finline-stringops=memset)
>>>>> +
>>>>> +config CC_OPT_INLINE_MEMSET
>>>>> + string
>>>>> + default "-finline-stringops=memset" if CC_HAS_OPT_INLINE_MEMSET
>>>>> +
>>>>> config LD_CAN_USE_KEEP_IN_OVERLAY
>>>>> # ld.lld prior to 21.0.0 did not support KEEP within an overlay description
>>>>> # https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fllvm%2Fllvm-project%2Fpull%2F130661&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659727352%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=03eAQvPTDs%2FN28bYiiZAVYcx2JFSkuOM7x2iwFU%2F%2FxA%3D&reserved=0
>>>>> diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c
>>>>> index 2851afa9154f..f5cad5641985 100644
>>>>> --- a/lib/vdso/getrandom.c
>>>>> +++ b/lib/vdso/getrandom.c
>>>>> @@ -29,6 +29,22 @@
>>>>> } \
>>>>> } while (0)
>>>>>
>>>>> +#if __has_builtin(__builtin_memset_inline)
>>>>> +#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
>>>>> +#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
>>>>> +#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
>>>>> +#else
>>>>> +static inline void *memset_inline(void *dst, int value, size_t size)
>>>>> +{
>>>>> + char *d = dst;
>>>>> +
>>>>> + while (size--)
>>>>> + *d++ = value;
>>>>> +
>>>>> + return d;
>>>>> +}
>>>>> +#endif
>>>>
>>>> Does this work?
>>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2FTx6EaGMfb&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659741160%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=Xv0rle85Js5BH2qNUL4q2Iv2ZwgJhJ4FaTuHYAvvEVo%3D&reserved=0
>>>
>>> Hmmm...possibly.
>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2Fec9rzd9Yf&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659754022%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=bLajY6c3CbYOZMJlBA4bYlVE3bNVc%2Fxe1KYk0rUJgjM%3D&reserved=0
>>> I don't get it...
>>
>> Just keep it under 2 pages, it will be fine:
>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2FqqoMqfxev&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659763804%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=Bcp1%2B%2Fir05tsPwf08OQkJx4vDkPliaSppam1e%2BTPprk%3D&reserved=0
>
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2F9W9f5a7Wx&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659773169%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=YPGYXcKrnM4e1Q2nHdshRUaMT36w%2BRkHuIWIgcbpA94%3D&reserved=0
>
> Apparently not on RISCV, which is what prompted this patch in the first
> place. So I suspect Nathan's v2 here is the way to go.
Don't you have -fno-builtin on RISCV like we have on powerpc ?
Or is it clang that is missing this option ?
Christophe
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-26 9:39 ` Andreas Schwab
@ 2026-09-26 12:19 ` Nathan Chancellor
2026-09-26 12:32 ` Jason A. Donenfeld
0 siblings, 1 reply; 14+ messages in thread
From: Nathan Chancellor @ 2026-09-26 12:19 UTC (permalink / raw)
To: Andreas Schwab
Cc: Andy Lutomirski, Thomas Gleixner, Theodore Ts'o,
Jason A. Donenfeld, Vincenzo Frascino, Nick Desaulniers,
Bill Wendling, Justin Stitt, Catalin Marinas, Will Deacon,
Mark Rutland, Huacai Chen, WANG Xuerui, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy (CS GROUP),
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
On Sat, Sep 26, 2026 at 11:39:43AM +0200, Andreas Schwab wrote:
> On Sep 25 2026, Nathan Chancellor wrote:
>
> > +#if __has_builtin(__builtin_memset_inline)
> > +#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
> > +#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
> > +#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
> > +#else
> > +static inline void *memset_inline(void *dst, int value, size_t size)
> > +{
> > + char *d = dst;
> > +
> > + while (size--)
> > + *d++ = value;
> > +
> > + return d;
> > +}
> > +#endif
> > +
>
> memset actually returns the original pointer, not the incremented one.
> Nothing uses the return value of memset_inline here, but it is
> confusing.
Whoops, good catch, I guess my fingers gave up on those last two
characters :) I will fix this for v3 once there has been some time for
further review.
--
Cheers,
Nathan
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-26 10:55 ` Christophe Leroy (CS GROUP)
@ 2026-09-26 12:29 ` Jason A. Donenfeld
2026-09-26 12:39 ` Nathan Chancellor
1 sibling, 0 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2026-09-26 12:29 UTC (permalink / raw)
To: Christophe Leroy (CS GROUP)
Cc: Nick Desaulniers, Nathan Chancellor, Andy Lutomirski,
Thomas Gleixner, Theodore Ts'o, Vincenzo Frascino,
Bill Wendling, Justin Stitt, Catalin Marinas, Will Deacon,
Mark Rutland, Huacai Chen, WANG Xuerui, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
On Sat, Sep 26, 2026 at 12:55:34PM +0200, Christophe Leroy (CS GROUP) wrote:
> Hi Jason,
>
> Le 26/09/2026 à 12:02, Jason A. Donenfeld a écrit :
> > On Fri, Sep 25, 2026 at 03:00:46PM -0700, Nick Desaulniers wrote:
> >> On Fri, Sep 25, 2026 at 2:56 PM Nick Desaulniers
> >> <ndesaulniers@google.com> wrote:
> >>>
> >>> On Fri, Sep 25, 2026 at 2:53 PM Nick Desaulniers
> >>> <ndesaulniers@google.com> wrote:
> >>>>
> >>>> On Fri, Sep 25, 2026 at 2:46 PM Nathan Chancellor <nathan@kernel.org> wrote:
> >>>>>
> >>>>> After a recent change in LLVM [1], builds with the random vDSO
> >>>>> implementation, such as PowerPC and RISC-V, fail when checking the vDSO:
> >>>>>
> >>>>> arch/powerpc/kernel/vdso/vdso32.so.dbg: dynamic relocations are not supported
> >>>>> arch/riscv/kernel/vdso/vdso.so.dbg: dynamic relocations are not supported
> >>>>>
> >>>>> memset() is now generated when zeroing params->reserved for some builds
> >>>>> because LLVM has an optimization (now run in more instances) that can
> >>>>> recognize at compile time when it is assigning a static value to a
> >>>>> contiguous area of memory and turn that into a call to memset(). Both
> >>>>> clang and GCC assume memset() is always available [2].
> >>>>>
> >>>>> clang provides a builtin, __builtin_memset_inline [3][4], that can be
> >>>>> used to ensure an external function call is not generated when zeroing
> >>>>> this memory. Use it when it is available.
> >>>>>
> >>>>> While GCC has no issues with the current code, it has generated memset()
> >>>>> before, as seen in commit b7bad082e113 ("random: vDSO: avoid call to out
> >>>>> of line memset()"). GCC 14 provides '-finline-stringops=memset' [5][6]
> >>>>> with a similar guarantee to the clang builtin, so use it and
> >>>>> __builtin_memset() when available.
> >>>>>
> >>>>> If no option is available, provide a simple memset_inline() like the one
> >>>>> from lib/string.c to avoid adding an ugly ifdef.
> >>>>>
> >>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fllvm%2Fllvm-project%2Fcommit%2F90cebef1411617fc3eedd359bdf00cb44b1c2439&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659627802%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=ku4l8Ol5OJ2qi%2BcSblspxxUKOA6rNpiUO3ZvGSoAb1s%3D&reserved=0 [1]
> >>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc-16.2.0%2Fgcc%2FStandards.html%23index-ffreestanding&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659651194%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=jQa1eTDLk3cPNTa3GEBwVEohHh67ukShaRHMZvA%2FHDg%3D&reserved=0 [2]
> >>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fllvm%2Fllvm-project%2Fcommit%2F38637ee477541370a90b37f149069d8e5c0c2efd&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659668579%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=zY7Kr9ZZNNZR%2FVsnwYRlubPRpbMaKe9QtMD2snd8ZvA%3D&reserved=0 [3]
> >>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fclang.llvm.org%2Fdocs%2FLanguageExtensions.html%23guaranteed-inlined-memset&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659678360%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=vUU2fhCVcUWsbQD3IsRaUzSO8KVSpxwSpgr9San4aq0%3D&reserved=0 [4]
> >>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fgit%2F%3Fp%3Dgcc.git%3Ba%3Dcommit%3Bh%3D1ff6d9f7428b0668cd8ab0b3e3ab94f1d733124d&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659687815%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=qHRqxAO252imwH1W93yHlp6jdcFGkFOr2Y2hXbG2MLU%3D&reserved=0 [5]
> >>>>> Link: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FOptimize-Options.html%23index-finline-stringops&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659698298%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=0ecc%2BXd6o3nozh3N71aq%2F98Xam%2Fdol7GUHmC637Iv7I%3D&reserved=0 [6]
> >>>>> Suggested-by: "Jason A. Donenfeld" <Jason@zx2c4.com>
> >>>>> Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
> >>>>> Signed-off-by: Nathan Chancellor <nathan@kernel.org>
> >>>>> ---
> >>>>> Changes in v2:
> >>>>> - Switch approach entirely (Jason, Nick)
> >>>>> - clang: use __builtin_memset_inline() to avoid external call
> >>>>> - GCC 14+: use __builtin_memset + -finline-stringops=memset (hence the
> >>>>> massive CC list increase)
> >>>>> - GCC < 14: no issues currently but avoid ifdef with simple memset
> >>>>> implementation
> >>>>> - Link to v1: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatch.msgid.link%2F20260916-vdso-getrandom-avoid-memset-llvm-24-v1-1-80a92f2e225a%40kernel.org&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659712983%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=%2Ftq3tUHqDmbXesqB69w6umXAuaTsfzOIhk54Jy76cwo%3D&reserved=0
> >>>>> ---
> >>>>> arch/arm64/kernel/vdso/Makefile | 2 +-
> >>>>> arch/loongarch/vdso/Makefile | 1 +
> >>>>> arch/powerpc/kernel/vdso/Makefile | 1 +
> >>>>> arch/riscv/kernel/vdso/Makefile | 1 +
> >>>>> arch/s390/kernel/vdso/Makefile | 1 +
> >>>>> arch/x86/entry/vdso/vdso64/Makefile | 2 +-
> >>>>> init/Kconfig | 7 +++++++
> >>>>> lib/vdso/getrandom.c | 19 +++++++++++++++++--
> >>>>> 8 files changed, 30 insertions(+), 4 deletions(-)
> >>>>>
> >>>>> diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
> >>>>> index 7dec05dd33b7..f6619e1cb2ce 100644
> >>>>> --- a/arch/arm64/kernel/vdso/Makefile
> >>>>> +++ b/arch/arm64/kernel/vdso/Makefile
> >>>>> @@ -41,7 +41,7 @@ CC_FLAGS_REMOVE_VDSO := $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \
> >>>>> $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
> >>>>> -Wmissing-prototypes -Wmissing-declarations
> >>>>>
> >>>>> -CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables
> >>>>> +CC_FLAGS_ADD_VDSO := -O2 -mcmodel=tiny -fasynchronous-unwind-tables $(CONFIG_CC_OPT_INLINE_MEMSET)
> >>>>>
> >>>>> CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_REMOVE_VDSO)
> >>>>> CFLAGS_REMOVE_vgetrandom.o = $(CC_FLAGS_REMOVE_VDSO)
> >>>>> diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
> >>>>> index 9c9181bb4071..0b84892d084b 100644
> >>>>> --- a/arch/loongarch/vdso/Makefile
> >>>>> +++ b/arch/loongarch/vdso/Makefile
> >>>>> @@ -16,6 +16,7 @@ ccflags-vdso := \
> >>>>> $(filter -m64,$(KBUILD_CFLAGS)) \
> >>>>> $(filter -march=%,$(KBUILD_CFLAGS)) \
> >>>>> $(filter -m%-float,$(KBUILD_CFLAGS)) \
> >>>>> + $(CONFIG_CC_OPT_INLINE_MEMSET) \
> >>>>> $(CLANG_FLAGS) \
> >>>>> -D__VDSO__
> >>>>>
> >>>>> diff --git a/arch/powerpc/kernel/vdso/Makefile b/arch/powerpc/kernel/vdso/Makefile
> >>>>> index 368759f81708..0d1a49529885 100644
> >>>>> --- a/arch/powerpc/kernel/vdso/Makefile
> >>>>> +++ b/arch/powerpc/kernel/vdso/Makefile
> >>>>> @@ -43,6 +43,7 @@ ccflags-y := -fno-common -fno-builtin -DBUILD_VDSO
> >>>>> ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN)
> >>>>> ccflags-y += $(call cc-option, -fno-stack-protector)
> >>>>> ccflags-y += -DDISABLE_BRANCH_PROFILING
> >>>>> +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
> >>>>> ccflags-y += -ffreestanding -fasynchronous-unwind-tables
> >>>>> ccflags-remove-y := $(CC_FLAGS_FTRACE)
> >>>>> ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)
> >>>>> diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
> >>>>> index 8dbf2532a573..c023046a3fd7 100644
> >>>>> --- a/arch/riscv/kernel/vdso/Makefile
> >>>>> +++ b/arch/riscv/kernel/vdso/Makefile
> >>>>> @@ -36,6 +36,7 @@ endif
> >>>>> ccflags-y := -fno-stack-protector
> >>>>> ccflags-y += -DDISABLE_BRANCH_PROFILING
> >>>>> ccflags-y += -fno-builtin
> >>>>> +ccflags-y += $(CONFIG_CC_OPT_INLINE_MEMSET)
> >>>>> ccflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
> >>>>> ccflags-y += $(CFI_FULL)
> >>>>> asflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
> >>>>> diff --git a/arch/s390/kernel/vdso/Makefile b/arch/s390/kernel/vdso/Makefile
> >>>>> index 35c834b895ec..54bcf2984ca1 100644
> >>>>> --- a/arch/s390/kernel/vdso/Makefile
> >>>>> +++ b/arch/s390/kernel/vdso/Makefile
> >>>>> @@ -29,6 +29,7 @@ KBUILD_CFLAGS_VDSO := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_VDSO))
> >>>>> KBUILD_CFLAGS_VDSO := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_VDSO))
> >>>>> KBUILD_CFLAGS_VDSO += -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
> >>>>> KBUILD_CFLAGS_VDSO += -fno-stack-protector $(DISABLE_KSTACK_ERASE)
> >>>>> +KBUILD_CFLAGS_VDSO += $(CONFIG_CC_OPT_INLINE_MEMSET)
> >>>>> ldflags-y := -shared -soname=linux-vdso.so.1 \
> >>>>> --hash-style=both --build-id=sha1 \
> >>>>> $(call ld-option, --eh-frame-hdr) -T
> >>>>> diff --git a/arch/x86/entry/vdso/vdso64/Makefile b/arch/x86/entry/vdso/vdso64/Makefile
> >>>>> index 7c0790065b5e..c2353a065279 100644
> >>>>> --- a/arch/x86/entry/vdso/vdso64/Makefile
> >>>>> +++ b/arch/x86/entry/vdso/vdso64/Makefile
> >>>>> @@ -14,7 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o
> >>>>> vobjs-$(CONFIG_FUTEX_ROBUST_UNLOCK) += vfutex.o
> >>>>>
> >>>>> # Compilation flags
> >>>>> -flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
> >>>>> +flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small $(CONFIG_CC_OPT_INLINE_MEMSET)
> >>>>>
> >>>>> # The location of this include matters!
> >>>>> include $(src)/../common/Makefile.include
> >>>>> diff --git a/init/Kconfig b/init/Kconfig
> >>>>> index 8583d9f06c52..ff3f8475dd2f 100644
> >>>>> --- a/init/Kconfig
> >>>>> +++ b/init/Kconfig
> >>>>> @@ -173,6 +173,13 @@ config CC_HAS_ALLOC_TOKEN
> >>>>> config CC_HAS_MULTIDIMENSIONAL_NONSTRING
> >>>>> def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
> >>>>>
> >>>>> +config CC_HAS_OPT_INLINE_MEMSET
> >>>>> + def_bool $(cc-option,-finline-stringops=memset)
> >>>>> +
> >>>>> +config CC_OPT_INLINE_MEMSET
> >>>>> + string
> >>>>> + default "-finline-stringops=memset" if CC_HAS_OPT_INLINE_MEMSET
> >>>>> +
> >>>>> config LD_CAN_USE_KEEP_IN_OVERLAY
> >>>>> # ld.lld prior to 21.0.0 did not support KEEP within an overlay description
> >>>>> # https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fllvm%2Fllvm-project%2Fpull%2F130661&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659727352%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=03eAQvPTDs%2FN28bYiiZAVYcx2JFSkuOM7x2iwFU%2F%2FxA%3D&reserved=0
> >>>>> diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c
> >>>>> index 2851afa9154f..f5cad5641985 100644
> >>>>> --- a/lib/vdso/getrandom.c
> >>>>> +++ b/lib/vdso/getrandom.c
> >>>>> @@ -29,6 +29,22 @@
> >>>>> } \
> >>>>> } while (0)
> >>>>>
> >>>>> +#if __has_builtin(__builtin_memset_inline)
> >>>>> +#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
> >>>>> +#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
> >>>>> +#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
> >>>>> +#else
> >>>>> +static inline void *memset_inline(void *dst, int value, size_t size)
> >>>>> +{
> >>>>> + char *d = dst;
> >>>>> +
> >>>>> + while (size--)
> >>>>> + *d++ = value;
> >>>>> +
> >>>>> + return d;
> >>>>> +}
> >>>>> +#endif
> >>>>
> >>>> Does this work?
> >>>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2FTx6EaGMfb&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659741160%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=Xv0rle85Js5BH2qNUL4q2Iv2ZwgJhJ4FaTuHYAvvEVo%3D&reserved=0
> >>>
> >>> Hmmm...possibly.
> >>> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2Fec9rzd9Yf&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659754022%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=bLajY6c3CbYOZMJlBA4bYlVE3bNVc%2Fxe1KYk0rUJgjM%3D&reserved=0
> >>> I don't get it...
> >>
> >> Just keep it under 2 pages, it will be fine:
> >> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2FqqoMqfxev&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659763804%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=Bcp1%2B%2Fir05tsPwf08OQkJx4vDkPliaSppam1e%2BTPprk%3D&reserved=0
> >
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgodbolt.org%2Fz%2F9W9f5a7Wx&data=05%7C02%7Cchristophe.leroy%40csgroup.eu%7C4df96063ffd94e6204df08df1bb54e3d%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639260137659773169%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=YPGYXcKrnM4e1Q2nHdshRUaMT36w%2BRkHuIWIgcbpA94%3D&reserved=0
> >
> > Apparently not on RISCV, which is what prompted this patch in the first
> > place. So I suspect Nathan's v2 here is the way to go.
>
>
> Don't you have -fno-builtin on RISCV like we have on powerpc ?
I think Nick mentioned this led to other problems and didn't exactly
solve the problem.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-26 12:19 ` Nathan Chancellor
@ 2026-09-26 12:32 ` Jason A. Donenfeld
2026-09-26 12:49 ` Nathan Chancellor
0 siblings, 1 reply; 14+ messages in thread
From: Jason A. Donenfeld @ 2026-09-26 12:32 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Andreas Schwab, Andy Lutomirski, Thomas Gleixner,
Theodore Ts'o, Vincenzo Frascino, Nick Desaulniers,
Bill Wendling, Justin Stitt, Catalin Marinas, Will Deacon,
Mark Rutland, Huacai Chen, WANG Xuerui, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy (CS GROUP),
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
On Sat, Sep 26, 2026 at 01:19:27PM +0100, Nathan Chancellor wrote:
> On Sat, Sep 26, 2026 at 11:39:43AM +0200, Andreas Schwab wrote:
> > On Sep 25 2026, Nathan Chancellor wrote:
> >
> > > +#if __has_builtin(__builtin_memset_inline)
> > > +#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
> > > +#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
> > > +#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
> > > +#else
> > > +static inline void *memset_inline(void *dst, int value, size_t size)
> > > +{
> > > + char *d = dst;
> > > +
> > > + while (size--)
> > > + *d++ = value;
> > > +
> > > + return d;
> > > +}
> > > +#endif
> > > +
> >
> > memset actually returns the original pointer, not the incremented one.
> > Nothing uses the return value of memset_inline here, but it is
> > confusing.
>
> Whoops, good catch, I guess my fingers gave up on those last two
> characters :) I will fix this for v3 once there has been some time for
> further review.
Do we even need to return a value at all? Might as well just make the
function two lines:
+ for (char *d = dst; size--;)
+ *d++ = value;
(Technically that could even be one, but maybe that sort of golf loses
clarity. Your choice.)
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-26 10:55 ` Christophe Leroy (CS GROUP)
2026-09-26 12:29 ` Jason A. Donenfeld
@ 2026-09-26 12:39 ` Nathan Chancellor
1 sibling, 0 replies; 14+ messages in thread
From: Nathan Chancellor @ 2026-09-26 12:39 UTC (permalink / raw)
To: Christophe Leroy (CS GROUP)
Cc: Jason A. Donenfeld, Nick Desaulniers, Andy Lutomirski,
Thomas Gleixner, Theodore Ts'o, Vincenzo Frascino,
Bill Wendling, Justin Stitt, Catalin Marinas, Will Deacon,
Mark Rutland, Huacai Chen, WANG Xuerui, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
On Sat, Sep 26, 2026 at 12:55:34PM +0200, Christophe Leroy (CS GROUP) wrote:
> Le 26/09/2026 à 12:02, Jason A. Donenfeld a écrit :
> > Apparently not on RISCV, which is what prompted this patch in the first
> > place. So I suspect Nathan's v2 here is the way to go.
>
>
> Don't you have -fno-builtin on RISCV like we have on powerpc ?
>
> Or is it clang that is missing this option ?
Yes, clang has -fno-builtin but as I mention in the commit message, that
may not always stop the compiler from generating calls to memset(),
which it is allowed to do even with -ffreestanding (which implies
-fno-builtin) per GCC's documentation. -fno-builtin with GCC < 14 just
happens to avoid generating memset() for memset_inline() in all of my
tests, hence why I went with this approach as suggested by Jason.
--
Cheers,
Nathan
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()
2026-09-26 12:32 ` Jason A. Donenfeld
@ 2026-09-26 12:49 ` Nathan Chancellor
0 siblings, 0 replies; 14+ messages in thread
From: Nathan Chancellor @ 2026-09-26 12:49 UTC (permalink / raw)
To: Jason A. Donenfeld
Cc: Andreas Schwab, Andy Lutomirski, Thomas Gleixner,
Theodore Ts'o, Vincenzo Frascino, Nick Desaulniers,
Bill Wendling, Justin Stitt, Catalin Marinas, Will Deacon,
Mark Rutland, Huacai Chen, WANG Xuerui, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy (CS GROUP),
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, x86,
linux-arm-kernel, linux-kernel, loongarch, linuxppc-dev,
linux-riscv, linux-s390, llvm
On Sat, Sep 26, 2026 at 02:32:49PM +0200, Jason A. Donenfeld wrote:
> On Sat, Sep 26, 2026 at 01:19:27PM +0100, Nathan Chancellor wrote:
> > On Sat, Sep 26, 2026 at 11:39:43AM +0200, Andreas Schwab wrote:
> > > On Sep 25 2026, Nathan Chancellor wrote:
> > >
> > > > +#if __has_builtin(__builtin_memset_inline)
> > > > +#define memset_inline(dst, value, size) __builtin_memset_inline(dst, value, size)
> > > > +#elif IS_ENABLED(CONFIG_CC_HAS_OPT_INLINE_MEMSET)
> > > > +#define memset_inline(dst, value, size) __builtin_memset(dst, value, size)
> > > > +#else
> > > > +static inline void *memset_inline(void *dst, int value, size_t size)
> > > > +{
> > > > + char *d = dst;
> > > > +
> > > > + while (size--)
> > > > + *d++ = value;
> > > > +
> > > > + return d;
> > > > +}
> > > > +#endif
> > > > +
> > >
> > > memset actually returns the original pointer, not the incremented one.
> > > Nothing uses the return value of memset_inline here, but it is
> > > confusing.
> >
> > Whoops, good catch, I guess my fingers gave up on those last two
> > characters :) I will fix this for v3 once there has been some time for
> > further review.
>
> Do we even need to return a value at all? Might as well just make the
> function two lines:
>
> + for (char *d = dst; size--;)
> + *d++ = value;
Yeah, good point, no point in returning something that we don't need
plus this is basically what we had before, just with a different pointer
type. Thanks for the suggestion.
> (Technically that could even be one, but maybe that sort of golf loses
> clarity. Your choice.)
I'll keep it two lines just for the sake of clarity.
--
Cheers,
Nathan
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-09-26 12:49 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-25 21:46 [PATCH v2] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data() Nathan Chancellor
2026-09-25 21:53 ` Nick Desaulniers
2026-09-25 21:56 ` Nick Desaulniers
2026-09-25 22:00 ` Nick Desaulniers
2026-09-25 22:19 ` Nathan Chancellor
2026-09-26 6:34 ` Christophe Leroy (CS GROUP)
2026-09-26 10:02 ` Jason A. Donenfeld
2026-09-26 10:55 ` Christophe Leroy (CS GROUP)
2026-09-26 12:29 ` Jason A. Donenfeld
2026-09-26 12:39 ` Nathan Chancellor
2026-09-26 9:39 ` Andreas Schwab
2026-09-26 12:19 ` Nathan Chancellor
2026-09-26 12:32 ` Jason A. Donenfeld
2026-09-26 12:49 ` Nathan Chancellor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®