To implement getrandom() in vDSO, we need to implement stack-less ChaCha20. ChaCha20 is designed to be SIMD-friendly, but LSX is not guaranteed to be available on all LoongArch CPU models. Perform alternative runtime patching on vDSO so we'll be able to use LSX in vDSO. Signed-off-by: Xi Ruoyao <xry111@xxxxxxxxxxx> --- arch/loongarch/kernel/vdso.c | 8 +++++++- arch/loongarch/vdso/vdso.lds.S | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/loongarch/kernel/vdso.c b/arch/loongarch/kernel/vdso.c index 90dfccb41c14..d606ddf65b97 100644 --- a/arch/loongarch/kernel/vdso.c +++ b/arch/loongarch/kernel/vdso.c @@ -17,6 +17,7 @@ #include <linux/time_namespace.h> #include <linux/timekeeper_internal.h> +#include <asm/alternative.h> #include <asm/page.h> #include <asm/vdso.h> #include <vdso/helpers.h> @@ -99,7 +100,7 @@ struct loongarch_vdso_info vdso_info = { static int __init init_vdso(void) { - unsigned long i, cpu, pfn; + unsigned long i, cpu, pfn, vdso; BUG_ON(!PAGE_ALIGNED(vdso_info.vdso)); BUG_ON(!PAGE_ALIGNED(vdso_info.size)); @@ -111,6 +112,11 @@ static int __init init_vdso(void) for (i = 0; i < vdso_info.size / PAGE_SIZE; i++) vdso_info.code_mapping.pages[i] = pfn_to_page(pfn + i); + vdso = (unsigned long)vdso_info.vdso; + + apply_alternatives((struct alt_instr *)(vdso + vdso_offset_alt), + (struct alt_instr *)(vdso + vdso_offset_alt_end)); + return 0; } subsys_initcall(init_vdso); diff --git a/arch/loongarch/vdso/vdso.lds.S b/arch/loongarch/vdso/vdso.lds.S index 56ad855896de..746d31bd4e90 100644 --- a/arch/loongarch/vdso/vdso.lds.S +++ b/arch/loongarch/vdso/vdso.lds.S @@ -35,6 +35,12 @@ SECTIONS .rodata : { *(.rodata*) } :text + .altinstructions : ALIGN(4) { + VDSO_alt = .; + *(.altinstructions) + VDSO_alt_end = .; + } :text + _end = .; PROVIDE(end = .); -- 2.46.0