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)  * SH specific backtracing code for oprofile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5)  * Copyright 2007 STMicroelectronics Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7)  * Author: Dave Peverley <dpeverley@mpc-data.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9)  * Based on ARM oprofile backtrace code by Richard Purdie and in turn, i386
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)  * oprofile backtrace code by John Levon, David Smith
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/oprofile.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kallsyms.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/unwinder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/sections.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/stacktrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static void backtrace_address(void *data, unsigned long addr, int reliable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 	unsigned int *depth = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 	if ((*depth)--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 		oprofile_add_trace(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static struct stacktrace_ops backtrace_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 	.address = backtrace_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Limit to stop backtracing too far. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static int backtrace_limit = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static unsigned long *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) user_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 	unsigned long buf_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 	/* Also check accessibility of address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 	if (!access_ok(stackaddr, sizeof(unsigned long)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 	if (__copy_from_user_inatomic(&buf_stack, stackaddr, sizeof(unsigned long)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 	/* Quick paranoia check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 	if (buf_stack & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 	oprofile_add_trace(buf_stack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 	stackaddr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 	return stackaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 	unsigned long *stackaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 	 * Paranoia - clip max depth as we could get lost in the weeds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 	if (depth > backtrace_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 		depth = backtrace_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 	stackaddr = (unsigned long *)kernel_stack_pointer(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 	if (!user_mode(regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 		if (depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 			unwind_stack(NULL, regs, stackaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 				     &backtrace_ops, &depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 	while (depth-- && (stackaddr != NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 		stackaddr = user_backtrace(stackaddr, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }