From 21393ff3eaf2003d0417f1c89ef8fadb315aabe2 Mon Sep 17 00:00:00 2001 From: Srinivas Ramana Date: Tue, 6 Feb 2018 21:10:15 +0530 Subject: [PATCH] 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 . Change-Id: I81e8e72e7fa219f12dfe8ec39836eb8eb3c4c7b0 Signed-off-by: Srinivas Ramana --- arch/arm64/include/asm/cputype.h | 2 ++ arch/arm64/kernel/cpu_errata.c | 36 +++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 4db7dfc8adc2..78e0aebbc1f2 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -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__ diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index d61772659595..e857248dd980 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -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 #include @@ -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 { }