FROMLIST: [PATCH v5 10/12] arm64: vdso: replace gettimeofday.S with global vgettimeof...
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / arch / arm64 / kernel / vdso / datapage.h
1 /*
2 * Userspace implementations of __get_datapage
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #ifndef __VDSO_DATAPAGE_H
18 #define __VDSO_DATAPAGE_H
19
20 #include <linux/bitops.h>
21 #include <linux/types.h>
22 #include <asm/vdso_datapage.h>
23
24 /*
25 * We use the hidden visibility to prevent the compiler from generating a GOT
26 * relocation. Not only is going through a GOT useless (the entry couldn't and
27 * mustn't be overridden by another library), it does not even work: the linker
28 * cannot generate an absolute address to the data page.
29 *
30 * With the hidden visibility, the compiler simply generates a PC-relative
31 * relocation (R_ARM_REL32), and this is what we need.
32 */
33 extern const struct vdso_data _vdso_data __attribute__((visibility("hidden")));
34
35 static inline const struct vdso_data *__get_datapage(void)
36 {
37 const struct vdso_data *ret;
38 /*
39 * This simply puts &_vdso_data into ret. The reason why we don't use
40 * `ret = &_vdso_data` is that the compiler tends to optimise this in a
41 * very suboptimal way: instead of keeping &_vdso_data in a register,
42 * it goes through a relocation almost every time _vdso_data must be
43 * accessed (even in subfunctions). This is both time and space
44 * consuming: each relocation uses a word in the code section, and it
45 * has to be loaded at runtime.
46 *
47 * This trick hides the assignment from the compiler. Since it cannot
48 * track where the pointer comes from, it will only use one relocation
49 * where __get_datapage() is called, and then keep the result in a
50 * register.
51 */
52 asm("" : "=r"(ret) : "0"(&_vdso_data));
53 return ret;
54 }
55
56 /* We can only guarantee 56 bits of precision. */
57 #define ARCH_CLOCK_FIXED_MASK GENMASK_ULL(55, 0)
58
59 #endif /* __VDSO_DATAPAGE_H */