diff options
Diffstat (limited to 'arch/arm64/kernel/traps.c')
-rw-r--r-- | arch/arm64/kernel/traps.c | 23 |
1 files changed, 7 insertions, 16 deletions
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 985721a1264c..a835a1a53826 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c | |||
@@ -55,16 +55,19 @@ static void dump_backtrace_entry(unsigned long where) | |||
55 | printk(" %pS\n", (void *)where); | 55 | printk(" %pS\n", (void *)where); |
56 | } | 56 | } |
57 | 57 | ||
58 | static void __dump_instr(const char *lvl, struct pt_regs *regs) | 58 | static void dump_kernel_instr(const char *lvl, struct pt_regs *regs) |
59 | { | 59 | { |
60 | unsigned long addr = instruction_pointer(regs); | 60 | unsigned long addr = instruction_pointer(regs); |
61 | char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str; | 61 | char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str; |
62 | int i; | 62 | int i; |
63 | 63 | ||
64 | if (user_mode(regs)) | ||
65 | return; | ||
66 | |||
64 | for (i = -4; i < 1; i++) { | 67 | for (i = -4; i < 1; i++) { |
65 | unsigned int val, bad; | 68 | unsigned int val, bad; |
66 | 69 | ||
67 | bad = get_user(val, &((u32 *)addr)[i]); | 70 | bad = aarch64_insn_read(&((u32 *)addr)[i], &val); |
68 | 71 | ||
69 | if (!bad) | 72 | if (!bad) |
70 | p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val); | 73 | p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val); |
@@ -73,19 +76,8 @@ static void __dump_instr(const char *lvl, struct pt_regs *regs) | |||
73 | break; | 76 | break; |
74 | } | 77 | } |
75 | } | 78 | } |
76 | printk("%sCode: %s\n", lvl, str); | ||
77 | } | ||
78 | 79 | ||
79 | static void dump_instr(const char *lvl, struct pt_regs *regs) | 80 | printk("%sCode: %s\n", lvl, str); |
80 | { | ||
81 | if (!user_mode(regs)) { | ||
82 | mm_segment_t fs = get_fs(); | ||
83 | set_fs(KERNEL_DS); | ||
84 | __dump_instr(lvl, regs); | ||
85 | set_fs(fs); | ||
86 | } else { | ||
87 | __dump_instr(lvl, regs); | ||
88 | } | ||
89 | } | 81 | } |
90 | 82 | ||
91 | void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) | 83 | void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) |
@@ -171,8 +163,7 @@ static int __die(const char *str, int err, struct pt_regs *regs) | |||
171 | print_modules(); | 163 | print_modules(); |
172 | show_regs(regs); | 164 | show_regs(regs); |
173 | 165 | ||
174 | if (!user_mode(regs)) | 166 | dump_kernel_instr(KERN_EMERG, regs); |
175 | dump_instr(KERN_EMERG, regs); | ||
176 | 167 | ||
177 | return ret; | 168 | return ret; |
178 | } | 169 | } |