On Thu, Aug 29, 2024 at 03:27:33PM +0200, Jason A. Donenfeld wrote: > One small question just occurred to me: > > > +static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_data( > > + void) > > +{ > > + return (const struct vdso_rng_data *)( > > + get_vdso_data() + > > + VVAR_LOONGARCH_PAGES_START * PAGE_SIZE + > > + offsetof(struct loongarch_vdso_data, rng_data)); > > +} > > Did you test this in a TIMENS? On x86, I had to deal with the page > offsets switching around depending on whether there was a TIMENS. I > tested this in my test harness with some basic code like: > > if (argc == 1) { > if (unshare(CLONE_NEWTIME)) > panic("unshare(CLONE_NEWTIME)"); > if (!fork()) { > if (execl(argv[0], argv[0], "now-in-timens")) > panic("execl"); > } > wait(NULL); > poweroff(); > } > > Because unlike other namespaces, the time one only becomes active after > fork/exec. > > But maybe loongarch is more organized and you don't need any special > handling in __arch_get_vdso...data() functions like I needed on x86. > Just thought I should check. Normal results: vdso: 25000000 times in 0.287330836 seconds libc: 25000000 times in 4.480710835 seconds syscall: 25000000 times in 4.411098048 seconds After applying diff --git a/arch/x86/include/asm/vdso/getrandom.h b/arch/x86/include/asm/vdso/getrandom.h index ff5334ad32a0..5cb1b318ebe3 100644 --- a/arch/x86/include/asm/vdso/getrandom.h +++ b/arch/x86/include/asm/vdso/getrandom.h @@ -32,8 +32,6 @@ static __always_inline ssize_t getrandom_syscall(void *buffer, size_t len, unsig static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_data(void) { - if (IS_ENABLED(CONFIG_TIME_NS) && __vdso_data->clock_mode == VDSO_CLOCKMODE_TIMENS) - return (void *)&__vdso_rng_data + ((void *)&__timens_vdso_data - (void *)&__vdso_data); return &__vdso_rng_data; } the results are: vdso: 25000000 times in 4.403789593 seconds libc: 25000000 times in 4.466771093 seconds syscall: 25000000 times in 4.428145416 seconds The difference is that when it finds the shared data in the wrong place, it thinks the RNG is uninitialized, so it always falls back to the syscall, hence all three times being the same. If you're unsure how timens handling works on loongarch, try this test yourself and see what you get. Jason