Commit 5efc447b authored by Zheng Zucheng's avatar Zheng Zucheng Committed by Zheng Zengkai
Browse files

fork: Allocate a new task_struct_resvd object for fork task

hulk inclusion
category: feature
bugzilla: 187196, https://gitee.com/openeuler/kernel/issues/I612CS



-------------------------------

Allocate a new task_struct_resvd object for the recently cloned task

Signed-off-by: default avatarZheng Zucheng <zhengzucheng@huawei.com>
Reviewed-by: default avatarZhang Qiao <zhangqiao22@huawei.com>
Reviewed-by: default avatarZhang Qiao <zhangqiao22@huawei.com>
Reviewed-by: default avatarNanyong Sun <sunnanyong@huawei.com>
Reviewed-by: default avatarZhang Qiao <zhangqiao22@huawei.com>
Reviewed-by: default avatarchenhui 00515652 <judy.chenhui@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent d10d0c69
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -677,6 +677,8 @@ struct wake_q_node {
* struct task_struct_resvd - KABI extension struct
*/
struct task_struct_resvd {
	/* pointer back to the main task_struct */
	struct task_struct	*task;
};

struct task_struct {
+5 −0
Original line number Diff line number Diff line
@@ -57,6 +57,10 @@ unsigned long init_shadow_call_stack[SCS_SIZE / sizeof(long)]
};
#endif

static struct task_struct_resvd init_task_struct_resvd = {
	.task = &init_task,
};

/*
 * Set up the first task table, touch at your own risk!. Base=0,
 * limit=0x1fffff (=2MB)
@@ -213,6 +217,7 @@ struct task_struct init_task
#ifdef CONFIG_SECCOMP_FILTER
	.seccomp	= { .filter_count = ATOMIC_INIT(0) },
#endif
	._resvd = &init_task_struct_resvd,
};
EXPORT_SYMBOL(init_task);

+20 −1
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ static inline struct task_struct *alloc_task_struct_node(int node)

static inline void free_task_struct(struct task_struct *tsk)
{
	kfree(tsk->_resvd);
	kmem_cache_free(task_struct_cachep, tsk);
}
#endif
@@ -851,6 +852,18 @@ void set_task_stack_end_magic(struct task_struct *tsk)
	*stackend = STACK_END_MAGIC;	/* for overflow detection */
}

static bool dup_resvd_task_struct(struct task_struct *dst,
				  struct task_struct *orig, int node)
{
	dst->_resvd = kmalloc_node(sizeof(struct task_struct_resvd),
					  GFP_KERNEL, node);
	if (!dst->_resvd)
		return false;

	dst->_resvd->task = dst;
	return true;
}

static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
{
	struct task_struct *tsk;
@@ -863,6 +876,12 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
	tsk = alloc_task_struct_node(node);
	if (!tsk)
		return NULL;
	/*
	 * before proceeding, we need to make tsk->_resvd = NULL,
	 * otherwise the error paths below, if taken, might end up causing
	 * a double-free for task_struct_resvd extension object.
	 */
	WRITE_ONCE(tsk->_resvd, NULL);

	stack = alloc_thread_stack_node(tsk, node);
	if (!stack)
@@ -888,7 +907,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
	refcount_set(&tsk->stack_refcount, 1);
#endif

	if (err)
	if (err || !dup_resvd_task_struct(tsk, orig, node))
		goto free_stack;

	err = scs_prepare(tsk, node);