Message ID | 20220916062330.430468-3-bgray@linux.ibm.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Out-of-line static calls for powerpc64 ELF V2 | expand |
Le 16/09/2022 à 08:23, Benjamin Gray a écrit : > The callee may set a field in `st_other` to 1 to indicate r2 should be > treated as caller-saved. This means a trampoline must be used to save > the current TOC before calling it and restore it afterwards, much like > external calls. > > This is necessary for supporting V2 ABI static calls that do not > preserve the TOC. > > Signed-off-by: Benjamin Gray <bgray@linux.ibm.com> > --- > arch/powerpc/kernel/module_64.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c > index 7e45dc98df8a..3656476097c2 100644 > --- a/arch/powerpc/kernel/module_64.c > +++ b/arch/powerpc/kernel/module_64.c > @@ -55,6 +55,11 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym) > * of function and try to derive r2 from it). */ > return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other); > } > + > +static bool need_r2save_stub(unsigned char st_other) { Please read https://docs.kernel.org/process/coding-style.html#placing-braces-and-spaces " ... functions: they have the opening brace at the beginning of the next line ..." > + return ((st_other & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT) == 1; > +} > + > #else > > static func_desc_t func_desc(unsigned long addr) > @@ -66,6 +71,10 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym) > return 0; > } > > +static bool need_r2save_stub(unsigned char st_other) { > + return false; > +} > + > void *dereference_module_function_descriptor(struct module *mod, void *ptr) > { > if (ptr < (void *)mod->arch.start_opd || > @@ -632,7 +641,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, > case R_PPC_REL24: > /* FIXME: Handle weak symbols here --RR */ > if (sym->st_shndx == SHN_UNDEF || > - sym->st_shndx == SHN_LIVEPATCH) { > + sym->st_shndx == SHN_LIVEPATCH || > + need_r2save_stub(sym->st_other)) { > /* External: go via stub */ > value = stub_for_addr(sechdrs, value, me, > strtab + sym->st_name);
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 7e45dc98df8a..3656476097c2 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -55,6 +55,11 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym) * of function and try to derive r2 from it). */ return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other); } + +static bool need_r2save_stub(unsigned char st_other) { + return ((st_other & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT) == 1; +} + #else static func_desc_t func_desc(unsigned long addr) @@ -66,6 +71,10 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym) return 0; } +static bool need_r2save_stub(unsigned char st_other) { + return false; +} + void *dereference_module_function_descriptor(struct module *mod, void *ptr) { if (ptr < (void *)mod->arch.start_opd || @@ -632,7 +641,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, case R_PPC_REL24: /* FIXME: Handle weak symbols here --RR */ if (sym->st_shndx == SHN_UNDEF || - sym->st_shndx == SHN_LIVEPATCH) { + sym->st_shndx == SHN_LIVEPATCH || + need_r2save_stub(sym->st_other)) { /* External: go via stub */ value = stub_for_addr(sechdrs, value, me, strtab + sym->st_name);
The callee may set a field in `st_other` to 1 to indicate r2 should be treated as caller-saved. This means a trampoline must be used to save the current TOC before calling it and restore it afterwards, much like external calls. This is necessary for supporting V2 ABI static calls that do not preserve the TOC. Signed-off-by: Benjamin Gray <bgray@linux.ibm.com> --- arch/powerpc/kernel/module_64.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)