int err_code;
int cpu;
int pass_exception;
- long threadid;
+ unsigned long threadid;
long kgdb_usethreadid;
struct pt_regs *linux_regs;
};
* the other CPUs might interfere with your debugging context, so
* use this with care:
*/
-int kgdb_do_roundup = 1;
+static int kgdb_do_roundup = 1;
static int __init opt_nokgdbroundup(char *str)
{
return 0;
}
+int __weak kgdb_skipexception(int exception, struct pt_regs *regs)
+{
+ return 0;
+}
+
+void __weak
+kgdb_post_primary_code(struct pt_regs *regs, int e_vector, int err_code)
+{
+ return;
+}
+
/**
* kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb.
* @regs: Current &struct pt_regs.
}
}
-static char *pack_hex_byte(char *pkt, u8 byte)
-{
- *pkt++ = hexchars[byte >> 4];
- *pkt++ = hexchars[byte & 0xf];
-
- return pkt;
-}
-
/*
* Convert the memory pointed to by mem into hex, placing result in buf.
* Return a pointer to the last char put in buf (null). May return an error.
* While we find nice hex chars, build a long_val.
* Return number of chars processed.
*/
-int kgdb_hex2long(char **ptr, long *long_val)
+int kgdb_hex2long(char **ptr, unsigned long *long_val)
{
int hex_val;
int num = 0;
smp_wmb();
atomic_set(&cpu_in_kgdb[cpu], 1);
- /*
- * The primary CPU must be active to enter here, but this is
- * guard in case the primary CPU had not been selected if
- * this was an entry via nmi.
- */
- while (atomic_read(&kgdb_active) == -1)
- cpu_relax();
-
- /* Wait till primary CPU goes completely into the debugger. */
- while (!atomic_read(&cpu_in_kgdb[atomic_read(&kgdb_active)]))
- cpu_relax();
-
/* Wait till primary CPU is done with debugging */
while (atomic_read(&passive_cpu_wait[cpu]))
cpu_relax();
if (!CACHE_FLUSH_IS_SAFE)
return;
- if (current->mm) {
+ if (current->mm && current->mm->mmap_cache) {
flush_cache_range(current->mm->mmap_cache,
addr, addr + BREAK_INSTR_SIZE);
- } else {
- flush_icache_range(addr, addr + BREAK_INSTR_SIZE);
}
+ /* Force flush instruction cache if it was outside the mm */
+ flush_icache_range(addr, addr + BREAK_INSTR_SIZE);
}
/*
return 0;
}
-int remove_all_break(void)
+static int remove_all_break(void)
{
unsigned long addr;
int error;
/* Clear memory breakpoints. */
for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
- if (kgdb_break[i].state != BP_SET)
- continue;
+ if (kgdb_break[i].state != BP_ACTIVE)
+ goto setundefined;
addr = kgdb_break[i].bpt_addr;
error = kgdb_arch_remove_breakpoint(addr,
kgdb_break[i].saved_instr);
if (error)
- return error;
- kgdb_break[i].state = BP_REMOVED;
+ printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n",
+ addr);
+setundefined:
+ kgdb_break[i].state = BP_UNDEFINED;
}
/* Clear hardware breakpoints. */
error = kgdb_remove_sw_break(addr);
else if (remcom_in_buffer[0] == 'Z')
error = arch_kgdb_ops.set_hw_breakpoint(addr,
- (int)length, *bpt_type);
+ (int)length, *bpt_type - '0');
else if (remcom_in_buffer[0] == 'z')
error = arch_kgdb_ops.remove_hw_breakpoint(addr,
- (int) length, *bpt_type);
+ (int) length, *bpt_type - '0');
if (error == 0)
strcpy(remcom_out_buffer, "OK");
exception_level = 0;
kgdb_skipexception(ks->ex_vector, ks->linux_regs);
kgdb_activate_sw_breakpoints();
- printk(KERN_CRIT "KGDB: re-enter error: breakpoint removed\n");
+ printk(KERN_CRIT "KGDB: re-enter error: breakpoint removed %lx\n",
+ addr);
WARN_ON_ONCE(1);
return 1;
atomic_set(&passive_cpu_wait[i], 1);
}
-#ifdef CONFIG_SMP
- /* Signal the other CPUs to enter kgdb_wait() */
- if ((!kgdb_single_step || !kgdb_contthread) && kgdb_do_roundup)
- kgdb_roundup_cpus(flags);
-#endif
-
/*
* spin_lock code is good enough as a barrier so we don't
* need one here:
*/
atomic_set(&cpu_in_kgdb[ks->cpu], 1);
+#ifdef CONFIG_SMP
+ /* Signal the other CPUs to enter kgdb_wait() */
+ if ((!kgdb_single_step || !kgdb_contthread) && kgdb_do_roundup)
+ kgdb_roundup_cpus(flags);
+#endif
+
/*
* Wait for the other CPUs to be notified and be waiting for us:
*/
{
#ifdef CONFIG_SMP
if (!atomic_read(&cpu_in_kgdb[cpu]) &&
- atomic_read(&kgdb_active) != cpu) {
+ atomic_read(&kgdb_active) != cpu &&
+ atomic_read(&cpu_in_kgdb[atomic_read(&kgdb_active)])) {
kgdb_wait((struct pt_regs *)regs);
return 0;
}
}
/**
- * kkgdb_register_io_module - register KGDB IO module
+ * kgdb_register_io_module - register KGDB IO module
* @new_kgdb_io_ops: the io ops vector
*
* Register it with the KGDB core.