1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Deferred user space unwinding 4 */ 5 #include <linux/kernel.h> 6 #include <linux/sched.h> 7 #include <linux/slab.h> 8 #include <linux/unwind_deferred.h> 9 10 #define UNWIND_MAX_ENTRIES 512 11 12 /** 13 * unwind_user_faultable - Produce a user stacktrace in faultable context 14 * @trace: The descriptor that will store the user stacktrace 15 * 16 * This must be called in a known faultable context (usually when entering 17 * or exiting user space). Depending on the available implementations 18 * the @trace will be loaded with the addresses of the user space stacktrace 19 * if it can be found. 20 * 21 * Return: 0 on success and negative on error 22 * On success @trace will contain the user space stacktrace 23 */ 24 int unwind_user_faultable(struct unwind_stacktrace *trace) 25 { 26 struct unwind_task_info *info = ¤t->unwind_info; 27 28 /* Should always be called from faultable context */ 29 might_fault(); 30 31 if (current->flags & PF_EXITING) 32 return -EINVAL; 33 34 if (!info->entries) { 35 info->entries = kmalloc_array(UNWIND_MAX_ENTRIES, sizeof(long), 36 GFP_KERNEL); 37 if (!info->entries) 38 return -ENOMEM; 39 } 40 41 trace->nr = 0; 42 trace->entries = info->entries; 43 unwind_user(trace, UNWIND_MAX_ENTRIES); 44 45 return 0; 46 } 47 48 void unwind_task_init(struct task_struct *task) 49 { 50 struct unwind_task_info *info = &task->unwind_info; 51 52 memset(info, 0, sizeof(*info)); 53 } 54 55 void unwind_task_free(struct task_struct *task) 56 { 57 struct unwind_task_info *info = &task->unwind_info; 58 59 kfree(info->entries); 60 } 61