xref: /openbmc/linux/arch/parisc/kernel/unwind.c (revision 287a0e6d)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Kernel unwinding support
4  *
5  * (c) 2002-2004 Randolph Chung <tausq@debian.org>
6  *
7  * Derived partially from the IA64 implementation. The PA-RISC
8  * Runtime Architecture Document is also a useful reference to
9  * understand what is happening here
10  */
11 
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/sched.h>
15 #include <linux/slab.h>
16 #include <linux/sort.h>
17 #include <linux/sched/task_stack.h>
18 
19 #include <linux/uaccess.h>
20 #include <asm/assembly.h>
21 #include <asm/asm-offsets.h>
22 #include <asm/ptrace.h>
23 
24 #include <asm/unwind.h>
25 #include <asm/switch_to.h>
26 #include <asm/sections.h>
27 #include <asm/ftrace.h>
28 
29 /* #define DEBUG 1 */
30 #ifdef DEBUG
31 #define dbg(x...) pr_debug(x)
32 #else
33 #define dbg(x...) do { } while (0)
34 #endif
35 
36 #define KERNEL_START (KERNEL_BINARY_TEXT_START)
37 
38 extern struct unwind_table_entry __start___unwind[];
39 extern struct unwind_table_entry __stop___unwind[];
40 
41 static DEFINE_SPINLOCK(unwind_lock);
42 /*
43  * the kernel unwind block is not dynamically allocated so that
44  * we can call unwind_init as early in the bootup process as
45  * possible (before the slab allocator is initialized)
46  */
47 static struct unwind_table kernel_unwind_table __ro_after_init;
48 static LIST_HEAD(unwind_tables);
49 
50 static inline const struct unwind_table_entry *
find_unwind_entry_in_table(const struct unwind_table * table,unsigned long addr)51 find_unwind_entry_in_table(const struct unwind_table *table, unsigned long addr)
52 {
53 	const struct unwind_table_entry *e = NULL;
54 	unsigned long lo, hi, mid;
55 
56 	lo = 0;
57 	hi = table->length - 1;
58 
59 	while (lo <= hi) {
60 		mid = (hi - lo) / 2 + lo;
61 		e = &table->table[mid];
62 		if (addr < e->region_start)
63 			hi = mid - 1;
64 		else if (addr > e->region_end)
65 			lo = mid + 1;
66 		else
67 			return e;
68 	}
69 
70 	return NULL;
71 }
72 
73 static const struct unwind_table_entry *
find_unwind_entry(unsigned long addr)74 find_unwind_entry(unsigned long addr)
75 {
76 	struct unwind_table *table;
77 	const struct unwind_table_entry *e = NULL;
78 
79 	if (addr >= kernel_unwind_table.start &&
80 	    addr <= kernel_unwind_table.end)
81 		e = find_unwind_entry_in_table(&kernel_unwind_table, addr);
82 	else {
83 		unsigned long flags;
84 
85 		spin_lock_irqsave(&unwind_lock, flags);
86 		list_for_each_entry(table, &unwind_tables, list) {
87 			if (addr >= table->start &&
88 			    addr <= table->end)
89 				e = find_unwind_entry_in_table(table, addr);
90 			if (e) {
91 				/* Move-to-front to exploit common traces */
92 				list_move(&table->list, &unwind_tables);
93 				break;
94 			}
95 		}
96 		spin_unlock_irqrestore(&unwind_lock, flags);
97 	}
98 
99 	return e;
100 }
101 
102 static void
unwind_table_init(struct unwind_table * table,const char * name,unsigned long base_addr,unsigned long gp,void * table_start,void * table_end)103 unwind_table_init(struct unwind_table *table, const char *name,
104 		  unsigned long base_addr, unsigned long gp,
105 		  void *table_start, void *table_end)
106 {
107 	struct unwind_table_entry *start = table_start;
108 	struct unwind_table_entry *end =
109 		(struct unwind_table_entry *)table_end - 1;
110 
111 	table->name = name;
112 	table->base_addr = base_addr;
113 	table->gp = gp;
114 	table->start = base_addr + start->region_start;
115 	table->end = base_addr + end->region_end;
116 	table->table = (struct unwind_table_entry *)table_start;
117 	table->length = end - start + 1;
118 	INIT_LIST_HEAD(&table->list);
119 
120 	for (; start <= end; start++) {
121 		if (start < end &&
122 		    start->region_end > (start+1)->region_start) {
123 			pr_warn("Out of order unwind entry! %px and %px\n",
124 				start, start+1);
125 		}
126 
127 		start->region_start += base_addr;
128 		start->region_end += base_addr;
129 	}
130 }
131 
cmp_unwind_table_entry(const void * a,const void * b)132 static int cmp_unwind_table_entry(const void *a, const void *b)
133 {
134 	return ((const struct unwind_table_entry *)a)->region_start
135 	     - ((const struct unwind_table_entry *)b)->region_start;
136 }
137 
138 static void
unwind_table_sort(struct unwind_table_entry * start,struct unwind_table_entry * finish)139 unwind_table_sort(struct unwind_table_entry *start,
140 		  struct unwind_table_entry *finish)
141 {
142 	sort(start, finish - start, sizeof(struct unwind_table_entry),
143 	     cmp_unwind_table_entry, NULL);
144 }
145 
146 struct unwind_table *
unwind_table_add(const char * name,unsigned long base_addr,unsigned long gp,void * start,void * end)147 unwind_table_add(const char *name, unsigned long base_addr,
148 		 unsigned long gp,
149                  void *start, void *end)
150 {
151 	struct unwind_table *table;
152 	unsigned long flags;
153 	struct unwind_table_entry *s = (struct unwind_table_entry *)start;
154 	struct unwind_table_entry *e = (struct unwind_table_entry *)end;
155 
156 	unwind_table_sort(s, e);
157 
158 	table = kmalloc(sizeof(struct unwind_table), GFP_USER);
159 	if (table == NULL)
160 		return NULL;
161 	unwind_table_init(table, name, base_addr, gp, start, end);
162 	spin_lock_irqsave(&unwind_lock, flags);
163 	list_add_tail(&table->list, &unwind_tables);
164 	spin_unlock_irqrestore(&unwind_lock, flags);
165 
166 	return table;
167 }
168 
unwind_table_remove(struct unwind_table * table)169 void unwind_table_remove(struct unwind_table *table)
170 {
171 	unsigned long flags;
172 
173 	spin_lock_irqsave(&unwind_lock, flags);
174 	list_del(&table->list);
175 	spin_unlock_irqrestore(&unwind_lock, flags);
176 
177 	kfree(table);
178 }
179 
180 /* Called from setup_arch to import the kernel unwind info */
unwind_init(void)181 int __init unwind_init(void)
182 {
183 	long start __maybe_unused, stop __maybe_unused;
184 	register unsigned long gp __asm__ ("r27");
185 
186 	start = (long)&__start___unwind[0];
187 	stop = (long)&__stop___unwind[0];
188 
189 	dbg("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n",
190 	    start, stop,
191 	    (stop - start) / sizeof(struct unwind_table_entry));
192 
193 	unwind_table_init(&kernel_unwind_table, "kernel", KERNEL_START,
194 			  gp,
195 			  &__start___unwind[0], &__stop___unwind[0]);
196 #if 0
197 	{
198 		int i;
199 		for (i = 0; i < 10; i++)
200 		{
201 			printk("region 0x%x-0x%x\n",
202 				__start___unwind[i].region_start,
203 				__start___unwind[i].region_end);
204 		}
205 	}
206 #endif
207 	return 0;
208 }
209 
pc_is_kernel_fn(unsigned long pc,void * fn)210 static bool pc_is_kernel_fn(unsigned long pc, void *fn)
211 {
212 	return (unsigned long)dereference_kernel_function_descriptor(fn) == pc;
213 }
214 
unwind_special(struct unwind_frame_info * info,unsigned long pc,int frame_size)215 static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size)
216 {
217 	/*
218 	 * We have to use void * instead of a function pointer, because
219 	 * function pointers aren't a pointer to the function on 64-bit.
220 	 * Make them const so the compiler knows they live in .text
221 	 * Note: We could use dereference_kernel_function_descriptor()
222 	 * instead but we want to keep it simple here.
223 	 */
224 	extern void * const ret_from_kernel_thread;
225 	extern void * const syscall_exit;
226 	extern void * const intr_return;
227 	extern void * const _switch_to_ret;
228 #ifdef CONFIG_IRQSTACKS
229 	extern void * const _call_on_stack;
230 #endif /* CONFIG_IRQSTACKS */
231 
232 	if (pc_is_kernel_fn(pc, handle_interruption)) {
233 		struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN);
234 		dbg("Unwinding through handle_interruption()\n");
235 		info->prev_sp = regs->gr[30];
236 		info->prev_ip = regs->iaoq[0];
237 		return 1;
238 	}
239 
240 	if (pc == (unsigned long)&ret_from_kernel_thread ||
241 	    pc == (unsigned long)&syscall_exit) {
242 		info->prev_sp = info->prev_ip = 0;
243 		return 1;
244 	}
245 
246 	if (pc == (unsigned long)&intr_return) {
247 		struct pt_regs *regs;
248 
249 		dbg("Found intr_return()\n");
250 		regs = (struct pt_regs *)(info->sp - PT_SZ_ALGN);
251 		info->prev_sp = regs->gr[30];
252 		info->prev_ip = regs->iaoq[0];
253 		info->rp = regs->gr[2];
254 		return 1;
255 	}
256 
257 	if (pc_is_kernel_fn(pc, _switch_to) ||
258 	    pc == (unsigned long)&_switch_to_ret) {
259 		info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE;
260 		info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
261 		return 1;
262 	}
263 
264 #ifdef CONFIG_IRQSTACKS
265 	if (pc == (unsigned long)&_call_on_stack) {
266 		info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ);
267 		info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET);
268 		return 1;
269 	}
270 #endif
271 	return 0;
272 }
273 
unwind_frame_regs(struct unwind_frame_info * info)274 static void unwind_frame_regs(struct unwind_frame_info *info)
275 {
276 	const struct unwind_table_entry *e;
277 	unsigned long npc;
278 	unsigned int insn;
279 	long frame_size = 0;
280 	int looking_for_rp, rpoffset = 0;
281 
282 	e = find_unwind_entry(info->ip);
283 	if (e == NULL) {
284 		unsigned long sp;
285 
286 		dbg("Cannot find unwind entry for %pS; forced unwinding\n",
287 			(void *) info->ip);
288 
289 		/* Since we are doing the unwinding blind, we don't know if
290 		   we are adjusting the stack correctly or extracting the rp
291 		   correctly. The rp is checked to see if it belongs to the
292 		   kernel text section, if not we assume we don't have a
293 		   correct stack frame and we continue to unwind the stack.
294 		   This is not quite correct, and will fail for loadable
295 		   modules. */
296 		sp = info->sp & ~63;
297 		do {
298 			unsigned long tmp;
299 
300 			info->prev_sp = sp - 64;
301 			info->prev_ip = 0;
302 
303 			/* Check if stack is inside kernel stack area */
304 			if ((info->prev_sp - (unsigned long) task_stack_page(info->t))
305 					>= THREAD_SIZE) {
306 				info->prev_sp = 0;
307 				break;
308 			}
309 
310 			if (copy_from_kernel_nofault(&tmp,
311 			    (void *)info->prev_sp - RP_OFFSET, sizeof(tmp)))
312 				break;
313 			info->prev_ip = tmp;
314 			sp = info->prev_sp;
315 		} while (!kernel_text_address(info->prev_ip));
316 
317 		info->rp = 0;
318 
319 		dbg("analyzing func @ %lx with no unwind info, setting "
320 		    "prev_sp=%lx prev_ip=%lx\n", info->ip,
321 		    info->prev_sp, info->prev_ip);
322 	} else {
323 		dbg("e->start = 0x%x, e->end = 0x%x, Save_SP = %d, "
324 		    "Save_RP = %d, Millicode = %d size = %u\n",
325 		    e->region_start, e->region_end, e->Save_SP, e->Save_RP,
326 		    e->Millicode, e->Total_frame_size);
327 
328 		looking_for_rp = e->Save_RP;
329 
330 		for (npc = e->region_start;
331 		     (frame_size < (e->Total_frame_size << 3) ||
332 		      looking_for_rp) &&
333 		     npc < info->ip;
334 		     npc += 4) {
335 
336 			insn = *(unsigned int *)npc;
337 
338 			if ((insn & 0xffffc001) == 0x37de0000 ||
339 			    (insn & 0xffe00001) == 0x6fc00000) {
340 				/* ldo X(sp), sp, or stwm X,D(sp) */
341 				frame_size += (insn & 0x3fff) >> 1;
342 				dbg("analyzing func @ %lx, insn=%08x @ "
343 				    "%lx, frame_size = %ld\n", info->ip,
344 				    insn, npc, frame_size);
345 			} else if ((insn & 0xffe00009) == 0x73c00008) {
346 				/* std,ma X,D(sp) */
347 				frame_size += ((insn >> 4) & 0x3ff) << 3;
348 				dbg("analyzing func @ %lx, insn=%08x @ "
349 				    "%lx, frame_size = %ld\n", info->ip,
350 				    insn, npc, frame_size);
351 			} else if (insn == 0x6bc23fd9) {
352 				/* stw rp,-20(sp) */
353 				rpoffset = 20;
354 				looking_for_rp = 0;
355 				dbg("analyzing func @ %lx, insn=stw rp,"
356 				    "-20(sp) @ %lx\n", info->ip, npc);
357 			} else if (insn == 0x0fc212c1) {
358 				/* std rp,-16(sr0,sp) */
359 				rpoffset = 16;
360 				looking_for_rp = 0;
361 				dbg("analyzing func @ %lx, insn=std rp,"
362 				    "-16(sp) @ %lx\n", info->ip, npc);
363 			}
364 		}
365 
366 		if (frame_size > e->Total_frame_size << 3)
367 			frame_size = e->Total_frame_size << 3;
368 
369 		if (!unwind_special(info, e->region_start, frame_size)) {
370 			info->prev_sp = info->sp - frame_size;
371 			if (e->Millicode)
372 				info->rp = info->r31;
373 			else if (rpoffset)
374 				info->rp = *(unsigned long *)(info->prev_sp - rpoffset);
375 			info->prev_ip = info->rp;
376 			info->rp = 0;
377 		}
378 
379 		dbg("analyzing func @ %lx, setting prev_sp=%lx "
380 		    "prev_ip=%lx npc=%lx\n", info->ip, info->prev_sp,
381 		    info->prev_ip, npc);
382 	}
383 }
384 
unwind_frame_init(struct unwind_frame_info * info,struct task_struct * t,struct pt_regs * regs)385 void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
386 		       struct pt_regs *regs)
387 {
388 	memset(info, 0, sizeof(struct unwind_frame_info));
389 	info->t = t;
390 	info->sp = regs->gr[30];
391 	info->ip = regs->iaoq[0];
392 	info->rp = regs->gr[2];
393 	info->r31 = regs->gr[31];
394 
395 	dbg("(%d) Start unwind from sp=%08lx ip=%08lx\n",
396 	    t ? (int)t->pid : -1, info->sp, info->ip);
397 }
398 
unwind_frame_init_from_blocked_task(struct unwind_frame_info * info,struct task_struct * t)399 void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t)
400 {
401 	struct pt_regs *r = &t->thread.regs;
402 	struct pt_regs *r2;
403 
404 	r2 = kmalloc(sizeof(struct pt_regs), GFP_ATOMIC);
405 	if (!r2)
406 		return;
407 	*r2 = *r;
408 	r2->gr[30] = r->ksp;
409 	r2->iaoq[0] = r->kpc;
410 	unwind_frame_init(info, t, r2);
411 	kfree(r2);
412 }
413 
414 #define get_parisc_stackpointer() ({ \
415 	unsigned long sp; \
416 	__asm__("copy %%r30, %0" : "=r"(sp)); \
417 	(sp); \
418 })
419 
unwind_frame_init_task(struct unwind_frame_info * info,struct task_struct * task,struct pt_regs * regs)420 void unwind_frame_init_task(struct unwind_frame_info *info,
421 	struct task_struct *task, struct pt_regs *regs)
422 {
423 	task = task ? task : current;
424 
425 	if (task == current) {
426 		struct pt_regs r;
427 
428 		if (!regs) {
429 			memset(&r, 0, sizeof(r));
430 			r.iaoq[0] =  _THIS_IP_;
431 			r.gr[2] = _RET_IP_;
432 			r.gr[30] = get_parisc_stackpointer();
433 			regs = &r;
434 		}
435 		unwind_frame_init(info, task, regs);
436 	} else {
437 		unwind_frame_init_from_blocked_task(info, task);
438 	}
439 }
440 
unwind_once(struct unwind_frame_info * next_frame)441 int unwind_once(struct unwind_frame_info *next_frame)
442 {
443 	unwind_frame_regs(next_frame);
444 
445 	if (next_frame->prev_sp == 0 ||
446 	    next_frame->prev_ip == 0)
447 		return -1;
448 
449 	next_frame->sp = next_frame->prev_sp;
450 	next_frame->ip = next_frame->prev_ip;
451 	next_frame->prev_sp = 0;
452 	next_frame->prev_ip = 0;
453 
454 	dbg("(%d) Continue unwind to sp=%08lx ip=%08lx\n",
455 	    next_frame->t ? (int)next_frame->t->pid : -1,
456 	    next_frame->sp, next_frame->ip);
457 
458 	return 0;
459 }
460 
unwind_to_user(struct unwind_frame_info * info)461 int unwind_to_user(struct unwind_frame_info *info)
462 {
463 	int ret;
464 
465 	do {
466 		ret = unwind_once(info);
467 	} while (!ret && !(info->ip & 3));
468 
469 	return ret;
470 }
471 
return_address(unsigned int level)472 unsigned long return_address(unsigned int level)
473 {
474 	struct unwind_frame_info info;
475 
476 	/* initialize unwind info */
477 	unwind_frame_init_task(&info, current, NULL);
478 
479 	/* unwind stack */
480 	level += 2;
481 	do {
482 		if (unwind_once(&info) < 0 || info.ip == 0)
483 			return 0;
484 		if (!kernel_text_address(info.ip))
485 			return 0;
486 	} while (info.ip && level--);
487 
488 	return info.ip;
489 }
490