Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3)  * Stack trace management functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5)  *  Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8) #include <linux/sched/debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/stacktrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/stacktrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)  * Save stack-backtrace addresses into a stack_trace buffer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static void save_raw_context_stack(struct stack_trace *trace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) 	unsigned long reg29, int savesched)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) 	unsigned long *sp = (unsigned long *)reg29;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 	while (!kstack_end(sp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 		addr = *sp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 		if (__kernel_text_address(addr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 		    (savesched || !in_sched_functions(addr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 			if (trace->skip > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 				trace->skip--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 				trace->entries[trace->nr_entries++] = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 			if (trace->nr_entries >= trace->max_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static void save_context_stack(struct stack_trace *trace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 	struct task_struct *tsk, struct pt_regs *regs, int savesched)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 	unsigned long sp = regs->regs[29];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #ifdef CONFIG_KALLSYMS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 	unsigned long ra = regs->regs[31];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 	unsigned long pc = regs->cp0_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 	if (raw_show_trace || !__kernel_text_address(pc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 		unsigned long stack_page =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 			(unsigned long)task_stack_page(tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 		if (stack_page && sp >= stack_page &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 		    sp <= stack_page + THREAD_SIZE - 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 			save_raw_context_stack(trace, sp, savesched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 		if (savesched || !in_sched_functions(pc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 			if (trace->skip > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 				trace->skip--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 				trace->entries[trace->nr_entries++] = pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 			if (trace->nr_entries >= trace->max_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 		pc = unwind_stack(tsk, &sp, pc, &ra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 	} while (pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 	save_raw_context_stack(trace, sp, savesched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)  * Save stack-backtrace addresses into a stack_trace buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) void save_stack_trace(struct stack_trace *trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 	save_stack_trace_tsk(current, trace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) EXPORT_SYMBOL_GPL(save_stack_trace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 	struct pt_regs dummyregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 	struct pt_regs *regs = &dummyregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) 	WARN_ON(trace->nr_entries || !trace->max_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 	if (tsk != current) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 		regs->regs[29] = tsk->thread.reg29;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) 		regs->regs[31] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) 		regs->cp0_epc = tsk->thread.reg31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 		prepare_frametrace(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 	save_context_stack(trace, tsk, regs, tsk == current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) EXPORT_SYMBOL_GPL(save_stack_trace_tsk);