diff options
author | Mark Rutland <mark.rutland@arm.com> | 2016-06-13 06:15:15 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2016-06-21 10:47:31 -0400 |
commit | 7ceb3a1040524c32aa71df8807427e348fac49da (patch) | |
tree | 180288227c5b05b89dad6a1b6bf0e389ff08f7e4 /arch/arm64/kernel/traps.c | |
parent | bffe1baff5d57521b0c41b6997c41ff1993e9818 (diff) |
arm64: simplify dump_mem
Currently dump_mem attempts to dump memory in 64-bit chunks when
reporting a failure in 64-bit code, or 32-bit chunks when reporting a
failure in 32-bit code. We added code to handle these two cases
separately in commit e147ae6d7f908412 ("arm64: modify the dump mem for
64 bit addresses").
However, in all cases dump_mem is called, the failing context is a
kernel rather than user context. Additionally dump_mem is assumed to
only be used for kernel contexts, as internally it switches to
KERNEL_DS, and its callers pass kernel stack bounds.
This patch removes the redundant 32-bit chunk logic and associated
compat parameter, largely reverting the aforementioned commit. For the
call in __die(), the check of in_interrupt() is removed also, as __die()
is only called in response to faults from the kernel's exception level,
and thus the !user_mode(regs) check is sufficient. Were this not the
case, the used of task_stack_page(tsk) to generate the stack bounds
would be erroneous.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/traps.c')
-rw-r--r-- | arch/arm64/kernel/traps.c | 31 |
1 files changed, 11 insertions, 20 deletions
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 2a43012616b7..d9da2c56e4f8 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c | |||
@@ -52,15 +52,14 @@ static const char *handler[]= { | |||
52 | int show_unhandled_signals = 1; | 52 | int show_unhandled_signals = 1; |
53 | 53 | ||
54 | /* | 54 | /* |
55 | * Dump out the contents of some memory nicely... | 55 | * Dump out the contents of some kernel memory nicely... |
56 | */ | 56 | */ |
57 | static void dump_mem(const char *lvl, const char *str, unsigned long bottom, | 57 | static void dump_mem(const char *lvl, const char *str, unsigned long bottom, |
58 | unsigned long top, bool compat) | 58 | unsigned long top) |
59 | { | 59 | { |
60 | unsigned long first; | 60 | unsigned long first; |
61 | mm_segment_t fs; | 61 | mm_segment_t fs; |
62 | int i; | 62 | int i; |
63 | unsigned int width = compat ? 4 : 8; | ||
64 | 63 | ||
65 | /* | 64 | /* |
66 | * We need to switch to kernel mode so that we can use __get_user | 65 | * We need to switch to kernel mode so that we can use __get_user |
@@ -78,22 +77,15 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, | |||
78 | memset(str, ' ', sizeof(str)); | 77 | memset(str, ' ', sizeof(str)); |
79 | str[sizeof(str) - 1] = '\0'; | 78 | str[sizeof(str) - 1] = '\0'; |
80 | 79 | ||
81 | for (p = first, i = 0; i < (32 / width) | 80 | for (p = first, i = 0; i < (32 / 8) |
82 | && p < top; i++, p += width) { | 81 | && p < top; i++, p += 8) { |
83 | if (p >= bottom && p < top) { | 82 | if (p >= bottom && p < top) { |
84 | unsigned long val; | 83 | unsigned long val; |
85 | 84 | ||
86 | if (width == 8) { | 85 | if (__get_user(val, (unsigned long *)p) == 0) |
87 | if (__get_user(val, (unsigned long *)p) == 0) | 86 | sprintf(str + i * 17, " %016lx", val); |
88 | sprintf(str + i * 17, " %016lx", val); | 87 | else |
89 | else | 88 | sprintf(str + i * 17, " ????????????????"); |
90 | sprintf(str + i * 17, " ????????????????"); | ||
91 | } else { | ||
92 | if (__get_user(val, (unsigned int *)p) == 0) | ||
93 | sprintf(str + i * 9, " %08lx", val); | ||
94 | else | ||
95 | sprintf(str + i * 9, " ????????"); | ||
96 | } | ||
97 | } | 89 | } |
98 | } | 90 | } |
99 | printk("%s%04lx:%s\n", lvl, first & 0xffff, str); | 91 | printk("%s%04lx:%s\n", lvl, first & 0xffff, str); |
@@ -216,7 +208,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) | |||
216 | stack = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr); | 208 | stack = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr); |
217 | 209 | ||
218 | dump_mem("", "Exception stack", stack, | 210 | dump_mem("", "Exception stack", stack, |
219 | stack + sizeof(struct pt_regs), false); | 211 | stack + sizeof(struct pt_regs)); |
220 | } | 212 | } |
221 | } | 213 | } |
222 | } | 214 | } |
@@ -254,10 +246,9 @@ static int __die(const char *str, int err, struct thread_info *thread, | |||
254 | pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", | 246 | pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", |
255 | TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1); | 247 | TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1); |
256 | 248 | ||
257 | if (!user_mode(regs) || in_interrupt()) { | 249 | if (!user_mode(regs)) { |
258 | dump_mem(KERN_EMERG, "Stack: ", regs->sp, | 250 | dump_mem(KERN_EMERG, "Stack: ", regs->sp, |
259 | THREAD_SIZE + (unsigned long)task_stack_page(tsk), | 251 | THREAD_SIZE + (unsigned long)task_stack_page(tsk)); |
260 | compat_user_mode(regs)); | ||
261 | dump_backtrace(regs, tsk); | 252 | dump_backtrace(regs, tsk); |
262 | dump_instr(KERN_EMERG, regs); | 253 | dump_instr(KERN_EMERG, regs); |
263 | } | 254 | } |