^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2005 Brian Rogan <bcr6@cornell.edu>, IBM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/oprofile.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/oprofile_impl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define STACK_SP(STACK) *(STACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define STACK_LR64(STACK) *((unsigned long *)(STACK) + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define STACK_LR32(STACK) *((unsigned int *)(STACK) + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define STACK_LR(STACK) STACK_LR64(STACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define STACK_LR(STACK) STACK_LR32(STACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static unsigned int user_getsp32(unsigned int sp, int is_first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) unsigned int stack_frame[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) void __user *p = compat_ptr(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * The most likely reason for this is that we returned -EFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * which means that we've done all that we can do from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * interrupt context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (copy_from_user_nofault(stack_frame, (void __user *)p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) sizeof(stack_frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (!is_first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) oprofile_add_trace(STACK_LR32(stack_frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * We do not enforce increasing stack addresses here because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * we may transition to a different stack, eg a signal handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return STACK_SP(stack_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static unsigned long user_getsp64(unsigned long sp, int is_first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned long stack_frame[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (copy_from_user_nofault(stack_frame, (void __user *)sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) sizeof(stack_frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (!is_first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) oprofile_add_trace(STACK_LR64(stack_frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return STACK_SP(stack_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static unsigned long kernel_getsp(unsigned long sp, int is_first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned long *stack_frame = (unsigned long *)sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (!is_first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) oprofile_add_trace(STACK_LR(stack_frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * We do not enforce increasing stack addresses here because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * we might be transitioning from an interrupt stack to a kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * stack. validate_sp() is designed to understand this, so just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * use it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return STACK_SP(stack_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned long sp = regs->gpr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int first_frame = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* We ditch the top stackframe so need to loop through an extra time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) depth += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (!user_mode(regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) while (depth--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) sp = kernel_getsp(sp, first_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) first_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (!is_32bit_task()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) while (depth--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) sp = user_getsp64(sp, first_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) first_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) while (depth--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) sp = user_getsp32(sp, first_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) first_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }