^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) * Performance counter callchain support - powerpc architecture code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright © 2009 Paul Mackerras, IBM Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/percpu.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/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/sigcontext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/ucontext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/vdso.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/pte-walk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "callchain.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * On 64-bit we don't want to invoke hash_page on user addresses from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * interrupt context, so if the access faults, we read the page tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * to find which page (if any) is mapped and access it directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int read_user_stack_slow(const void __user *ptr, void *buf, int nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned long addr = (unsigned long) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) void *kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (get_user_page_fast_only(addr, FOLL_WRITE, &page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) kaddr = page_address(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* align address to page boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) offset = addr & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) memcpy(buf, kaddr + offset, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int read_user_stack_64(const unsigned long __user *ptr, unsigned long *ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return __read_user_stack(ptr, ret, sizeof(*ret));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * 64-bit user processes use the same stack frame for RT and non-RT signals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct signal_frame_64 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) char dummy[__SIGNAL_FRAMESIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct ucontext uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned long unused[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned int tramp[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct siginfo *pinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) void *puc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct siginfo info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) char abigap[288];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int is_sigreturn_64_address(unsigned long nip, unsigned long fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (nip == fp + offsetof(struct signal_frame_64, tramp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (vdso64_rt_sigtramp && current->mm->context.vdso_base &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) nip == current->mm->context.vdso_base + vdso64_rt_sigtramp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^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) * Do some sanity checking on the signal frame pointed to by sp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * We check the pinfo and puc pointers in the frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static int sane_signal_64_frame(unsigned long sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct signal_frame_64 __user *sf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned long pinfo, puc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) sf = (struct signal_frame_64 __user *) sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (read_user_stack_64((unsigned long __user *) &sf->pinfo, &pinfo) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) read_user_stack_64((unsigned long __user *) &sf->puc, &puc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return pinfo == (unsigned long) &sf->info &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) puc == (unsigned long) &sf->uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned long sp, next_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned long next_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned long lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) long level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct signal_frame_64 __user *sigframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned long __user *fp, *uregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) next_ip = perf_instruction_pointer(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) lr = regs->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) sp = regs->gpr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) perf_callchain_store(entry, next_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) while (entry->nr < entry->max_stack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) fp = (unsigned long __user *) sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (invalid_user_sp(sp) || read_user_stack_64(fp, &next_sp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (level > 0 && read_user_stack_64(&fp[2], &next_ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * Note: the next_sp - sp >= signal frame size check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * is true when next_sp < sp, which can happen when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * transitioning from an alternate signal stack to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * normal stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (next_sp - sp >= sizeof(struct signal_frame_64) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) (is_sigreturn_64_address(next_ip, sp) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) (level <= 1 && is_sigreturn_64_address(lr, sp))) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) sane_signal_64_frame(sp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * This looks like an signal frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) sigframe = (struct signal_frame_64 __user *) sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) uregs = sigframe->uc.uc_mcontext.gp_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (read_user_stack_64(&uregs[PT_NIP], &next_ip) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) read_user_stack_64(&uregs[PT_LNK], &lr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) read_user_stack_64(&uregs[PT_R1], &sp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) perf_callchain_store_context(entry, PERF_CONTEXT_USER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) perf_callchain_store(entry, next_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (level == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) next_ip = lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) perf_callchain_store(entry, next_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ++level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) sp = next_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }