Commit 18efd0b1 authored by Xi Ruoyao's avatar Xi Ruoyao Committed by Jason A. Donenfeld
Browse files

LoongArch: vDSO: Wire up getrandom() vDSO implementation



Hook up the generic vDSO implementation to the LoongArch vDSO data page
by providing the required __arch_chacha20_blocks_nostack,
__arch_get_k_vdso_rng_data, and getrandom_syscall implementations. Also
wire up the selftests.

Signed-off-by: default avatarXi Ruoyao <xry111@xry111.site>
Acked-by: default avatarHuacai Chen <chenhuacai@kernel.org>
Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
parent 4d456f0c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -190,6 +190,7 @@ config LOONGARCH
	select TRACE_IRQFLAGS_SUPPORT
	select USE_PERCPU_NUMA_NODE_ID
	select USER_STACKTRACE_SUPPORT
	select VDSO_GETRANDOM
	select ZONE_DMA32

config 32BIT
+39 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2024 Xi Ruoyao <xry111@xry111.site>. All Rights Reserved.
 */
#ifndef __ASM_VDSO_GETRANDOM_H
#define __ASM_VDSO_GETRANDOM_H

#ifndef __ASSEMBLY__

#include <asm/unistd.h>
#include <asm/vdso/vdso.h>

static __always_inline ssize_t getrandom_syscall(void *_buffer, size_t _len, unsigned int _flags)
{
	register long ret asm("a0");
	register long nr asm("a7") = __NR_getrandom;
	register void *buffer asm("a0") = _buffer;
	register size_t len asm("a1") = _len;
	register unsigned int flags asm("a2") = _flags;

	asm volatile(
	"      syscall 0\n"
	: "+r" (ret)
	: "r" (nr), "r" (buffer), "r" (len), "r" (flags)
	: "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8",
	  "memory");

	return ret;
}

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));
}

#endif /* !__ASSEMBLY__ */

#endif /* __ASM_VDSO_GETRANDOM_H */
+6 −0
Original line number Diff line number Diff line
@@ -4,6 +4,9 @@
 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
 */

#ifndef _ASM_VDSO_VDSO_H
#define _ASM_VDSO_VDSO_H

#ifndef __ASSEMBLY__

#include <asm/asm.h>
@@ -16,6 +19,7 @@ struct vdso_pcpu_data {

struct loongarch_vdso_data {
	struct vdso_pcpu_data pdata[NR_CPUS];
	struct vdso_rng_data rng_data;
};

/*
@@ -63,3 +67,5 @@ static inline unsigned long get_vdso_data(void)
}

#endif /* __ASSEMBLY__ */

#endif
+8 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <vdso/datapage.h>

extern struct vdso_data *vdso_data;
extern struct vdso_rng_data *vdso_rng_data;

/*
 * Update the vDSO data page to keep in sync with kernel timekeeping.
@@ -19,6 +20,13 @@ struct vdso_data *__loongarch_get_k_vdso_data(void)
}
#define __arch_get_k_vdso_data __loongarch_get_k_vdso_data

static __always_inline
struct vdso_rng_data *__loongarch_get_k_vdso_rng_data(void)
{
	return vdso_rng_data;
}
#define __arch_get_k_vdso_rng_data __loongarch_get_k_vdso_rng_data

/* The asm-generic header needs to be included after the definitions above */
#include <asm-generic/vdso/vsyscall.h>

+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ static union {
static struct page *vdso_pages[] = { NULL };
struct vdso_data *vdso_data = generic_vdso_data.data;
struct vdso_pcpu_data *vdso_pdata = loongarch_vdso_data.vdata.pdata;
struct vdso_rng_data *vdso_rng_data = &loongarch_vdso_data.vdata.rng_data;

static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma)
{
Loading