Commit 44b3834b authored by James Morse's avatar James Morse Committed by Will Deacon

arm64: errata: Remove AES hwcap for COMPAT tasks

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: default avatarArd Biesheuvel <ardb@kernel.org>
Signed-off-by: default avatarJames Morse <james.morse@arm.com>
Link: https://lore.kernel.org/r/20220714161523.279570-3-james.morse@arm.comSigned-off-by: default avatarWill Deacon <will@kernel.org>
parent 39fdb65f
...@@ -82,10 +82,14 @@ stable kernels. ...@@ -82,10 +82,14 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A57 | #1319537 | ARM64_ERRATUM_1319367 | | ARM | Cortex-A57 | #1319537 | ARM64_ERRATUM_1319367 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A57 | #1742098 | ARM64_ERRATUM_1742098 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A72 | #853709 | N/A | | ARM | Cortex-A72 | #853709 | N/A |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A72 | #1319367 | ARM64_ERRATUM_1319367 | | ARM | Cortex-A72 | #1319367 | ARM64_ERRATUM_1319367 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A72 | #1655431 | ARM64_ERRATUM_1742098 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 | | ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A76 | #1188873,1418040| ARM64_ERRATUM_1418040 | | ARM | Cortex-A76 | #1188873,1418040| ARM64_ERRATUM_1418040 |
......
...@@ -503,6 +503,22 @@ config ARM64_ERRATUM_834220 ...@@ -503,6 +503,22 @@ config ARM64_ERRATUM_834220
If unsure, say Y. 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 config ARM64_ERRATUM_845719
bool "Cortex-A53: 845719: a load might read incorrect data" bool "Cortex-A53: 845719: a load might read incorrect data"
depends on COMPAT depends on COMPAT
......
...@@ -401,6 +401,14 @@ static struct midr_range trbe_write_out_of_range_cpus[] = { ...@@ -401,6 +401,14 @@ static struct midr_range trbe_write_out_of_range_cpus[] = {
}; };
#endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */ #endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
#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 /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
const struct arm64_cpu_capabilities arm64_errata[] = { const struct arm64_cpu_capabilities arm64_errata[] = {
#ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
{ {
...@@ -663,6 +671,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { ...@@ -663,6 +671,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
/* Cortex-A510 r0p0 - r0p1 */ /* Cortex-A510 r0p0 - r0p1 */
ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 1) ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 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 #endif
{ {
} }
......
...@@ -79,6 +79,7 @@ ...@@ -79,6 +79,7 @@
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/cpu_ops.h> #include <asm/cpu_ops.h>
#include <asm/fpsimd.h> #include <asm/fpsimd.h>
#include <asm/hwcap.h>
#include <asm/insn.h> #include <asm/insn.h>
#include <asm/kvm_host.h> #include <asm/kvm_host.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
...@@ -1971,6 +1972,14 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) ...@@ -1971,6 +1972,14 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
} }
#endif /* CONFIG_ARM64_MTE */ #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 #ifdef CONFIG_KVM
static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused) static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused)
{ {
...@@ -3143,8 +3152,10 @@ void __init setup_cpu_features(void) ...@@ -3143,8 +3152,10 @@ void __init setup_cpu_features(void)
setup_system_capabilities(); setup_system_capabilities();
setup_elf_hwcaps(arm64_elf_hwcaps); setup_elf_hwcaps(arm64_elf_hwcaps);
if (system_supports_32bit_el0()) if (system_supports_32bit_el0()) {
setup_elf_hwcaps(compat_elf_hwcaps); setup_elf_hwcaps(compat_elf_hwcaps);
elf_hwcap_fixup();
}
if (system_uses_ttbr0_pan()) if (system_uses_ttbr0_pan())
pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n"); pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
...@@ -3197,6 +3208,7 @@ static int enable_mismatched_32bit_el0(unsigned int cpu) ...@@ -3197,6 +3208,7 @@ static int enable_mismatched_32bit_el0(unsigned int cpu)
cpu_active_mask); cpu_active_mask);
get_cpu_device(lucky_winner)->offline_disabled = true; get_cpu_device(lucky_winner)->offline_disabled = true;
setup_elf_hwcaps(compat_elf_hwcaps); 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", pr_info("Asymmetric 32-bit EL0 support detected on CPU %u; CPU hot-unplug disabled on CPU %u\n",
cpu, lucky_winner); cpu, lucky_winner);
return 0; return 0;
......
...@@ -61,6 +61,7 @@ WORKAROUND_1418040 ...@@ -61,6 +61,7 @@ WORKAROUND_1418040
WORKAROUND_1463225 WORKAROUND_1463225
WORKAROUND_1508412 WORKAROUND_1508412
WORKAROUND_1542419 WORKAROUND_1542419
WORKAROUND_1742098
WORKAROUND_1902691 WORKAROUND_1902691
WORKAROUND_2038923 WORKAROUND_2038923
WORKAROUND_2064142 WORKAROUND_2064142
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment