arm64: Add BTAC/LinkStack sanitizations for Kryo cores

Kryo cores are exposed to two vulnerabilities due to subroutine return
(called LINK-STACK) and branch target predictors.
These two issues can be mitigated through software workarounds.

Kernel:
 - Apply LINK-STACK mitigation which is to issue 16 nested BL instructions
   on process context switch 'cpu_do_switch_mm()' where ASID changes.
 - Apply psci based branch predictor invalidation.

use the kryo core detection routine (based on MIDR) from the
commit bb48711800e6d ("arm64: cpu_errata: Add Kryo to Falkor 1003 errata")
by Stephen Boyd <sboyd@codeaurora.org>.

Change-Id: I81e8e72e7fa219f12dfe8ec39836eb8eb3c4c7b0
Signed-off-by: Srinivas Ramana <sramana@codeaurora.org>
This commit is contained in:
Srinivas Ramana 2018-02-06 21:10:15 +05:30 committed by Gerrit - the friendly Code Review server
parent f62d97e9b4
commit 21393ff3ea
2 changed files with 33 additions and 5 deletions

View file

@ -86,6 +86,7 @@
#define ARM_CPU_PART_CORTEX_A75 0xD0A
#define ARM_CPU_PART_KRYO2XX_GOLD 0x800
#define ARM_CPU_PART_KRYO2XX_SILVER 0x801
#define QCOM_CPU_PART_KRYO 0x200
#define APM_CPU_PART_POTENZA 0x000
@ -101,6 +102,7 @@
MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, ARM_CPU_PART_KRYO2XX_SILVER)
#define MIDR_KRYO2XX_GOLD \
MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, ARM_CPU_PART_KRYO2XX_GOLD)
#define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO)
#ifndef __ASSEMBLY__

View file

@ -29,6 +29,18 @@ is_affected_midr_range(const struct arm64_cpu_capabilities *entry)
entry->midr_range_max);
}
static bool __maybe_unused
is_kryo_midr(const struct arm64_cpu_capabilities *entry)
{
u32 model;
model = read_cpuid_id();
model &= MIDR_IMPLEMENTOR_MASK | (0xf00 << MIDR_PARTNUM_SHIFT) |
MIDR_ARCHITECTURE_MASK;
return model == entry->midr_model;
}
#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
@ -139,16 +151,24 @@ static void __maybe_unused qcom_link_stack_sanitization(void)
: "=&r" (tmp));
}
static int __maybe_unused qcom_enable_link_stack_sanitization(void *data)
static void __maybe_unused qcom_bp_hardening(void)
{
qcom_link_stack_sanitization();
if (psci_ops.get_version)
psci_ops.get_version();
}
static int __maybe_unused enable_qcom_bp_hardening(void *data)
{
const struct arm64_cpu_capabilities *entry = data;
install_bp_hardening_cb(entry, qcom_link_stack_sanitization,
__qcom_hyp_sanitize_link_stack_start,
__qcom_hyp_sanitize_link_stack_end);
install_bp_hardening_cb(entry,
(bp_hardening_cb_t)qcom_bp_hardening,
__psci_hyp_bp_inval_start,
__psci_hyp_bp_inval_end);
return 0;
}
#endif /* CONFIG_HARDEN_BRANCH_PREDICTOR */
#define MIDR_RANGE(model, min, max) \
@ -257,6 +277,12 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
MIDR_ALL_VERSIONS(MIDR_KRYO2XX_GOLD),
.enable = enable_psci_bp_hardening,
},
{
.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
.midr_model = MIDR_QCOM_KRYO,
.matches = is_kryo_midr,
.enable = enable_qcom_bp_hardening,
},
#endif
{
}