1 |
From 9c0a3a7f4704d553aba657c23451885f0d0dc152 Mon Sep 17 00:00:00 2001 |
2 |
From: Will Deacon <will.deacon@arm.com> |
3 |
Date: Tue, 7 Aug 2018 13:43:06 +0100 |
4 |
Subject: [PATCH 058/145] arm64: entry: Allow handling of undefined |
5 |
instructions from EL1 |
6 |
|
7 |
[ Upstream commit 0bf0f444b2c49241b2b39aa3cf210d7c95ef6c34 ] |
8 |
|
9 |
Rather than panic() when taking an undefined instruction exception from |
10 |
EL1, allow a hook to be registered in case we want to emulate the |
11 |
instruction, like we will for the SSBS PSTATE manipulation instructions. |
12 |
|
13 |
Signed-off-by: Will Deacon <will.deacon@arm.com> |
14 |
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> |
15 |
Signed-off-by: Sasha Levin <sashal@kernel.org> |
16 |
--- |
17 |
arch/arm64/kernel/entry.S | 2 +- |
18 |
arch/arm64/kernel/traps.c | 11 +++++++---- |
19 |
2 files changed, 8 insertions(+), 5 deletions(-) |
20 |
|
21 |
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S |
22 |
index 09dbea221a27..8556876c9109 100644 |
23 |
--- a/arch/arm64/kernel/entry.S |
24 |
+++ b/arch/arm64/kernel/entry.S |
25 |
@@ -589,7 +589,7 @@ el1_undef: |
26 |
inherit_daif pstate=x23, tmp=x2 |
27 |
mov x0, sp |
28 |
bl do_undefinstr |
29 |
- ASM_BUG() |
30 |
+ kernel_exit 1 |
31 |
el1_dbg: |
32 |
/* |
33 |
* Debug exception handling |
34 |
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c |
35 |
index 039e9ff379cc..b9da093e0341 100644 |
36 |
--- a/arch/arm64/kernel/traps.c |
37 |
+++ b/arch/arm64/kernel/traps.c |
38 |
@@ -310,10 +310,12 @@ static int call_undef_hook(struct pt_regs *regs) |
39 |
int (*fn)(struct pt_regs *regs, u32 instr) = NULL; |
40 |
void __user *pc = (void __user *)instruction_pointer(regs); |
41 |
|
42 |
- if (!user_mode(regs)) |
43 |
- return 1; |
44 |
- |
45 |
- if (compat_thumb_mode(regs)) { |
46 |
+ if (!user_mode(regs)) { |
47 |
+ __le32 instr_le; |
48 |
+ if (probe_kernel_address((__force __le32 *)pc, instr_le)) |
49 |
+ goto exit; |
50 |
+ instr = le32_to_cpu(instr_le); |
51 |
+ } else if (compat_thumb_mode(regs)) { |
52 |
/* 16-bit Thumb instruction */ |
53 |
__le16 instr_le; |
54 |
if (get_user(instr_le, (__le16 __user *)pc)) |
55 |
@@ -407,6 +409,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) |
56 |
return; |
57 |
|
58 |
force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc); |
59 |
+ BUG_ON(!user_mode(regs)); |
60 |
} |
61 |
|
62 |
void cpu_enable_cache_maint_trap(const struct arm64_cpu_capabilities *__unused) |
63 |
-- |
64 |
2.19.1 |
65 |
|