arm64: Restrict ARM64_ERRATUM_1188873 mitigation to AArch32
authorMarc Zyngier <marc.zyngier@arm.com>
Mon, 15 Apr 2019 12:03:51 +0000 (13:03 +0100)
committerWill Deacon <will.deacon@arm.com>
Tue, 30 Apr 2019 13:45:53 +0000 (14:45 +0100)
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>
arch/arm64/kernel/entry.S
drivers/clocksource/arm_arch_timer.c

index c50a7a75f2e0f791fc0a53f85e66fcf0140f3c7e..1a7811b7e3c4611fc132d44996955e7632a6876a 100644 (file)
@@ -336,6 +336,21 @@ alternative_if ARM64_WORKAROUND_845719
 alternative_else_nop_endif
 #endif
 3:
+#ifdef CONFIG_ARM64_ERRATUM_1188873
+alternative_if_not ARM64_WORKAROUND_1188873
+       b       4f
+alternative_else_nop_endif
+       /*
+        * if (x22.mode32 == cntkctl_el1.el0vcten)
+        *     cntkctl_el1.el0vcten = ~cntkctl_el1.el0vcten
+        */
+       mrs     x1, cntkctl_el1
+       eon     x0, x1, x22, lsr #3
+       tbz     x0, #1, 4f
+       eor     x1, x1, #2      // ARCH_TIMER_USR_VCT_ACCESS_EN
+       msr     cntkctl_el1, x1
+4:
+#endif
        apply_ssbd 0, x0, x1
        .endif
 
@@ -362,11 +377,11 @@ alternative_else_nop_endif
        .if     \el == 0
 alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
-       bne     4f
+       bne     5f
        msr     far_el1, x30
        tramp_alias     x30, tramp_exit_native
        br      x30
-4:
+5:
        tramp_alias     x30, tramp_exit_compat
        br      x30
 #endif
index aa4ec53281cea585214c3a5f8b4faf941e7e7bd3..da11a9508b7783bc2e999b3a46e2da5add225358 100644 (file)
@@ -319,13 +319,6 @@ static u64 notrace arm64_858921_read_cntvct_el0(void)
 }
 #endif
 
-#ifdef CONFIG_ARM64_ERRATUM_1188873
-static u64 notrace arm64_1188873_read_cntvct_el0(void)
-{
-       return read_sysreg(cntvct_el0);
-}
-#endif
-
 #ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
 /*
  * 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[] = {
                .read_cntvct_el0 = arm64_858921_read_cntvct_el0,
        },
 #endif
-#ifdef CONFIG_ARM64_ERRATUM_1188873
-       {
-               .match_type = ate_match_local_cap_id,
-               .id = (void *)ARM64_WORKAROUND_1188873,
-               .desc = "ARM erratum 1188873",
-               .read_cntvct_el0 = arm64_1188873_read_cntvct_el0,
-       },
-#endif
 #ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
        {
                .match_type = ate_match_dt,