Loading arch/arm64/include/asm/cpucaps.h +1 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ #define ARM64_SVE 22 #define ARM64_UNMAP_KERNEL_AT_EL0 23 #define ARM64_HARDEN_BRANCH_PREDICTOR 24 /* #define ARM64_UNUSED_CAP_TO_BE_REMOVED 25 */ #define ARM64_HARDEN_BP_POST_GUEST_EXIT 25 #define ARM64_HAS_RAS_EXTN 26 #define ARM64_NCAPS 27 Loading arch/arm64/include/asm/kvm_asm.h +2 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,8 @@ extern u32 __kvm_get_mdcr_el2(void); extern u32 __init_stage2_translation(void); extern void __qcom_hyp_sanitize_btac_predictors(void); #else /* __ASSEMBLY__ */ .macro get_host_ctxt reg, tmp Loading arch/arm64/kernel/bpi.S +8 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,14 @@ ENTRY(__bp_harden_hyp_vecs_end) .popsection 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) .macro smccc_workaround_1 inst sub sp, sp, #(8 * 4) stp x2, x3, [sp, #(8 * 0)] Loading arch/arm64/kernel/cpu_errata.c +36 −19 Original line number Diff line number Diff line Loading @@ -69,6 +69,8 @@ atomic_t arm64_el2_vector_last_slot = ATOMIC_INIT(-1); DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data); #ifdef CONFIG_KVM extern char __qcom_hyp_sanitize_link_stack_start[]; extern char __qcom_hyp_sanitize_link_stack_end[]; extern char __smccc_workaround_1_smc_start[]; extern char __smccc_workaround_1_smc_end[]; extern char __smccc_workaround_1_hvc_start[]; Loading Loading @@ -112,6 +114,8 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn, spin_unlock(&bp_lock); } #else #define __qcom_hyp_sanitize_link_stack_start NULL #define __qcom_hyp_sanitize_link_stack_end NULL #define __smccc_workaround_1_smc_start NULL #define __smccc_workaround_1_smc_end NULL #define __smccc_workaround_1_hvc_start NULL Loading Loading @@ -156,25 +160,12 @@ static void call_hvc_arch_workaround_1(void) arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL); } 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 enable_smccc_arch_workaround_1(void *data) { const struct arm64_cpu_capabilities *entry = data; bp_hardening_cb_t cb; void *smccc_start, *smccc_end; struct arm_smccc_res res; u32 midr = read_cpuid_id(); if (!entry->matches(entry, SCOPE_LOCAL_CPU)) return 0; Loading Loading @@ -207,15 +198,33 @@ static int enable_smccc_arch_workaround_1(void *data) return 0; } if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR) || ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)) cb = qcom_link_stack_sanitization; install_bp_hardening_cb(entry, cb, smccc_start, smccc_end); 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) \ Loading Loading @@ -390,12 +399,20 @@ const struct arm64_cpu_capabilities arm64_errata[] = { { .capability = ARM64_HARDEN_BRANCH_PREDICTOR, MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1), .enable = enable_smccc_arch_workaround_1, .enable = qcom_enable_link_stack_sanitization, }, { .capability = ARM64_HARDEN_BP_POST_GUEST_EXIT, MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1), }, { .capability = ARM64_HARDEN_BRANCH_PREDICTOR, MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR), .enable = enable_smccc_arch_workaround_1, .enable = qcom_enable_link_stack_sanitization, }, { .capability = ARM64_HARDEN_BP_POST_GUEST_EXIT, MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR), }, { .capability = ARM64_HARDEN_BRANCH_PREDICTOR, Loading arch/arm64/kvm/hyp/entry.S +12 −0 Original line number Diff line number Diff line Loading @@ -209,3 +209,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) Loading
arch/arm64/include/asm/cpucaps.h +1 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ #define ARM64_SVE 22 #define ARM64_UNMAP_KERNEL_AT_EL0 23 #define ARM64_HARDEN_BRANCH_PREDICTOR 24 /* #define ARM64_UNUSED_CAP_TO_BE_REMOVED 25 */ #define ARM64_HARDEN_BP_POST_GUEST_EXIT 25 #define ARM64_HAS_RAS_EXTN 26 #define ARM64_NCAPS 27 Loading
arch/arm64/include/asm/kvm_asm.h +2 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,8 @@ extern u32 __kvm_get_mdcr_el2(void); extern u32 __init_stage2_translation(void); extern void __qcom_hyp_sanitize_btac_predictors(void); #else /* __ASSEMBLY__ */ .macro get_host_ctxt reg, tmp Loading
arch/arm64/kernel/bpi.S +8 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,14 @@ ENTRY(__bp_harden_hyp_vecs_end) .popsection 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) .macro smccc_workaround_1 inst sub sp, sp, #(8 * 4) stp x2, x3, [sp, #(8 * 0)] Loading
arch/arm64/kernel/cpu_errata.c +36 −19 Original line number Diff line number Diff line Loading @@ -69,6 +69,8 @@ atomic_t arm64_el2_vector_last_slot = ATOMIC_INIT(-1); DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data); #ifdef CONFIG_KVM extern char __qcom_hyp_sanitize_link_stack_start[]; extern char __qcom_hyp_sanitize_link_stack_end[]; extern char __smccc_workaround_1_smc_start[]; extern char __smccc_workaround_1_smc_end[]; extern char __smccc_workaround_1_hvc_start[]; Loading Loading @@ -112,6 +114,8 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn, spin_unlock(&bp_lock); } #else #define __qcom_hyp_sanitize_link_stack_start NULL #define __qcom_hyp_sanitize_link_stack_end NULL #define __smccc_workaround_1_smc_start NULL #define __smccc_workaround_1_smc_end NULL #define __smccc_workaround_1_hvc_start NULL Loading Loading @@ -156,25 +160,12 @@ static void call_hvc_arch_workaround_1(void) arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL); } 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 enable_smccc_arch_workaround_1(void *data) { const struct arm64_cpu_capabilities *entry = data; bp_hardening_cb_t cb; void *smccc_start, *smccc_end; struct arm_smccc_res res; u32 midr = read_cpuid_id(); if (!entry->matches(entry, SCOPE_LOCAL_CPU)) return 0; Loading Loading @@ -207,15 +198,33 @@ static int enable_smccc_arch_workaround_1(void *data) return 0; } if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR) || ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)) cb = qcom_link_stack_sanitization; install_bp_hardening_cb(entry, cb, smccc_start, smccc_end); 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) \ Loading Loading @@ -390,12 +399,20 @@ const struct arm64_cpu_capabilities arm64_errata[] = { { .capability = ARM64_HARDEN_BRANCH_PREDICTOR, MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1), .enable = enable_smccc_arch_workaround_1, .enable = qcom_enable_link_stack_sanitization, }, { .capability = ARM64_HARDEN_BP_POST_GUEST_EXIT, MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1), }, { .capability = ARM64_HARDEN_BRANCH_PREDICTOR, MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR), .enable = enable_smccc_arch_workaround_1, .enable = qcom_enable_link_stack_sanitization, }, { .capability = ARM64_HARDEN_BP_POST_GUEST_EXIT, MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR), }, { .capability = ARM64_HARDEN_BRANCH_PREDICTOR, Loading
arch/arm64/kvm/hyp/entry.S +12 −0 Original line number Diff line number Diff line Loading @@ -209,3 +209,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)