Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * AArch64 KGDB support
0004  *
0005  * Based on arch/arm/kernel/kgdb.c
0006  *
0007  * Copyright (C) 2013 Cavium Inc.
0008  * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>
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      * struct pt_regs thinks PSTATE is 64-bits wide but gdb remote
0059      * protocol disagrees. Therefore we must extract only the lower
0060      * 32-bits. Look for the big comment in asm/kgdb.h for more
0061      * detail.
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     /* Initialize to zero */
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          * Packet D (Detach), k (kill). No special handling
0186          * is required here. Handle same as c packet.
0187          */
0188     case 'c':
0189         /*
0190          * Packet c (Continue) to continue executing.
0191          * Set pc to required address.
0192          * Try to read optional parameter and set pc.
0193          * If this was a compiled breakpoint, we need to move
0194          * to the next instruction else we will just breakpoint
0195          * over and over again.
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          * Received continue command, disable single step
0203          */
0204         if (kernel_active_single_step())
0205             kernel_disable_single_step();
0206 
0207         err = 0;
0208         break;
0209     case 's':
0210         /*
0211          * Update step address value with address passed
0212          * with step packet.
0213          * On debug exception return PC is copied to ELR
0214          * So just update PC.
0215          * If no step address is passed, resume from the address
0216          * pointed by PC. Do not update PC
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          * Enable single step handling
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      * Want to be lowest priority
0301      */
0302     .priority   = -INT_MAX,
0303 };
0304 
0305 /*
0306  * kgdb_arch_init - Perform any architecture specific initialization.
0307  * This function will handle the initialization of any architecture
0308  * specific callbacks.
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  * kgdb_arch_exit - Perform any architecture specific uninitalization.
0325  * This function will handle the uninitalization of any architecture
0326  * specific callbacks, for dynamic registration and unregistration.
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 }