1*c4338209SJason Wessel /* 2*c4338209SJason Wessel * KGDB stub. 3*c4338209SJason Wessel * 4*c4338209SJason Wessel * Maintainer: Jason Wessel <[email protected]> 5*c4338209SJason Wessel * 6*c4338209SJason Wessel * Copyright (C) 2000-2001 VERITAS Software Corporation. 7*c4338209SJason Wessel * Copyright (C) 2002-2004 Timesys Corporation 8*c4338209SJason Wessel * Copyright (C) 2003-2004 Amit S. Kale <[email protected]> 9*c4338209SJason Wessel * Copyright (C) 2004 Pavel Machek <[email protected]> 10*c4338209SJason Wessel * Copyright (C) 2004-2006 Tom Rini <[email protected]> 11*c4338209SJason Wessel * Copyright (C) 2004-2006 LinSysSoft Technologies Pvt. Ltd. 12*c4338209SJason Wessel * Copyright (C) 2005-2008 Wind River Systems, Inc. 13*c4338209SJason Wessel * Copyright (C) 2007 MontaVista Software, Inc. 14*c4338209SJason Wessel * Copyright (C) 2008 Red Hat, Inc., Ingo Molnar <[email protected]> 15*c4338209SJason Wessel * 16*c4338209SJason Wessel * Contributors at various stages not listed above: 17*c4338209SJason Wessel * Jason Wessel ( [email protected] ) 18*c4338209SJason Wessel * George Anzinger <[email protected]> 19*c4338209SJason Wessel * Anurekh Saxena ([email protected]) 20*c4338209SJason Wessel * Lake Stevens Instrument Division (Glenn Engel) 21*c4338209SJason Wessel * Jim Kingdon, Cygnus Support. 22*c4338209SJason Wessel * 23*c4338209SJason Wessel * Original KGDB stub: David Grothe <[email protected]>, 24*c4338209SJason Wessel * Tigran Aivazian <[email protected]> 25*c4338209SJason Wessel * 26*c4338209SJason Wessel * This file is licensed under the terms of the GNU General Public License 27*c4338209SJason Wessel * version 2. This program is licensed "as is" without any warranty of any 28*c4338209SJason Wessel * kind, whether express or implied. 29*c4338209SJason Wessel */ 30*c4338209SJason Wessel #include <linux/pid_namespace.h> 31*c4338209SJason Wessel #include <linux/clocksource.h> 32*c4338209SJason Wessel #include <linux/interrupt.h> 33*c4338209SJason Wessel #include <linux/spinlock.h> 34*c4338209SJason Wessel #include <linux/console.h> 35*c4338209SJason Wessel #include <linux/threads.h> 36*c4338209SJason Wessel #include <linux/uaccess.h> 37*c4338209SJason Wessel #include <linux/kernel.h> 38*c4338209SJason Wessel #include <linux/module.h> 39*c4338209SJason Wessel #include <linux/ptrace.h> 40*c4338209SJason Wessel #include <linux/reboot.h> 41*c4338209SJason Wessel #include <linux/string.h> 42*c4338209SJason Wessel #include <linux/delay.h> 43*c4338209SJason Wessel #include <linux/sched.h> 44*c4338209SJason Wessel #include <linux/sysrq.h> 45*c4338209SJason Wessel #include <linux/init.h> 46*c4338209SJason Wessel #include <linux/kgdb.h> 47*c4338209SJason Wessel #include <linux/pid.h> 48*c4338209SJason Wessel #include <linux/smp.h> 49*c4338209SJason Wessel #include <linux/mm.h> 50*c4338209SJason Wessel 51*c4338209SJason Wessel #include <asm/cacheflush.h> 52*c4338209SJason Wessel #include <asm/byteorder.h> 53*c4338209SJason Wessel #include <asm/atomic.h> 54*c4338209SJason Wessel #include <asm/system.h> 55*c4338209SJason Wessel #include <asm/unaligned.h> 56*c4338209SJason Wessel 57*c4338209SJason Wessel static int kgdb_break_asap; 58*c4338209SJason Wessel 59*c4338209SJason Wessel #define KGDB_MAX_THREAD_QUERY 17 60*c4338209SJason Wessel struct kgdb_state { 61*c4338209SJason Wessel int ex_vector; 62*c4338209SJason Wessel int signo; 63*c4338209SJason Wessel int err_code; 64*c4338209SJason Wessel int cpu; 65*c4338209SJason Wessel int pass_exception; 66*c4338209SJason Wessel unsigned long thr_query; 67*c4338209SJason Wessel unsigned long threadid; 68*c4338209SJason Wessel long kgdb_usethreadid; 69*c4338209SJason Wessel struct pt_regs *linux_regs; 70*c4338209SJason Wessel }; 71*c4338209SJason Wessel 72*c4338209SJason Wessel /* Exception state values */ 73*c4338209SJason Wessel #define DCPU_WANT_MASTER 0x1 /* Waiting to become a master kgdb cpu */ 74*c4338209SJason Wessel #define DCPU_NEXT_MASTER 0x2 /* Transition from one master cpu to another */ 75*c4338209SJason Wessel #define DCPU_IS_SLAVE 0x4 /* Slave cpu enter exception */ 76*c4338209SJason Wessel #define DCPU_SSTEP 0x8 /* CPU is single stepping */ 77*c4338209SJason Wessel 78*c4338209SJason Wessel static struct debuggerinfo_struct { 79*c4338209SJason Wessel void *debuggerinfo; 80*c4338209SJason Wessel struct task_struct *task; 81*c4338209SJason Wessel int exception_state; 82*c4338209SJason Wessel } kgdb_info[NR_CPUS]; 83*c4338209SJason Wessel 84*c4338209SJason Wessel /** 85*c4338209SJason Wessel * kgdb_connected - Is a host GDB connected to us? 86*c4338209SJason Wessel */ 87*c4338209SJason Wessel int kgdb_connected; 88*c4338209SJason Wessel EXPORT_SYMBOL_GPL(kgdb_connected); 89*c4338209SJason Wessel 90*c4338209SJason Wessel /* All the KGDB handlers are installed */ 91*c4338209SJason Wessel static int kgdb_io_module_registered; 92*c4338209SJason Wessel 93*c4338209SJason Wessel /* Guard for recursive entry */ 94*c4338209SJason Wessel static int exception_level; 95*c4338209SJason Wessel 96*c4338209SJason Wessel static struct kgdb_io *kgdb_io_ops; 97*c4338209SJason Wessel static DEFINE_SPINLOCK(kgdb_registration_lock); 98*c4338209SJason Wessel 99*c4338209SJason Wessel /* kgdb console driver is loaded */ 100*c4338209SJason Wessel static int kgdb_con_registered; 101*c4338209SJason Wessel /* determine if kgdb console output should be used */ 102*c4338209SJason Wessel static int kgdb_use_con; 103*c4338209SJason Wessel 104*c4338209SJason Wessel static int __init opt_kgdb_con(char *str) 105*c4338209SJason Wessel { 106*c4338209SJason Wessel kgdb_use_con = 1; 107*c4338209SJason Wessel return 0; 108*c4338209SJason Wessel } 109*c4338209SJason Wessel 110*c4338209SJason Wessel early_param("kgdbcon", opt_kgdb_con); 111*c4338209SJason Wessel 112*c4338209SJason Wessel module_param(kgdb_use_con, int, 0644); 113*c4338209SJason Wessel 114*c4338209SJason Wessel /* 115*c4338209SJason Wessel * Holds information about breakpoints in a kernel. These breakpoints are 116*c4338209SJason Wessel * added and removed by gdb. 117*c4338209SJason Wessel */ 118*c4338209SJason Wessel static struct kgdb_bkpt kgdb_break[KGDB_MAX_BREAKPOINTS] = { 119*c4338209SJason Wessel [0 ... KGDB_MAX_BREAKPOINTS-1] = { .state = BP_UNDEFINED } 120*c4338209SJason Wessel }; 121*c4338209SJason Wessel 122*c4338209SJason Wessel /* 123*c4338209SJason Wessel * The CPU# of the active CPU, or -1 if none: 124*c4338209SJason Wessel */ 125*c4338209SJason Wessel atomic_t kgdb_active = ATOMIC_INIT(-1); 126*c4338209SJason Wessel 127*c4338209SJason Wessel /* 128*c4338209SJason Wessel * We use NR_CPUs not PERCPU, in case kgdb is used to debug early 129*c4338209SJason Wessel * bootup code (which might not have percpu set up yet): 130*c4338209SJason Wessel */ 131*c4338209SJason Wessel static atomic_t passive_cpu_wait[NR_CPUS]; 132*c4338209SJason Wessel static atomic_t cpu_in_kgdb[NR_CPUS]; 133*c4338209SJason Wessel atomic_t kgdb_setting_breakpoint; 134*c4338209SJason Wessel 135*c4338209SJason Wessel struct task_struct *kgdb_usethread; 136*c4338209SJason Wessel struct task_struct *kgdb_contthread; 137*c4338209SJason Wessel 138*c4338209SJason Wessel int kgdb_single_step; 139*c4338209SJason Wessel pid_t kgdb_sstep_pid; 140*c4338209SJason Wessel 141*c4338209SJason Wessel /* Our I/O buffers. */ 142*c4338209SJason Wessel static char remcom_in_buffer[BUFMAX]; 143*c4338209SJason Wessel static char remcom_out_buffer[BUFMAX]; 144*c4338209SJason Wessel 145*c4338209SJason Wessel /* Storage for the registers, in GDB format. */ 146*c4338209SJason Wessel static unsigned long gdb_regs[(NUMREGBYTES + 147*c4338209SJason Wessel sizeof(unsigned long) - 1) / 148*c4338209SJason Wessel sizeof(unsigned long)]; 149*c4338209SJason Wessel 150*c4338209SJason Wessel /* to keep track of the CPU which is doing the single stepping*/ 151*c4338209SJason Wessel atomic_t kgdb_cpu_doing_single_step = ATOMIC_INIT(-1); 152*c4338209SJason Wessel 153*c4338209SJason Wessel /* 154*c4338209SJason Wessel * If you are debugging a problem where roundup (the collection of 155*c4338209SJason Wessel * all other CPUs) is a problem [this should be extremely rare], 156*c4338209SJason Wessel * then use the nokgdbroundup option to avoid roundup. In that case 157*c4338209SJason Wessel * the other CPUs might interfere with your debugging context, so 158*c4338209SJason Wessel * use this with care: 159*c4338209SJason Wessel */ 160*c4338209SJason Wessel static int kgdb_do_roundup = 1; 161*c4338209SJason Wessel 162*c4338209SJason Wessel static int __init opt_nokgdbroundup(char *str) 163*c4338209SJason Wessel { 164*c4338209SJason Wessel kgdb_do_roundup = 0; 165*c4338209SJason Wessel 166*c4338209SJason Wessel return 0; 167*c4338209SJason Wessel } 168*c4338209SJason Wessel 169*c4338209SJason Wessel early_param("nokgdbroundup", opt_nokgdbroundup); 170*c4338209SJason Wessel 171*c4338209SJason Wessel /* 172*c4338209SJason Wessel * Finally, some KGDB code :-) 173*c4338209SJason Wessel */ 174*c4338209SJason Wessel 175*c4338209SJason Wessel /* 176*c4338209SJason Wessel * Weak aliases for breakpoint management, 177*c4338209SJason Wessel * can be overriden by architectures when needed: 178*c4338209SJason Wessel */ 179*c4338209SJason Wessel int __weak kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) 180*c4338209SJason Wessel { 181*c4338209SJason Wessel int err; 182*c4338209SJason Wessel 183*c4338209SJason Wessel err = probe_kernel_read(saved_instr, (char *)addr, BREAK_INSTR_SIZE); 184*c4338209SJason Wessel if (err) 185*c4338209SJason Wessel return err; 186*c4338209SJason Wessel 187*c4338209SJason Wessel return probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr, 188*c4338209SJason Wessel BREAK_INSTR_SIZE); 189*c4338209SJason Wessel } 190*c4338209SJason Wessel 191*c4338209SJason Wessel int __weak kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) 192*c4338209SJason Wessel { 193*c4338209SJason Wessel return probe_kernel_write((char *)addr, 194*c4338209SJason Wessel (char *)bundle, BREAK_INSTR_SIZE); 195*c4338209SJason Wessel } 196*c4338209SJason Wessel 197*c4338209SJason Wessel int __weak kgdb_validate_break_address(unsigned long addr) 198*c4338209SJason Wessel { 199*c4338209SJason Wessel char tmp_variable[BREAK_INSTR_SIZE]; 200*c4338209SJason Wessel int err; 201*c4338209SJason Wessel /* Validate setting the breakpoint and then removing it. In the 202*c4338209SJason Wessel * remove fails, the kernel needs to emit a bad message because we 203*c4338209SJason Wessel * are deep trouble not being able to put things back the way we 204*c4338209SJason Wessel * found them. 205*c4338209SJason Wessel */ 206*c4338209SJason Wessel err = kgdb_arch_set_breakpoint(addr, tmp_variable); 207*c4338209SJason Wessel if (err) 208*c4338209SJason Wessel return err; 209*c4338209SJason Wessel err = kgdb_arch_remove_breakpoint(addr, tmp_variable); 210*c4338209SJason Wessel if (err) 211*c4338209SJason Wessel printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " 212*c4338209SJason Wessel "memory destroyed at: %lx", addr); 213*c4338209SJason Wessel return err; 214*c4338209SJason Wessel } 215*c4338209SJason Wessel 216*c4338209SJason Wessel unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs) 217*c4338209SJason Wessel { 218*c4338209SJason Wessel return instruction_pointer(regs); 219*c4338209SJason Wessel } 220*c4338209SJason Wessel 221*c4338209SJason Wessel int __weak kgdb_arch_init(void) 222*c4338209SJason Wessel { 223*c4338209SJason Wessel return 0; 224*c4338209SJason Wessel } 225*c4338209SJason Wessel 226*c4338209SJason Wessel int __weak kgdb_skipexception(int exception, struct pt_regs *regs) 227*c4338209SJason Wessel { 228*c4338209SJason Wessel return 0; 229*c4338209SJason Wessel } 230*c4338209SJason Wessel 231*c4338209SJason Wessel void __weak 232*c4338209SJason Wessel kgdb_post_primary_code(struct pt_regs *regs, int e_vector, int err_code) 233*c4338209SJason Wessel { 234*c4338209SJason Wessel return; 235*c4338209SJason Wessel } 236*c4338209SJason Wessel 237*c4338209SJason Wessel /** 238*c4338209SJason Wessel * kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb. 239*c4338209SJason Wessel * @regs: Current &struct pt_regs. 240*c4338209SJason Wessel * 241*c4338209SJason Wessel * This function will be called if the particular architecture must 242*c4338209SJason Wessel * disable hardware debugging while it is processing gdb packets or 243*c4338209SJason Wessel * handling exception. 244*c4338209SJason Wessel */ 245*c4338209SJason Wessel void __weak kgdb_disable_hw_debug(struct pt_regs *regs) 246*c4338209SJason Wessel { 247*c4338209SJason Wessel } 248*c4338209SJason Wessel 249*c4338209SJason Wessel /* 250*c4338209SJason Wessel * GDB remote protocol parser: 251*c4338209SJason Wessel */ 252*c4338209SJason Wessel 253*c4338209SJason Wessel static int hex(char ch) 254*c4338209SJason Wessel { 255*c4338209SJason Wessel if ((ch >= 'a') && (ch <= 'f')) 256*c4338209SJason Wessel return ch - 'a' + 10; 257*c4338209SJason Wessel if ((ch >= '0') && (ch <= '9')) 258*c4338209SJason Wessel return ch - '0'; 259*c4338209SJason Wessel if ((ch >= 'A') && (ch <= 'F')) 260*c4338209SJason Wessel return ch - 'A' + 10; 261*c4338209SJason Wessel return -1; 262*c4338209SJason Wessel } 263*c4338209SJason Wessel 264*c4338209SJason Wessel /* scan for the sequence $<data>#<checksum> */ 265*c4338209SJason Wessel static void get_packet(char *buffer) 266*c4338209SJason Wessel { 267*c4338209SJason Wessel unsigned char checksum; 268*c4338209SJason Wessel unsigned char xmitcsum; 269*c4338209SJason Wessel int count; 270*c4338209SJason Wessel char ch; 271*c4338209SJason Wessel 272*c4338209SJason Wessel do { 273*c4338209SJason Wessel /* 274*c4338209SJason Wessel * Spin and wait around for the start character, ignore all 275*c4338209SJason Wessel * other characters: 276*c4338209SJason Wessel */ 277*c4338209SJason Wessel while ((ch = (kgdb_io_ops->read_char())) != '$') 278*c4338209SJason Wessel /* nothing */; 279*c4338209SJason Wessel 280*c4338209SJason Wessel kgdb_connected = 1; 281*c4338209SJason Wessel checksum = 0; 282*c4338209SJason Wessel xmitcsum = -1; 283*c4338209SJason Wessel 284*c4338209SJason Wessel count = 0; 285*c4338209SJason Wessel 286*c4338209SJason Wessel /* 287*c4338209SJason Wessel * now, read until a # or end of buffer is found: 288*c4338209SJason Wessel */ 289*c4338209SJason Wessel while (count < (BUFMAX - 1)) { 290*c4338209SJason Wessel ch = kgdb_io_ops->read_char(); 291*c4338209SJason Wessel if (ch == '#') 292*c4338209SJason Wessel break; 293*c4338209SJason Wessel checksum = checksum + ch; 294*c4338209SJason Wessel buffer[count] = ch; 295*c4338209SJason Wessel count = count + 1; 296*c4338209SJason Wessel } 297*c4338209SJason Wessel buffer[count] = 0; 298*c4338209SJason Wessel 299*c4338209SJason Wessel if (ch == '#') { 300*c4338209SJason Wessel xmitcsum = hex(kgdb_io_ops->read_char()) << 4; 301*c4338209SJason Wessel xmitcsum += hex(kgdb_io_ops->read_char()); 302*c4338209SJason Wessel 303*c4338209SJason Wessel if (checksum != xmitcsum) 304*c4338209SJason Wessel /* failed checksum */ 305*c4338209SJason Wessel kgdb_io_ops->write_char('-'); 306*c4338209SJason Wessel else 307*c4338209SJason Wessel /* successful transfer */ 308*c4338209SJason Wessel kgdb_io_ops->write_char('+'); 309*c4338209SJason Wessel if (kgdb_io_ops->flush) 310*c4338209SJason Wessel kgdb_io_ops->flush(); 311*c4338209SJason Wessel } 312*c4338209SJason Wessel } while (checksum != xmitcsum); 313*c4338209SJason Wessel } 314*c4338209SJason Wessel 315*c4338209SJason Wessel /* 316*c4338209SJason Wessel * Send the packet in buffer. 317*c4338209SJason Wessel * Check for gdb connection if asked for. 318*c4338209SJason Wessel */ 319*c4338209SJason Wessel static void put_packet(char *buffer) 320*c4338209SJason Wessel { 321*c4338209SJason Wessel unsigned char checksum; 322*c4338209SJason Wessel int count; 323*c4338209SJason Wessel char ch; 324*c4338209SJason Wessel 325*c4338209SJason Wessel /* 326*c4338209SJason Wessel * $<packet info>#<checksum>. 327*c4338209SJason Wessel */ 328*c4338209SJason Wessel while (1) { 329*c4338209SJason Wessel kgdb_io_ops->write_char('$'); 330*c4338209SJason Wessel checksum = 0; 331*c4338209SJason Wessel count = 0; 332*c4338209SJason Wessel 333*c4338209SJason Wessel while ((ch = buffer[count])) { 334*c4338209SJason Wessel kgdb_io_ops->write_char(ch); 335*c4338209SJason Wessel checksum += ch; 336*c4338209SJason Wessel count++; 337*c4338209SJason Wessel } 338*c4338209SJason Wessel 339*c4338209SJason Wessel kgdb_io_ops->write_char('#'); 340*c4338209SJason Wessel kgdb_io_ops->write_char(hex_asc_hi(checksum)); 341*c4338209SJason Wessel kgdb_io_ops->write_char(hex_asc_lo(checksum)); 342*c4338209SJason Wessel if (kgdb_io_ops->flush) 343*c4338209SJason Wessel kgdb_io_ops->flush(); 344*c4338209SJason Wessel 345*c4338209SJason Wessel /* Now see what we get in reply. */ 346*c4338209SJason Wessel ch = kgdb_io_ops->read_char(); 347*c4338209SJason Wessel 348*c4338209SJason Wessel if (ch == 3) 349*c4338209SJason Wessel ch = kgdb_io_ops->read_char(); 350*c4338209SJason Wessel 351*c4338209SJason Wessel /* If we get an ACK, we are done. */ 352*c4338209SJason Wessel if (ch == '+') 353*c4338209SJason Wessel return; 354*c4338209SJason Wessel 355*c4338209SJason Wessel /* 356*c4338209SJason Wessel * If we get the start of another packet, this means 357*c4338209SJason Wessel * that GDB is attempting to reconnect. We will NAK 358*c4338209SJason Wessel * the packet being sent, and stop trying to send this 359*c4338209SJason Wessel * packet. 360*c4338209SJason Wessel */ 361*c4338209SJason Wessel if (ch == '$') { 362*c4338209SJason Wessel kgdb_io_ops->write_char('-'); 363*c4338209SJason Wessel if (kgdb_io_ops->flush) 364*c4338209SJason Wessel kgdb_io_ops->flush(); 365*c4338209SJason Wessel return; 366*c4338209SJason Wessel } 367*c4338209SJason Wessel } 368*c4338209SJason Wessel } 369*c4338209SJason Wessel 370*c4338209SJason Wessel /* 371*c4338209SJason Wessel * Convert the memory pointed to by mem into hex, placing result in buf. 372*c4338209SJason Wessel * Return a pointer to the last char put in buf (null). May return an error. 373*c4338209SJason Wessel */ 374*c4338209SJason Wessel int kgdb_mem2hex(char *mem, char *buf, int count) 375*c4338209SJason Wessel { 376*c4338209SJason Wessel char *tmp; 377*c4338209SJason Wessel int err; 378*c4338209SJason Wessel 379*c4338209SJason Wessel /* 380*c4338209SJason Wessel * We use the upper half of buf as an intermediate buffer for the 381*c4338209SJason Wessel * raw memory copy. Hex conversion will work against this one. 382*c4338209SJason Wessel */ 383*c4338209SJason Wessel tmp = buf + count; 384*c4338209SJason Wessel 385*c4338209SJason Wessel err = probe_kernel_read(tmp, mem, count); 386*c4338209SJason Wessel if (!err) { 387*c4338209SJason Wessel while (count > 0) { 388*c4338209SJason Wessel buf = pack_hex_byte(buf, *tmp); 389*c4338209SJason Wessel tmp++; 390*c4338209SJason Wessel count--; 391*c4338209SJason Wessel } 392*c4338209SJason Wessel 393*c4338209SJason Wessel *buf = 0; 394*c4338209SJason Wessel } 395*c4338209SJason Wessel 396*c4338209SJason Wessel return err; 397*c4338209SJason Wessel } 398*c4338209SJason Wessel 399*c4338209SJason Wessel /* 400*c4338209SJason Wessel * Copy the binary array pointed to by buf into mem. Fix $, #, and 401*c4338209SJason Wessel * 0x7d escaped with 0x7d. Return -EFAULT on failure or 0 on success. 402*c4338209SJason Wessel * The input buf is overwitten with the result to write to mem. 403*c4338209SJason Wessel */ 404*c4338209SJason Wessel static int kgdb_ebin2mem(char *buf, char *mem, int count) 405*c4338209SJason Wessel { 406*c4338209SJason Wessel int size = 0; 407*c4338209SJason Wessel char *c = buf; 408*c4338209SJason Wessel 409*c4338209SJason Wessel while (count-- > 0) { 410*c4338209SJason Wessel c[size] = *buf++; 411*c4338209SJason Wessel if (c[size] == 0x7d) 412*c4338209SJason Wessel c[size] = *buf++ ^ 0x20; 413*c4338209SJason Wessel size++; 414*c4338209SJason Wessel } 415*c4338209SJason Wessel 416*c4338209SJason Wessel return probe_kernel_write(mem, c, size); 417*c4338209SJason Wessel } 418*c4338209SJason Wessel 419*c4338209SJason Wessel /* 420*c4338209SJason Wessel * Convert the hex array pointed to by buf into binary to be placed in mem. 421*c4338209SJason Wessel * Return a pointer to the character AFTER the last byte written. 422*c4338209SJason Wessel * May return an error. 423*c4338209SJason Wessel */ 424*c4338209SJason Wessel int kgdb_hex2mem(char *buf, char *mem, int count) 425*c4338209SJason Wessel { 426*c4338209SJason Wessel char *tmp_raw; 427*c4338209SJason Wessel char *tmp_hex; 428*c4338209SJason Wessel 429*c4338209SJason Wessel /* 430*c4338209SJason Wessel * We use the upper half of buf as an intermediate buffer for the 431*c4338209SJason Wessel * raw memory that is converted from hex. 432*c4338209SJason Wessel */ 433*c4338209SJason Wessel tmp_raw = buf + count * 2; 434*c4338209SJason Wessel 435*c4338209SJason Wessel tmp_hex = tmp_raw - 1; 436*c4338209SJason Wessel while (tmp_hex >= buf) { 437*c4338209SJason Wessel tmp_raw--; 438*c4338209SJason Wessel *tmp_raw = hex(*tmp_hex--); 439*c4338209SJason Wessel *tmp_raw |= hex(*tmp_hex--) << 4; 440*c4338209SJason Wessel } 441*c4338209SJason Wessel 442*c4338209SJason Wessel return probe_kernel_write(mem, tmp_raw, count); 443*c4338209SJason Wessel } 444*c4338209SJason Wessel 445*c4338209SJason Wessel /* 446*c4338209SJason Wessel * While we find nice hex chars, build a long_val. 447*c4338209SJason Wessel * Return number of chars processed. 448*c4338209SJason Wessel */ 449*c4338209SJason Wessel int kgdb_hex2long(char **ptr, unsigned long *long_val) 450*c4338209SJason Wessel { 451*c4338209SJason Wessel int hex_val; 452*c4338209SJason Wessel int num = 0; 453*c4338209SJason Wessel int negate = 0; 454*c4338209SJason Wessel 455*c4338209SJason Wessel *long_val = 0; 456*c4338209SJason Wessel 457*c4338209SJason Wessel if (**ptr == '-') { 458*c4338209SJason Wessel negate = 1; 459*c4338209SJason Wessel (*ptr)++; 460*c4338209SJason Wessel } 461*c4338209SJason Wessel while (**ptr) { 462*c4338209SJason Wessel hex_val = hex(**ptr); 463*c4338209SJason Wessel if (hex_val < 0) 464*c4338209SJason Wessel break; 465*c4338209SJason Wessel 466*c4338209SJason Wessel *long_val = (*long_val << 4) | hex_val; 467*c4338209SJason Wessel num++; 468*c4338209SJason Wessel (*ptr)++; 469*c4338209SJason Wessel } 470*c4338209SJason Wessel 471*c4338209SJason Wessel if (negate) 472*c4338209SJason Wessel *long_val = -*long_val; 473*c4338209SJason Wessel 474*c4338209SJason Wessel return num; 475*c4338209SJason Wessel } 476*c4338209SJason Wessel 477*c4338209SJason Wessel /* Write memory due to an 'M' or 'X' packet. */ 478*c4338209SJason Wessel static int write_mem_msg(int binary) 479*c4338209SJason Wessel { 480*c4338209SJason Wessel char *ptr = &remcom_in_buffer[1]; 481*c4338209SJason Wessel unsigned long addr; 482*c4338209SJason Wessel unsigned long length; 483*c4338209SJason Wessel int err; 484*c4338209SJason Wessel 485*c4338209SJason Wessel if (kgdb_hex2long(&ptr, &addr) > 0 && *(ptr++) == ',' && 486*c4338209SJason Wessel kgdb_hex2long(&ptr, &length) > 0 && *(ptr++) == ':') { 487*c4338209SJason Wessel if (binary) 488*c4338209SJason Wessel err = kgdb_ebin2mem(ptr, (char *)addr, length); 489*c4338209SJason Wessel else 490*c4338209SJason Wessel err = kgdb_hex2mem(ptr, (char *)addr, length); 491*c4338209SJason Wessel if (err) 492*c4338209SJason Wessel return err; 493*c4338209SJason Wessel if (CACHE_FLUSH_IS_SAFE) 494*c4338209SJason Wessel flush_icache_range(addr, addr + length); 495*c4338209SJason Wessel return 0; 496*c4338209SJason Wessel } 497*c4338209SJason Wessel 498*c4338209SJason Wessel return -EINVAL; 499*c4338209SJason Wessel } 500*c4338209SJason Wessel 501*c4338209SJason Wessel static void error_packet(char *pkt, int error) 502*c4338209SJason Wessel { 503*c4338209SJason Wessel error = -error; 504*c4338209SJason Wessel pkt[0] = 'E'; 505*c4338209SJason Wessel pkt[1] = hex_asc[(error / 10)]; 506*c4338209SJason Wessel pkt[2] = hex_asc[(error % 10)]; 507*c4338209SJason Wessel pkt[3] = '\0'; 508*c4338209SJason Wessel } 509*c4338209SJason Wessel 510*c4338209SJason Wessel /* 511*c4338209SJason Wessel * Thread ID accessors. We represent a flat TID space to GDB, where 512*c4338209SJason Wessel * the per CPU idle threads (which under Linux all have PID 0) are 513*c4338209SJason Wessel * remapped to negative TIDs. 514*c4338209SJason Wessel */ 515*c4338209SJason Wessel 516*c4338209SJason Wessel #define BUF_THREAD_ID_SIZE 16 517*c4338209SJason Wessel 518*c4338209SJason Wessel static char *pack_threadid(char *pkt, unsigned char *id) 519*c4338209SJason Wessel { 520*c4338209SJason Wessel char *limit; 521*c4338209SJason Wessel 522*c4338209SJason Wessel limit = pkt + BUF_THREAD_ID_SIZE; 523*c4338209SJason Wessel while (pkt < limit) 524*c4338209SJason Wessel pkt = pack_hex_byte(pkt, *id++); 525*c4338209SJason Wessel 526*c4338209SJason Wessel return pkt; 527*c4338209SJason Wessel } 528*c4338209SJason Wessel 529*c4338209SJason Wessel static void int_to_threadref(unsigned char *id, int value) 530*c4338209SJason Wessel { 531*c4338209SJason Wessel unsigned char *scan; 532*c4338209SJason Wessel int i = 4; 533*c4338209SJason Wessel 534*c4338209SJason Wessel scan = (unsigned char *)id; 535*c4338209SJason Wessel while (i--) 536*c4338209SJason Wessel *scan++ = 0; 537*c4338209SJason Wessel put_unaligned_be32(value, scan); 538*c4338209SJason Wessel } 539*c4338209SJason Wessel 540*c4338209SJason Wessel static struct task_struct *getthread(struct pt_regs *regs, int tid) 541*c4338209SJason Wessel { 542*c4338209SJason Wessel /* 543*c4338209SJason Wessel * Non-positive TIDs are remapped to the cpu shadow information 544*c4338209SJason Wessel */ 545*c4338209SJason Wessel if (tid == 0 || tid == -1) 546*c4338209SJason Wessel tid = -atomic_read(&kgdb_active) - 2; 547*c4338209SJason Wessel if (tid < -1 && tid > -NR_CPUS - 2) { 548*c4338209SJason Wessel if (kgdb_info[-tid - 2].task) 549*c4338209SJason Wessel return kgdb_info[-tid - 2].task; 550*c4338209SJason Wessel else 551*c4338209SJason Wessel return idle_task(-tid - 2); 552*c4338209SJason Wessel } 553*c4338209SJason Wessel if (tid <= 0) { 554*c4338209SJason Wessel printk(KERN_ERR "KGDB: Internal thread select error\n"); 555*c4338209SJason Wessel dump_stack(); 556*c4338209SJason Wessel return NULL; 557*c4338209SJason Wessel } 558*c4338209SJason Wessel 559*c4338209SJason Wessel /* 560*c4338209SJason Wessel * find_task_by_pid_ns() does not take the tasklist lock anymore 561*c4338209SJason Wessel * but is nicely RCU locked - hence is a pretty resilient 562*c4338209SJason Wessel * thing to use: 563*c4338209SJason Wessel */ 564*c4338209SJason Wessel return find_task_by_pid_ns(tid, &init_pid_ns); 565*c4338209SJason Wessel } 566*c4338209SJason Wessel 567*c4338209SJason Wessel /* 568*c4338209SJason Wessel * Some architectures need cache flushes when we set/clear a 569*c4338209SJason Wessel * breakpoint: 570*c4338209SJason Wessel */ 571*c4338209SJason Wessel static void kgdb_flush_swbreak_addr(unsigned long addr) 572*c4338209SJason Wessel { 573*c4338209SJason Wessel if (!CACHE_FLUSH_IS_SAFE) 574*c4338209SJason Wessel return; 575*c4338209SJason Wessel 576*c4338209SJason Wessel if (current->mm && current->mm->mmap_cache) { 577*c4338209SJason Wessel flush_cache_range(current->mm->mmap_cache, 578*c4338209SJason Wessel addr, addr + BREAK_INSTR_SIZE); 579*c4338209SJason Wessel } 580*c4338209SJason Wessel /* Force flush instruction cache if it was outside the mm */ 581*c4338209SJason Wessel flush_icache_range(addr, addr + BREAK_INSTR_SIZE); 582*c4338209SJason Wessel } 583*c4338209SJason Wessel 584*c4338209SJason Wessel /* 585*c4338209SJason Wessel * SW breakpoint management: 586*c4338209SJason Wessel */ 587*c4338209SJason Wessel static int kgdb_activate_sw_breakpoints(void) 588*c4338209SJason Wessel { 589*c4338209SJason Wessel unsigned long addr; 590*c4338209SJason Wessel int error; 591*c4338209SJason Wessel int ret = 0; 592*c4338209SJason Wessel int i; 593*c4338209SJason Wessel 594*c4338209SJason Wessel for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { 595*c4338209SJason Wessel if (kgdb_break[i].state != BP_SET) 596*c4338209SJason Wessel continue; 597*c4338209SJason Wessel 598*c4338209SJason Wessel addr = kgdb_break[i].bpt_addr; 599*c4338209SJason Wessel error = kgdb_arch_set_breakpoint(addr, 600*c4338209SJason Wessel kgdb_break[i].saved_instr); 601*c4338209SJason Wessel if (error) { 602*c4338209SJason Wessel ret = error; 603*c4338209SJason Wessel printk(KERN_INFO "KGDB: BP install failed: %lx", addr); 604*c4338209SJason Wessel continue; 605*c4338209SJason Wessel } 606*c4338209SJason Wessel 607*c4338209SJason Wessel kgdb_flush_swbreak_addr(addr); 608*c4338209SJason Wessel kgdb_break[i].state = BP_ACTIVE; 609*c4338209SJason Wessel } 610*c4338209SJason Wessel return ret; 611*c4338209SJason Wessel } 612*c4338209SJason Wessel 613*c4338209SJason Wessel static int kgdb_set_sw_break(unsigned long addr) 614*c4338209SJason Wessel { 615*c4338209SJason Wessel int err = kgdb_validate_break_address(addr); 616*c4338209SJason Wessel int breakno = -1; 617*c4338209SJason Wessel int i; 618*c4338209SJason Wessel 619*c4338209SJason Wessel if (err) 620*c4338209SJason Wessel return err; 621*c4338209SJason Wessel 622*c4338209SJason Wessel for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { 623*c4338209SJason Wessel if ((kgdb_break[i].state == BP_SET) && 624*c4338209SJason Wessel (kgdb_break[i].bpt_addr == addr)) 625*c4338209SJason Wessel return -EEXIST; 626*c4338209SJason Wessel } 627*c4338209SJason Wessel for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { 628*c4338209SJason Wessel if (kgdb_break[i].state == BP_REMOVED && 629*c4338209SJason Wessel kgdb_break[i].bpt_addr == addr) { 630*c4338209SJason Wessel breakno = i; 631*c4338209SJason Wessel break; 632*c4338209SJason Wessel } 633*c4338209SJason Wessel } 634*c4338209SJason Wessel 635*c4338209SJason Wessel if (breakno == -1) { 636*c4338209SJason Wessel for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { 637*c4338209SJason Wessel if (kgdb_break[i].state == BP_UNDEFINED) { 638*c4338209SJason Wessel breakno = i; 639*c4338209SJason Wessel break; 640*c4338209SJason Wessel } 641*c4338209SJason Wessel } 642*c4338209SJason Wessel } 643*c4338209SJason Wessel 644*c4338209SJason Wessel if (breakno == -1) 645*c4338209SJason Wessel return -E2BIG; 646*c4338209SJason Wessel 647*c4338209SJason Wessel kgdb_break[breakno].state = BP_SET; 648*c4338209SJason Wessel kgdb_break[breakno].type = BP_BREAKPOINT; 649*c4338209SJason Wessel kgdb_break[breakno].bpt_addr = addr; 650*c4338209SJason Wessel 651*c4338209SJason Wessel return 0; 652*c4338209SJason Wessel } 653*c4338209SJason Wessel 654*c4338209SJason Wessel static int kgdb_deactivate_sw_breakpoints(void) 655*c4338209SJason Wessel { 656*c4338209SJason Wessel unsigned long addr; 657*c4338209SJason Wessel int error; 658*c4338209SJason Wessel int ret = 0; 659*c4338209SJason Wessel int i; 660*c4338209SJason Wessel 661*c4338209SJason Wessel for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { 662*c4338209SJason Wessel if (kgdb_break[i].state != BP_ACTIVE) 663*c4338209SJason Wessel continue; 664*c4338209SJason Wessel addr = kgdb_break[i].bpt_addr; 665*c4338209SJason Wessel error = kgdb_arch_remove_breakpoint(addr, 666*c4338209SJason Wessel kgdb_break[i].saved_instr); 667*c4338209SJason Wessel if (error) { 668*c4338209SJason Wessel printk(KERN_INFO "KGDB: BP remove failed: %lx\n", addr); 669*c4338209SJason Wessel ret = error; 670*c4338209SJason Wessel } 671*c4338209SJason Wessel 672*c4338209SJason Wessel kgdb_flush_swbreak_addr(addr); 673*c4338209SJason Wessel kgdb_break[i].state = BP_SET; 674*c4338209SJason Wessel } 675*c4338209SJason Wessel return ret; 676*c4338209SJason Wessel } 677*c4338209SJason Wessel 678*c4338209SJason Wessel static int kgdb_remove_sw_break(unsigned long addr) 679*c4338209SJason Wessel { 680*c4338209SJason Wessel int i; 681*c4338209SJason Wessel 682*c4338209SJason Wessel for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { 683*c4338209SJason Wessel if ((kgdb_break[i].state == BP_SET) && 684*c4338209SJason Wessel (kgdb_break[i].bpt_addr == addr)) { 685*c4338209SJason Wessel kgdb_break[i].state = BP_REMOVED; 686*c4338209SJason Wessel return 0; 687*c4338209SJason Wessel } 688*c4338209SJason Wessel } 689*c4338209SJason Wessel return -ENOENT; 690*c4338209SJason Wessel } 691*c4338209SJason Wessel 692*c4338209SJason Wessel int kgdb_isremovedbreak(unsigned long addr) 693*c4338209SJason Wessel { 694*c4338209SJason Wessel int i; 695*c4338209SJason Wessel 696*c4338209SJason Wessel for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { 697*c4338209SJason Wessel if ((kgdb_break[i].state == BP_REMOVED) && 698*c4338209SJason Wessel (kgdb_break[i].bpt_addr == addr)) 699*c4338209SJason Wessel return 1; 700*c4338209SJason Wessel } 701*c4338209SJason Wessel return 0; 702*c4338209SJason Wessel } 703*c4338209SJason Wessel 704*c4338209SJason Wessel static int remove_all_break(void) 705*c4338209SJason Wessel { 706*c4338209SJason Wessel unsigned long addr; 707*c4338209SJason Wessel int error; 708*c4338209SJason Wessel int i; 709*c4338209SJason Wessel 710*c4338209SJason Wessel /* Clear memory breakpoints. */ 711*c4338209SJason Wessel for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { 712*c4338209SJason Wessel if (kgdb_break[i].state != BP_ACTIVE) 713*c4338209SJason Wessel goto setundefined; 714*c4338209SJason Wessel addr = kgdb_break[i].bpt_addr; 715*c4338209SJason Wessel error = kgdb_arch_remove_breakpoint(addr, 716*c4338209SJason Wessel kgdb_break[i].saved_instr); 717*c4338209SJason Wessel if (error) 718*c4338209SJason Wessel printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", 719*c4338209SJason Wessel addr); 720*c4338209SJason Wessel setundefined: 721*c4338209SJason Wessel kgdb_break[i].state = BP_UNDEFINED; 722*c4338209SJason Wessel } 723*c4338209SJason Wessel 724*c4338209SJason Wessel /* Clear hardware breakpoints. */ 725*c4338209SJason Wessel if (arch_kgdb_ops.remove_all_hw_break) 726*c4338209SJason Wessel arch_kgdb_ops.remove_all_hw_break(); 727*c4338209SJason Wessel 728*c4338209SJason Wessel return 0; 729*c4338209SJason Wessel } 730*c4338209SJason Wessel 731*c4338209SJason Wessel /* 732*c4338209SJason Wessel * Remap normal tasks to their real PID, 733*c4338209SJason Wessel * CPU shadow threads are mapped to -CPU - 2 734*c4338209SJason Wessel */ 735*c4338209SJason Wessel static inline int shadow_pid(int realpid) 736*c4338209SJason Wessel { 737*c4338209SJason Wessel if (realpid) 738*c4338209SJason Wessel return realpid; 739*c4338209SJason Wessel 740*c4338209SJason Wessel return -raw_smp_processor_id() - 2; 741*c4338209SJason Wessel } 742*c4338209SJason Wessel 743*c4338209SJason Wessel static char gdbmsgbuf[BUFMAX + 1]; 744*c4338209SJason Wessel 745*c4338209SJason Wessel static void kgdb_msg_write(const char *s, int len) 746*c4338209SJason Wessel { 747*c4338209SJason Wessel char *bufptr; 748*c4338209SJason Wessel int wcount; 749*c4338209SJason Wessel int i; 750*c4338209SJason Wessel 751*c4338209SJason Wessel /* 'O'utput */ 752*c4338209SJason Wessel gdbmsgbuf[0] = 'O'; 753*c4338209SJason Wessel 754*c4338209SJason Wessel /* Fill and send buffers... */ 755*c4338209SJason Wessel while (len > 0) { 756*c4338209SJason Wessel bufptr = gdbmsgbuf + 1; 757*c4338209SJason Wessel 758*c4338209SJason Wessel /* Calculate how many this time */ 759*c4338209SJason Wessel if ((len << 1) > (BUFMAX - 2)) 760*c4338209SJason Wessel wcount = (BUFMAX - 2) >> 1; 761*c4338209SJason Wessel else 762*c4338209SJason Wessel wcount = len; 763*c4338209SJason Wessel 764*c4338209SJason Wessel /* Pack in hex chars */ 765*c4338209SJason Wessel for (i = 0; i < wcount; i++) 766*c4338209SJason Wessel bufptr = pack_hex_byte(bufptr, s[i]); 767*c4338209SJason Wessel *bufptr = '\0'; 768*c4338209SJason Wessel 769*c4338209SJason Wessel /* Move up */ 770*c4338209SJason Wessel s += wcount; 771*c4338209SJason Wessel len -= wcount; 772*c4338209SJason Wessel 773*c4338209SJason Wessel /* Write packet */ 774*c4338209SJason Wessel put_packet(gdbmsgbuf); 775*c4338209SJason Wessel } 776*c4338209SJason Wessel } 777*c4338209SJason Wessel 778*c4338209SJason Wessel /* 779*c4338209SJason Wessel * Return true if there is a valid kgdb I/O module. Also if no 780*c4338209SJason Wessel * debugger is attached a message can be printed to the console about 781*c4338209SJason Wessel * waiting for the debugger to attach. 782*c4338209SJason Wessel * 783*c4338209SJason Wessel * The print_wait argument is only to be true when called from inside 784*c4338209SJason Wessel * the core kgdb_handle_exception, because it will wait for the 785*c4338209SJason Wessel * debugger to attach. 786*c4338209SJason Wessel */ 787*c4338209SJason Wessel static int kgdb_io_ready(int print_wait) 788*c4338209SJason Wessel { 789*c4338209SJason Wessel if (!kgdb_io_ops) 790*c4338209SJason Wessel return 0; 791*c4338209SJason Wessel if (kgdb_connected) 792*c4338209SJason Wessel return 1; 793*c4338209SJason Wessel if (atomic_read(&kgdb_setting_breakpoint)) 794*c4338209SJason Wessel return 1; 795*c4338209SJason Wessel if (print_wait) 796*c4338209SJason Wessel printk(KERN_CRIT "KGDB: Waiting for remote debugger\n"); 797*c4338209SJason Wessel return 1; 798*c4338209SJason Wessel } 799*c4338209SJason Wessel 800*c4338209SJason Wessel /* 801*c4338209SJason Wessel * All the functions that start with gdb_cmd are the various 802*c4338209SJason Wessel * operations to implement the handlers for the gdbserial protocol 803*c4338209SJason Wessel * where KGDB is communicating with an external debugger 804*c4338209SJason Wessel */ 805*c4338209SJason Wessel 806*c4338209SJason Wessel /* Handle the '?' status packets */ 807*c4338209SJason Wessel static void gdb_cmd_status(struct kgdb_state *ks) 808*c4338209SJason Wessel { 809*c4338209SJason Wessel /* 810*c4338209SJason Wessel * We know that this packet is only sent 811*c4338209SJason Wessel * during initial connect. So to be safe, 812*c4338209SJason Wessel * we clear out our breakpoints now in case 813*c4338209SJason Wessel * GDB is reconnecting. 814*c4338209SJason Wessel */ 815*c4338209SJason Wessel remove_all_break(); 816*c4338209SJason Wessel 817*c4338209SJason Wessel remcom_out_buffer[0] = 'S'; 818*c4338209SJason Wessel pack_hex_byte(&remcom_out_buffer[1], ks->signo); 819*c4338209SJason Wessel } 820*c4338209SJason Wessel 821*c4338209SJason Wessel /* Handle the 'g' get registers request */ 822*c4338209SJason Wessel static void gdb_cmd_getregs(struct kgdb_state *ks) 823*c4338209SJason Wessel { 824*c4338209SJason Wessel struct task_struct *thread; 825*c4338209SJason Wessel void *local_debuggerinfo; 826*c4338209SJason Wessel int i; 827*c4338209SJason Wessel 828*c4338209SJason Wessel thread = kgdb_usethread; 829*c4338209SJason Wessel if (!thread) { 830*c4338209SJason Wessel thread = kgdb_info[ks->cpu].task; 831*c4338209SJason Wessel local_debuggerinfo = kgdb_info[ks->cpu].debuggerinfo; 832*c4338209SJason Wessel } else { 833*c4338209SJason Wessel local_debuggerinfo = NULL; 834*c4338209SJason Wessel for_each_online_cpu(i) { 835*c4338209SJason Wessel /* 836*c4338209SJason Wessel * Try to find the task on some other 837*c4338209SJason Wessel * or possibly this node if we do not 838*c4338209SJason Wessel * find the matching task then we try 839*c4338209SJason Wessel * to approximate the results. 840*c4338209SJason Wessel */ 841*c4338209SJason Wessel if (thread == kgdb_info[i].task) 842*c4338209SJason Wessel local_debuggerinfo = kgdb_info[i].debuggerinfo; 843*c4338209SJason Wessel } 844*c4338209SJason Wessel } 845*c4338209SJason Wessel 846*c4338209SJason Wessel /* 847*c4338209SJason Wessel * All threads that don't have debuggerinfo should be 848*c4338209SJason Wessel * in schedule() sleeping, since all other CPUs 849*c4338209SJason Wessel * are in kgdb_wait, and thus have debuggerinfo. 850*c4338209SJason Wessel */ 851*c4338209SJason Wessel if (local_debuggerinfo) { 852*c4338209SJason Wessel pt_regs_to_gdb_regs(gdb_regs, local_debuggerinfo); 853*c4338209SJason Wessel } else { 854*c4338209SJason Wessel /* 855*c4338209SJason Wessel * Pull stuff saved during switch_to; nothing 856*c4338209SJason Wessel * else is accessible (or even particularly 857*c4338209SJason Wessel * relevant). 858*c4338209SJason Wessel * 859*c4338209SJason Wessel * This should be enough for a stack trace. 860*c4338209SJason Wessel */ 861*c4338209SJason Wessel sleeping_thread_to_gdb_regs(gdb_regs, thread); 862*c4338209SJason Wessel } 863*c4338209SJason Wessel kgdb_mem2hex((char *)gdb_regs, remcom_out_buffer, NUMREGBYTES); 864*c4338209SJason Wessel } 865*c4338209SJason Wessel 866*c4338209SJason Wessel /* Handle the 'G' set registers request */ 867*c4338209SJason Wessel static void gdb_cmd_setregs(struct kgdb_state *ks) 868*c4338209SJason Wessel { 869*c4338209SJason Wessel kgdb_hex2mem(&remcom_in_buffer[1], (char *)gdb_regs, NUMREGBYTES); 870*c4338209SJason Wessel 871*c4338209SJason Wessel if (kgdb_usethread && kgdb_usethread != current) { 872*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 873*c4338209SJason Wessel } else { 874*c4338209SJason Wessel gdb_regs_to_pt_regs(gdb_regs, ks->linux_regs); 875*c4338209SJason Wessel strcpy(remcom_out_buffer, "OK"); 876*c4338209SJason Wessel } 877*c4338209SJason Wessel } 878*c4338209SJason Wessel 879*c4338209SJason Wessel /* Handle the 'm' memory read bytes */ 880*c4338209SJason Wessel static void gdb_cmd_memread(struct kgdb_state *ks) 881*c4338209SJason Wessel { 882*c4338209SJason Wessel char *ptr = &remcom_in_buffer[1]; 883*c4338209SJason Wessel unsigned long length; 884*c4338209SJason Wessel unsigned long addr; 885*c4338209SJason Wessel int err; 886*c4338209SJason Wessel 887*c4338209SJason Wessel if (kgdb_hex2long(&ptr, &addr) > 0 && *ptr++ == ',' && 888*c4338209SJason Wessel kgdb_hex2long(&ptr, &length) > 0) { 889*c4338209SJason Wessel err = kgdb_mem2hex((char *)addr, remcom_out_buffer, length); 890*c4338209SJason Wessel if (err) 891*c4338209SJason Wessel error_packet(remcom_out_buffer, err); 892*c4338209SJason Wessel } else { 893*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 894*c4338209SJason Wessel } 895*c4338209SJason Wessel } 896*c4338209SJason Wessel 897*c4338209SJason Wessel /* Handle the 'M' memory write bytes */ 898*c4338209SJason Wessel static void gdb_cmd_memwrite(struct kgdb_state *ks) 899*c4338209SJason Wessel { 900*c4338209SJason Wessel int err = write_mem_msg(0); 901*c4338209SJason Wessel 902*c4338209SJason Wessel if (err) 903*c4338209SJason Wessel error_packet(remcom_out_buffer, err); 904*c4338209SJason Wessel else 905*c4338209SJason Wessel strcpy(remcom_out_buffer, "OK"); 906*c4338209SJason Wessel } 907*c4338209SJason Wessel 908*c4338209SJason Wessel /* Handle the 'X' memory binary write bytes */ 909*c4338209SJason Wessel static void gdb_cmd_binwrite(struct kgdb_state *ks) 910*c4338209SJason Wessel { 911*c4338209SJason Wessel int err = write_mem_msg(1); 912*c4338209SJason Wessel 913*c4338209SJason Wessel if (err) 914*c4338209SJason Wessel error_packet(remcom_out_buffer, err); 915*c4338209SJason Wessel else 916*c4338209SJason Wessel strcpy(remcom_out_buffer, "OK"); 917*c4338209SJason Wessel } 918*c4338209SJason Wessel 919*c4338209SJason Wessel /* Handle the 'D' or 'k', detach or kill packets */ 920*c4338209SJason Wessel static void gdb_cmd_detachkill(struct kgdb_state *ks) 921*c4338209SJason Wessel { 922*c4338209SJason Wessel int error; 923*c4338209SJason Wessel 924*c4338209SJason Wessel /* The detach case */ 925*c4338209SJason Wessel if (remcom_in_buffer[0] == 'D') { 926*c4338209SJason Wessel error = remove_all_break(); 927*c4338209SJason Wessel if (error < 0) { 928*c4338209SJason Wessel error_packet(remcom_out_buffer, error); 929*c4338209SJason Wessel } else { 930*c4338209SJason Wessel strcpy(remcom_out_buffer, "OK"); 931*c4338209SJason Wessel kgdb_connected = 0; 932*c4338209SJason Wessel } 933*c4338209SJason Wessel put_packet(remcom_out_buffer); 934*c4338209SJason Wessel } else { 935*c4338209SJason Wessel /* 936*c4338209SJason Wessel * Assume the kill case, with no exit code checking, 937*c4338209SJason Wessel * trying to force detach the debugger: 938*c4338209SJason Wessel */ 939*c4338209SJason Wessel remove_all_break(); 940*c4338209SJason Wessel kgdb_connected = 0; 941*c4338209SJason Wessel } 942*c4338209SJason Wessel } 943*c4338209SJason Wessel 944*c4338209SJason Wessel /* Handle the 'R' reboot packets */ 945*c4338209SJason Wessel static int gdb_cmd_reboot(struct kgdb_state *ks) 946*c4338209SJason Wessel { 947*c4338209SJason Wessel /* For now, only honor R0 */ 948*c4338209SJason Wessel if (strcmp(remcom_in_buffer, "R0") == 0) { 949*c4338209SJason Wessel printk(KERN_CRIT "Executing emergency reboot\n"); 950*c4338209SJason Wessel strcpy(remcom_out_buffer, "OK"); 951*c4338209SJason Wessel put_packet(remcom_out_buffer); 952*c4338209SJason Wessel 953*c4338209SJason Wessel /* 954*c4338209SJason Wessel * Execution should not return from 955*c4338209SJason Wessel * machine_emergency_restart() 956*c4338209SJason Wessel */ 957*c4338209SJason Wessel machine_emergency_restart(); 958*c4338209SJason Wessel kgdb_connected = 0; 959*c4338209SJason Wessel 960*c4338209SJason Wessel return 1; 961*c4338209SJason Wessel } 962*c4338209SJason Wessel return 0; 963*c4338209SJason Wessel } 964*c4338209SJason Wessel 965*c4338209SJason Wessel /* Handle the 'q' query packets */ 966*c4338209SJason Wessel static void gdb_cmd_query(struct kgdb_state *ks) 967*c4338209SJason Wessel { 968*c4338209SJason Wessel struct task_struct *g; 969*c4338209SJason Wessel struct task_struct *p; 970*c4338209SJason Wessel unsigned char thref[8]; 971*c4338209SJason Wessel char *ptr; 972*c4338209SJason Wessel int i; 973*c4338209SJason Wessel int cpu; 974*c4338209SJason Wessel int finished = 0; 975*c4338209SJason Wessel 976*c4338209SJason Wessel switch (remcom_in_buffer[1]) { 977*c4338209SJason Wessel case 's': 978*c4338209SJason Wessel case 'f': 979*c4338209SJason Wessel if (memcmp(remcom_in_buffer + 2, "ThreadInfo", 10)) { 980*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 981*c4338209SJason Wessel break; 982*c4338209SJason Wessel } 983*c4338209SJason Wessel 984*c4338209SJason Wessel i = 0; 985*c4338209SJason Wessel remcom_out_buffer[0] = 'm'; 986*c4338209SJason Wessel ptr = remcom_out_buffer + 1; 987*c4338209SJason Wessel if (remcom_in_buffer[1] == 'f') { 988*c4338209SJason Wessel /* Each cpu is a shadow thread */ 989*c4338209SJason Wessel for_each_online_cpu(cpu) { 990*c4338209SJason Wessel ks->thr_query = 0; 991*c4338209SJason Wessel int_to_threadref(thref, -cpu - 2); 992*c4338209SJason Wessel pack_threadid(ptr, thref); 993*c4338209SJason Wessel ptr += BUF_THREAD_ID_SIZE; 994*c4338209SJason Wessel *(ptr++) = ','; 995*c4338209SJason Wessel i++; 996*c4338209SJason Wessel } 997*c4338209SJason Wessel } 998*c4338209SJason Wessel 999*c4338209SJason Wessel do_each_thread(g, p) { 1000*c4338209SJason Wessel if (i >= ks->thr_query && !finished) { 1001*c4338209SJason Wessel int_to_threadref(thref, p->pid); 1002*c4338209SJason Wessel pack_threadid(ptr, thref); 1003*c4338209SJason Wessel ptr += BUF_THREAD_ID_SIZE; 1004*c4338209SJason Wessel *(ptr++) = ','; 1005*c4338209SJason Wessel ks->thr_query++; 1006*c4338209SJason Wessel if (ks->thr_query % KGDB_MAX_THREAD_QUERY == 0) 1007*c4338209SJason Wessel finished = 1; 1008*c4338209SJason Wessel } 1009*c4338209SJason Wessel i++; 1010*c4338209SJason Wessel } while_each_thread(g, p); 1011*c4338209SJason Wessel 1012*c4338209SJason Wessel *(--ptr) = '\0'; 1013*c4338209SJason Wessel break; 1014*c4338209SJason Wessel 1015*c4338209SJason Wessel case 'C': 1016*c4338209SJason Wessel /* Current thread id */ 1017*c4338209SJason Wessel strcpy(remcom_out_buffer, "QC"); 1018*c4338209SJason Wessel ks->threadid = shadow_pid(current->pid); 1019*c4338209SJason Wessel int_to_threadref(thref, ks->threadid); 1020*c4338209SJason Wessel pack_threadid(remcom_out_buffer + 2, thref); 1021*c4338209SJason Wessel break; 1022*c4338209SJason Wessel case 'T': 1023*c4338209SJason Wessel if (memcmp(remcom_in_buffer + 1, "ThreadExtraInfo,", 16)) { 1024*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 1025*c4338209SJason Wessel break; 1026*c4338209SJason Wessel } 1027*c4338209SJason Wessel ks->threadid = 0; 1028*c4338209SJason Wessel ptr = remcom_in_buffer + 17; 1029*c4338209SJason Wessel kgdb_hex2long(&ptr, &ks->threadid); 1030*c4338209SJason Wessel if (!getthread(ks->linux_regs, ks->threadid)) { 1031*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 1032*c4338209SJason Wessel break; 1033*c4338209SJason Wessel } 1034*c4338209SJason Wessel if ((int)ks->threadid > 0) { 1035*c4338209SJason Wessel kgdb_mem2hex(getthread(ks->linux_regs, 1036*c4338209SJason Wessel ks->threadid)->comm, 1037*c4338209SJason Wessel remcom_out_buffer, 16); 1038*c4338209SJason Wessel } else { 1039*c4338209SJason Wessel static char tmpstr[23 + BUF_THREAD_ID_SIZE]; 1040*c4338209SJason Wessel 1041*c4338209SJason Wessel sprintf(tmpstr, "shadowCPU%d", 1042*c4338209SJason Wessel (int)(-ks->threadid - 2)); 1043*c4338209SJason Wessel kgdb_mem2hex(tmpstr, remcom_out_buffer, strlen(tmpstr)); 1044*c4338209SJason Wessel } 1045*c4338209SJason Wessel break; 1046*c4338209SJason Wessel } 1047*c4338209SJason Wessel } 1048*c4338209SJason Wessel 1049*c4338209SJason Wessel /* Handle the 'H' task query packets */ 1050*c4338209SJason Wessel static void gdb_cmd_task(struct kgdb_state *ks) 1051*c4338209SJason Wessel { 1052*c4338209SJason Wessel struct task_struct *thread; 1053*c4338209SJason Wessel char *ptr; 1054*c4338209SJason Wessel 1055*c4338209SJason Wessel switch (remcom_in_buffer[1]) { 1056*c4338209SJason Wessel case 'g': 1057*c4338209SJason Wessel ptr = &remcom_in_buffer[2]; 1058*c4338209SJason Wessel kgdb_hex2long(&ptr, &ks->threadid); 1059*c4338209SJason Wessel thread = getthread(ks->linux_regs, ks->threadid); 1060*c4338209SJason Wessel if (!thread && ks->threadid > 0) { 1061*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 1062*c4338209SJason Wessel break; 1063*c4338209SJason Wessel } 1064*c4338209SJason Wessel kgdb_usethread = thread; 1065*c4338209SJason Wessel ks->kgdb_usethreadid = ks->threadid; 1066*c4338209SJason Wessel strcpy(remcom_out_buffer, "OK"); 1067*c4338209SJason Wessel break; 1068*c4338209SJason Wessel case 'c': 1069*c4338209SJason Wessel ptr = &remcom_in_buffer[2]; 1070*c4338209SJason Wessel kgdb_hex2long(&ptr, &ks->threadid); 1071*c4338209SJason Wessel if (!ks->threadid) { 1072*c4338209SJason Wessel kgdb_contthread = NULL; 1073*c4338209SJason Wessel } else { 1074*c4338209SJason Wessel thread = getthread(ks->linux_regs, ks->threadid); 1075*c4338209SJason Wessel if (!thread && ks->threadid > 0) { 1076*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 1077*c4338209SJason Wessel break; 1078*c4338209SJason Wessel } 1079*c4338209SJason Wessel kgdb_contthread = thread; 1080*c4338209SJason Wessel } 1081*c4338209SJason Wessel strcpy(remcom_out_buffer, "OK"); 1082*c4338209SJason Wessel break; 1083*c4338209SJason Wessel } 1084*c4338209SJason Wessel } 1085*c4338209SJason Wessel 1086*c4338209SJason Wessel /* Handle the 'T' thread query packets */ 1087*c4338209SJason Wessel static void gdb_cmd_thread(struct kgdb_state *ks) 1088*c4338209SJason Wessel { 1089*c4338209SJason Wessel char *ptr = &remcom_in_buffer[1]; 1090*c4338209SJason Wessel struct task_struct *thread; 1091*c4338209SJason Wessel 1092*c4338209SJason Wessel kgdb_hex2long(&ptr, &ks->threadid); 1093*c4338209SJason Wessel thread = getthread(ks->linux_regs, ks->threadid); 1094*c4338209SJason Wessel if (thread) 1095*c4338209SJason Wessel strcpy(remcom_out_buffer, "OK"); 1096*c4338209SJason Wessel else 1097*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 1098*c4338209SJason Wessel } 1099*c4338209SJason Wessel 1100*c4338209SJason Wessel /* Handle the 'z' or 'Z' breakpoint remove or set packets */ 1101*c4338209SJason Wessel static void gdb_cmd_break(struct kgdb_state *ks) 1102*c4338209SJason Wessel { 1103*c4338209SJason Wessel /* 1104*c4338209SJason Wessel * Since GDB-5.3, it's been drafted that '0' is a software 1105*c4338209SJason Wessel * breakpoint, '1' is a hardware breakpoint, so let's do that. 1106*c4338209SJason Wessel */ 1107*c4338209SJason Wessel char *bpt_type = &remcom_in_buffer[1]; 1108*c4338209SJason Wessel char *ptr = &remcom_in_buffer[2]; 1109*c4338209SJason Wessel unsigned long addr; 1110*c4338209SJason Wessel unsigned long length; 1111*c4338209SJason Wessel int error = 0; 1112*c4338209SJason Wessel 1113*c4338209SJason Wessel if (arch_kgdb_ops.set_hw_breakpoint && *bpt_type >= '1') { 1114*c4338209SJason Wessel /* Unsupported */ 1115*c4338209SJason Wessel if (*bpt_type > '4') 1116*c4338209SJason Wessel return; 1117*c4338209SJason Wessel } else { 1118*c4338209SJason Wessel if (*bpt_type != '0' && *bpt_type != '1') 1119*c4338209SJason Wessel /* Unsupported. */ 1120*c4338209SJason Wessel return; 1121*c4338209SJason Wessel } 1122*c4338209SJason Wessel 1123*c4338209SJason Wessel /* 1124*c4338209SJason Wessel * Test if this is a hardware breakpoint, and 1125*c4338209SJason Wessel * if we support it: 1126*c4338209SJason Wessel */ 1127*c4338209SJason Wessel if (*bpt_type == '1' && !(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT)) 1128*c4338209SJason Wessel /* Unsupported. */ 1129*c4338209SJason Wessel return; 1130*c4338209SJason Wessel 1131*c4338209SJason Wessel if (*(ptr++) != ',') { 1132*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 1133*c4338209SJason Wessel return; 1134*c4338209SJason Wessel } 1135*c4338209SJason Wessel if (!kgdb_hex2long(&ptr, &addr)) { 1136*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 1137*c4338209SJason Wessel return; 1138*c4338209SJason Wessel } 1139*c4338209SJason Wessel if (*(ptr++) != ',' || 1140*c4338209SJason Wessel !kgdb_hex2long(&ptr, &length)) { 1141*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 1142*c4338209SJason Wessel return; 1143*c4338209SJason Wessel } 1144*c4338209SJason Wessel 1145*c4338209SJason Wessel if (remcom_in_buffer[0] == 'Z' && *bpt_type == '0') 1146*c4338209SJason Wessel error = kgdb_set_sw_break(addr); 1147*c4338209SJason Wessel else if (remcom_in_buffer[0] == 'z' && *bpt_type == '0') 1148*c4338209SJason Wessel error = kgdb_remove_sw_break(addr); 1149*c4338209SJason Wessel else if (remcom_in_buffer[0] == 'Z') 1150*c4338209SJason Wessel error = arch_kgdb_ops.set_hw_breakpoint(addr, 1151*c4338209SJason Wessel (int)length, *bpt_type - '0'); 1152*c4338209SJason Wessel else if (remcom_in_buffer[0] == 'z') 1153*c4338209SJason Wessel error = arch_kgdb_ops.remove_hw_breakpoint(addr, 1154*c4338209SJason Wessel (int) length, *bpt_type - '0'); 1155*c4338209SJason Wessel 1156*c4338209SJason Wessel if (error == 0) 1157*c4338209SJason Wessel strcpy(remcom_out_buffer, "OK"); 1158*c4338209SJason Wessel else 1159*c4338209SJason Wessel error_packet(remcom_out_buffer, error); 1160*c4338209SJason Wessel } 1161*c4338209SJason Wessel 1162*c4338209SJason Wessel /* Handle the 'C' signal / exception passing packets */ 1163*c4338209SJason Wessel static int gdb_cmd_exception_pass(struct kgdb_state *ks) 1164*c4338209SJason Wessel { 1165*c4338209SJason Wessel /* C09 == pass exception 1166*c4338209SJason Wessel * C15 == detach kgdb, pass exception 1167*c4338209SJason Wessel */ 1168*c4338209SJason Wessel if (remcom_in_buffer[1] == '0' && remcom_in_buffer[2] == '9') { 1169*c4338209SJason Wessel 1170*c4338209SJason Wessel ks->pass_exception = 1; 1171*c4338209SJason Wessel remcom_in_buffer[0] = 'c'; 1172*c4338209SJason Wessel 1173*c4338209SJason Wessel } else if (remcom_in_buffer[1] == '1' && remcom_in_buffer[2] == '5') { 1174*c4338209SJason Wessel 1175*c4338209SJason Wessel ks->pass_exception = 1; 1176*c4338209SJason Wessel remcom_in_buffer[0] = 'D'; 1177*c4338209SJason Wessel remove_all_break(); 1178*c4338209SJason Wessel kgdb_connected = 0; 1179*c4338209SJason Wessel return 1; 1180*c4338209SJason Wessel 1181*c4338209SJason Wessel } else { 1182*c4338209SJason Wessel kgdb_msg_write("KGDB only knows signal 9 (pass)" 1183*c4338209SJason Wessel " and 15 (pass and disconnect)\n" 1184*c4338209SJason Wessel "Executing a continue without signal passing\n", 0); 1185*c4338209SJason Wessel remcom_in_buffer[0] = 'c'; 1186*c4338209SJason Wessel } 1187*c4338209SJason Wessel 1188*c4338209SJason Wessel /* Indicate fall through */ 1189*c4338209SJason Wessel return -1; 1190*c4338209SJason Wessel } 1191*c4338209SJason Wessel 1192*c4338209SJason Wessel /* 1193*c4338209SJason Wessel * This function performs all gdbserial command procesing 1194*c4338209SJason Wessel */ 1195*c4338209SJason Wessel static int gdb_serial_stub(struct kgdb_state *ks) 1196*c4338209SJason Wessel { 1197*c4338209SJason Wessel int error = 0; 1198*c4338209SJason Wessel int tmp; 1199*c4338209SJason Wessel 1200*c4338209SJason Wessel /* Clear the out buffer. */ 1201*c4338209SJason Wessel memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer)); 1202*c4338209SJason Wessel 1203*c4338209SJason Wessel if (kgdb_connected) { 1204*c4338209SJason Wessel unsigned char thref[8]; 1205*c4338209SJason Wessel char *ptr; 1206*c4338209SJason Wessel 1207*c4338209SJason Wessel /* Reply to host that an exception has occurred */ 1208*c4338209SJason Wessel ptr = remcom_out_buffer; 1209*c4338209SJason Wessel *ptr++ = 'T'; 1210*c4338209SJason Wessel ptr = pack_hex_byte(ptr, ks->signo); 1211*c4338209SJason Wessel ptr += strlen(strcpy(ptr, "thread:")); 1212*c4338209SJason Wessel int_to_threadref(thref, shadow_pid(current->pid)); 1213*c4338209SJason Wessel ptr = pack_threadid(ptr, thref); 1214*c4338209SJason Wessel *ptr++ = ';'; 1215*c4338209SJason Wessel put_packet(remcom_out_buffer); 1216*c4338209SJason Wessel } 1217*c4338209SJason Wessel 1218*c4338209SJason Wessel kgdb_usethread = kgdb_info[ks->cpu].task; 1219*c4338209SJason Wessel ks->kgdb_usethreadid = shadow_pid(kgdb_info[ks->cpu].task->pid); 1220*c4338209SJason Wessel ks->pass_exception = 0; 1221*c4338209SJason Wessel 1222*c4338209SJason Wessel while (1) { 1223*c4338209SJason Wessel error = 0; 1224*c4338209SJason Wessel 1225*c4338209SJason Wessel /* Clear the out buffer. */ 1226*c4338209SJason Wessel memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer)); 1227*c4338209SJason Wessel 1228*c4338209SJason Wessel get_packet(remcom_in_buffer); 1229*c4338209SJason Wessel 1230*c4338209SJason Wessel switch (remcom_in_buffer[0]) { 1231*c4338209SJason Wessel case '?': /* gdbserial status */ 1232*c4338209SJason Wessel gdb_cmd_status(ks); 1233*c4338209SJason Wessel break; 1234*c4338209SJason Wessel case 'g': /* return the value of the CPU registers */ 1235*c4338209SJason Wessel gdb_cmd_getregs(ks); 1236*c4338209SJason Wessel break; 1237*c4338209SJason Wessel case 'G': /* set the value of the CPU registers - return OK */ 1238*c4338209SJason Wessel gdb_cmd_setregs(ks); 1239*c4338209SJason Wessel break; 1240*c4338209SJason Wessel case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ 1241*c4338209SJason Wessel gdb_cmd_memread(ks); 1242*c4338209SJason Wessel break; 1243*c4338209SJason Wessel case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA..AA */ 1244*c4338209SJason Wessel gdb_cmd_memwrite(ks); 1245*c4338209SJason Wessel break; 1246*c4338209SJason Wessel case 'X': /* XAA..AA,LLLL: Write LLLL bytes at address AA..AA */ 1247*c4338209SJason Wessel gdb_cmd_binwrite(ks); 1248*c4338209SJason Wessel break; 1249*c4338209SJason Wessel /* kill or detach. KGDB should treat this like a 1250*c4338209SJason Wessel * continue. 1251*c4338209SJason Wessel */ 1252*c4338209SJason Wessel case 'D': /* Debugger detach */ 1253*c4338209SJason Wessel case 'k': /* Debugger detach via kill */ 1254*c4338209SJason Wessel gdb_cmd_detachkill(ks); 1255*c4338209SJason Wessel goto default_handle; 1256*c4338209SJason Wessel case 'R': /* Reboot */ 1257*c4338209SJason Wessel if (gdb_cmd_reboot(ks)) 1258*c4338209SJason Wessel goto default_handle; 1259*c4338209SJason Wessel break; 1260*c4338209SJason Wessel case 'q': /* query command */ 1261*c4338209SJason Wessel gdb_cmd_query(ks); 1262*c4338209SJason Wessel break; 1263*c4338209SJason Wessel case 'H': /* task related */ 1264*c4338209SJason Wessel gdb_cmd_task(ks); 1265*c4338209SJason Wessel break; 1266*c4338209SJason Wessel case 'T': /* Query thread status */ 1267*c4338209SJason Wessel gdb_cmd_thread(ks); 1268*c4338209SJason Wessel break; 1269*c4338209SJason Wessel case 'z': /* Break point remove */ 1270*c4338209SJason Wessel case 'Z': /* Break point set */ 1271*c4338209SJason Wessel gdb_cmd_break(ks); 1272*c4338209SJason Wessel break; 1273*c4338209SJason Wessel case 'C': /* Exception passing */ 1274*c4338209SJason Wessel tmp = gdb_cmd_exception_pass(ks); 1275*c4338209SJason Wessel if (tmp > 0) 1276*c4338209SJason Wessel goto default_handle; 1277*c4338209SJason Wessel if (tmp == 0) 1278*c4338209SJason Wessel break; 1279*c4338209SJason Wessel /* Fall through on tmp < 0 */ 1280*c4338209SJason Wessel case 'c': /* Continue packet */ 1281*c4338209SJason Wessel case 's': /* Single step packet */ 1282*c4338209SJason Wessel if (kgdb_contthread && kgdb_contthread != current) { 1283*c4338209SJason Wessel /* Can't switch threads in kgdb */ 1284*c4338209SJason Wessel error_packet(remcom_out_buffer, -EINVAL); 1285*c4338209SJason Wessel break; 1286*c4338209SJason Wessel } 1287*c4338209SJason Wessel kgdb_activate_sw_breakpoints(); 1288*c4338209SJason Wessel /* Fall through to default processing */ 1289*c4338209SJason Wessel default: 1290*c4338209SJason Wessel default_handle: 1291*c4338209SJason Wessel error = kgdb_arch_handle_exception(ks->ex_vector, 1292*c4338209SJason Wessel ks->signo, 1293*c4338209SJason Wessel ks->err_code, 1294*c4338209SJason Wessel remcom_in_buffer, 1295*c4338209SJason Wessel remcom_out_buffer, 1296*c4338209SJason Wessel ks->linux_regs); 1297*c4338209SJason Wessel /* 1298*c4338209SJason Wessel * Leave cmd processing on error, detach, 1299*c4338209SJason Wessel * kill, continue, or single step. 1300*c4338209SJason Wessel */ 1301*c4338209SJason Wessel if (error >= 0 || remcom_in_buffer[0] == 'D' || 1302*c4338209SJason Wessel remcom_in_buffer[0] == 'k') { 1303*c4338209SJason Wessel error = 0; 1304*c4338209SJason Wessel goto kgdb_exit; 1305*c4338209SJason Wessel } 1306*c4338209SJason Wessel 1307*c4338209SJason Wessel } 1308*c4338209SJason Wessel 1309*c4338209SJason Wessel /* reply to the request */ 1310*c4338209SJason Wessel put_packet(remcom_out_buffer); 1311*c4338209SJason Wessel } 1312*c4338209SJason Wessel 1313*c4338209SJason Wessel kgdb_exit: 1314*c4338209SJason Wessel if (ks->pass_exception) 1315*c4338209SJason Wessel error = 1; 1316*c4338209SJason Wessel return error; 1317*c4338209SJason Wessel } 1318*c4338209SJason Wessel 1319*c4338209SJason Wessel static int kgdb_reenter_check(struct kgdb_state *ks) 1320*c4338209SJason Wessel { 1321*c4338209SJason Wessel unsigned long addr; 1322*c4338209SJason Wessel 1323*c4338209SJason Wessel if (atomic_read(&kgdb_active) != raw_smp_processor_id()) 1324*c4338209SJason Wessel return 0; 1325*c4338209SJason Wessel 1326*c4338209SJason Wessel /* Panic on recursive debugger calls: */ 1327*c4338209SJason Wessel exception_level++; 1328*c4338209SJason Wessel addr = kgdb_arch_pc(ks->ex_vector, ks->linux_regs); 1329*c4338209SJason Wessel kgdb_deactivate_sw_breakpoints(); 1330*c4338209SJason Wessel 1331*c4338209SJason Wessel /* 1332*c4338209SJason Wessel * If the break point removed ok at the place exception 1333*c4338209SJason Wessel * occurred, try to recover and print a warning to the end 1334*c4338209SJason Wessel * user because the user planted a breakpoint in a place that 1335*c4338209SJason Wessel * KGDB needs in order to function. 1336*c4338209SJason Wessel */ 1337*c4338209SJason Wessel if (kgdb_remove_sw_break(addr) == 0) { 1338*c4338209SJason Wessel exception_level = 0; 1339*c4338209SJason Wessel kgdb_skipexception(ks->ex_vector, ks->linux_regs); 1340*c4338209SJason Wessel kgdb_activate_sw_breakpoints(); 1341*c4338209SJason Wessel printk(KERN_CRIT "KGDB: re-enter error: breakpoint removed %lx\n", 1342*c4338209SJason Wessel addr); 1343*c4338209SJason Wessel WARN_ON_ONCE(1); 1344*c4338209SJason Wessel 1345*c4338209SJason Wessel return 1; 1346*c4338209SJason Wessel } 1347*c4338209SJason Wessel remove_all_break(); 1348*c4338209SJason Wessel kgdb_skipexception(ks->ex_vector, ks->linux_regs); 1349*c4338209SJason Wessel 1350*c4338209SJason Wessel if (exception_level > 1) { 1351*c4338209SJason Wessel dump_stack(); 1352*c4338209SJason Wessel panic("Recursive entry to debugger"); 1353*c4338209SJason Wessel } 1354*c4338209SJason Wessel 1355*c4338209SJason Wessel printk(KERN_CRIT "KGDB: re-enter exception: ALL breakpoints killed\n"); 1356*c4338209SJason Wessel dump_stack(); 1357*c4338209SJason Wessel panic("Recursive entry to debugger"); 1358*c4338209SJason Wessel 1359*c4338209SJason Wessel return 1; 1360*c4338209SJason Wessel } 1361*c4338209SJason Wessel 1362*c4338209SJason Wessel static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs) 1363*c4338209SJason Wessel { 1364*c4338209SJason Wessel unsigned long flags; 1365*c4338209SJason Wessel int sstep_tries = 100; 1366*c4338209SJason Wessel int error = 0; 1367*c4338209SJason Wessel int i, cpu; 1368*c4338209SJason Wessel int trace_on = 0; 1369*c4338209SJason Wessel acquirelock: 1370*c4338209SJason Wessel /* 1371*c4338209SJason Wessel * Interrupts will be restored by the 'trap return' code, except when 1372*c4338209SJason Wessel * single stepping. 1373*c4338209SJason Wessel */ 1374*c4338209SJason Wessel local_irq_save(flags); 1375*c4338209SJason Wessel 1376*c4338209SJason Wessel cpu = ks->cpu; 1377*c4338209SJason Wessel kgdb_info[cpu].debuggerinfo = regs; 1378*c4338209SJason Wessel kgdb_info[cpu].task = current; 1379*c4338209SJason Wessel /* 1380*c4338209SJason Wessel * Make sure the above info reaches the primary CPU before 1381*c4338209SJason Wessel * our cpu_in_kgdb[] flag setting does: 1382*c4338209SJason Wessel */ 1383*c4338209SJason Wessel atomic_inc(&cpu_in_kgdb[cpu]); 1384*c4338209SJason Wessel 1385*c4338209SJason Wessel /* 1386*c4338209SJason Wessel * CPU will loop if it is a slave or request to become a kgdb 1387*c4338209SJason Wessel * master cpu and acquire the kgdb_active lock: 1388*c4338209SJason Wessel */ 1389*c4338209SJason Wessel while (1) { 1390*c4338209SJason Wessel if (kgdb_info[cpu].exception_state & DCPU_WANT_MASTER) { 1391*c4338209SJason Wessel if (atomic_cmpxchg(&kgdb_active, -1, cpu) == cpu) 1392*c4338209SJason Wessel break; 1393*c4338209SJason Wessel } else if (kgdb_info[cpu].exception_state & DCPU_IS_SLAVE) { 1394*c4338209SJason Wessel if (!atomic_read(&passive_cpu_wait[cpu])) 1395*c4338209SJason Wessel goto return_normal; 1396*c4338209SJason Wessel } else { 1397*c4338209SJason Wessel return_normal: 1398*c4338209SJason Wessel /* Return to normal operation by executing any 1399*c4338209SJason Wessel * hw breakpoint fixup. 1400*c4338209SJason Wessel */ 1401*c4338209SJason Wessel if (arch_kgdb_ops.correct_hw_break) 1402*c4338209SJason Wessel arch_kgdb_ops.correct_hw_break(); 1403*c4338209SJason Wessel if (trace_on) 1404*c4338209SJason Wessel tracing_on(); 1405*c4338209SJason Wessel atomic_dec(&cpu_in_kgdb[cpu]); 1406*c4338209SJason Wessel touch_softlockup_watchdog_sync(); 1407*c4338209SJason Wessel clocksource_touch_watchdog(); 1408*c4338209SJason Wessel local_irq_restore(flags); 1409*c4338209SJason Wessel return 0; 1410*c4338209SJason Wessel } 1411*c4338209SJason Wessel cpu_relax(); 1412*c4338209SJason Wessel } 1413*c4338209SJason Wessel 1414*c4338209SJason Wessel /* 1415*c4338209SJason Wessel * For single stepping, try to only enter on the processor 1416*c4338209SJason Wessel * that was single stepping. To gaurd against a deadlock, the 1417*c4338209SJason Wessel * kernel will only try for the value of sstep_tries before 1418*c4338209SJason Wessel * giving up and continuing on. 1419*c4338209SJason Wessel */ 1420*c4338209SJason Wessel if (atomic_read(&kgdb_cpu_doing_single_step) != -1 && 1421*c4338209SJason Wessel (kgdb_info[cpu].task && 1422*c4338209SJason Wessel kgdb_info[cpu].task->pid != kgdb_sstep_pid) && --sstep_tries) { 1423*c4338209SJason Wessel atomic_set(&kgdb_active, -1); 1424*c4338209SJason Wessel touch_softlockup_watchdog_sync(); 1425*c4338209SJason Wessel clocksource_touch_watchdog(); 1426*c4338209SJason Wessel local_irq_restore(flags); 1427*c4338209SJason Wessel 1428*c4338209SJason Wessel goto acquirelock; 1429*c4338209SJason Wessel } 1430*c4338209SJason Wessel 1431*c4338209SJason Wessel if (!kgdb_io_ready(1)) { 1432*c4338209SJason Wessel error = 1; 1433*c4338209SJason Wessel goto kgdb_restore; /* No I/O connection, so resume the system */ 1434*c4338209SJason Wessel } 1435*c4338209SJason Wessel 1436*c4338209SJason Wessel /* 1437*c4338209SJason Wessel * Don't enter if we have hit a removed breakpoint. 1438*c4338209SJason Wessel */ 1439*c4338209SJason Wessel if (kgdb_skipexception(ks->ex_vector, ks->linux_regs)) 1440*c4338209SJason Wessel goto kgdb_restore; 1441*c4338209SJason Wessel 1442*c4338209SJason Wessel /* Call the I/O driver's pre_exception routine */ 1443*c4338209SJason Wessel if (kgdb_io_ops->pre_exception) 1444*c4338209SJason Wessel kgdb_io_ops->pre_exception(); 1445*c4338209SJason Wessel 1446*c4338209SJason Wessel kgdb_disable_hw_debug(ks->linux_regs); 1447*c4338209SJason Wessel 1448*c4338209SJason Wessel /* 1449*c4338209SJason Wessel * Get the passive CPU lock which will hold all the non-primary 1450*c4338209SJason Wessel * CPU in a spin state while the debugger is active 1451*c4338209SJason Wessel */ 1452*c4338209SJason Wessel if (!kgdb_single_step) { 1453*c4338209SJason Wessel for (i = 0; i < NR_CPUS; i++) 1454*c4338209SJason Wessel atomic_inc(&passive_cpu_wait[i]); 1455*c4338209SJason Wessel } 1456*c4338209SJason Wessel 1457*c4338209SJason Wessel #ifdef CONFIG_SMP 1458*c4338209SJason Wessel /* Signal the other CPUs to enter kgdb_wait() */ 1459*c4338209SJason Wessel if ((!kgdb_single_step) && kgdb_do_roundup) 1460*c4338209SJason Wessel kgdb_roundup_cpus(flags); 1461*c4338209SJason Wessel #endif 1462*c4338209SJason Wessel 1463*c4338209SJason Wessel /* 1464*c4338209SJason Wessel * Wait for the other CPUs to be notified and be waiting for us: 1465*c4338209SJason Wessel */ 1466*c4338209SJason Wessel for_each_online_cpu(i) { 1467*c4338209SJason Wessel while (!atomic_read(&cpu_in_kgdb[i])) 1468*c4338209SJason Wessel cpu_relax(); 1469*c4338209SJason Wessel } 1470*c4338209SJason Wessel 1471*c4338209SJason Wessel /* 1472*c4338209SJason Wessel * At this point the primary processor is completely 1473*c4338209SJason Wessel * in the debugger and all secondary CPUs are quiescent 1474*c4338209SJason Wessel */ 1475*c4338209SJason Wessel kgdb_post_primary_code(ks->linux_regs, ks->ex_vector, ks->err_code); 1476*c4338209SJason Wessel kgdb_deactivate_sw_breakpoints(); 1477*c4338209SJason Wessel kgdb_single_step = 0; 1478*c4338209SJason Wessel kgdb_contthread = current; 1479*c4338209SJason Wessel exception_level = 0; 1480*c4338209SJason Wessel trace_on = tracing_is_on(); 1481*c4338209SJason Wessel if (trace_on) 1482*c4338209SJason Wessel tracing_off(); 1483*c4338209SJason Wessel 1484*c4338209SJason Wessel /* Talk to debugger with gdbserial protocol */ 1485*c4338209SJason Wessel error = gdb_serial_stub(ks); 1486*c4338209SJason Wessel 1487*c4338209SJason Wessel /* Call the I/O driver's post_exception routine */ 1488*c4338209SJason Wessel if (kgdb_io_ops->post_exception) 1489*c4338209SJason Wessel kgdb_io_ops->post_exception(); 1490*c4338209SJason Wessel 1491*c4338209SJason Wessel atomic_dec(&cpu_in_kgdb[ks->cpu]); 1492*c4338209SJason Wessel 1493*c4338209SJason Wessel if (!kgdb_single_step) { 1494*c4338209SJason Wessel for (i = NR_CPUS-1; i >= 0; i--) 1495*c4338209SJason Wessel atomic_dec(&passive_cpu_wait[i]); 1496*c4338209SJason Wessel /* 1497*c4338209SJason Wessel * Wait till all the CPUs have quit 1498*c4338209SJason Wessel * from the debugger. 1499*c4338209SJason Wessel */ 1500*c4338209SJason Wessel for_each_online_cpu(i) { 1501*c4338209SJason Wessel while (atomic_read(&cpu_in_kgdb[i])) 1502*c4338209SJason Wessel cpu_relax(); 1503*c4338209SJason Wessel } 1504*c4338209SJason Wessel } 1505*c4338209SJason Wessel 1506*c4338209SJason Wessel kgdb_restore: 1507*c4338209SJason Wessel if (atomic_read(&kgdb_cpu_doing_single_step) != -1) { 1508*c4338209SJason Wessel int sstep_cpu = atomic_read(&kgdb_cpu_doing_single_step); 1509*c4338209SJason Wessel if (kgdb_info[sstep_cpu].task) 1510*c4338209SJason Wessel kgdb_sstep_pid = kgdb_info[sstep_cpu].task->pid; 1511*c4338209SJason Wessel else 1512*c4338209SJason Wessel kgdb_sstep_pid = 0; 1513*c4338209SJason Wessel } 1514*c4338209SJason Wessel if (trace_on) 1515*c4338209SJason Wessel tracing_on(); 1516*c4338209SJason Wessel /* Free kgdb_active */ 1517*c4338209SJason Wessel atomic_set(&kgdb_active, -1); 1518*c4338209SJason Wessel touch_softlockup_watchdog_sync(); 1519*c4338209SJason Wessel clocksource_touch_watchdog(); 1520*c4338209SJason Wessel local_irq_restore(flags); 1521*c4338209SJason Wessel 1522*c4338209SJason Wessel return error; 1523*c4338209SJason Wessel } 1524*c4338209SJason Wessel 1525*c4338209SJason Wessel /* 1526*c4338209SJason Wessel * kgdb_handle_exception() - main entry point from a kernel exception 1527*c4338209SJason Wessel * 1528*c4338209SJason Wessel * Locking hierarchy: 1529*c4338209SJason Wessel * interface locks, if any (begin_session) 1530*c4338209SJason Wessel * kgdb lock (kgdb_active) 1531*c4338209SJason Wessel */ 1532*c4338209SJason Wessel int 1533*c4338209SJason Wessel kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) 1534*c4338209SJason Wessel { 1535*c4338209SJason Wessel struct kgdb_state kgdb_var; 1536*c4338209SJason Wessel struct kgdb_state *ks = &kgdb_var; 1537*c4338209SJason Wessel int ret; 1538*c4338209SJason Wessel 1539*c4338209SJason Wessel ks->cpu = raw_smp_processor_id(); 1540*c4338209SJason Wessel ks->ex_vector = evector; 1541*c4338209SJason Wessel ks->signo = signo; 1542*c4338209SJason Wessel ks->ex_vector = evector; 1543*c4338209SJason Wessel ks->err_code = ecode; 1544*c4338209SJason Wessel ks->kgdb_usethreadid = 0; 1545*c4338209SJason Wessel ks->linux_regs = regs; 1546*c4338209SJason Wessel 1547*c4338209SJason Wessel if (kgdb_reenter_check(ks)) 1548*c4338209SJason Wessel return 0; /* Ouch, double exception ! */ 1549*c4338209SJason Wessel kgdb_info[ks->cpu].exception_state |= DCPU_WANT_MASTER; 1550*c4338209SJason Wessel ret = kgdb_cpu_enter(ks, regs); 1551*c4338209SJason Wessel kgdb_info[ks->cpu].exception_state &= ~DCPU_WANT_MASTER; 1552*c4338209SJason Wessel return ret; 1553*c4338209SJason Wessel } 1554*c4338209SJason Wessel 1555*c4338209SJason Wessel int kgdb_nmicallback(int cpu, void *regs) 1556*c4338209SJason Wessel { 1557*c4338209SJason Wessel #ifdef CONFIG_SMP 1558*c4338209SJason Wessel struct kgdb_state kgdb_var; 1559*c4338209SJason Wessel struct kgdb_state *ks = &kgdb_var; 1560*c4338209SJason Wessel 1561*c4338209SJason Wessel memset(ks, 0, sizeof(struct kgdb_state)); 1562*c4338209SJason Wessel ks->cpu = cpu; 1563*c4338209SJason Wessel ks->linux_regs = regs; 1564*c4338209SJason Wessel 1565*c4338209SJason Wessel if (!atomic_read(&cpu_in_kgdb[cpu]) && 1566*c4338209SJason Wessel atomic_read(&kgdb_active) != -1 && 1567*c4338209SJason Wessel atomic_read(&kgdb_active) != cpu) { 1568*c4338209SJason Wessel kgdb_info[cpu].exception_state |= DCPU_IS_SLAVE; 1569*c4338209SJason Wessel kgdb_cpu_enter(ks, regs); 1570*c4338209SJason Wessel kgdb_info[cpu].exception_state &= ~DCPU_IS_SLAVE; 1571*c4338209SJason Wessel return 0; 1572*c4338209SJason Wessel } 1573*c4338209SJason Wessel #endif 1574*c4338209SJason Wessel return 1; 1575*c4338209SJason Wessel } 1576*c4338209SJason Wessel 1577*c4338209SJason Wessel static void kgdb_console_write(struct console *co, const char *s, 1578*c4338209SJason Wessel unsigned count) 1579*c4338209SJason Wessel { 1580*c4338209SJason Wessel unsigned long flags; 1581*c4338209SJason Wessel 1582*c4338209SJason Wessel /* If we're debugging, or KGDB has not connected, don't try 1583*c4338209SJason Wessel * and print. */ 1584*c4338209SJason Wessel if (!kgdb_connected || atomic_read(&kgdb_active) != -1) 1585*c4338209SJason Wessel return; 1586*c4338209SJason Wessel 1587*c4338209SJason Wessel local_irq_save(flags); 1588*c4338209SJason Wessel kgdb_msg_write(s, count); 1589*c4338209SJason Wessel local_irq_restore(flags); 1590*c4338209SJason Wessel } 1591*c4338209SJason Wessel 1592*c4338209SJason Wessel static struct console kgdbcons = { 1593*c4338209SJason Wessel .name = "kgdb", 1594*c4338209SJason Wessel .write = kgdb_console_write, 1595*c4338209SJason Wessel .flags = CON_PRINTBUFFER | CON_ENABLED, 1596*c4338209SJason Wessel .index = -1, 1597*c4338209SJason Wessel }; 1598*c4338209SJason Wessel 1599*c4338209SJason Wessel #ifdef CONFIG_MAGIC_SYSRQ 1600*c4338209SJason Wessel static void sysrq_handle_gdb(int key, struct tty_struct *tty) 1601*c4338209SJason Wessel { 1602*c4338209SJason Wessel if (!kgdb_io_ops) { 1603*c4338209SJason Wessel printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); 1604*c4338209SJason Wessel return; 1605*c4338209SJason Wessel } 1606*c4338209SJason Wessel if (!kgdb_connected) 1607*c4338209SJason Wessel printk(KERN_CRIT "Entering KGDB\n"); 1608*c4338209SJason Wessel 1609*c4338209SJason Wessel kgdb_breakpoint(); 1610*c4338209SJason Wessel } 1611*c4338209SJason Wessel 1612*c4338209SJason Wessel static struct sysrq_key_op sysrq_gdb_op = { 1613*c4338209SJason Wessel .handler = sysrq_handle_gdb, 1614*c4338209SJason Wessel .help_msg = "debug(G)", 1615*c4338209SJason Wessel .action_msg = "DEBUG", 1616*c4338209SJason Wessel }; 1617*c4338209SJason Wessel #endif 1618*c4338209SJason Wessel 1619*c4338209SJason Wessel static void kgdb_register_callbacks(void) 1620*c4338209SJason Wessel { 1621*c4338209SJason Wessel if (!kgdb_io_module_registered) { 1622*c4338209SJason Wessel kgdb_io_module_registered = 1; 1623*c4338209SJason Wessel kgdb_arch_init(); 1624*c4338209SJason Wessel #ifdef CONFIG_MAGIC_SYSRQ 1625*c4338209SJason Wessel register_sysrq_key('g', &sysrq_gdb_op); 1626*c4338209SJason Wessel #endif 1627*c4338209SJason Wessel if (kgdb_use_con && !kgdb_con_registered) { 1628*c4338209SJason Wessel register_console(&kgdbcons); 1629*c4338209SJason Wessel kgdb_con_registered = 1; 1630*c4338209SJason Wessel } 1631*c4338209SJason Wessel } 1632*c4338209SJason Wessel } 1633*c4338209SJason Wessel 1634*c4338209SJason Wessel static void kgdb_unregister_callbacks(void) 1635*c4338209SJason Wessel { 1636*c4338209SJason Wessel /* 1637*c4338209SJason Wessel * When this routine is called KGDB should unregister from the 1638*c4338209SJason Wessel * panic handler and clean up, making sure it is not handling any 1639*c4338209SJason Wessel * break exceptions at the time. 1640*c4338209SJason Wessel */ 1641*c4338209SJason Wessel if (kgdb_io_module_registered) { 1642*c4338209SJason Wessel kgdb_io_module_registered = 0; 1643*c4338209SJason Wessel kgdb_arch_exit(); 1644*c4338209SJason Wessel #ifdef CONFIG_MAGIC_SYSRQ 1645*c4338209SJason Wessel unregister_sysrq_key('g', &sysrq_gdb_op); 1646*c4338209SJason Wessel #endif 1647*c4338209SJason Wessel if (kgdb_con_registered) { 1648*c4338209SJason Wessel unregister_console(&kgdbcons); 1649*c4338209SJason Wessel kgdb_con_registered = 0; 1650*c4338209SJason Wessel } 1651*c4338209SJason Wessel } 1652*c4338209SJason Wessel } 1653*c4338209SJason Wessel 1654*c4338209SJason Wessel static void kgdb_initial_breakpoint(void) 1655*c4338209SJason Wessel { 1656*c4338209SJason Wessel kgdb_break_asap = 0; 1657*c4338209SJason Wessel 1658*c4338209SJason Wessel printk(KERN_CRIT "kgdb: Waiting for connection from remote gdb...\n"); 1659*c4338209SJason Wessel kgdb_breakpoint(); 1660*c4338209SJason Wessel } 1661*c4338209SJason Wessel 1662*c4338209SJason Wessel /** 1663*c4338209SJason Wessel * kgdb_register_io_module - register KGDB IO module 1664*c4338209SJason Wessel * @new_kgdb_io_ops: the io ops vector 1665*c4338209SJason Wessel * 1666*c4338209SJason Wessel * Register it with the KGDB core. 1667*c4338209SJason Wessel */ 1668*c4338209SJason Wessel int kgdb_register_io_module(struct kgdb_io *new_kgdb_io_ops) 1669*c4338209SJason Wessel { 1670*c4338209SJason Wessel int err; 1671*c4338209SJason Wessel 1672*c4338209SJason Wessel spin_lock(&kgdb_registration_lock); 1673*c4338209SJason Wessel 1674*c4338209SJason Wessel if (kgdb_io_ops) { 1675*c4338209SJason Wessel spin_unlock(&kgdb_registration_lock); 1676*c4338209SJason Wessel 1677*c4338209SJason Wessel printk(KERN_ERR "kgdb: Another I/O driver is already " 1678*c4338209SJason Wessel "registered with KGDB.\n"); 1679*c4338209SJason Wessel return -EBUSY; 1680*c4338209SJason Wessel } 1681*c4338209SJason Wessel 1682*c4338209SJason Wessel if (new_kgdb_io_ops->init) { 1683*c4338209SJason Wessel err = new_kgdb_io_ops->init(); 1684*c4338209SJason Wessel if (err) { 1685*c4338209SJason Wessel spin_unlock(&kgdb_registration_lock); 1686*c4338209SJason Wessel return err; 1687*c4338209SJason Wessel } 1688*c4338209SJason Wessel } 1689*c4338209SJason Wessel 1690*c4338209SJason Wessel kgdb_io_ops = new_kgdb_io_ops; 1691*c4338209SJason Wessel 1692*c4338209SJason Wessel spin_unlock(&kgdb_registration_lock); 1693*c4338209SJason Wessel 1694*c4338209SJason Wessel printk(KERN_INFO "kgdb: Registered I/O driver %s.\n", 1695*c4338209SJason Wessel new_kgdb_io_ops->name); 1696*c4338209SJason Wessel 1697*c4338209SJason Wessel /* Arm KGDB now. */ 1698*c4338209SJason Wessel kgdb_register_callbacks(); 1699*c4338209SJason Wessel 1700*c4338209SJason Wessel if (kgdb_break_asap) 1701*c4338209SJason Wessel kgdb_initial_breakpoint(); 1702*c4338209SJason Wessel 1703*c4338209SJason Wessel return 0; 1704*c4338209SJason Wessel } 1705*c4338209SJason Wessel EXPORT_SYMBOL_GPL(kgdb_register_io_module); 1706*c4338209SJason Wessel 1707*c4338209SJason Wessel /** 1708*c4338209SJason Wessel * kkgdb_unregister_io_module - unregister KGDB IO module 1709*c4338209SJason Wessel * @old_kgdb_io_ops: the io ops vector 1710*c4338209SJason Wessel * 1711*c4338209SJason Wessel * Unregister it with the KGDB core. 1712*c4338209SJason Wessel */ 1713*c4338209SJason Wessel void kgdb_unregister_io_module(struct kgdb_io *old_kgdb_io_ops) 1714*c4338209SJason Wessel { 1715*c4338209SJason Wessel BUG_ON(kgdb_connected); 1716*c4338209SJason Wessel 1717*c4338209SJason Wessel /* 1718*c4338209SJason Wessel * KGDB is no longer able to communicate out, so 1719*c4338209SJason Wessel * unregister our callbacks and reset state. 1720*c4338209SJason Wessel */ 1721*c4338209SJason Wessel kgdb_unregister_callbacks(); 1722*c4338209SJason Wessel 1723*c4338209SJason Wessel spin_lock(&kgdb_registration_lock); 1724*c4338209SJason Wessel 1725*c4338209SJason Wessel WARN_ON_ONCE(kgdb_io_ops != old_kgdb_io_ops); 1726*c4338209SJason Wessel kgdb_io_ops = NULL; 1727*c4338209SJason Wessel 1728*c4338209SJason Wessel spin_unlock(&kgdb_registration_lock); 1729*c4338209SJason Wessel 1730*c4338209SJason Wessel printk(KERN_INFO 1731*c4338209SJason Wessel "kgdb: Unregistered I/O driver %s, debugger disabled.\n", 1732*c4338209SJason Wessel old_kgdb_io_ops->name); 1733*c4338209SJason Wessel } 1734*c4338209SJason Wessel EXPORT_SYMBOL_GPL(kgdb_unregister_io_module); 1735*c4338209SJason Wessel 1736*c4338209SJason Wessel /** 1737*c4338209SJason Wessel * kgdb_breakpoint - generate breakpoint exception 1738*c4338209SJason Wessel * 1739*c4338209SJason Wessel * This function will generate a breakpoint exception. It is used at the 1740*c4338209SJason Wessel * beginning of a program to sync up with a debugger and can be used 1741*c4338209SJason Wessel * otherwise as a quick means to stop program execution and "break" into 1742*c4338209SJason Wessel * the debugger. 1743*c4338209SJason Wessel */ 1744*c4338209SJason Wessel void kgdb_breakpoint(void) 1745*c4338209SJason Wessel { 1746*c4338209SJason Wessel atomic_inc(&kgdb_setting_breakpoint); 1747*c4338209SJason Wessel wmb(); /* Sync point before breakpoint */ 1748*c4338209SJason Wessel arch_kgdb_breakpoint(); 1749*c4338209SJason Wessel wmb(); /* Sync point after breakpoint */ 1750*c4338209SJason Wessel atomic_dec(&kgdb_setting_breakpoint); 1751*c4338209SJason Wessel } 1752*c4338209SJason Wessel EXPORT_SYMBOL_GPL(kgdb_breakpoint); 1753*c4338209SJason Wessel 1754*c4338209SJason Wessel static int __init opt_kgdb_wait(char *str) 1755*c4338209SJason Wessel { 1756*c4338209SJason Wessel kgdb_break_asap = 1; 1757*c4338209SJason Wessel 1758*c4338209SJason Wessel if (kgdb_io_module_registered) 1759*c4338209SJason Wessel kgdb_initial_breakpoint(); 1760*c4338209SJason Wessel 1761*c4338209SJason Wessel return 0; 1762*c4338209SJason Wessel } 1763*c4338209SJason Wessel 1764*c4338209SJason Wessel early_param("kgdbwait", opt_kgdb_wait); 1765