Commit b8f32206 authored by laokz's avatar laokz Committed by laokz
Browse files

livepatch: add arch hook before doing klp_resolve_symbols

community inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I7USO2



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

Normally, the hook is NOP. But for arches, such as RISC-V,
there are special livepatch symbols which do not need KLP
resolving. The RISC-V psABI said:

   In the linker relaxation optimization, we introduce a concept
   called relocation group; a relocation group consists of 1)
   relocations associated with the same target symbol and can be
   applied with the same relaxation, or 2) relocations with the
   linkage relationship (e.g. `R_RISCV_PCREL_LO12_S` linked with
   a `R_RISCV_PCREL_HI20`); all relocations in a single group must
   be present in the same section, otherwise will split into another
   relocation group.

When patches reference external non-exported globals, their
R_RISCV_PCREL_HI20/R_RISCV_PCREL_LO12_I relocations target the same
symbol and must live in the same section:

   R_RISCV_PCREL_HI20 entry should be moved to .klp.rela.xxx section
                      when making patch, and when loading livepatch
                      core will resolve the target symbol address
   R_RISCV_PCREL_LO12_I should also be moved to .klp.rela.xxx section
                      when making patch, but when loading livepatch
                      core MUST ignore it because R_RISCV_PCREL_LO12_I
                      indeed is just a link to the R_RISCV_PCREL_HI20

Signed-off-by: default avatarKai Zhang <zhangkai@iscas.ac.cn>
parent c8e916a3
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -212,6 +212,13 @@ static int klp_find_object_symbol(const char *objname, const char *name,
	return -EINVAL;
}

#ifdef CONFIG_LIVEPATCH_WO_FTRACE
bool __weak arch_klp_skip_resolve(unsigned int type)
{
	return false;
}
#endif

static int klp_resolve_symbols(Elf_Shdr *sechdrs, const char *strtab,
			       unsigned int symndx, Elf_Shdr *relasec,
			       const char *sec_objname)
@@ -248,6 +255,10 @@ static int klp_resolve_symbols(Elf_Shdr *sechdrs, const char *strtab,
#endif
	/* For each rela in this klp relocation section */
	for (i = 0; i < relasec->sh_size / sizeof(*relas); i++) {
#ifdef CONFIG_LIVEPATCH_WO_FTRACE
		if (arch_klp_skip_resolve(ELF_R_TYPE(relas[i].r_info)))
			continue;
#endif
		sym = (Elf_Sym *)sechdrs[symndx].sh_addr + ELF_R_SYM(relas[i].r_info);
		if (sym->st_shndx != SHN_LIVEPATCH) {
			pr_err("symbol %s is not marked as a livepatch symbol\n",