[PATCH 3/4] arm64: cpufeature: mitigate CVE-2024-7881
Mark Rutland
mark.rutland at arm.com
Tue Jan 28 07:54:27 PST 2025
On some CPUs from Arm Ltd, it is possible for unprivileged code to cause
a hardware prefetcher to form an address using the contents of a memory
location which is accessible by privileged accesses in the active
translation regime, potentially leaking the contents of this memory
location via a side channel. This has been assigned CVE-2024-7881:
https://developer.arm.com/Arm%20Security%20Center/Arm%20CPU%20Vulnerability%20CVE-2024-7881
Arm's recommended mitigation is that firmware configures an
IMPLEMENTATION DEFINED control bit (CPUACTLR6_EL1[41]) to disable the
affected prefetcher, and updates to Trusted Firmware-A are available to
do this. Presence of the firmware mitigation is indicated by the
presence of a new SMCCC call, SMCCC_ARCH_WORKAROUND_4, which is
documented in the SMCCC 1.6 G BET0 specification:
https://developer.arm.com/documentation/den0028/gbet0/?lang=en
Note that SMCCC_ARCH_WORKAROUND_4 has no return value, and exists solely
such that it can be detected via SMCCC_ARCH_FEATURES.
On systems which have not yet received a firmware update, enabling KPTI
will help to mitigate the issue. This patch enables KPTI on affected
parts where the lack of SMCCC_ARCH_WORKAROUND_4 indicates the absence of
the firmware workaround. This will implicitly disable SPE and/or TRBE if
either of these are present.
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
arch/arm64/kernel/cpufeature.c | 34 +++++++++++++++++++++++++++++++++-
include/linux/arm-smccc.h | 5 +++++
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index b746bb16ee785..e90bf4dcb6f1c 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1793,6 +1793,35 @@ static bool cpu_is_meltdown_safe(void)
return false;
}
+static bool cpu_has_leaky_prefetcher(void)
+{
+ struct arm_smccc_res res;
+
+ /* CPUs which are affected by CVE-2024-7881 */
+ static const struct midr_range leaky_prefetcher_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
+ { /* sentinel */ }
+ };
+
+ if (!is_midr_in_range_list(read_cpuid_id(), leaky_prefetcher_list))
+ return false;
+
+ /*
+ * If ARCH_WORKAROUND_4 is implemented, then the firmware mitigation is
+ * present. There is no need to call ARCH_WORKAROUND_4 itself.
+ */
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_4, &res);
+ if (res.a0 == SMCCC_RET_SUCCESS)
+ return false;
+
+ return true;
+}
+
static bool __meltdown_safe = true;
static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
@@ -1800,6 +1829,7 @@ static bool needs_kpti(const struct arm64_cpu_capabilities *entry, int scope)
{
char const *str = "kpti command line option";
bool meltdown_safe;
+ bool prefetcher_safe;
WARN_ON(scope != SCOPE_LOCAL_CPU);
@@ -1807,6 +1837,8 @@ static bool needs_kpti(const struct arm64_cpu_capabilities *entry, int scope)
if (!meltdown_safe)
__meltdown_safe = false;
+ prefetcher_safe = !cpu_has_leaky_prefetcher();
+
/*
* For reasons that aren't entirely clear, enabling KPTI on Cavium
* ThunderX leads to apparent I-cache corruption of kernel text, which
@@ -1846,7 +1878,7 @@ static bool needs_kpti(const struct arm64_cpu_capabilities *entry, int scope)
return __kpti_forced > 0;
}
- return !meltdown_safe;
+ return !meltdown_safe || !prefetcher_safe;
}
static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 67f6fdf2e7cd8..e77103ab2adfd 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -100,6 +100,11 @@
ARM_SMCCC_SMC_32, \
0, 0x3fff)
+#define ARM_SMCCC_ARCH_WORKAROUND_4 \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_32, \
+ 0, 0x0004)
+
#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
--
2.30.2
More information about the linux-arm-kernel
mailing list