aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/debug/debug_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/debug/debug_core.c')
-rw-r--r--kernel/debug/debug_core.c54
1 files changed, 24 insertions, 30 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 3f88a45e6f0a..0557f24c6bca 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -53,7 +53,6 @@
53#include <asm/cacheflush.h> 53#include <asm/cacheflush.h>
54#include <asm/byteorder.h> 54#include <asm/byteorder.h>
55#include <linux/atomic.h> 55#include <linux/atomic.h>
56#include <asm/system.h>
57 56
58#include "debug_core.h" 57#include "debug_core.h"
59 58
@@ -161,37 +160,39 @@ early_param("nokgdbroundup", opt_nokgdbroundup);
161 * Weak aliases for breakpoint management, 160 * Weak aliases for breakpoint management,
162 * can be overriden by architectures when needed: 161 * can be overriden by architectures when needed:
163 */ 162 */
164int __weak kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) 163int __weak kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
165{ 164{
166 int err; 165 int err;
167 166
168 err = probe_kernel_read(saved_instr, (char *)addr, BREAK_INSTR_SIZE); 167 err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
168 BREAK_INSTR_SIZE);
169 if (err) 169 if (err)
170 return err; 170 return err;
171 171 err = probe_kernel_write((char *)bpt->bpt_addr,
172 return probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr, 172 arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
173 BREAK_INSTR_SIZE); 173 return err;
174} 174}
175 175
176int __weak kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) 176int __weak kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
177{ 177{
178 return probe_kernel_write((char *)addr, 178 return probe_kernel_write((char *)bpt->bpt_addr,
179 (char *)bundle, BREAK_INSTR_SIZE); 179 (char *)bpt->saved_instr, BREAK_INSTR_SIZE);
180} 180}
181 181
182int __weak kgdb_validate_break_address(unsigned long addr) 182int __weak kgdb_validate_break_address(unsigned long addr)
183{ 183{
184 char tmp_variable[BREAK_INSTR_SIZE]; 184 struct kgdb_bkpt tmp;
185 int err; 185 int err;
186 /* Validate setting the breakpoint and then removing it. In the 186 /* Validate setting the breakpoint and then removing it. If the
187 * remove fails, the kernel needs to emit a bad message because we 187 * remove fails, the kernel needs to emit a bad message because we
188 * are deep trouble not being able to put things back the way we 188 * are deep trouble not being able to put things back the way we
189 * found them. 189 * found them.
190 */ 190 */
191 err = kgdb_arch_set_breakpoint(addr, tmp_variable); 191 tmp.bpt_addr = addr;
192 err = kgdb_arch_set_breakpoint(&tmp);
192 if (err) 193 if (err)
193 return err; 194 return err;
194 err = kgdb_arch_remove_breakpoint(addr, tmp_variable); 195 err = kgdb_arch_remove_breakpoint(&tmp);
195 if (err) 196 if (err)
196 printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " 197 printk(KERN_ERR "KGDB: Critical breakpoint error, kernel "
197 "memory destroyed at: %lx", addr); 198 "memory destroyed at: %lx", addr);
@@ -235,7 +236,6 @@ static void kgdb_flush_swbreak_addr(unsigned long addr)
235 */ 236 */
236int dbg_activate_sw_breakpoints(void) 237int dbg_activate_sw_breakpoints(void)
237{ 238{
238 unsigned long addr;
239 int error; 239 int error;
240 int ret = 0; 240 int ret = 0;
241 int i; 241 int i;
@@ -244,16 +244,15 @@ int dbg_activate_sw_breakpoints(void)
244 if (kgdb_break[i].state != BP_SET) 244 if (kgdb_break[i].state != BP_SET)
245 continue; 245 continue;
246 246
247 addr = kgdb_break[i].bpt_addr; 247 error = kgdb_arch_set_breakpoint(&kgdb_break[i]);
248 error = kgdb_arch_set_breakpoint(addr,
249 kgdb_break[i].saved_instr);
250 if (error) { 248 if (error) {
251 ret = error; 249 ret = error;
252 printk(KERN_INFO "KGDB: BP install failed: %lx", addr); 250 printk(KERN_INFO "KGDB: BP install failed: %lx",
251 kgdb_break[i].bpt_addr);
253 continue; 252 continue;
254 } 253 }
255 254
256 kgdb_flush_swbreak_addr(addr); 255 kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr);
257 kgdb_break[i].state = BP_ACTIVE; 256 kgdb_break[i].state = BP_ACTIVE;
258 } 257 }
259 return ret; 258 return ret;
@@ -302,7 +301,6 @@ int dbg_set_sw_break(unsigned long addr)
302 301
303int dbg_deactivate_sw_breakpoints(void) 302int dbg_deactivate_sw_breakpoints(void)
304{ 303{
305 unsigned long addr;
306 int error; 304 int error;
307 int ret = 0; 305 int ret = 0;
308 int i; 306 int i;
@@ -310,15 +308,14 @@ int dbg_deactivate_sw_breakpoints(void)
310 for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { 308 for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
311 if (kgdb_break[i].state != BP_ACTIVE) 309 if (kgdb_break[i].state != BP_ACTIVE)
312 continue; 310 continue;
313 addr = kgdb_break[i].bpt_addr; 311 error = kgdb_arch_remove_breakpoint(&kgdb_break[i]);
314 error = kgdb_arch_remove_breakpoint(addr,
315 kgdb_break[i].saved_instr);
316 if (error) { 312 if (error) {
317 printk(KERN_INFO "KGDB: BP remove failed: %lx\n", addr); 313 printk(KERN_INFO "KGDB: BP remove failed: %lx\n",
314 kgdb_break[i].bpt_addr);
318 ret = error; 315 ret = error;
319 } 316 }
320 317
321 kgdb_flush_swbreak_addr(addr); 318 kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr);
322 kgdb_break[i].state = BP_SET; 319 kgdb_break[i].state = BP_SET;
323 } 320 }
324 return ret; 321 return ret;
@@ -352,7 +349,6 @@ int kgdb_isremovedbreak(unsigned long addr)
352 349
353int dbg_remove_all_break(void) 350int dbg_remove_all_break(void)
354{ 351{
355 unsigned long addr;
356 int error; 352 int error;
357 int i; 353 int i;
358 354
@@ -360,12 +356,10 @@ int dbg_remove_all_break(void)
360 for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { 356 for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
361 if (kgdb_break[i].state != BP_ACTIVE) 357 if (kgdb_break[i].state != BP_ACTIVE)
362 goto setundefined; 358 goto setundefined;
363 addr = kgdb_break[i].bpt_addr; 359 error = kgdb_arch_remove_breakpoint(&kgdb_break[i]);
364 error = kgdb_arch_remove_breakpoint(addr,
365 kgdb_break[i].saved_instr);
366 if (error) 360 if (error)
367 printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", 361 printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n",
368 addr); 362 kgdb_break[i].bpt_addr);
369setundefined: 363setundefined:
370 kgdb_break[i].state = BP_UNDEFINED; 364 kgdb_break[i].state = BP_UNDEFINED;
371 } 365 }