hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/arch/arm64/include/asm/arch_timer.h
....@@ -1,25 +1,15 @@
1
+/* SPDX-License-Identifier: GPL-2.0-only */
12 /*
23 * arch/arm64/include/asm/arch_timer.h
34 *
45 * Copyright (C) 2012 ARM Ltd.
56 * Author: Marc Zyngier <marc.zyngier@arm.com>
6
- *
7
- * This program is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
187 */
198 #ifndef __ASM_ARCH_TIMER_H
209 #define __ASM_ARCH_TIMER_H
2110
2211 #include <asm/barrier.h>
12
+#include <asm/hwcap.h>
2313 #include <asm/sysreg.h>
2414
2515 #include <linux/bug.h>
....@@ -31,11 +21,23 @@
3121 #include <clocksource/arm_arch_timer.h>
3222
3323 #if IS_ENABLED(CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND)
34
-extern struct static_key_false arch_timer_read_ool_enabled;
35
-#define needs_unstable_timer_counter_workaround() \
36
- static_branch_unlikely(&arch_timer_read_ool_enabled)
24
+#define has_erratum_handler(h) \
25
+ ({ \
26
+ const struct arch_timer_erratum_workaround *__wa; \
27
+ __wa = __this_cpu_read(timer_unstable_counter_workaround); \
28
+ (__wa && __wa->h); \
29
+ })
30
+
31
+#define erratum_handler(h) \
32
+ ({ \
33
+ const struct arch_timer_erratum_workaround *__wa; \
34
+ __wa = __this_cpu_read(timer_unstable_counter_workaround); \
35
+ (__wa && __wa->h) ? __wa->h : arch_timer_##h; \
36
+ })
37
+
3738 #else
38
-#define needs_unstable_timer_counter_workaround() false
39
+#define has_erratum_handler(h) false
40
+#define erratum_handler(h) (arch_timer_##h)
3941 #endif
4042
4143 enum arch_timer_erratum_match_type {
....@@ -56,28 +58,43 @@
5658 u64 (*read_cntvct_el0)(void);
5759 int (*set_next_event_phys)(unsigned long, struct clock_event_device *);
5860 int (*set_next_event_virt)(unsigned long, struct clock_event_device *);
61
+ bool disable_compat_vdso;
5962 };
6063
6164 DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
6265 timer_unstable_counter_workaround);
6366
67
+/* inline sysreg accessors that make erratum_handler() work */
68
+static inline notrace u32 arch_timer_read_cntp_tval_el0(void)
69
+{
70
+ return read_sysreg(cntp_tval_el0);
71
+}
72
+
73
+static inline notrace u32 arch_timer_read_cntv_tval_el0(void)
74
+{
75
+ return read_sysreg(cntv_tval_el0);
76
+}
77
+
78
+static inline notrace u64 arch_timer_read_cntpct_el0(void)
79
+{
80
+ return read_sysreg(cntpct_el0);
81
+}
82
+
83
+static inline notrace u64 arch_timer_read_cntvct_el0(void)
84
+{
85
+ return read_sysreg(cntvct_el0);
86
+}
87
+
6488 #define arch_timer_reg_read_stable(reg) \
65
-({ \
66
- u64 _val; \
67
- if (needs_unstable_timer_counter_workaround()) { \
68
- const struct arch_timer_erratum_workaround *wa; \
89
+ ({ \
90
+ u64 _val; \
91
+ \
6992 preempt_disable_notrace(); \
70
- wa = __this_cpu_read(timer_unstable_counter_workaround); \
71
- if (wa && wa->read_##reg) \
72
- _val = wa->read_##reg(); \
73
- else \
74
- _val = read_sysreg(reg); \
93
+ _val = erratum_handler(read_ ## reg)(); \
7594 preempt_enable_notrace(); \
76
- } else { \
77
- _val = read_sysreg(reg); \
78
- } \
79
- _val; \
80
-})
95
+ \
96
+ _val; \
97
+ })
8198
8299 /*
83100 * These register accessors are marked inline so the compiler can
....@@ -148,26 +165,7 @@
148165 isb();
149166 }
150167
151
-/*
152
- * Ensure that reads of the counter are treated the same as memory reads
153
- * for the purposes of ordering by subsequent memory barriers.
154
- *
155
- * This insanity brought to you by speculative system register reads,
156
- * out-of-order memory accesses, sequence locks and Thomas Gleixner.
157
- *
158
- * http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html
159
- */
160
-#define arch_counter_enforce_ordering(val) do { \
161
- u64 tmp, _val = (val); \
162
- \
163
- asm volatile( \
164
- " eor %0, %1, %1\n" \
165
- " add %0, sp, %0\n" \
166
- " ldr xzr, [%0]" \
167
- : "=r" (tmp) : "r" (_val)); \
168
-} while (0)
169
-
170
-static inline u64 arch_counter_get_cntpct(void)
168
+static __always_inline u64 __arch_counter_get_cntpct_stable(void)
171169 {
172170 u64 cnt;
173171
....@@ -177,7 +175,17 @@
177175 return cnt;
178176 }
179177
180
-static inline u64 arch_counter_get_cntvct(void)
178
+static __always_inline u64 __arch_counter_get_cntpct(void)
179
+{
180
+ u64 cnt;
181
+
182
+ isb();
183
+ cnt = read_sysreg(cntpct_el0);
184
+ arch_counter_enforce_ordering(cnt);
185
+ return cnt;
186
+}
187
+
188
+static __always_inline u64 __arch_counter_get_cntvct_stable(void)
181189 {
182190 u64 cnt;
183191
....@@ -187,11 +195,31 @@
187195 return cnt;
188196 }
189197
190
-#undef arch_counter_enforce_ordering
198
+static __always_inline u64 __arch_counter_get_cntvct(void)
199
+{
200
+ u64 cnt;
201
+
202
+ isb();
203
+ cnt = read_sysreg(cntvct_el0);
204
+ arch_counter_enforce_ordering(cnt);
205
+ return cnt;
206
+}
191207
192208 static inline int arch_timer_arch_init(void)
193209 {
194210 return 0;
195211 }
196212
213
+static inline void arch_timer_set_evtstrm_feature(void)
214
+{
215
+ cpu_set_named_feature(EVTSTRM);
216
+#ifdef CONFIG_COMPAT
217
+ compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
218
+#endif
219
+}
220
+
221
+static inline bool arch_timer_have_evtstrm_feature(void)
222
+{
223
+ return cpu_have_named_feature(EVTSTRM);
224
+}
197225 #endif