Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[sfrench/cifs-2.6.git] / arch / mips / vdso / vdso.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright (C) 2015 Imagination Technologies
4  * Author: Alex Smith <alex.smith@imgtec.com>
5  */
6
7 #include <asm/sgidefs.h>
8
9 #if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT)
10
11 /* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */
12 #undef CONFIG_64BIT
13 #define CONFIG_32BIT 1
14 #ifndef __ASSEMBLY__
15 #include <asm-generic/atomic64.h>
16 #endif
17 #endif
18
19 #ifndef __ASSEMBLY__
20
21 #include <asm/asm.h>
22 #include <asm/page.h>
23 #include <asm/vdso.h>
24
25 static inline unsigned long get_vdso_base(void)
26 {
27         unsigned long addr;
28
29         /*
30          * We can't use cpu_has_mips_r6 since it needs the cpu_data[]
31          * kernel symbol.
32          */
33 #ifdef CONFIG_CPU_MIPSR6
34         /*
35          * lapc <symbol> is an alias to addiupc reg, <symbol> - .
36          *
37          * We can't use addiupc because there is no label-label
38          * support for the addiupc reloc
39          */
40         __asm__("lapc   %0, _start                      \n"
41                 : "=r" (addr) : :);
42 #else
43         /*
44          * Get the base load address of the VDSO. We have to avoid generating
45          * relocations and references to the GOT because ld.so does not peform
46          * relocations on the VDSO. We use the current offset from the VDSO base
47          * and perform a PC-relative branch which gives the absolute address in
48          * ra, and take the difference. The assembler chokes on
49          * "li %0, _start - .", so embed the offset as a word and branch over
50          * it.
51          *
52          */
53
54         __asm__(
55         "       .set push                               \n"
56         "       .set noreorder                          \n"
57         "       bal     1f                              \n"
58         "        nop                                    \n"
59         "       .word   _start - .                      \n"
60         "1:     lw      %0, 0($31)                      \n"
61         "       " STR(PTR_ADDU) " %0, $31, %0           \n"
62         "       .set pop                                \n"
63         : "=r" (addr)
64         :
65         : "$31");
66 #endif /* CONFIG_CPU_MIPSR6 */
67
68         return addr;
69 }
70
71 static inline const union mips_vdso_data *get_vdso_data(void)
72 {
73         return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE);
74 }
75
76 #ifdef CONFIG_CLKSRC_MIPS_GIC
77
78 static inline void __iomem *get_gic(const union mips_vdso_data *data)
79 {
80         return (void __iomem *)data - PAGE_SIZE;
81 }
82
83 #endif /* CONFIG_CLKSRC_MIPS_GIC */
84
85 #endif /* __ASSEMBLY__ */