Loading arch/arm64/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -1793,6 +1793,14 @@ config BUILD_ARM64_DT_OVERLAY required flags to add DT overlay in the compilation. config TLB_CONF_HANDLER bool "enable handler for TLB conflict" help This option enables graceful handling of TLB conflict in EL2. Say yes here to enable TLB conflict handler. If unsure, Say n. config SYSVIPC_COMPAT def_bool y depends on COMPAT && SYSVIPC Loading arch/arm64/mm/fault.c +17 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ #include <linux/preempt.h> #include <linux/hugetlb.h> #ifdef CONFIG_TLB_CONF_HANDLER #include <linux/qcom_scm.h> #endif #include <asm/acpi.h> #include <asm/bug.h> #include <asm/cmpxchg.h> Loading Loading @@ -691,6 +695,15 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) return 0; } #ifdef CONFIG_TLB_CONF_HANDLER static int do_tlb_conf_fault(unsigned long addr, unsigned int esr, struct pt_regs *regs) { if (qcom_scm_tlb_conf_handler(addr)) return 1; return 0; } #endif static const struct fault_info fault_info[] = { { do_bad, SIGKILL, SI_KERNEL, "ttbr address size fault" }, { do_bad, SIGKILL, SI_KERNEL, "level 1 address size fault" }, Loading Loading @@ -740,7 +753,11 @@ static const struct fault_info fault_info[] = { { do_bad, SIGKILL, SI_KERNEL, "unknown 45" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 46" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 47" }, #ifdef CONFIG_TLB_CONF_HANDLER { do_tlb_conf_fault, SIGKILL, SI_KERNEL, "TLB conflict abort" }, #else { do_bad, SIGKILL, SI_KERNEL, "TLB conflict abort" }, #endif { do_bad, SIGKILL, SI_KERNEL, "Unsupported atomic hardware update fault" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 50" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 51" }, Loading drivers/firmware/qcom_scm-smc.c +21 −0 Original line number Diff line number Diff line Loading @@ -1020,6 +1020,27 @@ int __qcom_scm_sec_wdog_trigger(struct device *dev) return ret ? : desc.res[0]; } #ifdef CONFIG_TLB_CONF_HANDLER int __qcom_scm_tlb_conf_handler(struct device *dev, unsigned long addr) { int ret; #define SCM_TLB_CONFLICT_CMD 0x1F struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_MP, .cmd = SCM_TLB_CONFLICT_CMD, .owner = ARM_SMCCC_OWNER_SIP, }; desc.args[0] = addr; desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call_atomic(dev, &desc); return ret ? : desc.res[0]; } #endif void __qcom_scm_disable_sdi(struct device *dev) { int ret; Loading drivers/firmware/qcom_scm.c +8 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,14 @@ int qcom_scm_sec_wdog_trigger(void) } EXPORT_SYMBOL(qcom_scm_sec_wdog_trigger); #ifdef CONFIG_TLB_CONF_HANDLER int qcom_scm_tlb_conf_handler(unsigned long addr) { return __qcom_scm_tlb_conf_handler(__scm->dev, addr); } EXPORT_SYMBOL(qcom_scm_tlb_conf_handler); #endif /** * qcom_scm_disable_sdi() - Disable SDI */ Loading drivers/firmware/qcom_scm.h +3 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,9 @@ extern void __qcom_scm_cpu_power_down(struct device *dev, u32 flags); extern void __qcom_scm_cpu_hp(struct device *dev, u32 flags); extern int __qcom_scm_sec_wdog_deactivate(struct device *dev); extern int __qcom_scm_sec_wdog_trigger(struct device *dev); #ifdef CONFIG_TLB_CONF_HANDLER extern int __qcom_scm_tlb_conf_handler(struct device *dev, unsigned long addr); #endif extern void __qcom_scm_disable_sdi(struct device *dev); extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id); extern int __qcom_scm_spin_cpu(struct device *dev); Loading Loading
arch/arm64/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -1793,6 +1793,14 @@ config BUILD_ARM64_DT_OVERLAY required flags to add DT overlay in the compilation. config TLB_CONF_HANDLER bool "enable handler for TLB conflict" help This option enables graceful handling of TLB conflict in EL2. Say yes here to enable TLB conflict handler. If unsure, Say n. config SYSVIPC_COMPAT def_bool y depends on COMPAT && SYSVIPC Loading
arch/arm64/mm/fault.c +17 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ #include <linux/preempt.h> #include <linux/hugetlb.h> #ifdef CONFIG_TLB_CONF_HANDLER #include <linux/qcom_scm.h> #endif #include <asm/acpi.h> #include <asm/bug.h> #include <asm/cmpxchg.h> Loading Loading @@ -691,6 +695,15 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) return 0; } #ifdef CONFIG_TLB_CONF_HANDLER static int do_tlb_conf_fault(unsigned long addr, unsigned int esr, struct pt_regs *regs) { if (qcom_scm_tlb_conf_handler(addr)) return 1; return 0; } #endif static const struct fault_info fault_info[] = { { do_bad, SIGKILL, SI_KERNEL, "ttbr address size fault" }, { do_bad, SIGKILL, SI_KERNEL, "level 1 address size fault" }, Loading Loading @@ -740,7 +753,11 @@ static const struct fault_info fault_info[] = { { do_bad, SIGKILL, SI_KERNEL, "unknown 45" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 46" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 47" }, #ifdef CONFIG_TLB_CONF_HANDLER { do_tlb_conf_fault, SIGKILL, SI_KERNEL, "TLB conflict abort" }, #else { do_bad, SIGKILL, SI_KERNEL, "TLB conflict abort" }, #endif { do_bad, SIGKILL, SI_KERNEL, "Unsupported atomic hardware update fault" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 50" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 51" }, Loading
drivers/firmware/qcom_scm-smc.c +21 −0 Original line number Diff line number Diff line Loading @@ -1020,6 +1020,27 @@ int __qcom_scm_sec_wdog_trigger(struct device *dev) return ret ? : desc.res[0]; } #ifdef CONFIG_TLB_CONF_HANDLER int __qcom_scm_tlb_conf_handler(struct device *dev, unsigned long addr) { int ret; #define SCM_TLB_CONFLICT_CMD 0x1F struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_MP, .cmd = SCM_TLB_CONFLICT_CMD, .owner = ARM_SMCCC_OWNER_SIP, }; desc.args[0] = addr; desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call_atomic(dev, &desc); return ret ? : desc.res[0]; } #endif void __qcom_scm_disable_sdi(struct device *dev) { int ret; Loading
drivers/firmware/qcom_scm.c +8 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,14 @@ int qcom_scm_sec_wdog_trigger(void) } EXPORT_SYMBOL(qcom_scm_sec_wdog_trigger); #ifdef CONFIG_TLB_CONF_HANDLER int qcom_scm_tlb_conf_handler(unsigned long addr) { return __qcom_scm_tlb_conf_handler(__scm->dev, addr); } EXPORT_SYMBOL(qcom_scm_tlb_conf_handler); #endif /** * qcom_scm_disable_sdi() - Disable SDI */ Loading
drivers/firmware/qcom_scm.h +3 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,9 @@ extern void __qcom_scm_cpu_power_down(struct device *dev, u32 flags); extern void __qcom_scm_cpu_hp(struct device *dev, u32 flags); extern int __qcom_scm_sec_wdog_deactivate(struct device *dev); extern int __qcom_scm_sec_wdog_trigger(struct device *dev); #ifdef CONFIG_TLB_CONF_HANDLER extern int __qcom_scm_tlb_conf_handler(struct device *dev, unsigned long addr); #endif extern void __qcom_scm_disable_sdi(struct device *dev); extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id); extern int __qcom_scm_spin_cpu(struct device *dev); Loading