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)
 
 
 #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)
        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,
 
        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) \
                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
        {
        }
 
 
        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)
 
                /* 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);