1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Fast user context implementation of getcpu()
4 */
5
6#include <asm/vdso.h>
7#include <linux/getcpu.h>
8
9static __always_inline int read_cpu_id(void)
10{
11	int cpu_id;
12
13	__asm__ __volatile__(
14	"	rdtime.d $zero, %0\n"
15	: "=r" (cpu_id)
16	:
17	: "memory");
18
19	return cpu_id;
20}
21
22static __always_inline const struct vdso_pcpu_data *get_pcpu_data(void)
23{
24	return (struct vdso_pcpu_data *)(get_vdso_data() + VVAR_LOONGARCH_PAGES_START * PAGE_SIZE);
25}
26
27extern
28int __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused);
29int __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused)
30{
31	int cpu_id;
32	const struct vdso_pcpu_data *data;
33
34	cpu_id = read_cpu_id();
35
36	if (cpu)
37		*cpu = cpu_id;
38
39	if (node) {
40		data = get_pcpu_data();
41		*node = data[cpu_id].node;
42	}
43
44	return 0;
45}
46