aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2019-04-15 08:03:51 -0400
committerWill Deacon <will.deacon@arm.com>2019-04-30 09:45:53 -0400
commit0f80cad3124f986d0e46c14d46b8da06d87a2bf4 (patch)
tree23b6c711f1bf624708c45a7dc54d464b8687400e
parent79a3aaa7b82e3106be97842dedfd8429248896e6 (diff)
arm64: Restrict ARM64_ERRATUM_1188873 mitigation to AArch32
We currently deal with ARM64_ERRATUM_1188873 by always trapping EL0 accesses for both instruction sets. Although nothing wrong comes out of that, people trying to squeeze the last drop of performance from buggy HW find this over the top. Oh well. Let's change the mitigation by flipping the counter enable bit on return to userspace. Non-broken HW gets an extra branch on the fast path, which is hopefully not the end of the world. The arch timer workaround is also removed. Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--arch/arm64/kernel/entry.S19
-rw-r--r--drivers/clocksource/arm_arch_timer.c15
2 files changed, 17 insertions, 17 deletions
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/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index aa4ec53281ce..da11a9508b77 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -319,13 +319,6 @@ static u64 notrace arm64_858921_read_cntvct_el0(void)
319} 319}
320#endif 320#endif
321 321
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 322#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
330/* 323/*
331 * The low bits of the counter registers are indeterminate while bit 10 or 324 * The low bits of the counter registers are indeterminate while bit 10 or
@@ -457,14 +450,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
457 .read_cntvct_el0 = arm64_858921_read_cntvct_el0, 450 .read_cntvct_el0 = arm64_858921_read_cntvct_el0,
458 }, 451 },
459#endif 452#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 453#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
469 { 454 {
470 .match_type = ate_match_dt, 455 .match_type = ate_match_dt,