Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b8561af authored by Prasad Sodagudi's avatar Prasad Sodagudi Committed by Runmin Wang
Browse files

arm64: raise exception to EL2 for sync aborts



Raise exception to EL2 for every EL1 sync data aborts,
so that EL2 handles the TLB conflicts.

Change-Id: Ib140599e23c399b23c12ddbeb59979d6caf5d38e
Signed-off-by: default avatarPrasad Sodagudi <psodagud@codeaurora.org>
Signed-off-by: default avatarRunmin Wang <runminw@codeaurora.org>
parent d24550bb
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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
+11 −11
Original line number Diff line number Diff line
@@ -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
 *
@@ -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"			},