diff options
Diffstat (limited to 'arch/arm64/kernel/traps.c')
-rw-r--r-- | arch/arm64/kernel/traps.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index f7cf463107df..2a43012616b7 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c | |||
@@ -64,8 +64,7 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, | |||
64 | 64 | ||
65 | /* | 65 | /* |
66 | * We need to switch to kernel mode so that we can use __get_user | 66 | * We need to switch to kernel mode so that we can use __get_user |
67 | * to safely read from kernel space. Note that we now dump the | 67 | * to safely read from kernel space. |
68 | * code first, just in case the backtrace kills us. | ||
69 | */ | 68 | */ |
70 | fs = get_fs(); | 69 | fs = get_fs(); |
71 | set_fs(KERNEL_DS); | 70 | set_fs(KERNEL_DS); |
@@ -111,21 +110,12 @@ static void dump_backtrace_entry(unsigned long where) | |||
111 | print_ip_sym(where); | 110 | print_ip_sym(where); |
112 | } | 111 | } |
113 | 112 | ||
114 | static void dump_instr(const char *lvl, struct pt_regs *regs) | 113 | static void __dump_instr(const char *lvl, struct pt_regs *regs) |
115 | { | 114 | { |
116 | unsigned long addr = instruction_pointer(regs); | 115 | unsigned long addr = instruction_pointer(regs); |
117 | mm_segment_t fs; | ||
118 | char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str; | 116 | char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str; |
119 | int i; | 117 | int i; |
120 | 118 | ||
121 | /* | ||
122 | * We need to switch to kernel mode so that we can use __get_user | ||
123 | * to safely read from kernel space. Note that we now dump the | ||
124 | * code first, just in case the backtrace kills us. | ||
125 | */ | ||
126 | fs = get_fs(); | ||
127 | set_fs(KERNEL_DS); | ||
128 | |||
129 | for (i = -4; i < 1; i++) { | 119 | for (i = -4; i < 1; i++) { |
130 | unsigned int val, bad; | 120 | unsigned int val, bad; |
131 | 121 | ||
@@ -139,8 +129,18 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) | |||
139 | } | 129 | } |
140 | } | 130 | } |
141 | printk("%sCode: %s\n", lvl, str); | 131 | printk("%sCode: %s\n", lvl, str); |
132 | } | ||
142 | 133 | ||
143 | set_fs(fs); | 134 | static void dump_instr(const char *lvl, struct pt_regs *regs) |
135 | { | ||
136 | if (!user_mode(regs)) { | ||
137 | mm_segment_t fs = get_fs(); | ||
138 | set_fs(KERNEL_DS); | ||
139 | __dump_instr(lvl, regs); | ||
140 | set_fs(fs); | ||
141 | } else { | ||
142 | __dump_instr(lvl, regs); | ||
143 | } | ||
144 | } | 144 | } |
145 | 145 | ||
146 | static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) | 146 | static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) |