summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2019-05-01 10:45:36 -0400
committerWill Deacon <will.deacon@arm.com>2019-05-01 10:45:36 -0400
commit24cf262da1ad303fc940c798aab0bd1bd50e3fc2 (patch)
treeda38a3ae51128dfb959fb53d633201ab4ffb4209
parent50abbe19623e08e2aa34e0e526bd6115569f3dc3 (diff)
parent0ea415390cd345b7d09e8c9ebd4b68adfe873043 (diff)
Merge branch 'for-next/timers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux into for-next/core
Conflicts: arch/arm64/Kconfig arch/arm64/include/asm/arch_timer.h
-rw-r--r--Documentation/arm64/silicon-errata.txt1
-rw-r--r--arch/arm/include/asm/arch_timer.h18
-rw-r--r--arch/arm/include/asm/cp15.h2
-rw-r--r--arch/arm/vdso/vgettimeofday.c5
-rw-r--r--arch/arm64/Kconfig12
-rw-r--r--arch/arm64/include/asm/arch_timer.h86
-rw-r--r--arch/arm64/include/asm/cputype.h2
-rw-r--r--arch/arm64/kernel/cpu_errata.c13
-rw-r--r--arch/arm64/kernel/entry.S19
-rw-r--r--arch/arm64/kernel/traps.c4
-rw-r--r--drivers/clocksource/arm_arch_timer.c130
-rw-r--r--drivers/watchdog/sbsa_gwdt.c2
12 files changed, 185 insertions, 109 deletions
diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index d1e2bb801e1b..d5a124d7e242 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -61,6 +61,7 @@ stable kernels.
61| ARM | Cortex-A76 | #1188873 | ARM64_ERRATUM_1188873 | 61| ARM | Cortex-A76 | #1188873 | ARM64_ERRATUM_1188873 |
62| ARM | Cortex-A76 | #1165522 | ARM64_ERRATUM_1165522 | 62| ARM | Cortex-A76 | #1165522 | ARM64_ERRATUM_1165522 |
63| ARM | Cortex-A76 | #1286807 | ARM64_ERRATUM_1286807 | 63| ARM | Cortex-A76 | #1286807 | ARM64_ERRATUM_1286807 |
64| ARM | Neoverse-N1 | #1188873 | ARM64_ERRATUM_1188873 |
64| ARM | MMU-500 | #841119,#826419 | N/A | 65| ARM | MMU-500 | #841119,#826419 | N/A |
65| | | | | 66| | | | |
66| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 | 67| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index 0a8d7bba2cb0..4b66ecd6be99 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -11,6 +11,10 @@
11#include <clocksource/arm_arch_timer.h> 11#include <clocksource/arm_arch_timer.h>
12 12
13#ifdef CONFIG_ARM_ARCH_TIMER 13#ifdef CONFIG_ARM_ARCH_TIMER
14/* 32bit ARM doesn't know anything about timer errata... */
15#define has_erratum_handler(h) (false)
16#define erratum_handler(h) (arch_timer_##h)
17
14int arch_timer_arch_init(void); 18int arch_timer_arch_init(void);
15 19
16/* 20/*
@@ -79,7 +83,7 @@ static inline u32 arch_timer_get_cntfrq(void)
79 return val; 83 return val;
80} 84}
81 85
82static inline u64 arch_counter_get_cntpct(void) 86static inline u64 __arch_counter_get_cntpct(void)
83{ 87{
84 u64 cval; 88 u64 cval;
85 89
@@ -88,7 +92,12 @@ static inline u64 arch_counter_get_cntpct(void)
88 return cval; 92 return cval;
89} 93}
90 94
91static inline u64 arch_counter_get_cntvct(void) 95static inline u64 __arch_counter_get_cntpct_stable(void)
96{
97 return __arch_counter_get_cntpct();
98}
99
100static inline u64 __arch_counter_get_cntvct(void)
92{ 101{
93 u64 cval; 102 u64 cval;
94 103
@@ -97,6 +106,11 @@ static inline u64 arch_counter_get_cntvct(void)
97 return cval; 106 return cval;
98} 107}
99 108
109static inline u64 __arch_counter_get_cntvct_stable(void)
110{
111 return __arch_counter_get_cntvct();
112}
113
100static inline u32 arch_timer_get_cntkctl(void) 114static inline u32 arch_timer_get_cntkctl(void)
101{ 115{
102 u32 cntkctl; 116 u32 cntkctl;
diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
index 07e27f212dc7..d2453e2d3f1f 100644
--- a/arch/arm/include/asm/cp15.h
+++ b/arch/arm/include/asm/cp15.h
@@ -68,6 +68,8 @@
68#define BPIALL __ACCESS_CP15(c7, 0, c5, 6) 68#define BPIALL __ACCESS_CP15(c7, 0, c5, 6)
69#define ICIALLU __ACCESS_CP15(c7, 0, c5, 0) 69#define ICIALLU __ACCESS_CP15(c7, 0, c5, 0)
70 70
71#define CNTVCT __ACCESS_CP15_64(1, c14)
72
71extern unsigned long cr_alignment; /* defined in entry-armv.S */ 73extern unsigned long cr_alignment; /* defined in entry-armv.S */
72 74
73static inline unsigned long get_cr(void) 75static inline unsigned long get_cr(void)
diff --git a/arch/arm/vdso/vgettimeofday.c b/arch/arm/vdso/vgettimeofday.c
index a9dd619c6c29..7bdbf5d5c47d 100644
--- a/arch/arm/vdso/vgettimeofday.c
+++ b/arch/arm/vdso/vgettimeofday.c
@@ -18,9 +18,9 @@
18#include <linux/compiler.h> 18#include <linux/compiler.h>
19#include <linux/hrtimer.h> 19#include <linux/hrtimer.h>
20#include <linux/time.h> 20#include <linux/time.h>
21#include <asm/arch_timer.h>
22#include <asm/barrier.h> 21#include <asm/barrier.h>
23#include <asm/bug.h> 22#include <asm/bug.h>
23#include <asm/cp15.h>
24#include <asm/page.h> 24#include <asm/page.h>
25#include <asm/unistd.h> 25#include <asm/unistd.h>
26#include <asm/vdso_datapage.h> 26#include <asm/vdso_datapage.h>
@@ -123,7 +123,8 @@ static notrace u64 get_ns(struct vdso_data *vdata)
123 u64 cycle_now; 123 u64 cycle_now;
124 u64 nsec; 124 u64 nsec;
125 125
126 cycle_now = arch_counter_get_cntvct(); 126 isb();
127 cycle_now = read_sysreg(CNTVCT);
127 128
128 cycle_delta = (cycle_now - vdata->cs_cycle_last) & vdata->cs_mask; 129 cycle_delta = (cycle_now - vdata->cs_cycle_last) & vdata->cs_mask;
129 130
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b5c6943225ce..1c0cb5131c2a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -477,15 +477,17 @@ config ARM64_ERRATUM_1024718
477 If unsure, say Y. 477 If unsure, say Y.
478 478
479config ARM64_ERRATUM_1188873 479config ARM64_ERRATUM_1188873
480 bool "Cortex-A76: MRC read following MRRC read of specific Generic Timer in AArch32 might give incorrect result" 480 bool "Cortex-A76/Neoverse-N1: MRC read following MRRC read of specific Generic Timer in AArch32 might give incorrect result"
481 default y 481 default y
482 depends on COMPAT
482 select ARM_ARCH_TIMER_OOL_WORKAROUND 483 select ARM_ARCH_TIMER_OOL_WORKAROUND
483 help 484 help
484 This option adds a workaround for ARM Cortex-A76 erratum 1188873. 485 This option adds a workaround for ARM Cortex-A76/Neoverse-N1
486 erratum 1188873.
485 487
486 Affected Cortex-A76 cores (r0p0, r1p0, r2p0) could cause 488 Affected Cortex-A76/Neoverse-N1 cores (r0p0, r1p0, r2p0) could
487 register corruption when accessing the timer registers from 489 cause register corruption when accessing the timer registers
488 AArch32 userspace. 490 from AArch32 userspace.
489 491
490 If unsure, say Y. 492 If unsure, say Y.
491 493
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 93e07512b4b6..b7bca1ae09e6 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -31,11 +31,23 @@
31#include <clocksource/arm_arch_timer.h> 31#include <clocksource/arm_arch_timer.h>
32 32
33#if IS_ENABLED(CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND) 33#if IS_ENABLED(CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND)
34extern struct static_key_false arch_timer_read_ool_enabled; 34#define has_erratum_handler(h) \
35#define needs_unstable_timer_counter_workaround() \ 35 ({ \
36 static_branch_unlikely(&arch_timer_read_ool_enabled) 36 const struct arch_timer_erratum_workaround *__wa; \
37 __wa = __this_cpu_read(timer_unstable_counter_workaround); \
38 (__wa && __wa->h); \
39 })
40
41#define erratum_handler(h) \
42 ({ \
43 const struct arch_timer_erratum_workaround *__wa; \
44 __wa = __this_cpu_read(timer_unstable_counter_workaround); \
45 (__wa && __wa->h) ? __wa->h : arch_timer_##h; \
46 })
47
37#else 48#else
38#define needs_unstable_timer_counter_workaround() false 49#define has_erratum_handler(h) false
50#define erratum_handler(h) (arch_timer_##h)
39#endif 51#endif
40 52
41enum arch_timer_erratum_match_type { 53enum arch_timer_erratum_match_type {
@@ -61,23 +73,37 @@ struct arch_timer_erratum_workaround {
61DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *, 73DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
62 timer_unstable_counter_workaround); 74 timer_unstable_counter_workaround);
63 75
76/* inline sysreg accessors that make erratum_handler() work */
77static inline notrace u32 arch_timer_read_cntp_tval_el0(void)
78{
79 return read_sysreg(cntp_tval_el0);
80}
81
82static inline notrace u32 arch_timer_read_cntv_tval_el0(void)
83{
84 return read_sysreg(cntv_tval_el0);
85}
86
87static inline notrace u64 arch_timer_read_cntpct_el0(void)
88{
89 return read_sysreg(cntpct_el0);
90}
91
92static inline notrace u64 arch_timer_read_cntvct_el0(void)
93{
94 return read_sysreg(cntvct_el0);
95}
96
64#define arch_timer_reg_read_stable(reg) \ 97#define arch_timer_reg_read_stable(reg) \
65({ \ 98 ({ \
66 u64 _val; \ 99 u64 _val; \
67 if (needs_unstable_timer_counter_workaround()) { \ 100 \
68 const struct arch_timer_erratum_workaround *wa; \
69 preempt_disable_notrace(); \ 101 preempt_disable_notrace(); \
70 wa = __this_cpu_read(timer_unstable_counter_workaround); \ 102 _val = erratum_handler(read_ ## reg)(); \
71 if (wa && wa->read_##reg) \
72 _val = wa->read_##reg(); \
73 else \
74 _val = read_sysreg(reg); \
75 preempt_enable_notrace(); \ 103 preempt_enable_notrace(); \
76 } else { \ 104 \
77 _val = read_sysreg(reg); \ 105 _val; \
78 } \ 106 })
79 _val; \
80})
81 107
82/* 108/*
83 * These register accessors are marked inline so the compiler can 109 * These register accessors are marked inline so the compiler can
@@ -167,7 +193,7 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)
167 : "=r" (tmp) : "r" (_val)); \ 193 : "=r" (tmp) : "r" (_val)); \
168} while (0) 194} while (0)
169 195
170static inline u64 arch_counter_get_cntpct(void) 196static inline u64 __arch_counter_get_cntpct_stable(void)
171{ 197{
172 u64 cnt; 198 u64 cnt;
173 199
@@ -177,7 +203,17 @@ static inline u64 arch_counter_get_cntpct(void)
177 return cnt; 203 return cnt;
178} 204}
179 205
180static inline u64 arch_counter_get_cntvct(void) 206static inline u64 __arch_counter_get_cntpct(void)
207{
208 u64 cnt;
209
210 isb();
211 cnt = read_sysreg(cntpct_el0);
212 arch_counter_enforce_ordering(cnt);
213 return cnt;
214}
215
216static inline u64 __arch_counter_get_cntvct_stable(void)
181{ 217{
182 u64 cnt; 218 u64 cnt;
183 219
@@ -187,6 +223,16 @@ static inline u64 arch_counter_get_cntvct(void)
187 return cnt; 223 return cnt;
188} 224}
189 225
226static inline u64 __arch_counter_get_cntvct(void)
227{
228 u64 cnt;
229
230 isb();
231 cnt = read_sysreg(cntvct_el0);
232 arch_counter_enforce_ordering(cnt);
233 return cnt;
234}
235
190#undef arch_counter_enforce_ordering 236#undef arch_counter_enforce_ordering
191 237
192static inline int arch_timer_arch_init(void) 238static inline int arch_timer_arch_init(void)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 5f1437099b99..2602bae334fb 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -89,6 +89,7 @@
89#define ARM_CPU_PART_CORTEX_A35 0xD04 89#define ARM_CPU_PART_CORTEX_A35 0xD04
90#define ARM_CPU_PART_CORTEX_A55 0xD05 90#define ARM_CPU_PART_CORTEX_A55 0xD05
91#define ARM_CPU_PART_CORTEX_A76 0xD0B 91#define ARM_CPU_PART_CORTEX_A76 0xD0B
92#define ARM_CPU_PART_NEOVERSE_N1 0xD0C
92 93
93#define APM_CPU_PART_POTENZA 0x000 94#define APM_CPU_PART_POTENZA 0x000
94 95
@@ -118,6 +119,7 @@
118#define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35) 119#define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35)
119#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55) 120#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
120#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) 121#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
122#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
121#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) 123#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
122#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) 124#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
123#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) 125#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 1b9ce0fdd81d..e88d4e7bdfc7 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -682,6 +682,16 @@ static const struct midr_range workaround_clean_cache[] = {
682}; 682};
683#endif 683#endif
684 684
685#ifdef CONFIG_ARM64_ERRATUM_1188873
686static const struct midr_range erratum_1188873_list[] = {
687 /* Cortex-A76 r0p0 to r2p0 */
688 MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 2, 0),
689 /* Neoverse-N1 r0p0 to r2p0 */
690 MIDR_RANGE(MIDR_NEOVERSE_N1, 0, 0, 2, 0),
691 {},
692};
693#endif
694
685const struct arm64_cpu_capabilities arm64_errata[] = { 695const struct arm64_cpu_capabilities arm64_errata[] = {
686#ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE 696#ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
687 { 697 {
@@ -801,10 +811,9 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
801 }, 811 },
802#ifdef CONFIG_ARM64_ERRATUM_1188873 812#ifdef CONFIG_ARM64_ERRATUM_1188873
803 { 813 {
804 /* Cortex-A76 r0p0 to r2p0 */
805 .desc = "ARM erratum 1188873", 814 .desc = "ARM erratum 1188873",
806 .capability = ARM64_WORKAROUND_1188873, 815 .capability = ARM64_WORKAROUND_1188873,
807 ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 2, 0), 816 ERRATA_MIDR_RANGE_LIST(erratum_1188873_list),
808 }, 817 },
809#endif 818#endif
810#ifdef CONFIG_ARM64_ERRATUM_1165522 819#ifdef CONFIG_ARM64_ERRATUM_1165522
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index c50a7a75f2e0..1a7811b7e3c4 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -336,6 +336,21 @@ alternative_if ARM64_WORKAROUND_845719
336alternative_else_nop_endif 336alternative_else_nop_endif
337#endif 337#endif
3383: 3383:
339#ifdef CONFIG_ARM64_ERRATUM_1188873
340alternative_if_not ARM64_WORKAROUND_1188873
341 b 4f
342alternative_else_nop_endif
343 /*
344 * if (x22.mode32 == cntkctl_el1.el0vcten)
345 * cntkctl_el1.el0vcten = ~cntkctl_el1.el0vcten
346 */
347 mrs x1, cntkctl_el1
348 eon x0, x1, x22, lsr #3
349 tbz x0, #1, 4f
350 eor x1, x1, #2 // ARCH_TIMER_USR_VCT_ACCESS_EN
351 msr cntkctl_el1, x1
3524:
353#endif
339 apply_ssbd 0, x0, x1 354 apply_ssbd 0, x0, x1
340 .endif 355 .endif
341 356
@@ -362,11 +377,11 @@ alternative_else_nop_endif
362 .if \el == 0 377 .if \el == 0
363alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 378alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
364#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 379#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
365 bne 4f 380 bne 5f
366 msr far_el1, x30 381 msr far_el1, x30
367 tramp_alias x30, tramp_exit_native 382 tramp_alias x30, tramp_exit_native
368 br x30 383 br x30
3694: 3845:
370 tramp_alias x30, tramp_exit_compat 385 tramp_alias x30, tramp_exit_compat
371 br x30 386 br x30
372#endif 387#endif
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 21e73954762c..48432027969c 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -496,7 +496,7 @@ static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs)
496{ 496{
497 int rt = ESR_ELx_SYS64_ISS_RT(esr); 497 int rt = ESR_ELx_SYS64_ISS_RT(esr);
498 498
499 pt_regs_write_reg(regs, rt, arch_counter_get_cntvct()); 499 pt_regs_write_reg(regs, rt, arch_timer_read_counter());
500 arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); 500 arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE);
501} 501}
502 502
@@ -668,7 +668,7 @@ static void compat_cntvct_read_handler(unsigned int esr, struct pt_regs *regs)
668{ 668{
669 int rt = (esr & ESR_ELx_CP15_64_ISS_RT_MASK) >> ESR_ELx_CP15_64_ISS_RT_SHIFT; 669 int rt = (esr & ESR_ELx_CP15_64_ISS_RT_MASK) >> ESR_ELx_CP15_64_ISS_RT_SHIFT;
670 int rt2 = (esr & ESR_ELx_CP15_64_ISS_RT2_MASK) >> ESR_ELx_CP15_64_ISS_RT2_SHIFT; 670 int rt2 = (esr & ESR_ELx_CP15_64_ISS_RT2_MASK) >> ESR_ELx_CP15_64_ISS_RT2_SHIFT;
671 u64 val = arch_counter_get_cntvct(); 671 u64 val = arch_timer_read_counter();
672 672
673 pt_regs_write_reg(regs, rt, lower_32_bits(val)); 673 pt_regs_write_reg(regs, rt, lower_32_bits(val));
674 pt_regs_write_reg(regs, rt2, upper_32_bits(val)); 674 pt_regs_write_reg(regs, rt2, upper_32_bits(val));
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 6cc8aff83805..9a2f23df7610 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -152,6 +152,26 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
152 return val; 152 return val;
153} 153}
154 154
155static u64 arch_counter_get_cntpct_stable(void)
156{
157 return __arch_counter_get_cntpct_stable();
158}
159
160static u64 arch_counter_get_cntpct(void)
161{
162 return __arch_counter_get_cntpct();
163}
164
165static u64 arch_counter_get_cntvct_stable(void)
166{
167 return __arch_counter_get_cntvct_stable();
168}
169
170static u64 arch_counter_get_cntvct(void)
171{
172 return __arch_counter_get_cntvct();
173}
174
155/* 175/*
156 * Default to cp15 based access because arm64 uses this function for 176 * Default to cp15 based access because arm64 uses this function for
157 * sched_clock() before DT is probed and the cp15 method is guaranteed 177 * sched_clock() before DT is probed and the cp15 method is guaranteed
@@ -319,13 +339,6 @@ static u64 notrace arm64_858921_read_cntvct_el0(void)
319} 339}
320#endif 340#endif
321 341
322#ifdef CONFIG_ARM64_ERRATUM_1188873
323static u64 notrace arm64_1188873_read_cntvct_el0(void)
324{
325 return read_sysreg(cntvct_el0);
326}
327#endif
328
329#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1 342#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
330/* 343/*
331 * The low bits of the counter registers are indeterminate while bit 10 or 344 * The low bits of the counter registers are indeterminate while bit 10 or
@@ -372,8 +385,7 @@ static u32 notrace sun50i_a64_read_cntv_tval_el0(void)
372DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround); 385DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround);
373EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround); 386EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
374 387
375DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled); 388static atomic_t timer_unstable_counter_workaround_in_use = ATOMIC_INIT(0);
376EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
377 389
378static void erratum_set_next_event_tval_generic(const int access, unsigned long evt, 390static void erratum_set_next_event_tval_generic(const int access, unsigned long evt,
379 struct clock_event_device *clk) 391 struct clock_event_device *clk)
@@ -457,14 +469,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
457 .read_cntvct_el0 = arm64_858921_read_cntvct_el0, 469 .read_cntvct_el0 = arm64_858921_read_cntvct_el0,
458 }, 470 },
459#endif 471#endif
460#ifdef CONFIG_ARM64_ERRATUM_1188873
461 {
462 .match_type = ate_match_local_cap_id,
463 .id = (void *)ARM64_WORKAROUND_1188873,
464 .desc = "ARM erratum 1188873",
465 .read_cntvct_el0 = arm64_1188873_read_cntvct_el0,
466 },
467#endif
468#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1 472#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
469 { 473 {
470 .match_type = ate_match_dt, 474 .match_type = ate_match_dt,
@@ -552,11 +556,8 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa
552 per_cpu(timer_unstable_counter_workaround, i) = wa; 556 per_cpu(timer_unstable_counter_workaround, i) = wa;
553 } 557 }
554 558
555 /* 559 if (wa->read_cntvct_el0 || wa->read_cntpct_el0)
556 * Use the locked version, as we're called from the CPU 560 atomic_set(&timer_unstable_counter_workaround_in_use, 1);
557 * hotplug framework. Otherwise, we end-up in deadlock-land.
558 */
559 static_branch_enable_cpuslocked(&arch_timer_read_ool_enabled);
560 561
561 /* 562 /*
562 * Don't use the vdso fastpath if errata require using the 563 * Don't use the vdso fastpath if errata require using the
@@ -573,7 +574,7 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa
573static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type, 574static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type,
574 void *arg) 575 void *arg)
575{ 576{
576 const struct arch_timer_erratum_workaround *wa; 577 const struct arch_timer_erratum_workaround *wa, *__wa;
577 ate_match_fn_t match_fn = NULL; 578 ate_match_fn_t match_fn = NULL;
578 bool local = false; 579 bool local = false;
579 580
@@ -597,53 +598,32 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
597 if (!wa) 598 if (!wa)
598 return; 599 return;
599 600
600 if (needs_unstable_timer_counter_workaround()) { 601 __wa = __this_cpu_read(timer_unstable_counter_workaround);
601 const struct arch_timer_erratum_workaround *__wa; 602 if (__wa && wa != __wa)
602 __wa = __this_cpu_read(timer_unstable_counter_workaround); 603 pr_warn("Can't enable workaround for %s (clashes with %s\n)",
603 if (__wa && wa != __wa) 604 wa->desc, __wa->desc);
604 pr_warn("Can't enable workaround for %s (clashes with %s\n)",
605 wa->desc, __wa->desc);
606 605
607 if (__wa) 606 if (__wa)
608 return; 607 return;
609 }
610 608
611 arch_timer_enable_workaround(wa, local); 609 arch_timer_enable_workaround(wa, local);
612 pr_info("Enabling %s workaround for %s\n", 610 pr_info("Enabling %s workaround for %s\n",
613 local ? "local" : "global", wa->desc); 611 local ? "local" : "global", wa->desc);
614} 612}
615 613
616#define erratum_handler(fn, r, ...) \
617({ \
618 bool __val; \
619 if (needs_unstable_timer_counter_workaround()) { \
620 const struct arch_timer_erratum_workaround *__wa; \
621 __wa = __this_cpu_read(timer_unstable_counter_workaround); \
622 if (__wa && __wa->fn) { \
623 r = __wa->fn(__VA_ARGS__); \
624 __val = true; \
625 } else { \
626 __val = false; \
627 } \
628 } else { \
629 __val = false; \
630 } \
631 __val; \
632})
633
634static bool arch_timer_this_cpu_has_cntvct_wa(void) 614static bool arch_timer_this_cpu_has_cntvct_wa(void)
635{ 615{
636 const struct arch_timer_erratum_workaround *wa; 616 return has_erratum_handler(read_cntvct_el0);
617}
637 618
638 wa = __this_cpu_read(timer_unstable_counter_workaround); 619static bool arch_timer_counter_has_wa(void)
639 return wa && wa->read_cntvct_el0; 620{
621 return atomic_read(&timer_unstable_counter_workaround_in_use);
640} 622}
641#else 623#else
642#define arch_timer_check_ool_workaround(t,a) do { } while(0) 624#define arch_timer_check_ool_workaround(t,a) do { } while(0)
643#define erratum_set_next_event_tval_virt(...) ({BUG(); 0;})
644#define erratum_set_next_event_tval_phys(...) ({BUG(); 0;})
645#define erratum_handler(fn, r, ...) ({false;})
646#define arch_timer_this_cpu_has_cntvct_wa() ({false;}) 625#define arch_timer_this_cpu_has_cntvct_wa() ({false;})
626#define arch_timer_counter_has_wa() ({false;})
647#endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */ 627#endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
648 628
649static __always_inline irqreturn_t timer_handler(const int access, 629static __always_inline irqreturn_t timer_handler(const int access,
@@ -736,11 +716,6 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
736static int arch_timer_set_next_event_virt(unsigned long evt, 716static int arch_timer_set_next_event_virt(unsigned long evt,
737 struct clock_event_device *clk) 717 struct clock_event_device *clk)
738{ 718{
739 int ret;
740
741 if (erratum_handler(set_next_event_virt, ret, evt, clk))
742 return ret;
743
744 set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk); 719 set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
745 return 0; 720 return 0;
746} 721}
@@ -748,11 +723,6 @@ static int arch_timer_set_next_event_virt(unsigned long evt,
748static int arch_timer_set_next_event_phys(unsigned long evt, 723static int arch_timer_set_next_event_phys(unsigned long evt,
749 struct clock_event_device *clk) 724 struct clock_event_device *clk)
750{ 725{
751 int ret;
752
753 if (erratum_handler(set_next_event_phys, ret, evt, clk))
754 return ret;
755
756 set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk); 726 set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
757 return 0; 727 return 0;
758} 728}
@@ -777,6 +747,10 @@ static void __arch_timer_setup(unsigned type,
777 clk->features = CLOCK_EVT_FEAT_ONESHOT; 747 clk->features = CLOCK_EVT_FEAT_ONESHOT;
778 748
779 if (type == ARCH_TIMER_TYPE_CP15) { 749 if (type == ARCH_TIMER_TYPE_CP15) {
750 typeof(clk->set_next_event) sne;
751
752 arch_timer_check_ool_workaround(ate_match_local_cap_id, NULL);
753
780 if (arch_timer_c3stop) 754 if (arch_timer_c3stop)
781 clk->features |= CLOCK_EVT_FEAT_C3STOP; 755 clk->features |= CLOCK_EVT_FEAT_C3STOP;
782 clk->name = "arch_sys_timer"; 756 clk->name = "arch_sys_timer";
@@ -787,20 +761,20 @@ static void __arch_timer_setup(unsigned type,
787 case ARCH_TIMER_VIRT_PPI: 761 case ARCH_TIMER_VIRT_PPI:
788 clk->set_state_shutdown = arch_timer_shutdown_virt; 762 clk->set_state_shutdown = arch_timer_shutdown_virt;
789 clk->set_state_oneshot_stopped = arch_timer_shutdown_virt; 763 clk->set_state_oneshot_stopped = arch_timer_shutdown_virt;
790 clk->set_next_event = arch_timer_set_next_event_virt; 764 sne = erratum_handler(set_next_event_virt);
791 break; 765 break;
792 case ARCH_TIMER_PHYS_SECURE_PPI: 766 case ARCH_TIMER_PHYS_SECURE_PPI:
793 case ARCH_TIMER_PHYS_NONSECURE_PPI: 767 case ARCH_TIMER_PHYS_NONSECURE_PPI:
794 case ARCH_TIMER_HYP_PPI: 768 case ARCH_TIMER_HYP_PPI:
795 clk->set_state_shutdown = arch_timer_shutdown_phys; 769 clk->set_state_shutdown = arch_timer_shutdown_phys;
796 clk->set_state_oneshot_stopped = arch_timer_shutdown_phys; 770 clk->set_state_oneshot_stopped = arch_timer_shutdown_phys;
797 clk->set_next_event = arch_timer_set_next_event_phys; 771 sne = erratum_handler(set_next_event_phys);
798 break; 772 break;
799 default: 773 default:
800 BUG(); 774 BUG();
801 } 775 }
802 776
803 arch_timer_check_ool_workaround(ate_match_local_cap_id, NULL); 777 clk->set_next_event = sne;
804 } else { 778 } else {
805 clk->features |= CLOCK_EVT_FEAT_DYNIRQ; 779 clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
806 clk->name = "arch_mem_timer"; 780 clk->name = "arch_mem_timer";
@@ -1002,12 +976,22 @@ static void __init arch_counter_register(unsigned type)
1002 976
1003 /* Register the CP15 based counter if we have one */ 977 /* Register the CP15 based counter if we have one */
1004 if (type & ARCH_TIMER_TYPE_CP15) { 978 if (type & ARCH_TIMER_TYPE_CP15) {
979 u64 (*rd)(void);
980
1005 if ((IS_ENABLED(CONFIG_ARM64) && !is_hyp_mode_available()) || 981 if ((IS_ENABLED(CONFIG_ARM64) && !is_hyp_mode_available()) ||
1006 arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) 982 arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) {
1007 arch_timer_read_counter = arch_counter_get_cntvct; 983 if (arch_timer_counter_has_wa())
1008 else 984 rd = arch_counter_get_cntvct_stable;
1009 arch_timer_read_counter = arch_counter_get_cntpct; 985 else
986 rd = arch_counter_get_cntvct;
987 } else {
988 if (arch_timer_counter_has_wa())
989 rd = arch_counter_get_cntpct_stable;
990 else
991 rd = arch_counter_get_cntpct;
992 }
1010 993
994 arch_timer_read_counter = rd;
1011 clocksource_counter.archdata.vdso_direct = vdso_default; 995 clocksource_counter.archdata.vdso_direct = vdso_default;
1012 } else { 996 } else {
1013 arch_timer_read_counter = arch_counter_get_cntvct_mem; 997 arch_timer_read_counter = arch_counter_get_cntvct_mem;
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
index e8bd9887c566..e221e47396ab 100644
--- a/drivers/watchdog/sbsa_gwdt.c
+++ b/drivers/watchdog/sbsa_gwdt.c
@@ -161,7 +161,7 @@ static unsigned int sbsa_gwdt_get_timeleft(struct watchdog_device *wdd)
161 timeleft += readl(gwdt->control_base + SBSA_GWDT_WOR); 161 timeleft += readl(gwdt->control_base + SBSA_GWDT_WOR);
162 162
163 timeleft += lo_hi_readq(gwdt->control_base + SBSA_GWDT_WCV) - 163 timeleft += lo_hi_readq(gwdt->control_base + SBSA_GWDT_WCV) -
164 arch_counter_get_cntvct(); 164 arch_timer_read_counter();
165 165
166 do_div(timeleft, gwdt->clk); 166 do_div(timeleft, gwdt->clk);
167 167