diff options
Diffstat (limited to 'kernel/task_work.c')
| -rw-r--r-- | kernel/task_work.c | 15 | 
1 files changed, 13 insertions, 2 deletions
diff --git a/kernel/task_work.c b/kernel/task_work.c index 5d14d639ac71..c969f1f26be5 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -55,15 +55,26 @@ int task_work_add(struct task_struct *task, struct callback_head *work,  		  enum task_work_notify_mode notify)  {  	struct callback_head *head; +	int flags = notify & TWA_FLAGS; +	notify &= ~TWA_FLAGS;  	if (notify == TWA_NMI_CURRENT) {  		if (WARN_ON_ONCE(task != current))  			return -EINVAL;  		if (!IS_ENABLED(CONFIG_IRQ_WORK))  			return -EINVAL;  	} else { -		/* record the work call stack in order to print it in KASAN reports */ -		kasan_record_aux_stack(work); +		/* +		 * Record the work call stack in order to print it in KASAN +		 * reports. +		 * +		 * Note that stack allocation can fail if TWAF_NO_ALLOC flag +		 * is set and new page is needed to expand the stack buffer. +		 */ +		if (flags & TWAF_NO_ALLOC) +			kasan_record_aux_stack_noalloc(work); +		else +			kasan_record_aux_stack(work);  	}  	head = READ_ONCE(task->task_works);  | 
