Merge tag 'for-5.14-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[linux-2.6-microblaze.git] / arch / arm64 / kernel / kgdb.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * AArch64 KGDB support
4  *
5  * Based on arch/arm/kernel/kgdb.c
6  *
7  * Copyright (C) 2013 Cavium Inc.
8  * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>
9  */
10
11 #include <linux/bug.h>
12 #include <linux/irq.h>
13 #include <linux/kdebug.h>
14 #include <linux/kgdb.h>
15 #include <linux/kprobes.h>
16 #include <linux/sched/task_stack.h>
17
18 #include <asm/debug-monitors.h>
19 #include <asm/insn.h>
20 #include <asm/patching.h>
21 #include <asm/traps.h>
22
23 struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
24         { "x0", 8, offsetof(struct pt_regs, regs[0])},
25         { "x1", 8, offsetof(struct pt_regs, regs[1])},
26         { "x2", 8, offsetof(struct pt_regs, regs[2])},
27         { "x3", 8, offsetof(struct pt_regs, regs[3])},
28         { "x4", 8, offsetof(struct pt_regs, regs[4])},
29         { "x5", 8, offsetof(struct pt_regs, regs[5])},
30         { "x6", 8, offsetof(struct pt_regs, regs[6])},
31         { "x7", 8, offsetof(struct pt_regs, regs[7])},
32         { "x8", 8, offsetof(struct pt_regs, regs[8])},
33         { "x9", 8, offsetof(struct pt_regs, regs[9])},
34         { "x10", 8, offsetof(struct pt_regs, regs[10])},
35         { "x11", 8, offsetof(struct pt_regs, regs[11])},
36         { "x12", 8, offsetof(struct pt_regs, regs[12])},
37         { "x13", 8, offsetof(struct pt_regs, regs[13])},
38         { "x14", 8, offsetof(struct pt_regs, regs[14])},
39         { "x15", 8, offsetof(struct pt_regs, regs[15])},
40         { "x16", 8, offsetof(struct pt_regs, regs[16])},
41         { "x17", 8, offsetof(struct pt_regs, regs[17])},
42         { "x18", 8, offsetof(struct pt_regs, regs[18])},
43         { "x19", 8, offsetof(struct pt_regs, regs[19])},
44         { "x20", 8, offsetof(struct pt_regs, regs[20])},
45         { "x21", 8, offsetof(struct pt_regs, regs[21])},
46         { "x22", 8, offsetof(struct pt_regs, regs[22])},
47         { "x23", 8, offsetof(struct pt_regs, regs[23])},
48         { "x24", 8, offsetof(struct pt_regs, regs[24])},
49         { "x25", 8, offsetof(struct pt_regs, regs[25])},
50         { "x26", 8, offsetof(struct pt_regs, regs[26])},
51         { "x27", 8, offsetof(struct pt_regs, regs[27])},
52         { "x28", 8, offsetof(struct pt_regs, regs[28])},
53         { "x29", 8, offsetof(struct pt_regs, regs[29])},
54         { "x30", 8, offsetof(struct pt_regs, regs[30])},
55         { "sp", 8, offsetof(struct pt_regs, sp)},
56         { "pc", 8, offsetof(struct pt_regs, pc)},
57         /*
58          * struct pt_regs thinks PSTATE is 64-bits wide but gdb remote
59          * protocol disagrees. Therefore we must extract only the lower
60          * 32-bits. Look for the big comment in asm/kgdb.h for more
61          * detail.
62          */
63         { "pstate", 4, offsetof(struct pt_regs, pstate)
64 #ifdef CONFIG_CPU_BIG_ENDIAN
65                                                         + 4
66 #endif
67         },
68         { "v0", 16, -1 },
69         { "v1", 16, -1 },
70         { "v2", 16, -1 },
71         { "v3", 16, -1 },
72         { "v4", 16, -1 },
73         { "v5", 16, -1 },
74         { "v6", 16, -1 },
75         { "v7", 16, -1 },
76         { "v8", 16, -1 },
77         { "v9", 16, -1 },
78         { "v10", 16, -1 },
79         { "v11", 16, -1 },
80         { "v12", 16, -1 },
81         { "v13", 16, -1 },
82         { "v14", 16, -1 },
83         { "v15", 16, -1 },
84         { "v16", 16, -1 },
85         { "v17", 16, -1 },
86         { "v18", 16, -1 },
87         { "v19", 16, -1 },
88         { "v20", 16, -1 },
89         { "v21", 16, -1 },
90         { "v22", 16, -1 },
91         { "v23", 16, -1 },
92         { "v24", 16, -1 },
93         { "v25", 16, -1 },
94         { "v26", 16, -1 },
95         { "v27", 16, -1 },
96         { "v28", 16, -1 },
97         { "v29", 16, -1 },
98         { "v30", 16, -1 },
99         { "v31", 16, -1 },
100         { "fpsr", 4, -1 },
101         { "fpcr", 4, -1 },
102 };
103
104 char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
105 {
106         if (regno >= DBG_MAX_REG_NUM || regno < 0)
107                 return NULL;
108
109         if (dbg_reg_def[regno].offset != -1)
110                 memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
111                        dbg_reg_def[regno].size);
112         else
113                 memset(mem, 0, dbg_reg_def[regno].size);
114         return dbg_reg_def[regno].name;
115 }
116
117 int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
118 {
119         if (regno >= DBG_MAX_REG_NUM || regno < 0)
120                 return -EINVAL;
121
122         if (dbg_reg_def[regno].offset != -1)
123                 memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
124                        dbg_reg_def[regno].size);
125         return 0;
126 }
127
128 void
129 sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
130 {
131         struct cpu_context *cpu_context = &task->thread.cpu_context;
132
133         /* Initialize to zero */
134         memset((char *)gdb_regs, 0, NUMREGBYTES);
135
136         gdb_regs[19] = cpu_context->x19;
137         gdb_regs[20] = cpu_context->x20;
138         gdb_regs[21] = cpu_context->x21;
139         gdb_regs[22] = cpu_context->x22;
140         gdb_regs[23] = cpu_context->x23;
141         gdb_regs[24] = cpu_context->x24;
142         gdb_regs[25] = cpu_context->x25;
143         gdb_regs[26] = cpu_context->x26;
144         gdb_regs[27] = cpu_context->x27;
145         gdb_regs[28] = cpu_context->x28;
146         gdb_regs[29] = cpu_context->fp;
147
148         gdb_regs[31] = cpu_context->sp;
149         gdb_regs[32] = cpu_context->pc;
150 }
151
152 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
153 {
154         regs->pc = pc;
155 }
156
157 static int compiled_break;
158
159 static void kgdb_arch_update_addr(struct pt_regs *regs,
160                                 char *remcom_in_buffer)
161 {
162         unsigned long addr;
163         char *ptr;
164
165         ptr = &remcom_in_buffer[1];
166         if (kgdb_hex2long(&ptr, &addr))
167                 kgdb_arch_set_pc(regs, addr);
168         else if (compiled_break == 1)
169                 kgdb_arch_set_pc(regs, regs->pc + 4);
170
171         compiled_break = 0;
172 }
173
174 int kgdb_arch_handle_exception(int exception_vector, int signo,
175                                int err_code, char *remcom_in_buffer,
176                                char *remcom_out_buffer,
177                                struct pt_regs *linux_regs)
178 {
179         int err;
180
181         switch (remcom_in_buffer[0]) {
182         case 'D':
183         case 'k':
184                 /*
185                  * Packet D (Detach), k (kill). No special handling
186                  * is required here. Handle same as c packet.
187                  */
188         case 'c':
189                 /*
190                  * Packet c (Continue) to continue executing.
191                  * Set pc to required address.
192                  * Try to read optional parameter and set pc.
193                  * If this was a compiled breakpoint, we need to move
194                  * to the next instruction else we will just breakpoint
195                  * over and over again.
196                  */
197                 kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
198                 atomic_set(&kgdb_cpu_doing_single_step, -1);
199                 kgdb_single_step =  0;
200
201                 /*
202                  * Received continue command, disable single step
203                  */
204                 if (kernel_active_single_step())
205                         kernel_disable_single_step();
206
207                 err = 0;
208                 break;
209         case 's':
210                 /*
211                  * Update step address value with address passed
212                  * with step packet.
213                  * On debug exception return PC is copied to ELR
214                  * So just update PC.
215                  * If no step address is passed, resume from the address
216                  * pointed by PC. Do not update PC
217                  */
218                 kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
219                 atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id());
220                 kgdb_single_step =  1;
221
222                 /*
223                  * Enable single step handling
224                  */
225                 if (!kernel_active_single_step())
226                         kernel_enable_single_step(linux_regs);
227                 err = 0;
228                 break;
229         default:
230                 err = -1;
231         }
232         return err;
233 }
234
235 static int kgdb_brk_fn(struct pt_regs *regs, unsigned int esr)
236 {
237         kgdb_handle_exception(1, SIGTRAP, 0, regs);
238         return DBG_HOOK_HANDLED;
239 }
240 NOKPROBE_SYMBOL(kgdb_brk_fn)
241
242 static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
243 {
244         compiled_break = 1;
245         kgdb_handle_exception(1, SIGTRAP, 0, regs);
246
247         return DBG_HOOK_HANDLED;
248 }
249 NOKPROBE_SYMBOL(kgdb_compiled_brk_fn);
250
251 static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
252 {
253         if (!kgdb_single_step)
254                 return DBG_HOOK_ERROR;
255
256         kgdb_handle_exception(0, SIGTRAP, 0, regs);
257         return DBG_HOOK_HANDLED;
258 }
259 NOKPROBE_SYMBOL(kgdb_step_brk_fn);
260
261 static struct break_hook kgdb_brkpt_hook = {
262         .fn             = kgdb_brk_fn,
263         .imm            = KGDB_DYN_DBG_BRK_IMM,
264 };
265
266 static struct break_hook kgdb_compiled_brkpt_hook = {
267         .fn             = kgdb_compiled_brk_fn,
268         .imm            = KGDB_COMPILED_DBG_BRK_IMM,
269 };
270
271 static struct step_hook kgdb_step_hook = {
272         .fn             = kgdb_step_brk_fn
273 };
274
275 static int __kgdb_notify(struct die_args *args, unsigned long cmd)
276 {
277         struct pt_regs *regs = args->regs;
278
279         if (kgdb_handle_exception(1, args->signr, cmd, regs))
280                 return NOTIFY_DONE;
281         return NOTIFY_STOP;
282 }
283
284 static int
285 kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
286 {
287         unsigned long flags;
288         int ret;
289
290         local_irq_save(flags);
291         ret = __kgdb_notify(ptr, cmd);
292         local_irq_restore(flags);
293
294         return ret;
295 }
296
297 static struct notifier_block kgdb_notifier = {
298         .notifier_call  = kgdb_notify,
299         /*
300          * Want to be lowest priority
301          */
302         .priority       = -INT_MAX,
303 };
304
305 /*
306  * kgdb_arch_init - Perform any architecture specific initialization.
307  * This function will handle the initialization of any architecture
308  * specific callbacks.
309  */
310 int kgdb_arch_init(void)
311 {
312         int ret = register_die_notifier(&kgdb_notifier);
313
314         if (ret != 0)
315                 return ret;
316
317         register_kernel_break_hook(&kgdb_brkpt_hook);
318         register_kernel_break_hook(&kgdb_compiled_brkpt_hook);
319         register_kernel_step_hook(&kgdb_step_hook);
320         return 0;
321 }
322
323 /*
324  * kgdb_arch_exit - Perform any architecture specific uninitalization.
325  * This function will handle the uninitalization of any architecture
326  * specific callbacks, for dynamic registration and unregistration.
327  */
328 void kgdb_arch_exit(void)
329 {
330         unregister_kernel_break_hook(&kgdb_brkpt_hook);
331         unregister_kernel_break_hook(&kgdb_compiled_brkpt_hook);
332         unregister_kernel_step_hook(&kgdb_step_hook);
333         unregister_die_notifier(&kgdb_notifier);
334 }
335
336 const struct kgdb_arch arch_kgdb_ops;
337
338 int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
339 {
340         int err;
341
342         BUILD_BUG_ON(AARCH64_INSN_SIZE != BREAK_INSTR_SIZE);
343
344         err = aarch64_insn_read((void *)bpt->bpt_addr, (u32 *)bpt->saved_instr);
345         if (err)
346                 return err;
347
348         return aarch64_insn_write((void *)bpt->bpt_addr,
349                         (u32)AARCH64_BREAK_KGDB_DYN_DBG);
350 }
351
352 int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
353 {
354         return aarch64_insn_write((void *)bpt->bpt_addr,
355                         *(u32 *)bpt->saved_instr);
356 }