0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/bug.h>
0012 #include <linux/irq.h>
0013 #include <linux/kdebug.h>
0014 #include <linux/kgdb.h>
0015 #include <linux/kprobes.h>
0016 #include <linux/sched/task_stack.h>
0017
0018 #include <asm/debug-monitors.h>
0019 #include <asm/insn.h>
0020 #include <asm/patching.h>
0021 #include <asm/traps.h>
0022
0023 struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
0024 { "x0", 8, offsetof(struct pt_regs, regs[0])},
0025 { "x1", 8, offsetof(struct pt_regs, regs[1])},
0026 { "x2", 8, offsetof(struct pt_regs, regs[2])},
0027 { "x3", 8, offsetof(struct pt_regs, regs[3])},
0028 { "x4", 8, offsetof(struct pt_regs, regs[4])},
0029 { "x5", 8, offsetof(struct pt_regs, regs[5])},
0030 { "x6", 8, offsetof(struct pt_regs, regs[6])},
0031 { "x7", 8, offsetof(struct pt_regs, regs[7])},
0032 { "x8", 8, offsetof(struct pt_regs, regs[8])},
0033 { "x9", 8, offsetof(struct pt_regs, regs[9])},
0034 { "x10", 8, offsetof(struct pt_regs, regs[10])},
0035 { "x11", 8, offsetof(struct pt_regs, regs[11])},
0036 { "x12", 8, offsetof(struct pt_regs, regs[12])},
0037 { "x13", 8, offsetof(struct pt_regs, regs[13])},
0038 { "x14", 8, offsetof(struct pt_regs, regs[14])},
0039 { "x15", 8, offsetof(struct pt_regs, regs[15])},
0040 { "x16", 8, offsetof(struct pt_regs, regs[16])},
0041 { "x17", 8, offsetof(struct pt_regs, regs[17])},
0042 { "x18", 8, offsetof(struct pt_regs, regs[18])},
0043 { "x19", 8, offsetof(struct pt_regs, regs[19])},
0044 { "x20", 8, offsetof(struct pt_regs, regs[20])},
0045 { "x21", 8, offsetof(struct pt_regs, regs[21])},
0046 { "x22", 8, offsetof(struct pt_regs, regs[22])},
0047 { "x23", 8, offsetof(struct pt_regs, regs[23])},
0048 { "x24", 8, offsetof(struct pt_regs, regs[24])},
0049 { "x25", 8, offsetof(struct pt_regs, regs[25])},
0050 { "x26", 8, offsetof(struct pt_regs, regs[26])},
0051 { "x27", 8, offsetof(struct pt_regs, regs[27])},
0052 { "x28", 8, offsetof(struct pt_regs, regs[28])},
0053 { "x29", 8, offsetof(struct pt_regs, regs[29])},
0054 { "x30", 8, offsetof(struct pt_regs, regs[30])},
0055 { "sp", 8, offsetof(struct pt_regs, sp)},
0056 { "pc", 8, offsetof(struct pt_regs, pc)},
0057
0058
0059
0060
0061
0062
0063 { "pstate", 4, offsetof(struct pt_regs, pstate)
0064 #ifdef CONFIG_CPU_BIG_ENDIAN
0065 + 4
0066 #endif
0067 },
0068 { "v0", 16, -1 },
0069 { "v1", 16, -1 },
0070 { "v2", 16, -1 },
0071 { "v3", 16, -1 },
0072 { "v4", 16, -1 },
0073 { "v5", 16, -1 },
0074 { "v6", 16, -1 },
0075 { "v7", 16, -1 },
0076 { "v8", 16, -1 },
0077 { "v9", 16, -1 },
0078 { "v10", 16, -1 },
0079 { "v11", 16, -1 },
0080 { "v12", 16, -1 },
0081 { "v13", 16, -1 },
0082 { "v14", 16, -1 },
0083 { "v15", 16, -1 },
0084 { "v16", 16, -1 },
0085 { "v17", 16, -1 },
0086 { "v18", 16, -1 },
0087 { "v19", 16, -1 },
0088 { "v20", 16, -1 },
0089 { "v21", 16, -1 },
0090 { "v22", 16, -1 },
0091 { "v23", 16, -1 },
0092 { "v24", 16, -1 },
0093 { "v25", 16, -1 },
0094 { "v26", 16, -1 },
0095 { "v27", 16, -1 },
0096 { "v28", 16, -1 },
0097 { "v29", 16, -1 },
0098 { "v30", 16, -1 },
0099 { "v31", 16, -1 },
0100 { "fpsr", 4, -1 },
0101 { "fpcr", 4, -1 },
0102 };
0103
0104 char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
0105 {
0106 if (regno >= DBG_MAX_REG_NUM || regno < 0)
0107 return NULL;
0108
0109 if (dbg_reg_def[regno].offset != -1)
0110 memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
0111 dbg_reg_def[regno].size);
0112 else
0113 memset(mem, 0, dbg_reg_def[regno].size);
0114 return dbg_reg_def[regno].name;
0115 }
0116
0117 int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
0118 {
0119 if (regno >= DBG_MAX_REG_NUM || regno < 0)
0120 return -EINVAL;
0121
0122 if (dbg_reg_def[regno].offset != -1)
0123 memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
0124 dbg_reg_def[regno].size);
0125 return 0;
0126 }
0127
0128 void
0129 sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
0130 {
0131 struct cpu_context *cpu_context = &task->thread.cpu_context;
0132
0133
0134 memset((char *)gdb_regs, 0, NUMREGBYTES);
0135
0136 gdb_regs[19] = cpu_context->x19;
0137 gdb_regs[20] = cpu_context->x20;
0138 gdb_regs[21] = cpu_context->x21;
0139 gdb_regs[22] = cpu_context->x22;
0140 gdb_regs[23] = cpu_context->x23;
0141 gdb_regs[24] = cpu_context->x24;
0142 gdb_regs[25] = cpu_context->x25;
0143 gdb_regs[26] = cpu_context->x26;
0144 gdb_regs[27] = cpu_context->x27;
0145 gdb_regs[28] = cpu_context->x28;
0146 gdb_regs[29] = cpu_context->fp;
0147
0148 gdb_regs[31] = cpu_context->sp;
0149 gdb_regs[32] = cpu_context->pc;
0150 }
0151
0152 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
0153 {
0154 regs->pc = pc;
0155 }
0156
0157 static int compiled_break;
0158
0159 static void kgdb_arch_update_addr(struct pt_regs *regs,
0160 char *remcom_in_buffer)
0161 {
0162 unsigned long addr;
0163 char *ptr;
0164
0165 ptr = &remcom_in_buffer[1];
0166 if (kgdb_hex2long(&ptr, &addr))
0167 kgdb_arch_set_pc(regs, addr);
0168 else if (compiled_break == 1)
0169 kgdb_arch_set_pc(regs, regs->pc + 4);
0170
0171 compiled_break = 0;
0172 }
0173
0174 int kgdb_arch_handle_exception(int exception_vector, int signo,
0175 int err_code, char *remcom_in_buffer,
0176 char *remcom_out_buffer,
0177 struct pt_regs *linux_regs)
0178 {
0179 int err;
0180
0181 switch (remcom_in_buffer[0]) {
0182 case 'D':
0183 case 'k':
0184
0185
0186
0187
0188 case 'c':
0189
0190
0191
0192
0193
0194
0195
0196
0197 kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
0198 atomic_set(&kgdb_cpu_doing_single_step, -1);
0199 kgdb_single_step = 0;
0200
0201
0202
0203
0204 if (kernel_active_single_step())
0205 kernel_disable_single_step();
0206
0207 err = 0;
0208 break;
0209 case 's':
0210
0211
0212
0213
0214
0215
0216
0217
0218 kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
0219 atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id());
0220 kgdb_single_step = 1;
0221
0222
0223
0224
0225 if (!kernel_active_single_step())
0226 kernel_enable_single_step(linux_regs);
0227 err = 0;
0228 break;
0229 default:
0230 err = -1;
0231 }
0232 return err;
0233 }
0234
0235 static int kgdb_brk_fn(struct pt_regs *regs, unsigned long esr)
0236 {
0237 kgdb_handle_exception(1, SIGTRAP, 0, regs);
0238 return DBG_HOOK_HANDLED;
0239 }
0240 NOKPROBE_SYMBOL(kgdb_brk_fn)
0241
0242 static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned long esr)
0243 {
0244 compiled_break = 1;
0245 kgdb_handle_exception(1, SIGTRAP, 0, regs);
0246
0247 return DBG_HOOK_HANDLED;
0248 }
0249 NOKPROBE_SYMBOL(kgdb_compiled_brk_fn);
0250
0251 static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned long esr)
0252 {
0253 if (!kgdb_single_step)
0254 return DBG_HOOK_ERROR;
0255
0256 kgdb_handle_exception(0, SIGTRAP, 0, regs);
0257 return DBG_HOOK_HANDLED;
0258 }
0259 NOKPROBE_SYMBOL(kgdb_step_brk_fn);
0260
0261 static struct break_hook kgdb_brkpt_hook = {
0262 .fn = kgdb_brk_fn,
0263 .imm = KGDB_DYN_DBG_BRK_IMM,
0264 };
0265
0266 static struct break_hook kgdb_compiled_brkpt_hook = {
0267 .fn = kgdb_compiled_brk_fn,
0268 .imm = KGDB_COMPILED_DBG_BRK_IMM,
0269 };
0270
0271 static struct step_hook kgdb_step_hook = {
0272 .fn = kgdb_step_brk_fn
0273 };
0274
0275 static int __kgdb_notify(struct die_args *args, unsigned long cmd)
0276 {
0277 struct pt_regs *regs = args->regs;
0278
0279 if (kgdb_handle_exception(1, args->signr, cmd, regs))
0280 return NOTIFY_DONE;
0281 return NOTIFY_STOP;
0282 }
0283
0284 static int
0285 kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
0286 {
0287 unsigned long flags;
0288 int ret;
0289
0290 local_irq_save(flags);
0291 ret = __kgdb_notify(ptr, cmd);
0292 local_irq_restore(flags);
0293
0294 return ret;
0295 }
0296
0297 static struct notifier_block kgdb_notifier = {
0298 .notifier_call = kgdb_notify,
0299
0300
0301
0302 .priority = -INT_MAX,
0303 };
0304
0305
0306
0307
0308
0309
0310 int kgdb_arch_init(void)
0311 {
0312 int ret = register_die_notifier(&kgdb_notifier);
0313
0314 if (ret != 0)
0315 return ret;
0316
0317 register_kernel_break_hook(&kgdb_brkpt_hook);
0318 register_kernel_break_hook(&kgdb_compiled_brkpt_hook);
0319 register_kernel_step_hook(&kgdb_step_hook);
0320 return 0;
0321 }
0322
0323
0324
0325
0326
0327
0328 void kgdb_arch_exit(void)
0329 {
0330 unregister_kernel_break_hook(&kgdb_brkpt_hook);
0331 unregister_kernel_break_hook(&kgdb_compiled_brkpt_hook);
0332 unregister_kernel_step_hook(&kgdb_step_hook);
0333 unregister_die_notifier(&kgdb_notifier);
0334 }
0335
0336 const struct kgdb_arch arch_kgdb_ops;
0337
0338 int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
0339 {
0340 int err;
0341
0342 BUILD_BUG_ON(AARCH64_INSN_SIZE != BREAK_INSTR_SIZE);
0343
0344 err = aarch64_insn_read((void *)bpt->bpt_addr, (u32 *)bpt->saved_instr);
0345 if (err)
0346 return err;
0347
0348 return aarch64_insn_write((void *)bpt->bpt_addr,
0349 (u32)AARCH64_BREAK_KGDB_DYN_DBG);
0350 }
0351
0352 int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
0353 {
0354 return aarch64_insn_write((void *)bpt->bpt_addr,
0355 *(u32 *)bpt->saved_instr);
0356 }