Commit 8b458d5f authored by Yang Jihong's avatar Yang Jihong Committed by Zheng Zengkai
Browse files

livepatch/powerpc64: Add do_check_calltrace

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



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

The calltrace check code is independent as do_check_calltrace,
for calltrace check of module.
No functional change.

Signed-off-by: default avatarYang Jihong <yangjihong1@huawei.com>
Reviewed-by: default avatarXu Kuohai <xukuohai@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 1daef7b0
Loading
Loading
Loading
Loading
+30 −22
Original line number Diff line number Diff line
@@ -339,22 +339,12 @@ static void free_list(struct klp_func_list **funcs)
	}
}

int klp_check_calltrace(struct klp_patch *patch, int enable)
static int do_check_calltrace(struct walk_stackframe_args *args,
			      int (*fn)(struct stackframe *, void *))
{
	struct task_struct *g, *t;
	struct stackframe frame;
	unsigned long *stack;
	int ret = 0;
	struct klp_func_list *check_funcs = NULL;
	struct walk_stackframe_args args;

	ret = klp_check_activeness_func(patch, enable, &check_funcs);
	if (ret) {
		pr_err("collect active functions failed, ret=%d\n", ret);
		goto out;
	}
	args.check_funcs = check_funcs;
	args.ret = 0;

	for_each_process_thread(g, t) {
		if (t == current) {
@@ -396,19 +386,37 @@ int klp_check_calltrace(struct klp_patch *patch, int enable)
		frame.sp = (unsigned long)stack;
		frame.pc = stack[STACK_FRAME_LR_SAVE];
		frame.nip = 0;
		if (check_funcs != NULL) {
			klp_walk_stackframe(&frame, klp_check_jump_func, t, &args);
			if (args.ret) {
				ret = args.ret;
		klp_walk_stackframe(&frame, fn, t, args);
		if (args->ret) {
			pr_debug("%s FAILED when %s\n", __func__,
					 enable ? "enabling" : "disabling");
				 args->enable ? "enabling" : "disabling");
			pr_info("PID: %d Comm: %.20s\n", t->pid, t->comm);
			show_stack(t, NULL, KERN_INFO);
				goto out;
			return args->ret;
		}
	}
	return 0;
}

int klp_check_calltrace(struct klp_patch *patch, int enable)
{
	int ret = 0;
	struct klp_func_list *check_funcs = NULL;
	struct walk_stackframe_args args;

	ret = klp_check_activeness_func(patch, enable, &check_funcs);
	if (ret) {
		pr_err("collect active functions failed, ret=%d\n", ret);
		goto out;
	}
	if (!check_funcs)
		goto out;

	args.check_funcs = check_funcs;
	args.ret = 0;
	args.enable = enable;
	ret = do_check_calltrace(&args, klp_check_jump_func);

out:
	free_list(&check_funcs);
	return ret;