18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci#ifndef _POWERPC_PERF_CALLCHAIN_H 38c2ecf20Sopenharmony_ci#define _POWERPC_PERF_CALLCHAIN_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ciint read_user_stack_slow(const void __user *ptr, void *buf, int nb); 68c2ecf20Sopenharmony_civoid perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, 78c2ecf20Sopenharmony_ci struct pt_regs *regs); 88c2ecf20Sopenharmony_civoid perf_callchain_user_32(struct perf_callchain_entry_ctx *entry, 98c2ecf20Sopenharmony_ci struct pt_regs *regs); 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistatic inline bool invalid_user_sp(unsigned long sp) 128c2ecf20Sopenharmony_ci{ 138c2ecf20Sopenharmony_ci unsigned long mask = is_32bit_task() ? 3 : 7; 148c2ecf20Sopenharmony_ci unsigned long top = STACK_TOP - (is_32bit_task() ? 16 : 32); 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci return (!sp || (sp & mask) || (sp > top)); 178c2ecf20Sopenharmony_ci} 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/* 208c2ecf20Sopenharmony_ci * On 32-bit we just access the address and let hash_page create a 218c2ecf20Sopenharmony_ci * HPTE if necessary, so there is no need to fall back to reading 228c2ecf20Sopenharmony_ci * the page tables. Since this is called at interrupt level, 238c2ecf20Sopenharmony_ci * do_page_fault() won't treat a DSI as a page fault. 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_cistatic inline int __read_user_stack(const void __user *ptr, void *ret, 268c2ecf20Sopenharmony_ci size_t size) 278c2ecf20Sopenharmony_ci{ 288c2ecf20Sopenharmony_ci unsigned long addr = (unsigned long)ptr; 298c2ecf20Sopenharmony_ci int rc; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci if (addr > TASK_SIZE - size || (addr & (size - 1))) 328c2ecf20Sopenharmony_ci return -EFAULT; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci rc = copy_from_user_nofault(ret, ptr, size); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_PPC64) && rc) 378c2ecf20Sopenharmony_ci return read_user_stack_slow(ptr, ret, size); 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci return rc; 408c2ecf20Sopenharmony_ci} 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci#endif /* _POWERPC_PERF_CALLCHAIN_H */ 43