xref: /OK3568_Linux_fs/kernel/include/vdso/datapage.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef __VDSO_DATAPAGE_H
3*4882a593Smuzhiyun #define __VDSO_DATAPAGE_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #ifndef __ASSEMBLY__
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <linux/compiler.h>
8*4882a593Smuzhiyun #include <uapi/linux/time.h>
9*4882a593Smuzhiyun #include <uapi/linux/types.h>
10*4882a593Smuzhiyun #include <uapi/asm-generic/errno-base.h>
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <vdso/bits.h>
13*4882a593Smuzhiyun #include <vdso/clocksource.h>
14*4882a593Smuzhiyun #include <vdso/ktime.h>
15*4882a593Smuzhiyun #include <vdso/limits.h>
16*4882a593Smuzhiyun #include <vdso/math64.h>
17*4882a593Smuzhiyun #include <vdso/processor.h>
18*4882a593Smuzhiyun #include <vdso/time.h>
19*4882a593Smuzhiyun #include <vdso/time32.h>
20*4882a593Smuzhiyun #include <vdso/time64.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #ifdef CONFIG_ARCH_HAS_VDSO_DATA
23*4882a593Smuzhiyun #include <asm/vdso/data.h>
24*4882a593Smuzhiyun #else
25*4882a593Smuzhiyun struct arch_vdso_data {};
26*4882a593Smuzhiyun #endif
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define VDSO_BASES	(CLOCK_TAI + 1)
29*4882a593Smuzhiyun #define VDSO_HRES	(BIT(CLOCK_REALTIME)		| \
30*4882a593Smuzhiyun 			 BIT(CLOCK_MONOTONIC)		| \
31*4882a593Smuzhiyun 			 BIT(CLOCK_BOOTTIME)		| \
32*4882a593Smuzhiyun 			 BIT(CLOCK_TAI))
33*4882a593Smuzhiyun #define VDSO_COARSE	(BIT(CLOCK_REALTIME_COARSE)	| \
34*4882a593Smuzhiyun 			 BIT(CLOCK_MONOTONIC_COARSE))
35*4882a593Smuzhiyun #define VDSO_RAW	(BIT(CLOCK_MONOTONIC_RAW))
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #define CS_HRES_COARSE	0
38*4882a593Smuzhiyun #define CS_RAW		1
39*4882a593Smuzhiyun #define CS_BASES	(CS_RAW + 1)
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /**
42*4882a593Smuzhiyun  * struct vdso_timestamp - basetime per clock_id
43*4882a593Smuzhiyun  * @sec:	seconds
44*4882a593Smuzhiyun  * @nsec:	nanoseconds
45*4882a593Smuzhiyun  *
46*4882a593Smuzhiyun  * There is one vdso_timestamp object in vvar for each vDSO-accelerated
47*4882a593Smuzhiyun  * clock_id. For high-resolution clocks, this encodes the time
48*4882a593Smuzhiyun  * corresponding to vdso_data.cycle_last. For coarse clocks this encodes
49*4882a593Smuzhiyun  * the actual time.
50*4882a593Smuzhiyun  *
51*4882a593Smuzhiyun  * To be noticed that for highres clocks nsec is left-shifted by
52*4882a593Smuzhiyun  * vdso_data.cs[x].shift.
53*4882a593Smuzhiyun  */
54*4882a593Smuzhiyun struct vdso_timestamp {
55*4882a593Smuzhiyun 	u64	sec;
56*4882a593Smuzhiyun 	u64	nsec;
57*4882a593Smuzhiyun };
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /**
60*4882a593Smuzhiyun  * struct vdso_data - vdso datapage representation
61*4882a593Smuzhiyun  * @seq:		timebase sequence counter
62*4882a593Smuzhiyun  * @clock_mode:		clock mode
63*4882a593Smuzhiyun  * @cycle_last:		timebase at clocksource init
64*4882a593Smuzhiyun  * @mask:		clocksource mask
65*4882a593Smuzhiyun  * @mult:		clocksource multiplier
66*4882a593Smuzhiyun  * @shift:		clocksource shift
67*4882a593Smuzhiyun  * @basetime[clock_id]:	basetime per clock_id
68*4882a593Smuzhiyun  * @offset[clock_id]:	time namespace offset per clock_id
69*4882a593Smuzhiyun  * @tz_minuteswest:	minutes west of Greenwich
70*4882a593Smuzhiyun  * @tz_dsttime:		type of DST correction
71*4882a593Smuzhiyun  * @hrtimer_res:	hrtimer resolution
72*4882a593Smuzhiyun  * @__unused:		unused
73*4882a593Smuzhiyun  * @arch_data:		architecture specific data (optional, defaults
74*4882a593Smuzhiyun  *			to an empty struct)
75*4882a593Smuzhiyun  *
76*4882a593Smuzhiyun  * vdso_data will be accessed by 64 bit and compat code at the same time
77*4882a593Smuzhiyun  * so we should be careful before modifying this structure.
78*4882a593Smuzhiyun  *
79*4882a593Smuzhiyun  * @basetime is used to store the base time for the system wide time getter
80*4882a593Smuzhiyun  * VVAR page.
81*4882a593Smuzhiyun  *
82*4882a593Smuzhiyun  * @offset is used by the special time namespace VVAR pages which are
83*4882a593Smuzhiyun  * installed instead of the real VVAR page. These namespace pages must set
84*4882a593Smuzhiyun  * @seq to 1 and @clock_mode to VDSO_CLOCKMODE_TIMENS to force the code into
85*4882a593Smuzhiyun  * the time namespace slow path. The namespace aware functions retrieve the
86*4882a593Smuzhiyun  * real system wide VVAR page, read host time and add the per clock offset.
87*4882a593Smuzhiyun  * For clocks which are not affected by time namespace adjustment the
88*4882a593Smuzhiyun  * offset must be zero.
89*4882a593Smuzhiyun  */
90*4882a593Smuzhiyun struct vdso_data {
91*4882a593Smuzhiyun 	u32			seq;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	s32			clock_mode;
94*4882a593Smuzhiyun 	u64			cycle_last;
95*4882a593Smuzhiyun 	u64			mask;
96*4882a593Smuzhiyun 	u32			mult;
97*4882a593Smuzhiyun 	u32			shift;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	union {
100*4882a593Smuzhiyun 		struct vdso_timestamp	basetime[VDSO_BASES];
101*4882a593Smuzhiyun 		struct timens_offset	offset[VDSO_BASES];
102*4882a593Smuzhiyun 	};
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	s32			tz_minuteswest;
105*4882a593Smuzhiyun 	s32			tz_dsttime;
106*4882a593Smuzhiyun 	u32			hrtimer_res;
107*4882a593Smuzhiyun 	u32			__unused;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	struct arch_vdso_data	arch_data;
110*4882a593Smuzhiyun };
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun /*
113*4882a593Smuzhiyun  * We use the hidden visibility to prevent the compiler from generating a GOT
114*4882a593Smuzhiyun  * relocation. Not only is going through a GOT useless (the entry couldn't and
115*4882a593Smuzhiyun  * must not be overridden by another library), it does not even work: the linker
116*4882a593Smuzhiyun  * cannot generate an absolute address to the data page.
117*4882a593Smuzhiyun  *
118*4882a593Smuzhiyun  * With the hidden visibility, the compiler simply generates a PC-relative
119*4882a593Smuzhiyun  * relocation, and this is what we need.
120*4882a593Smuzhiyun  */
121*4882a593Smuzhiyun extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
122*4882a593Smuzhiyun extern struct vdso_data _timens_data[CS_BASES] __attribute__((visibility("hidden")));
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun /*
125*4882a593Smuzhiyun  * The generic vDSO implementation requires that gettimeofday.h
126*4882a593Smuzhiyun  * provides:
127*4882a593Smuzhiyun  * - __arch_get_vdso_data(): to get the vdso datapage.
128*4882a593Smuzhiyun  * - __arch_get_hw_counter(): to get the hw counter based on the
129*4882a593Smuzhiyun  *   clock_mode.
130*4882a593Smuzhiyun  * - gettimeofday_fallback(): fallback for gettimeofday.
131*4882a593Smuzhiyun  * - clock_gettime_fallback(): fallback for clock_gettime.
132*4882a593Smuzhiyun  * - clock_getres_fallback(): fallback for clock_getres.
133*4882a593Smuzhiyun  */
134*4882a593Smuzhiyun #ifdef ENABLE_COMPAT_VDSO
135*4882a593Smuzhiyun #include <asm/vdso/compat_gettimeofday.h>
136*4882a593Smuzhiyun #else
137*4882a593Smuzhiyun #include <asm/vdso/gettimeofday.h>
138*4882a593Smuzhiyun #endif /* ENABLE_COMPAT_VDSO */
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun #endif /* !__ASSEMBLY__ */
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun #endif /* __VDSO_DATAPAGE_H */
143