Skip to content

Commit

Permalink
arm64: Implement branch predictor hardening for Falkor
Browse files Browse the repository at this point in the history
Falkor is susceptible to branch predictor aliasing and can
theoretically be attacked by malicious code. This patch
implements a mitigation for these attacks, preventing any
malicious entries from affecting other victim contexts.

Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org>
[will: fix label name when !CONFIG_KVM and remove references to MIDR_FALKOR]
Signed-off-by: Will Deacon <will.deacon@arm.com>

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
  • Loading branch information
Shanker Donthineni authored and ctmarinas committed Jan 8, 2018
1 parent aa6acde commit ec82b56
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 3 deletions.
3 changes: 2 additions & 1 deletion arch/arm64/include/asm/cpucaps.h
Expand Up @@ -43,7 +43,8 @@
#define ARM64_SVE 22
#define ARM64_UNMAP_KERNEL_AT_EL0 23
#define ARM64_HARDEN_BRANCH_PREDICTOR 24
#define ARM64_HARDEN_BP_POST_GUEST_EXIT 25

#define ARM64_NCAPS 25
#define ARM64_NCAPS 26

#endif /* __ASM_CPUCAPS_H */
2 changes: 2 additions & 0 deletions arch/arm64/include/asm/kvm_asm.h
Expand Up @@ -68,6 +68,8 @@ extern u32 __kvm_get_mdcr_el2(void);

extern u32 __init_stage2_translation(void);

extern void __qcom_hyp_sanitize_btac_predictors(void);

#endif

#endif /* __ARM_KVM_ASM_H__ */
8 changes: 8 additions & 0 deletions arch/arm64/kernel/bpi.S
Expand Up @@ -77,3 +77,11 @@ ENTRY(__psci_hyp_bp_inval_start)
ldp x0, x1, [sp, #(16 * 8)]
add sp, sp, #(8 * 18)
ENTRY(__psci_hyp_bp_inval_end)

ENTRY(__qcom_hyp_sanitize_link_stack_start)
stp x29, x30, [sp, #-16]!
.rept 16
bl . + 4
.endr
ldp x29, x30, [sp], #16
ENTRY(__qcom_hyp_sanitize_link_stack_end)
40 changes: 38 additions & 2 deletions arch/arm64/kernel/cpu_errata.c
Expand Up @@ -54,6 +54,8 @@ DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);

#ifdef CONFIG_KVM
extern char __psci_hyp_bp_inval_start[], __psci_hyp_bp_inval_end[];
extern char __qcom_hyp_sanitize_link_stack_start[];
extern char __qcom_hyp_sanitize_link_stack_end[];

static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
const char *hyp_vecs_end)
Expand Down Expand Up @@ -96,8 +98,10 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
spin_unlock(&bp_lock);
}
#else
#define __psci_hyp_bp_inval_start NULL
#define __psci_hyp_bp_inval_end NULL
#define __psci_hyp_bp_inval_start NULL
#define __psci_hyp_bp_inval_end NULL
#define __qcom_hyp_sanitize_link_stack_start NULL
#define __qcom_hyp_sanitize_link_stack_end NULL

static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
const char *hyp_vecs_start,
Expand Down Expand Up @@ -138,6 +142,29 @@ static int enable_psci_bp_hardening(void *data)

return 0;
}

static void qcom_link_stack_sanitization(void)
{
u64 tmp;

asm volatile("mov %0, x30 \n"
".rept 16 \n"
"bl . + 4 \n"
".endr \n"
"mov x30, %0 \n"
: "=&r" (tmp));
}

static int qcom_enable_link_stack_sanitization(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);

return 0;
}
#endif /* CONFIG_HARDEN_BRANCH_PREDICTOR */

#define MIDR_RANGE(model, min, max) \
Expand Down Expand Up @@ -302,6 +329,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
.enable = enable_psci_bp_hardening,
},
{
.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1),
.enable = qcom_enable_link_stack_sanitization,
},
{
.capability = ARM64_HARDEN_BP_POST_GUEST_EXIT,
MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1),
},
#endif
{
}
Expand Down
12 changes: 12 additions & 0 deletions arch/arm64/kvm/hyp/entry.S
Expand Up @@ -196,3 +196,15 @@ alternative_endif

eret
ENDPROC(__fpsimd_guest_restore)

ENTRY(__qcom_hyp_sanitize_btac_predictors)
/**
* Call SMC64 with Silicon provider serviceID 23<<8 (0xc2001700)
* 0xC2000000-0xC200FFFF: assigned to SiP Service Calls
* b15-b0: contains SiP functionID
*/
movz x0, #0x1700
movk x0, #0xc200, lsl #16
smc #0
ret
ENDPROC(__qcom_hyp_sanitize_btac_predictors)
8 changes: 8 additions & 0 deletions arch/arm64/kvm/hyp/switch.c
Expand Up @@ -406,6 +406,14 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
/* 0 falls through to be handled out of EL2 */
}

if (cpus_have_const_cap(ARM64_HARDEN_BP_POST_GUEST_EXIT)) {
u32 midr = read_cpuid_id();

/* Apply BTAC predictors mitigation to all Falkor chips */
if ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)
__qcom_hyp_sanitize_btac_predictors();
}

fp_enabled = __fpsimd_enabled();

__sysreg_save_guest_state(guest_ctxt);
Expand Down

0 comments on commit ec82b56

Please sign in to comment.