LoongArch: Add vDSO syscall __vdso_getcpu()
[linux-2.6-microblaze.git] / arch / loongarch / vdso / vgetcpu.c
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 }