Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb:
kgdb,ppc: Individual register get/set for ppc
kgdbts: prevent re-entry to kgdbts before it unregisters
debug_core,x86,blackfin: Clean up hw debug disable API
kdb: Fix early debugging crash regression
kgdb,arm: fix register dump
kdb: fix per_cpu command to remove supress mask
kdb: Add kdb kernel module sample

+238 -146
+12 -1
Documentation/DocBook/kgdb.tmpl
··· 710 710 <listitem><para>A simple shell</para></listitem> 711 711 <listitem><para>The kdb core command set</para></listitem> 712 712 <listitem><para>A registration API to register additional kdb shell commands.</para> 713 - <para>A good example of a self-contained kdb module is the "ftdump" command for dumping the ftrace buffer. See: kernel/trace/trace_kdb.c</para></listitem> 713 + <itemizedlist> 714 + <listitem><para>A good example of a self-contained kdb module 715 + is the "ftdump" command for dumping the ftrace buffer. See: 716 + kernel/trace/trace_kdb.c</para></listitem> 717 + <listitem><para>For an example of how to dynamically register 718 + a new kdb command you can build the kdb_hello.ko kernel module 719 + from samples/kdb/kdb_hello.c. To build this example you can 720 + set CONFIG_SAMPLES=y and CONFIG_SAMPLE_KDB=m in your kernel 721 + config. Later run "modprobe kdb_hello" and the next time you 722 + enter the kdb shell, you can run the "hello" 723 + command.</para></listitem> 724 + </itemizedlist></listitem> 714 725 <listitem><para>The implementation for kdb_printf() which 715 726 emits messages directly to I/O drivers, bypassing the kernel 716 727 log.</para></listitem>
+3 -2
arch/arm/include/asm/kgdb.h
··· 70 70 #define _GP_REGS 16 71 71 #define _FP_REGS 8 72 72 #define _EXTRA_REGS 2 73 - #define DBG_MAX_REG_NUM (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) 73 + #define GDB_MAX_REGS (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) 74 + #define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS) 74 75 75 76 #define KGDB_MAX_NO_CPUS 1 76 77 #define BUFMAX 400 ··· 94 93 #define _SPT 13 95 94 #define _LR 14 96 95 #define _PC 15 97 - #define _CPSR (DBG_MAX_REG_NUM - 1) 96 + #define _CPSR (GDB_MAX_REGS - 1) 98 97 99 98 /* 100 99 * So that we can denote the end of a frame for tracing,
+1 -1
arch/arm/kernel/kgdb.c
··· 79 79 return; 80 80 81 81 /* Initialize to zero */ 82 - for (regno = 0; regno < DBG_MAX_REG_NUM; regno++) 82 + for (regno = 0; regno < GDB_MAX_REGS; regno++) 83 83 gdb_regs[regno] = 0; 84 84 85 85 /* Otherwise, we have only some registers from switch_to() */
+2 -1
arch/blackfin/kernel/kgdb.c
··· 320 320 } 321 321 } 322 322 323 - void kgdb_disable_hw_debug(struct pt_regs *regs) 323 + static void bfin_disable_hw_debug(struct pt_regs *regs) 324 324 { 325 325 /* Disable hardware debugging while we are in kgdb */ 326 326 bfin_write_WPIACTL(0); ··· 406 406 #endif 407 407 .set_hw_breakpoint = bfin_set_hw_break, 408 408 .remove_hw_breakpoint = bfin_remove_hw_break, 409 + .disable_hw_break = bfin_disable_hw_debug, 409 410 .remove_all_hw_break = bfin_remove_all_hw_break, 410 411 .correct_hw_break = bfin_correct_hw_break, 411 412 };
+1
arch/powerpc/include/asm/kgdb.h
··· 31 31 asm(".long 0x7d821008"); /* twge r2, r2 */ 32 32 } 33 33 #define CACHE_FLUSH_IS_SAFE 1 34 + #define DBG_MAX_REG_NUM 70 34 35 35 36 /* The number bytes of registers we have to save depends on a few 36 37 * things. For 64bit we default to not including vector registers and
+128 -66
arch/powerpc/kernel/kgdb.c
··· 194 194 ptr = (unsigned long *)ptr32; \ 195 195 } while (0) 196 196 197 - 198 - void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) 199 - { 200 - unsigned long *ptr = gdb_regs; 201 - int reg; 202 - 203 - memset(gdb_regs, 0, NUMREGBYTES); 204 - 205 - for (reg = 0; reg < 32; reg++) 206 - PACK64(ptr, regs->gpr[reg]); 207 - 208 - #ifdef CONFIG_FSL_BOOKE 209 - #ifdef CONFIG_SPE 210 - for (reg = 0; reg < 32; reg++) 211 - PACK64(ptr, current->thread.evr[reg]); 212 - #else 213 - ptr += 32; 214 - #endif 215 - #else 216 - /* fp registers not used by kernel, leave zero */ 217 - ptr += 32 * 8 / sizeof(long); 218 - #endif 219 - 220 - PACK64(ptr, regs->nip); 221 - PACK64(ptr, regs->msr); 222 - PACK32(ptr, regs->ccr); 223 - PACK64(ptr, regs->link); 224 - PACK64(ptr, regs->ctr); 225 - PACK32(ptr, regs->xer); 226 - 227 - BUG_ON((unsigned long)ptr > 228 - (unsigned long)(((void *)gdb_regs) + NUMREGBYTES)); 229 - } 230 - 231 197 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) 232 198 { 233 199 struct pt_regs *regs = (struct pt_regs *)(p->thread.ksp + ··· 237 271 (unsigned long)(((void *)gdb_regs) + NUMREGBYTES)); 238 272 } 239 273 240 - #define UNPACK64(dest, ptr) do { dest = *(ptr++); } while (0) 241 - 242 - #define UNPACK32(dest, ptr) do { \ 243 - u32 *ptr32; \ 244 - ptr32 = (u32 *)ptr; \ 245 - dest = *(ptr32++); \ 246 - ptr = (unsigned long *)ptr32; \ 247 - } while (0) 248 - 249 - void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) 250 - { 251 - unsigned long *ptr = gdb_regs; 252 - int reg; 253 - 254 - for (reg = 0; reg < 32; reg++) 255 - UNPACK64(regs->gpr[reg], ptr); 274 + #define GDB_SIZEOF_REG sizeof(unsigned long) 275 + #define GDB_SIZEOF_REG_U32 sizeof(u32) 256 276 257 277 #ifdef CONFIG_FSL_BOOKE 258 - #ifdef CONFIG_SPE 259 - for (reg = 0; reg < 32; reg++) 260 - UNPACK64(current->thread.evr[reg], ptr); 278 + #define GDB_SIZEOF_FLOAT_REG sizeof(unsigned long) 261 279 #else 262 - ptr += 32; 263 - #endif 264 - #else 265 - /* fp registers not used by kernel, leave zero */ 266 - ptr += 32 * 8 / sizeof(int); 280 + #define GDB_SIZEOF_FLOAT_REG sizeof(u64) 267 281 #endif 268 282 269 - UNPACK64(regs->nip, ptr); 270 - UNPACK64(regs->msr, ptr); 271 - UNPACK32(regs->ccr, ptr); 272 - UNPACK64(regs->link, ptr); 273 - UNPACK64(regs->ctr, ptr); 274 - UNPACK32(regs->xer, ptr); 283 + struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = 284 + { 285 + { "r0", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[0]) }, 286 + { "r1", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[1]) }, 287 + { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[2]) }, 288 + { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[3]) }, 289 + { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[4]) }, 290 + { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[5]) }, 291 + { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[6]) }, 292 + { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[7]) }, 293 + { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[8]) }, 294 + { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[9]) }, 295 + { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[10]) }, 296 + { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[11]) }, 297 + { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[12]) }, 298 + { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[13]) }, 299 + { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[14]) }, 300 + { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[15]) }, 301 + { "r16", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[16]) }, 302 + { "r17", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[17]) }, 303 + { "r18", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[18]) }, 304 + { "r19", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[19]) }, 305 + { "r20", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[20]) }, 306 + { "r21", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[21]) }, 307 + { "r22", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[22]) }, 308 + { "r23", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[23]) }, 309 + { "r24", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[24]) }, 310 + { "r25", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[25]) }, 311 + { "r26", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[26]) }, 312 + { "r27", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[27]) }, 313 + { "r28", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[28]) }, 314 + { "r29", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[29]) }, 315 + { "r30", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[30]) }, 316 + { "r31", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[31]) }, 275 317 276 - BUG_ON((unsigned long)ptr > 277 - (unsigned long)(((void *)gdb_regs) + NUMREGBYTES)); 318 + { "f0", GDB_SIZEOF_FLOAT_REG, 0 }, 319 + { "f1", GDB_SIZEOF_FLOAT_REG, 1 }, 320 + { "f2", GDB_SIZEOF_FLOAT_REG, 2 }, 321 + { "f3", GDB_SIZEOF_FLOAT_REG, 3 }, 322 + { "f4", GDB_SIZEOF_FLOAT_REG, 4 }, 323 + { "f5", GDB_SIZEOF_FLOAT_REG, 5 }, 324 + { "f6", GDB_SIZEOF_FLOAT_REG, 6 }, 325 + { "f7", GDB_SIZEOF_FLOAT_REG, 7 }, 326 + { "f8", GDB_SIZEOF_FLOAT_REG, 8 }, 327 + { "f9", GDB_SIZEOF_FLOAT_REG, 9 }, 328 + { "f10", GDB_SIZEOF_FLOAT_REG, 10 }, 329 + { "f11", GDB_SIZEOF_FLOAT_REG, 11 }, 330 + { "f12", GDB_SIZEOF_FLOAT_REG, 12 }, 331 + { "f13", GDB_SIZEOF_FLOAT_REG, 13 }, 332 + { "f14", GDB_SIZEOF_FLOAT_REG, 14 }, 333 + { "f15", GDB_SIZEOF_FLOAT_REG, 15 }, 334 + { "f16", GDB_SIZEOF_FLOAT_REG, 16 }, 335 + { "f17", GDB_SIZEOF_FLOAT_REG, 17 }, 336 + { "f18", GDB_SIZEOF_FLOAT_REG, 18 }, 337 + { "f19", GDB_SIZEOF_FLOAT_REG, 19 }, 338 + { "f20", GDB_SIZEOF_FLOAT_REG, 20 }, 339 + { "f21", GDB_SIZEOF_FLOAT_REG, 21 }, 340 + { "f22", GDB_SIZEOF_FLOAT_REG, 22 }, 341 + { "f23", GDB_SIZEOF_FLOAT_REG, 23 }, 342 + { "f24", GDB_SIZEOF_FLOAT_REG, 24 }, 343 + { "f25", GDB_SIZEOF_FLOAT_REG, 25 }, 344 + { "f26", GDB_SIZEOF_FLOAT_REG, 26 }, 345 + { "f27", GDB_SIZEOF_FLOAT_REG, 27 }, 346 + { "f28", GDB_SIZEOF_FLOAT_REG, 28 }, 347 + { "f29", GDB_SIZEOF_FLOAT_REG, 29 }, 348 + { "f30", GDB_SIZEOF_FLOAT_REG, 30 }, 349 + { "f31", GDB_SIZEOF_FLOAT_REG, 31 }, 350 + 351 + { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, nip) }, 352 + { "msr", GDB_SIZEOF_REG, offsetof(struct pt_regs, msr) }, 353 + { "cr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ccr) }, 354 + { "lr", GDB_SIZEOF_REG, offsetof(struct pt_regs, link) }, 355 + { "ctr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ctr) }, 356 + { "xer", GDB_SIZEOF_REG, offsetof(struct pt_regs, xer) }, 357 + }; 358 + 359 + char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) 360 + { 361 + if (regno >= DBG_MAX_REG_NUM || regno < 0) 362 + return NULL; 363 + 364 + if (regno < 32 || regno >= 64) 365 + /* First 0 -> 31 gpr registers*/ 366 + /* pc, msr, ls... registers 64 -> 69 */ 367 + memcpy(mem, (void *)regs + dbg_reg_def[regno].offset, 368 + dbg_reg_def[regno].size); 369 + 370 + if (regno >= 32 && regno < 64) { 371 + /* FP registers 32 -> 63 */ 372 + #if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE) 373 + if (current) 374 + memcpy(mem, current->thread.evr[regno-32], 375 + dbg_reg_def[regno].size); 376 + #else 377 + /* fp registers not used by kernel, leave zero */ 378 + memset(mem, 0, dbg_reg_def[regno].size); 379 + #endif 380 + } 381 + 382 + return dbg_reg_def[regno].name; 383 + } 384 + 385 + int dbg_set_reg(int regno, void *mem, struct pt_regs *regs) 386 + { 387 + if (regno >= DBG_MAX_REG_NUM || regno < 0) 388 + return -EINVAL; 389 + 390 + if (regno < 32 || regno >= 64) 391 + /* First 0 -> 31 gpr registers*/ 392 + /* pc, msr, ls... registers 64 -> 69 */ 393 + memcpy((void *)regs + dbg_reg_def[regno].offset, mem, 394 + dbg_reg_def[regno].size); 395 + 396 + if (regno >= 32 && regno < 64) { 397 + /* FP registers 32 -> 63 */ 398 + #if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE) 399 + memcpy(current->thread.evr[regno-32], mem, 400 + dbg_reg_def[regno].size); 401 + #else 402 + /* fp registers not used by kernel, leave zero */ 403 + return 0; 404 + #endif 405 + } 406 + 407 + return 0; 278 408 } 279 409 280 410 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+2 -1
arch/x86/kernel/kgdb.c
··· 387 387 * disable hardware debugging while it is processing gdb packets or 388 388 * handling exception. 389 389 */ 390 - void kgdb_disable_hw_debug(struct pt_regs *regs) 390 + static void kgdb_disable_hw_debug(struct pt_regs *regs) 391 391 { 392 392 int i; 393 393 int cpu = raw_smp_processor_id(); ··· 724 724 .flags = KGDB_HW_BREAKPOINT, 725 725 .set_hw_breakpoint = kgdb_set_hw_break, 726 726 .remove_hw_breakpoint = kgdb_remove_hw_break, 727 + .disable_hw_break = kgdb_disable_hw_debug, 727 728 .remove_all_hw_break = kgdb_remove_all_hw_break, 728 729 .correct_hw_break = kgdb_correct_hw_break, 729 730 };
+2 -14
drivers/misc/kgdbts.c
··· 1044 1044 return configure_kgdbts(); 1045 1045 } 1046 1046 1047 - static void cleanup_kgdbts(void) 1048 - { 1049 - if (configured == 1) 1050 - kgdb_unregister_io_module(&kgdbts_io_ops); 1051 - } 1052 - 1053 1047 static int kgdbts_get_char(void) 1054 1048 { 1055 1049 int val = 0; ··· 1075 1081 return 0; 1076 1082 } 1077 1083 1078 - if (kgdb_connected) { 1079 - printk(KERN_ERR 1080 - "kgdbts: Cannot reconfigure while KGDB is connected.\n"); 1081 - 1084 + if (configured == 1) { 1085 + printk(KERN_ERR "kgdbts: ERROR: Already configured and running.\n"); 1082 1086 return -EBUSY; 1083 1087 } 1084 1088 ··· 1084 1092 /* Chop out \n char as a result of echo */ 1085 1093 if (config[len - 1] == '\n') 1086 1094 config[len - 1] = '\0'; 1087 - 1088 - if (configured == 1) 1089 - cleanup_kgdbts(); 1090 1095 1091 1096 /* Go and configure with the new params. */ 1092 1097 return configure_kgdbts(); ··· 1112 1123 }; 1113 1124 1114 1125 module_init(init_kgdbts); 1115 - module_exit(cleanup_kgdbts); 1116 1126 module_param_call(kgdbts, param_set_kgdbts_var, param_get_string, &kps, 0644); 1117 1127 MODULE_PARM_DESC(kgdbts, "<A|V1|V2>[F#|S#][N#]"); 1118 1128 MODULE_DESCRIPTION("KGDB Test Suite");
+3 -10
include/linux/kgdb.h
··· 35 35 */ 36 36 extern int kgdb_skipexception(int exception, struct pt_regs *regs); 37 37 38 - /** 39 - * kgdb_disable_hw_debug - (optional) Disable hardware debugging hook 40 - * @regs: Current &struct pt_regs. 41 - * 42 - * This function will be called if the particular architecture must 43 - * disable hardware debugging while it is processing gdb packets or 44 - * handling exception. 45 - */ 46 - extern void kgdb_disable_hw_debug(struct pt_regs *regs); 47 - 48 38 struct tasklet_struct; 49 39 struct task_struct; 50 40 struct uart_port; ··· 233 243 * breakpoint. 234 244 * @remove_hw_breakpoint: Allow an architecture to specify how to remove a 235 245 * hardware breakpoint. 246 + * @disable_hw_break: Allow an architecture to specify how to disable 247 + * hardware breakpoints for a single cpu. 236 248 * @remove_all_hw_break: Allow an architecture to specify how to remove all 237 249 * hardware breakpoints. 238 250 * @correct_hw_break: Allow an architecture to specify how to correct the ··· 248 256 int (*remove_breakpoint)(unsigned long, char *); 249 257 int (*set_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); 250 258 int (*remove_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); 259 + void (*disable_hw_break)(struct pt_regs *regs); 251 260 void (*remove_all_hw_break)(void); 252 261 void (*correct_hw_break)(void); 253 262 };
+3 -13
kernel/debug/debug_core.c
··· 209 209 return 0; 210 210 } 211 211 212 - /** 213 - * kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb. 214 - * @regs: Current &struct pt_regs. 215 - * 216 - * This function will be called if the particular architecture must 217 - * disable hardware debugging while it is processing gdb packets or 218 - * handling exception. 219 - */ 220 - void __weak kgdb_disable_hw_debug(struct pt_regs *regs) 221 - { 222 - } 223 - 224 212 /* 225 213 * Some architectures need cache flushes when we set/clear a 226 214 * breakpoint: ··· 472 484 atomic_inc(&masters_in_kgdb); 473 485 else 474 486 atomic_inc(&slaves_in_kgdb); 475 - kgdb_disable_hw_debug(ks->linux_regs); 487 + 488 + if (arch_kgdb_ops.disable_hw_break) 489 + arch_kgdb_ops.disable_hw_break(regs); 476 490 477 491 acquirelock: 478 492 /*
+12 -36
kernel/debug/kdb/kdb_main.c
··· 1127 1127 /* special case below */ 1128 1128 } else { 1129 1129 kdb_printf("\nEntering kdb (current=0x%p, pid %d) ", 1130 - kdb_current, kdb_current->pid); 1130 + kdb_current, kdb_current ? kdb_current->pid : 0); 1131 1131 #if defined(CONFIG_SMP) 1132 1132 kdb_printf("on processor %d ", raw_smp_processor_id()); 1133 1133 #endif ··· 2603 2603 */ 2604 2604 static int kdb_per_cpu(int argc, const char **argv) 2605 2605 { 2606 - char buf[256], fmtstr[64]; 2607 - kdb_symtab_t symtab; 2608 - cpumask_t suppress = CPU_MASK_NONE; 2609 - int cpu, diag; 2610 - unsigned long addr, val, bytesperword = 0, whichcpu = ~0UL; 2606 + char fmtstr[64]; 2607 + int cpu, diag, nextarg = 1; 2608 + unsigned long addr, symaddr, val, bytesperword = 0, whichcpu = ~0UL; 2611 2609 2612 2610 if (argc < 1 || argc > 3) 2613 2611 return KDB_ARGCOUNT; 2614 2612 2615 - snprintf(buf, sizeof(buf), "per_cpu__%s", argv[1]); 2616 - if (!kdbgetsymval(buf, &symtab)) { 2617 - kdb_printf("%s is not a per_cpu variable\n", argv[1]); 2618 - return KDB_BADADDR; 2619 - } 2613 + diag = kdbgetaddrarg(argc, argv, &nextarg, &symaddr, NULL, NULL); 2614 + if (diag) 2615 + return diag; 2616 + 2620 2617 if (argc >= 2) { 2621 2618 diag = kdbgetularg(argv[2], &bytesperword); 2622 2619 if (diag) ··· 2646 2649 #define KDB_PCU(cpu) 0 2647 2650 #endif 2648 2651 #endif 2649 - 2650 2652 for_each_online_cpu(cpu) { 2653 + if (KDB_FLAG(CMD_INTERRUPT)) 2654 + return 0; 2655 + 2651 2656 if (whichcpu != ~0UL && whichcpu != cpu) 2652 2657 continue; 2653 - addr = symtab.sym_start + KDB_PCU(cpu); 2658 + addr = symaddr + KDB_PCU(cpu); 2654 2659 diag = kdb_getword(&val, addr, bytesperword); 2655 2660 if (diag) { 2656 2661 kdb_printf("%5d " kdb_bfd_vma_fmt0 " - unable to " 2657 2662 "read, diag=%d\n", cpu, addr, diag); 2658 2663 continue; 2659 2664 } 2660 - #ifdef CONFIG_SMP 2661 - if (!val) { 2662 - cpu_set(cpu, suppress); 2663 - continue; 2664 - } 2665 - #endif /* CONFIG_SMP */ 2666 2665 kdb_printf("%5d ", cpu); 2667 2666 kdb_md_line(fmtstr, addr, 2668 2667 bytesperword == KDB_WORD_SIZE, 2669 2668 1, bytesperword, 1, 1, 0); 2670 2669 } 2671 - if (cpus_weight(suppress) == 0) 2672 - return 0; 2673 - kdb_printf("Zero suppressed cpu(s):"); 2674 - for (cpu = first_cpu(suppress); cpu < num_possible_cpus(); 2675 - cpu = next_cpu(cpu, suppress)) { 2676 - kdb_printf(" %d", cpu); 2677 - if (cpu == num_possible_cpus() - 1 || 2678 - next_cpu(cpu, suppress) != cpu + 1) 2679 - continue; 2680 - while (cpu < num_possible_cpus() && 2681 - next_cpu(cpu, suppress) == cpu + 1) 2682 - ++cpu; 2683 - kdb_printf("-%d", cpu); 2684 - } 2685 - kdb_printf("\n"); 2686 - 2687 2670 #undef KDB_PCU 2688 - 2689 2671 return 0; 2690 2672 } 2691 2673
+7
samples/Kconfig
··· 54 54 55 55 If in doubt, say "N" here. 56 56 57 + config SAMPLE_KDB 58 + tristate "Build kdb command exmaple -- loadable modules only" 59 + depends on KGDB_KDB && m 60 + help 61 + Build an example of how to dynamically add the hello 62 + command to the kdb shell. 63 + 57 64 endif # SAMPLES
+1 -1
samples/Makefile
··· 1 1 # Makefile for Linux samples code 2 2 3 3 obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ 4 - hw_breakpoint/ kfifo/ 4 + hw_breakpoint/ kfifo/ kdb/
+1
samples/kdb/Makefile
··· 1 + obj-$(CONFIG_SAMPLE_KDB) += kdb_hello.o
+60
samples/kdb/kdb_hello.c
··· 1 + /* 2 + * Created by: Jason Wessel <jason.wessel@windriver.com> 3 + * 4 + * Copyright (c) 2010 Wind River Systems, Inc. All Rights Reserved. 5 + * 6 + * This file is licensed under the terms of the GNU General Public 7 + * License version 2. This program is licensed "as is" without any 8 + * warranty of any kind, whether express or implied. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/kdb.h> 13 + 14 + /* 15 + * All kdb shell command call backs receive argc and argv, where 16 + * argv[0] is the command the end user typed 17 + */ 18 + static int kdb_hello_cmd(int argc, const char **argv) 19 + { 20 + if (argc > 1) 21 + return KDB_ARGCOUNT; 22 + 23 + if (argc) 24 + kdb_printf("Hello %s.\n", argv[1]); 25 + else 26 + kdb_printf("Hello world!\n"); 27 + 28 + return 0; 29 + } 30 + 31 + 32 + static int __init kdb_hello_cmd_init(void) 33 + { 34 + /* 35 + * Registration of a dynamically added kdb command is done with 36 + * kdb_register() with the arguments being: 37 + * 1: The name of the shell command 38 + * 2: The function that processes the command 39 + * 3: Description of the usage of any arguments 40 + * 4: Descriptive text when you run help 41 + * 5: Number of characters to complete the command 42 + * 0 == type the whole command 43 + * 1 == match both "g" and "go" for example 44 + */ 45 + kdb_register("hello", kdb_hello_cmd, "[string]", 46 + "Say Hello World or Hello [string]", 0); 47 + return 0; 48 + } 49 + 50 + static void __exit kdb_hello_cmd_exit(void) 51 + { 52 + kdb_unregister("hello"); 53 + } 54 + 55 + module_init(kdb_hello_cmd_init); 56 + module_exit(kdb_hello_cmd_exit); 57 + 58 + MODULE_AUTHOR("WindRiver"); 59 + MODULE_DESCRIPTION("KDB example to add a hello command"); 60 + MODULE_LICENSE("GPL");