xref: /openbmc/linux/arch/loongarch/vdso/vgetcpu.c (revision 3b73c45e)
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_base() - VDSO_DATA_SIZE);
25 }
26 
27 int __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused)
28 {
29 	int cpu_id;
30 	const struct vdso_pcpu_data *data;
31 
32 	cpu_id = read_cpu_id();
33 
34 	if (cpu)
35 		*cpu = cpu_id;
36 
37 	if (node) {
38 		data = get_pcpu_data();
39 		*node = data[cpu_id].node;
40 	}
41 
42 	return 0;
43 }
44