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

Commit f7bb6f3a authored by Will Deacon's avatar Will Deacon Committed by Mayank Grover
Browse files

arm64: entry: Allow handling of undefined instructions from EL1



[ Upstream commit 0bf0f444b2c49241b2b39aa3cf210d7c95ef6c34 ]

Rather than panic() when taking an undefined instruction exception from
EL1, allow a hook to be registered in case we want to emulate the
instruction, like we will for the SSBS PSTATE manipulation instructions.

Change-Id: I283fa8f4e8f4ebb078b4455342a6cd3501447157
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Git-commit: 0bf0f444b2c49241b2b39aa3cf210d7c95ef6c34
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


[groverm@codeaurora: Resolve merge conflicts]
Signed-off-by: default avatarMayank Grover <groverm@codeaurora.org>
parent c38c34b6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -602,7 +602,7 @@ el1_undef:
	enable_dbg
	mov	x0, sp
	bl	do_undefinstr
	ASM_BUG()
	kernel_exit 1
el1_dbg:
	/*
	 * Debug exception handling
+7 −4
Original line number Diff line number Diff line
@@ -303,10 +303,12 @@ static int call_undef_hook(struct pt_regs *regs)
	int (*fn)(struct pt_regs *regs, u32 instr) = NULL;
	void __user *pc = (void __user *)instruction_pointer(regs);

	if (!user_mode(regs))
		return 1;

	if (compat_thumb_mode(regs)) {
	if (!user_mode(regs)) {
		__le32 instr_le;
		if (probe_kernel_address((__force __le32 *)pc, instr_le))
			goto exit;
		instr = le32_to_cpu(instr_le);
	} else if (compat_thumb_mode(regs)) {
		/* 16-bit Thumb instruction */
		__le16 instr_le;
		if (get_user(instr_le, (__le16 __user *)pc))
@@ -404,6 +406,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
	trace_undef_instr(regs, pc);

	force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0);
	BUG_ON(!user_mode(regs));
}

int cpu_enable_cache_maint_trap(void *__unused)