1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Performance counter callchain support - powerpc architecture code
5 * Copyright © 2009 Paul Mackerras, IBM Corporation.
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/perf_event.h>
10 #include <linux/percpu.h>
11 #include <linux/uaccess.h>
13 #include <asm/ptrace.h>
14 #include <asm/sigcontext.h>
15 #include <asm/ucontext.h>
17 #include <asm/pte-walk.h>
19 #include "callchain.h"
22 * On 64-bit we don't want to invoke hash_page on user addresses from
23 * interrupt context, so if the access faults, we read the page tables
24 * to find which page (if any) is mapped and access it directly.
26 int read_user_stack_slow(const void __user
*ptr
, void *buf
, int nb
)
29 unsigned long addr
= (unsigned long) ptr
;
34 if (get_user_page_fast_only(addr
, FOLL_WRITE
, &page
)) {
35 kaddr
= page_address(page
);
37 /* align address to page boundary */
38 offset
= addr
& ~PAGE_MASK
;
40 memcpy(buf
, kaddr
+ offset
, nb
);
47 static int read_user_stack_64(const unsigned long __user
*ptr
, unsigned long *ret
)
49 return __read_user_stack(ptr
, ret
, sizeof(*ret
));
53 * 64-bit user processes use the same stack frame for RT and non-RT signals.
55 struct signal_frame_64
{
56 char dummy
[__SIGNAL_FRAMESIZE
];
58 unsigned long unused
[2];
59 unsigned int tramp
[6];
60 struct siginfo
*pinfo
;
66 static int is_sigreturn_64_address(unsigned long nip
, unsigned long fp
)
68 if (nip
== fp
+ offsetof(struct signal_frame_64
, tramp
))
70 if (vdso64_rt_sigtramp
&& current
->mm
->context
.vdso_base
&&
71 nip
== current
->mm
->context
.vdso_base
+ vdso64_rt_sigtramp
)
77 * Do some sanity checking on the signal frame pointed to by sp.
78 * We check the pinfo and puc pointers in the frame.
80 static int sane_signal_64_frame(unsigned long sp
)
82 struct signal_frame_64 __user
*sf
;
83 unsigned long pinfo
, puc
;
85 sf
= (struct signal_frame_64 __user
*) sp
;
86 if (read_user_stack_64((unsigned long __user
*) &sf
->pinfo
, &pinfo
) ||
87 read_user_stack_64((unsigned long __user
*) &sf
->puc
, &puc
))
89 return pinfo
== (unsigned long) &sf
->info
&&
90 puc
== (unsigned long) &sf
->uc
;
93 void perf_callchain_user_64(struct perf_callchain_entry_ctx
*entry
,
96 unsigned long sp
, next_sp
;
97 unsigned long next_ip
;
100 struct signal_frame_64 __user
*sigframe
;
101 unsigned long __user
*fp
, *uregs
;
103 next_ip
= perf_instruction_pointer(regs
);
106 perf_callchain_store(entry
, next_ip
);
108 while (entry
->nr
< entry
->max_stack
) {
109 fp
= (unsigned long __user
*) sp
;
110 if (invalid_user_sp(sp
) || read_user_stack_64(fp
, &next_sp
))
112 if (level
> 0 && read_user_stack_64(&fp
[2], &next_ip
))
116 * Note: the next_sp - sp >= signal frame size check
117 * is true when next_sp < sp, which can happen when
118 * transitioning from an alternate signal stack to the
121 if (next_sp
- sp
>= sizeof(struct signal_frame_64
) &&
122 (is_sigreturn_64_address(next_ip
, sp
) ||
123 (level
<= 1 && is_sigreturn_64_address(lr
, sp
))) &&
124 sane_signal_64_frame(sp
)) {
126 * This looks like an signal frame
128 sigframe
= (struct signal_frame_64 __user
*) sp
;
129 uregs
= sigframe
->uc
.uc_mcontext
.gp_regs
;
130 if (read_user_stack_64(&uregs
[PT_NIP
], &next_ip
) ||
131 read_user_stack_64(&uregs
[PT_LNK
], &lr
) ||
132 read_user_stack_64(&uregs
[PT_R1
], &sp
))
135 perf_callchain_store_context(entry
, PERF_CONTEXT_USER
);
136 perf_callchain_store(entry
, next_ip
);
142 perf_callchain_store(entry
, next_ip
);