Skip to content

Commit 5633e85

Browse files
sergey-senozhatskypmladek
authored andcommitted
powerpc64: Add .opd based function descriptor dereference
We are moving towards separate kernel and module function descriptor dereference callbacks. This patch enables it for powerpc64. For pointers that belong to the kernel - Added __start_opd and __end_opd pointers, to track the kernel .opd section address range; - Added dereference_kernel_function_descriptor(). Now we will dereference only function pointers that are within [__start_opd, __end_opd); For pointers that belong to a module - Added dereference_module_function_descriptor() to handle module function descriptor dereference. Now we will dereference only pointers that are within [module->opd.start, module->opd.end). Link: http://lkml.kernel.org/r/[email protected] To: Tony Luck <[email protected]> To: Fenghua Yu <[email protected]> To: Helge Deller <[email protected]> To: Benjamin Herrenschmidt <[email protected]> To: Paul Mackerras <[email protected]> To: Michael Ellerman <[email protected]> To: James Bottomley <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Jessica Yu <[email protected]> Cc: Petr Mladek <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: Sergey Senozhatsky <[email protected]> Cc: Sergey Senozhatsky <[email protected]> Signed-off-by: Sergey Senozhatsky <[email protected]> Tested-by: Santosh Sivaraj <[email protected]> #powerpc Signed-off-by: Petr Mladek <[email protected]>
1 parent 8e30788 commit 5633e85

File tree

4 files changed

+31
-0
lines changed

4 files changed

+31
-0
lines changed

arch/powerpc/include/asm/module.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ struct mod_arch_specific {
4545
unsigned long tramp;
4646
#endif
4747

48+
/* For module function descriptor dereference */
49+
unsigned long start_opd;
50+
unsigned long end_opd;
4851
#else /* powerpc64 */
4952
/* Indices of PLT sections within module. */
5053
unsigned int core_plt_section;

arch/powerpc/include/asm/sections.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ static inline int overlaps_kvm_tmp(unsigned long start, unsigned long end)
6666
}
6767

6868
#ifdef PPC64_ELF_ABI_v1
69+
70+
#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
71+
6972
#undef dereference_function_descriptor
7073
static inline void *dereference_function_descriptor(void *ptr)
7174
{
@@ -76,6 +79,15 @@ static inline void *dereference_function_descriptor(void *ptr)
7679
ptr = p;
7780
return ptr;
7881
}
82+
83+
#undef dereference_kernel_function_descriptor
84+
static inline void *dereference_kernel_function_descriptor(void *ptr)
85+
{
86+
if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
87+
return ptr;
88+
89+
return dereference_function_descriptor(ptr);
90+
}
7991
#endif /* PPC64_ELF_ABI_v1 */
8092

8193
#endif

arch/powerpc/kernel/module_64.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
9393
{
9494
return 0;
9595
}
96+
97+
void *dereference_module_function_descriptor(struct module *mod, void *ptr)
98+
{
99+
if (ptr < (void *)mod->arch.start_opd ||
100+
ptr >= (void *)mod->arch.end_opd)
101+
return ptr;
102+
103+
return dereference_function_descriptor(ptr);
104+
}
96105
#endif
97106

98107
#define STUB_MAGIC 0x73747562 /* stub */
@@ -344,6 +353,11 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
344353
else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
345354
dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
346355
sechdrs[i].sh_size);
356+
else if (!strcmp(secstrings + sechdrs[i].sh_name, ".opd")) {
357+
me->arch.start_opd = sechdrs[i].sh_addr;
358+
me->arch.end_opd = sechdrs[i].sh_addr +
359+
sechdrs[i].sh_size;
360+
}
347361

348362
/* We don't handle .init for the moment: rename to _init */
349363
while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init")))

arch/powerpc/kernel/vmlinux.lds.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,9 @@ SECTIONS
278278
}
279279

280280
.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
281+
__start_opd = .;
281282
*(.opd)
283+
__end_opd = .;
282284
}
283285

284286
. = ALIGN(256);

0 commit comments

Comments
 (0)