]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
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>
Thu, 3 Nov 2022 14:49:15 +0000 (23:49 +0900)
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.txt
arch/arm64/Kconfig
arch/arm64/include/asm/cpucaps.h
arch/arm64/kernel/cpu_errata.c
arch/arm64/kernel/cpufeature.c

index 47df2c25302acc551c84e2c11bd44d763712fa83..e6aced550e238908380a9b34acc13baed8e9f486 100644 (file)
@@ -53,7 +53,9 @@ stable kernels.
 | ARM            | Cortex-A57      | #832075         | ARM64_ERRATUM_832075        |
 | ARM            | Cortex-A57      | #852523         | N/A                         |
 | ARM            | Cortex-A57      | #834220         | ARM64_ERRATUM_834220        |
+| ARM            | Cortex-A57      | #1742098        | ARM64_ERRATUM_1742098       |
 | ARM            | Cortex-A72      | #853709         | N/A                         |
+| ARM            | Cortex-A72      | #1655431        | ARM64_ERRATUM_1742098       |
 | ARM            | Cortex-A55      | #1024718        | ARM64_ERRATUM_1024718       |
 | ARM            | Cortex-A76      | #1188873        | ARM64_ERRATUM_1188873       |
 | ARM            | MMU-500         | #841119,#826419 | N/A                         |
index 6d12c3b787771b679a4e7e87d3bb6d3ec62907ca..3e0be8648ce773ef83e8f890eb07be21437dabd2 100644 (file)
@@ -455,6 +455,22 @@ config ARM64_ERRATUM_1188873
 
          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 CAVIUM_ERRATUM_22375
        bool "Cavium erratum 22375, 24313"
        default y
index 9935e55a3cc750b78cb185799d43e5f5c5b228d1..91d365d87694e9bfeea517bebb1220904cdf7f8c 100644 (file)
@@ -40,7 +40,8 @@
 #define ARM64_MISMATCHED_CACHE_TYPE            19
 #define ARM64_WORKAROUND_1188873               20
 #define ARM64_SPECTRE_BHB                      21
+#define ARM64_WORKAROUND_1742098               22
 
-#define ARM64_NCAPS                            22
+#define ARM64_NCAPS                            23
 
 #endif /* __ASM_CPUCAPS_H */
index f0cdf21b1006bef1e4b72bce27f306e86994ad4c..17208f1b10a93fc119a8614da7ded7eb597c45c6 100644 (file)
@@ -448,6 +448,14 @@ static const struct midr_range arm64_bp_harden_smccc_cpus[] = {
 
 #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[] = {
 #if    defined(CONFIG_ARM64_ERRATUM_826319) || \
        defined(CONFIG_ARM64_ERRATUM_827319) || \
@@ -567,6 +575,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
                .cpu_enable = spectre_bhb_enable_mitigation,
 #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 9b7e7d2f236ee18020c4c0f6f56f927d400cf60c..0f62adbe1b075b9f09a0003e76e53dd8fbd3f4e2 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/cpu.h>
 #include <asm/cpufeature.h>
 #include <asm/cpu_ops.h>
+#include <asm/hwcap.h>
 #include <asm/mmu_context.h>
 #include <asm/processor.h>
 #include <asm/sysreg.h>
@@ -885,6 +886,14 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused)
                write_sysreg(read_sysreg(tpidr_el1), tpidr_el2);
 }
 
+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 */
+}
+
 static const struct arm64_cpu_capabilities arm64_features[] = {
        {
                .desc = "GIC system register CPU interface",
@@ -1304,8 +1313,10 @@ void __init setup_cpu_features(void)
        mark_const_caps_ready();
        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();
+       }
 
        /* Advertise that we have computed the system capabilities */
        set_sys_caps_initialised();