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 | |