arm64: errata: Remove AES hwcap for COMPAT tasks
authorJames Morse <james.morse@arm.com>
Thu, 14 Jul 2022 16:15:23 +0000 (17:15 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 29 Oct 2022 08:12:53 +0000 (10:12 +0200)
commit 44b3834b2eed595af07021b1c64e6f9bc396398b upstream.

Cortex-A57 and Cortex-A72 have an erratum where an interrupt that
occurs between a pair of AES instructions in aarch32 mode may corrupt
the ELR. The task will subsequently produce the wrong AES result.

The AES instructions are part of the cryptographic extensions, which are
optional. User-space software will detect the support for these
instructions from the hwcaps. If the platform doesn't support these
instructions a software implementation should be used.

Remove the hwcap bits on affected parts to indicate user-space should
not use the AES instructions.

Acked-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: James Morse <james.morse@arm.com>
Link: https://lore.kernel.org/r/20220714161523.279570-3-james.morse@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
[florian: resolved conflicts in arch/arm64/tools/cpucaps and cpu_errata.c]
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/arm64/silicon-errata.rst
arch/arm64/Kconfig
arch/arm64/kernel/cpu_errata.c
arch/arm64/kernel/cpufeature.c
arch/arm64/tools/cpucaps

index 21715d1e538d033ab00f94e28d1d3b0c82bf3256..1cee230338a23fd2407f4048e8c1f186d1d85444 100644 (file)
@@ -78,10 +78,14 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A57      | #1319537        | ARM64_ERRATUM_1319367       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A57      | #1742098        | ARM64_ERRATUM_1742098       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A72      | #853709         | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A72      | #1319367        | ARM64_ERRATUM_1319367       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A72      | #1655431        | ARM64_ERRATUM_1742098       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A73      | #858921         | ARM64_ERRATUM_858921        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A76      | #1188873,1418040| ARM64_ERRATUM_1418040       |
index 1e5a03d51d46525eaa1180d64143009324d1f4a4..9d3cbe786f8df2e288b07b8b444909444be9d7d7 100644 (file)
@@ -487,6 +487,22 @@ config ARM64_ERRATUM_834220
 
          If unsure, say Y.
 
+config ARM64_ERRATUM_1742098
+       bool "Cortex-A57/A72: 1742098: ELR recorded incorrectly on interrupt taken between cryptographic instructions in a sequence"
+       depends on COMPAT
+       default y
+       help
+         This option removes the AES hwcap for aarch32 user-space to
+         workaround erratum 1742098 on Cortex-A57 and Cortex-A72.
+
+         Affected parts may corrupt the AES state if an interrupt is
+         taken between a pair of AES instructions. These instructions
+         are only present if the cryptography extensions are present.
+         All software should have a fallback implementation for CPUs
+         that don't implement the cryptography extensions.
+
+         If unsure, say Y.
+
 config ARM64_ERRATUM_845719
        bool "Cortex-A53: 845719: a load might read incorrect data"
        depends on COMPAT
index a3a9b153732900bebab226dd70cc8c550feba9ba..ce59811616d8cff288d80434dbe4bd6266978468 100644 (file)
@@ -355,6 +355,14 @@ static const struct midr_range erratum_1463225[] = {
 };
 #endif
 
+#ifdef CONFIG_ARM64_ERRATUM_1742098
+static struct midr_range broken_aarch32_aes[] = {
+       MIDR_RANGE(MIDR_CORTEX_A57, 0, 1, 0xf, 0xf),
+       MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
+       {},
+};
+#endif
+
 const struct arm64_cpu_capabilities arm64_errata[] = {
 #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
        {
@@ -564,6 +572,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
                /* Cortex-A510 r0p0-r1p1 */
                CAP_MIDR_RANGE(MIDR_CORTEX_A510, 0, 0, 1, 1)
        },
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_1742098
+       {
+               .desc = "ARM erratum 1742098",
+               .capability = ARM64_WORKAROUND_1742098,
+               CAP_MIDR_RANGE_LIST(broken_aarch32_aes),
+               .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+       },
 #endif
        {
        }
index 3e52a9e8b50be798924cabfe3d62e71d6529c44a..13e3cb1acbdf2bd05acdbe4b348342b415dfd67f 100644 (file)
@@ -79,6 +79,7 @@
 #include <asm/cpufeature.h>
 #include <asm/cpu_ops.h>
 #include <asm/fpsimd.h>
+#include <asm/hwcap.h>
 #include <asm/insn.h>
 #include <asm/kvm_host.h>
 #include <asm/mmu_context.h>
@@ -1915,6 +1916,14 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
 }
 #endif /* CONFIG_ARM64_MTE */
 
+static void elf_hwcap_fixup(void)
+{
+#ifdef CONFIG_ARM64_ERRATUM_1742098
+       if (cpus_have_const_cap(ARM64_WORKAROUND_1742098))
+               compat_elf_hwcap2 &= ~COMPAT_HWCAP2_AES;
+#endif /* ARM64_ERRATUM_1742098 */
+}
+
 #ifdef CONFIG_KVM
 static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused)
 {
@@ -2942,8 +2951,10 @@ void __init setup_cpu_features(void)
        setup_system_capabilities();
        setup_elf_hwcaps(arm64_elf_hwcaps);
 
-       if (system_supports_32bit_el0())
+       if (system_supports_32bit_el0()) {
                setup_elf_hwcaps(compat_elf_hwcaps);
+               elf_hwcap_fixup();
+       }
 
        if (system_uses_ttbr0_pan())
                pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
@@ -2995,6 +3006,7 @@ static int enable_mismatched_32bit_el0(unsigned int cpu)
                                                         cpu_active_mask);
        get_cpu_device(lucky_winner)->offline_disabled = true;
        setup_elf_hwcaps(compat_elf_hwcaps);
+       elf_hwcap_fixup();
        pr_info("Asymmetric 32-bit EL0 support detected on CPU %u; CPU hot-unplug disabled on CPU %u\n",
                cpu, lucky_winner);
        return 0;
index cfaffd3c828907912c9f233edf43d997da32323a..6b1e70aee8cffd491f0cfbd000f958485bfffe0d 100644 (file)
@@ -54,6 +54,7 @@ WORKAROUND_1418040
 WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
+WORKAROUND_1742098
 WORKAROUND_2457168
 WORKAROUND_CAVIUM_23154
 WORKAROUND_CAVIUM_27456