| .. | .. |
|---|
| 20 | 20 | |
|---|
| 21 | 21 | #define VDSO_HAS_CLOCK_GETRES 1 |
|---|
| 22 | 22 | |
|---|
| 23 | | -#define __VDSO_USE_SYSCALL ULLONG_MAX |
|---|
| 23 | +#if MIPS_ISA_REV < 6 |
|---|
| 24 | +#define VDSO_SYSCALL_CLOBBERS "hi", "lo", |
|---|
| 25 | +#else |
|---|
| 26 | +#define VDSO_SYSCALL_CLOBBERS |
|---|
| 27 | +#endif |
|---|
| 24 | 28 | |
|---|
| 25 | 29 | static __always_inline long gettimeofday_fallback( |
|---|
| 26 | 30 | struct __kernel_old_timeval *_tv, |
|---|
| .. | .. |
|---|
| 37 | 41 | : "=r" (ret), "=r" (error) |
|---|
| 38 | 42 | : "r" (tv), "r" (tz), "r" (nr) |
|---|
| 39 | 43 | : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", |
|---|
| 40 | | - "$14", "$15", "$24", "$25", "hi", "lo", "memory"); |
|---|
| 44 | + "$14", "$15", "$24", "$25", |
|---|
| 45 | + VDSO_SYSCALL_CLOBBERS |
|---|
| 46 | + "memory"); |
|---|
| 41 | 47 | |
|---|
| 42 | 48 | return error ? -ret : ret; |
|---|
| 43 | 49 | } |
|---|
| .. | .. |
|---|
| 61 | 67 | : "=r" (ret), "=r" (error) |
|---|
| 62 | 68 | : "r" (clkid), "r" (ts), "r" (nr) |
|---|
| 63 | 69 | : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", |
|---|
| 64 | | - "$14", "$15", "$24", "$25", "hi", "lo", "memory"); |
|---|
| 70 | + "$14", "$15", "$24", "$25", |
|---|
| 71 | + VDSO_SYSCALL_CLOBBERS |
|---|
| 72 | + "memory"); |
|---|
| 65 | 73 | |
|---|
| 66 | 74 | return error ? -ret : ret; |
|---|
| 67 | 75 | } |
|---|
| .. | .. |
|---|
| 85 | 93 | : "=r" (ret), "=r" (error) |
|---|
| 86 | 94 | : "r" (clkid), "r" (ts), "r" (nr) |
|---|
| 87 | 95 | : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", |
|---|
| 88 | | - "$14", "$15", "$24", "$25", "hi", "lo", "memory"); |
|---|
| 96 | + "$14", "$15", "$24", "$25", |
|---|
| 97 | + VDSO_SYSCALL_CLOBBERS |
|---|
| 98 | + "memory"); |
|---|
| 89 | 99 | |
|---|
| 90 | 100 | return error ? -ret : ret; |
|---|
| 91 | 101 | } |
|---|
| 92 | 102 | |
|---|
| 93 | 103 | #if _MIPS_SIM != _MIPS_SIM_ABI64 |
|---|
| 94 | | - |
|---|
| 95 | | -#define VDSO_HAS_32BIT_FALLBACK 1 |
|---|
| 96 | 104 | |
|---|
| 97 | 105 | static __always_inline long clock_gettime32_fallback( |
|---|
| 98 | 106 | clockid_t _clkid, |
|---|
| .. | .. |
|---|
| 109 | 117 | : "=r" (ret), "=r" (error) |
|---|
| 110 | 118 | : "r" (clkid), "r" (ts), "r" (nr) |
|---|
| 111 | 119 | : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", |
|---|
| 112 | | - "$14", "$15", "$24", "$25", "hi", "lo", "memory"); |
|---|
| 120 | + "$14", "$15", "$24", "$25", |
|---|
| 121 | + VDSO_SYSCALL_CLOBBERS |
|---|
| 122 | + "memory"); |
|---|
| 113 | 123 | |
|---|
| 114 | 124 | return error ? -ret : ret; |
|---|
| 115 | 125 | } |
|---|
| .. | .. |
|---|
| 129 | 139 | : "=r" (ret), "=r" (error) |
|---|
| 130 | 140 | : "r" (clkid), "r" (ts), "r" (nr) |
|---|
| 131 | 141 | : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", |
|---|
| 132 | | - "$14", "$15", "$24", "$25", "hi", "lo", "memory"); |
|---|
| 142 | + "$14", "$15", "$24", "$25", |
|---|
| 143 | + VDSO_SYSCALL_CLOBBERS |
|---|
| 144 | + "memory"); |
|---|
| 133 | 145 | |
|---|
| 134 | 146 | return error ? -ret : ret; |
|---|
| 135 | 147 | } |
|---|
| .. | .. |
|---|
| 171 | 183 | |
|---|
| 172 | 184 | #endif |
|---|
| 173 | 185 | |
|---|
| 174 | | -static __always_inline u64 __arch_get_hw_counter(s32 clock_mode) |
|---|
| 186 | +static __always_inline u64 __arch_get_hw_counter(s32 clock_mode, |
|---|
| 187 | + const struct vdso_data *vd) |
|---|
| 175 | 188 | { |
|---|
| 176 | | -#ifdef CONFIG_CLKSRC_MIPS_GIC |
|---|
| 177 | | - const struct vdso_data *data = get_vdso_data(); |
|---|
| 178 | | -#endif |
|---|
| 179 | | - u64 cycle_now; |
|---|
| 180 | | - |
|---|
| 181 | | - switch (clock_mode) { |
|---|
| 182 | 189 | #ifdef CONFIG_CSRC_R4K |
|---|
| 183 | | - case VDSO_CLOCK_R4K: |
|---|
| 184 | | - cycle_now = read_r4k_count(); |
|---|
| 185 | | - break; |
|---|
| 190 | + if (clock_mode == VDSO_CLOCKMODE_R4K) |
|---|
| 191 | + return read_r4k_count(); |
|---|
| 186 | 192 | #endif |
|---|
| 187 | 193 | #ifdef CONFIG_CLKSRC_MIPS_GIC |
|---|
| 188 | | - case VDSO_CLOCK_GIC: |
|---|
| 189 | | - cycle_now = read_gic_count(data); |
|---|
| 190 | | - break; |
|---|
| 194 | + if (clock_mode == VDSO_CLOCKMODE_GIC) |
|---|
| 195 | + return read_gic_count(vd); |
|---|
| 191 | 196 | #endif |
|---|
| 192 | | - default: |
|---|
| 193 | | - cycle_now = __VDSO_USE_SYSCALL; |
|---|
| 194 | | - break; |
|---|
| 195 | | - } |
|---|
| 196 | | - |
|---|
| 197 | | - return cycle_now; |
|---|
| 197 | + /* |
|---|
| 198 | + * Core checks mode already. So this raced against a concurrent |
|---|
| 199 | + * update. Return something. Core will do another round see the |
|---|
| 200 | + * change and fallback to syscall. |
|---|
| 201 | + */ |
|---|
| 202 | + return 0; |
|---|
| 198 | 203 | } |
|---|
| 199 | 204 | |
|---|
| 205 | +static inline bool mips_vdso_hres_capable(void) |
|---|
| 206 | +{ |
|---|
| 207 | + return IS_ENABLED(CONFIG_CSRC_R4K) || |
|---|
| 208 | + IS_ENABLED(CONFIG_CLKSRC_MIPS_GIC); |
|---|
| 209 | +} |
|---|
| 210 | +#define __arch_vdso_hres_capable mips_vdso_hres_capable |
|---|
| 211 | + |
|---|
| 200 | 212 | static __always_inline const struct vdso_data *__arch_get_vdso_data(void) |
|---|
| 201 | 213 | { |
|---|
| 202 | 214 | return get_vdso_data(); |
|---|