summaryrefslogtreecommitdiff
path: root/arch/arm64/kernel/proton-pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/kernel/proton-pack.c')
-rw-r--r--arch/arm64/kernel/proton-pack.c40
1 files changed, 19 insertions, 21 deletions
diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index 68b710f1b43f..25f3c80b5ffe 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -67,7 +67,8 @@ ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr,
* - Mitigated in hardware and advertised by ID_AA64PFR0_EL1.CSV2.
* - Mitigated in hardware and listed in our "safe list".
* - Mitigated in software by firmware.
- * - Mitigated in software by a CPU-specific dance in the kernel.
+ * - Mitigated in software by a CPU-specific dance in the kernel and a
+ * firmware call at EL2.
* - Vulnerable.
*
* It's not unlikely for different CPUs in a big.LITTLE system to fall into
@@ -204,8 +205,8 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn)
__SMCCC_WORKAROUND_1_SMC_SZ;
/*
- * detect_harden_bp_fw() passes NULL for the hyp_vecs start/end if
- * we're a guest. Skip the hyp-vectors work.
+ * Vinz Clortho takes the hyp_vecs start/end "keys" at
+ * the door when we're a guest. Skip the hyp-vectors work.
*/
if (!is_hyp_mode_available()) {
__this_cpu_write(bp_hardening_data.fn, fn);
@@ -259,6 +260,16 @@ static void qcom_link_stack_sanitisation(void)
: "=&r" (tmp));
}
+static bp_hardening_cb_t spectre_v2_get_sw_mitigation_cb(void)
+{
+ u32 midr = read_cpuid_id();
+ if (((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR) &&
+ ((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR_V1))
+ return NULL;
+
+ return qcom_link_stack_sanitisation;
+}
+
static enum mitigation_state spectre_v2_enable_fw_mitigation(void)
{
bp_hardening_cb_t cb;
@@ -284,26 +295,15 @@ static enum mitigation_state spectre_v2_enable_fw_mitigation(void)
return SPECTRE_VULNERABLE;
}
+ /*
+ * Prefer a CPU-specific workaround if it exists. Note that we
+ * still rely on firmware for the mitigation at EL2.
+ */
+ cb = spectre_v2_get_sw_mitigation_cb() ?: cb;
install_bp_hardening_cb(cb);
return SPECTRE_MITIGATED;
}
-static enum mitigation_state spectre_v2_enable_sw_mitigation(void)
-{
- u32 midr;
-
- if (spectre_v2_mitigations_off())
- return SPECTRE_VULNERABLE;
-
- midr = read_cpuid_id();
- if (((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR) &&
- ((midr & MIDR_CPU_MODEL_MASK) != MIDR_QCOM_FALKOR_V1))
- return SPECTRE_VULNERABLE;
-
- install_bp_hardening_cb(qcom_link_stack_sanitisation);
- return SPECTRE_MITIGATED;
-}
-
void spectre_v2_enable_mitigation(const struct arm64_cpu_capabilities *__unused)
{
enum mitigation_state state;
@@ -313,8 +313,6 @@ void spectre_v2_enable_mitigation(const struct arm64_cpu_capabilities *__unused)
state = spectre_v2_get_cpu_hw_mitigation_state();
if (state == SPECTRE_VULNERABLE)
state = spectre_v2_enable_fw_mitigation();
- if (state == SPECTRE_VULNERABLE)
- state = spectre_v2_enable_sw_mitigation();
update_mitigation_state(&spectre_v2_state, state);
}