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