xref: /openbmc/linux/arch/loongarch/vdso/vgetcpu.c (revision 7f1005dd)
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 
9 static __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 
22 static __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 
27 extern
28 int __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused);
29 int __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