Commit 9522ef85 authored by Zheng Yejian's avatar Zheng Yejian
Browse files

livepatch/ppc64: Adjust instruction replace order for KLP_STACK_OPTIMIZE mode

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



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

Signed-off-by: default avatarZheng Yejian <zhengyejian1@huawei.com>
parent b980761b
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -412,20 +412,17 @@ void arch_klp_unpatch_func(struct klp_func *func)
	struct klp_func_node *func_node;
	struct klp_func *next_func;
	unsigned long pc;
	int i;
	int ret;

	func_node = func->func_node;
	pc = (unsigned long)func_node->old_func;
	list_del_rcu(&func->stack_node);
	if (list_empty(&func_node->func_stack)) {
		for (i = 0; i < LJMP_INSN_SIZE; i++) {
			ret = patch_instruction((struct ppc_inst *)((u32 *)pc + i),
						ppc_inst(func_node->arch_data.old_insns[i]));
		ret = klp_patch_text((u32 *)pc, func_node->arch_data.old_insns,
				     LJMP_INSN_SIZE);
		if (ret) {
				pr_err("restore instruction %d failed, ret=%d\n", i, ret);
				break;
			}
			pr_err("restore instruction failed, ret=%d\n", ret);
			return;
		}

		pr_debug("[%s %d] restore insns at 0x%lx\n", __func__, __LINE__, pc);
+20 −9
Original line number Diff line number Diff line
@@ -817,17 +817,18 @@ int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs)
 * Patch jump stub to reference trampoline
 * without saved the old R2 and load the new R2.
 */
static int livepatch_create_bstub(struct ppc64_klp_bstub_entry *entry,
static int livepatch_create_bstub(void *pc,
				  unsigned long addr,
				  struct module *me)
{
	long reladdr;
	unsigned long my_r2;
	unsigned long stub_start, stub_end, stub_size;
	struct ppc64_klp_bstub_entry entry;

	/* Stub uses address relative to r2. */
	my_r2 = me ? me->arch.toc : kernel_toc_addr();
	reladdr = (unsigned long)entry - my_r2;
	reladdr = (unsigned long)pc - my_r2;
	if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
		pr_err("%s: Address %p of jump stub out of range of %p.\n",
		       me ? me->name : "kernel",
@@ -839,15 +840,25 @@ static int livepatch_create_bstub(struct ppc64_klp_bstub_entry *entry,
	stub_start = ppc_function_entry((void *)livepatch_branch_stub);
	stub_end = ppc_function_entry((void *)livepatch_branch_stub_end);
	stub_size = stub_end - stub_start;
	memcpy(entry->jump, (u32 *)stub_start, stub_size);
	memcpy(entry.jump, (u32 *)stub_start, stub_size);

	entry.jump[0] |= PPC_HA(reladdr);
	entry.jump[1] |= PPC_LO(reladdr);
	entry.magic = BRANCH_STUB_MAGIC;
	entry.trampoline = addr;

	entry->jump[0] |= PPC_HA(reladdr);
	entry->jump[1] |= PPC_LO(reladdr);
	entry->magic = BRANCH_STUB_MAGIC;
	entry->trampoline = addr;

	/* skip breakpoint at first */
	memcpy(pc + PPC64_INSN_SIZE, (void *)&entry + PPC64_INSN_SIZE,
	       sizeof(entry) - PPC64_INSN_SIZE);
	/*
	 * Avoid compile optimization, make sure that instructions
	 * except first breakpoint has been patched.
	 */
	barrier();
	memcpy(pc, (void *)&entry, PPC64_INSN_SIZE);
	pr_debug("Create livepatch branch stub 0x%px with reladdr 0x%lx r2 0x%lx to trampoline 0x%lx\n",
		(void *)entry, reladdr, my_r2, addr);
		pc, reladdr, my_r2, addr);

	return 1;
}
@@ -898,7 +909,7 @@ int livepatch_create_branch(unsigned long pc,
#endif

	/* Create stub to trampoline */
	if (!livepatch_create_bstub((struct ppc64_klp_bstub_entry *)pc, trampoline, me))
	if (!livepatch_create_bstub((void *)pc, trampoline, me))
		return -EINVAL;

	return 0;