Loading arch/arm64/Kconfig +5 −0 Original line number Diff line number Diff line Loading @@ -620,6 +620,11 @@ config ARCH_NR_GPIO If unsure, leave the default value. config QCOM_TLB_EL2_HANDLER bool "Raise TLB conflict exception to EL2" help This option enables TLB conflict to be handled by EL2. source kernel/Kconfig.preempt source kernel/Kconfig.hz Loading arch/arm64/kernel/entry.S +3 −0 Original line number Diff line number Diff line Loading @@ -347,6 +347,9 @@ ENDPROC(el1_error_invalid) */ .align 6 el1_sync: #ifdef CONFIG_TLB_EL2_HANDLER smc #0xffff #endif kernel_entry 1 mrs x1, esr_el1 // read the syndrome register lsr x24, x1, #ESR_ELx_EC_SHIFT // exception class Loading arch/arm64/mm/fault.c +11 −11 Original line number Diff line number Diff line Loading @@ -410,23 +410,19 @@ no_context: return 0; } /* * TLB conflict is already handled in EL2. This rourtine should return zero * so that, do_mem_abort would not crash kernel thinking TLB conflict not * handled. */ #ifdef QCOM_TLB_EL2_HANDLER static int do_tlb_conf_fault(unsigned long addr, unsigned int esr, struct pt_regs *regs) { #define SCM_TLB_CONFLICT_CMD 0x1B struct scm_desc desc = { .args[0] = addr, .arginfo = SCM_ARGS(1), }; if (scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_MP, SCM_TLB_CONFLICT_CMD), &desc)) return 1; return 0; } #endif /* * First Level Translation Fault Handler * Loading Loading @@ -518,7 +514,11 @@ static struct fault_info { { do_bad, SIGBUS, 0, "unknown 45" }, { do_bad, SIGBUS, 0, "unknown 46" }, { do_bad, SIGBUS, 0, "unknown 47" }, #ifdef QCOM_TLB_EL2_HANDLER { do_tlb_conf_fault, SIGBUS, 0, "TLB conflict abort" }, #else { do_bad, SIGBUS, 0, "TLB conflict abort" }, #endif { do_bad, SIGBUS, 0, "unknown 49" }, { do_bad, SIGBUS, 0, "unknown 50" }, { do_bad, SIGBUS, 0, "unknown 51" }, Loading Loading
arch/arm64/Kconfig +5 −0 Original line number Diff line number Diff line Loading @@ -620,6 +620,11 @@ config ARCH_NR_GPIO If unsure, leave the default value. config QCOM_TLB_EL2_HANDLER bool "Raise TLB conflict exception to EL2" help This option enables TLB conflict to be handled by EL2. source kernel/Kconfig.preempt source kernel/Kconfig.hz Loading
arch/arm64/kernel/entry.S +3 −0 Original line number Diff line number Diff line Loading @@ -347,6 +347,9 @@ ENDPROC(el1_error_invalid) */ .align 6 el1_sync: #ifdef CONFIG_TLB_EL2_HANDLER smc #0xffff #endif kernel_entry 1 mrs x1, esr_el1 // read the syndrome register lsr x24, x1, #ESR_ELx_EC_SHIFT // exception class Loading
arch/arm64/mm/fault.c +11 −11 Original line number Diff line number Diff line Loading @@ -410,23 +410,19 @@ no_context: return 0; } /* * TLB conflict is already handled in EL2. This rourtine should return zero * so that, do_mem_abort would not crash kernel thinking TLB conflict not * handled. */ #ifdef QCOM_TLB_EL2_HANDLER static int do_tlb_conf_fault(unsigned long addr, unsigned int esr, struct pt_regs *regs) { #define SCM_TLB_CONFLICT_CMD 0x1B struct scm_desc desc = { .args[0] = addr, .arginfo = SCM_ARGS(1), }; if (scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_MP, SCM_TLB_CONFLICT_CMD), &desc)) return 1; return 0; } #endif /* * First Level Translation Fault Handler * Loading Loading @@ -518,7 +514,11 @@ static struct fault_info { { do_bad, SIGBUS, 0, "unknown 45" }, { do_bad, SIGBUS, 0, "unknown 46" }, { do_bad, SIGBUS, 0, "unknown 47" }, #ifdef QCOM_TLB_EL2_HANDLER { do_tlb_conf_fault, SIGBUS, 0, "TLB conflict abort" }, #else { do_bad, SIGBUS, 0, "TLB conflict abort" }, #endif { do_bad, SIGBUS, 0, "unknown 49" }, { do_bad, SIGBUS, 0, "unknown 50" }, { do_bad, SIGBUS, 0, "unknown 51" }, Loading