Commit d6749cb4 authored by Zheng Yejian's avatar Zheng Yejian
Browse files

livepatch/ppc32: Implement arch_klp_check_task_calltrace()

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9R2TB



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

Signed-off-by: default avatarZheng Yejian <zhengyejian1@huawei.com>
parent 8e77a794
Loading
Loading
Loading
Loading
+63 −35
Original line number Diff line number Diff line
@@ -233,14 +233,12 @@ static int klp_check_jump_func(struct stackframe *frame, void *ws_args)
	return 0;
}

static int do_check_calltrace(struct walk_stackframe_args *args,
static int check_task_calltrace(struct task_struct *t,
				struct walk_stackframe_args *args,
				int (*fn)(struct stackframe *, void *))
{
	struct task_struct *g, *t;
	unsigned long *stack;

	for_each_process_thread(g, t) {
	struct stackframe frame = { 0 };
	unsigned long *stack;

	if (t == current) {
		/*
@@ -251,8 +249,6 @@ static int do_check_calltrace(struct walk_stackframe_args *args,
		 * backtrace is so similar
		 */
		stack = (unsigned long *)current_stack_pointer;
		} else if (klp_is_migration_thread(t->comm)) {
			continue;
	} else {
		/*
		 * Skip the first frame since it does not contain lr
@@ -263,7 +259,7 @@ static int do_check_calltrace(struct walk_stackframe_args *args,
		unsigned long s = *(unsigned long *)t->thread.ksp;

		if (!validate_sp(s, t, STACK_FRAME_OVERHEAD))
				continue;
			return 0;
		stack = (unsigned long *)s;
	}

@@ -275,10 +271,42 @@ static int do_check_calltrace(struct walk_stackframe_args *args,
		show_stack(t, NULL, KERN_INFO);
		return args->ret;
	}
	return 0;
}

static int do_check_calltrace(struct walk_stackframe_args *args,
			      int (*fn)(struct stackframe *, void *))
{
	int ret;
	struct task_struct *g, *t;

	for_each_process_thread(g, t) {
		if (klp_is_migration_thread(t->comm))
			continue;
		ret = check_task_calltrace(t, args, fn);
		if (ret)
			return ret;
	}
	return 0;
}

#ifdef CONFIG_LIVEPATCH_BREAKPOINT_NO_STOP_MACHINE
int arch_klp_check_task_calltrace(struct task_struct *t,
				  bool (*check_func)(void *, int *, unsigned long),
				  void *data)
{
	struct walk_stackframe_args args = {
		.data = data,
		.ret = 0,
		.check_func = check_func,
	};

	if (t == NULL)
		return -EINVAL;
	return check_task_calltrace(t, &args, klp_check_jump_func);
}
#endif

int arch_klp_check_calltrace(bool (*check_func)(void *, int *, unsigned long), void *data)
{
	struct walk_stackframe_args args = {