Re: [PATCH] random: vDSO: Avoid call to memset() when zeroing reserved in __cvdso_getrandom_data()

From: Jason A. Donenfeld

Date: Fri Sep 18 2026 - 08:59:52 EST


On Fri, Sep 18, 2026 at 10:20:45AM +0200, Jason A. Donenfeld wrote:
> On Thu, Sep 17, 2026 at 6:49 PM Nick Desaulniers
> <ndesaulniers@xxxxxxxxxx> wrote:
> >
> > On Thu, Sep 17, 2026 at 10:39 AM Nathan Chancellor <nathan@xxxxxxxxxx> wrote:
> > >
> > > On Thu, Sep 17, 2026 at 11:26:46AM +0200, Jason A. Donenfeld wrote:
> > > > I don't suspect this is the right change. On x86_64, this changes to
> > > > code from:
> > > >
> > > > rep stosq
> > > >
> > > > into:
> > > >
> > > > loc_2D9:
> > > > mov dword ptr [rbx+rax*4+0Ch], 0
> > > > add rax, 1
> > > > cmp rax, 0Ch
> > > > jbe short loc_2D9
> >
> > /me nods
> >
> > > >
> > > > Which is a lot less compact. It seems like the actual solution is for
> > > > gcc&clang to emit this inline memset mnemonic when the platform has a
> > > > good one, and otherwise not. But disabling optimizations for all
> > > > platforms, because it's broken on one, seems bad.
> >
> > Ideally, yeah.
> > Pragmatically:
> > the compiler doesn't know what you will link against or not; so it
> > just emits relocations that the linker will (hopefully) resolve. I've
> > definitely looked at how llvm decides when to emit libcalls to
> > compiler-rt/libgcc ("the compiler runtime") and thought "I wonder how
> > this works with compiler runtime version N-1?"
> >
> > There's also the requirement gcc and clang have about memcpy, memmove,
> > memset, memcmp always being available (-ffreestanding or not) noted
> > below.
> >
> > > > In this case, the compiler is being smart: it identifies a loop and
> > > > rightly turns it into memset. But if this isn't a compilation
> > > > environment that has an outline function, it should do something else.
> > >
> > > As I mentioned in the commit message, compilers require all environments
> > > (hosted or not) to provide memset(), so the "doing something else" is
> > > nothing :)
> > >
> > > GCC requires the freestanding environment provide memcpy, memmove,
> > > memset and memcmp.
> >
> > +1
> >
> > >
> > > I guess another option is to just include a basic memset() like the one
> > > in lib/string.c so that it is only used if the compiler makes this sort
> > > of transformation, while leaving all other architectures alone.
> >
> > It's also possible to get GCC to emit the libcall, even in the
> > presence of -ffreestanding: https://godbolt.org/z/6hTrYq9z8
> >
> > And it's not the first time this code in particular has had this issue;
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b7bad082e113640fc81200ff869e5c2d7a9c29a2
> >
> > (is this patch a Fixes: for that?)
> >
> > Clang has __builtin_memset_inline to avoid explicit libcalls; AFAICT
> > GCC does not. So we could use that here to provide such a guarantee
> > with clang; the code would remain brittle and likely break again with
> > GCC.
>
> It sounds like this is broken currently only on clang on riscv, right?
> So maybe we can use __builtin_memset_inline, and get something similar
> into gcc, before a future gcc version also breaks? That way it doesn't
> break in the future.

There's -finline-stringops=memset for gcc (>=14), which should keep
things sane there. So, we can use that on gcc, and alias memset to
__builtin_memset_inline on clang. And then we should be good?