Skip to content

Commit 2d65f41

Browse files
committed
powerpc64/modules: replace stub allocation sentinel with an explicit counter
JIRA: https://issues.redhat.com/browse/RHEL-113085 commit b137312 Author: Joe Lawrence <joe.lawrence@redhat.com> Date: Fri Sep 12 10:27:40 2025 -0400 powerpc64/modules: replace stub allocation sentinel with an explicit counter The logic for allocating ppc64_stub_entry trampolines in the .stubs section relies on an inline sentinel, where a NULL .funcdata member indicates an available slot. While preceding commits fixed the initialization bugs that led to ftrace stub corruption, the sentinel-based approach remains fragile: it depends on an implicit convention between subsystems modifying different struct types in the same memory area. Replace the sentinel with an explicit counter, module->arch.num_stubs. Instead of iterating through memory to find a NULL marker, the module loader uses this counter as the boundary for the next free slot. This simplifies the allocation code, hardens it against future changes to stub structures, and removes the need for an extra relocation slot previously reserved to terminate the sentinel search. Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> Acked-by: Naveen N Rao (AMD) <naveen@kernel.org> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/20250912142740.3581368-4-joe.lawrence@redhat.com Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
1 parent 4b693d3 commit 2d65f41

File tree

2 files changed

+9
-18
lines changed

2 files changed

+9
-18
lines changed

arch/powerpc/include/asm/module.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct ppc_plt_entry {
2727
struct mod_arch_specific {
2828
#ifdef __powerpc64__
2929
unsigned int stubs_section; /* Index of stubs section in module */
30+
unsigned int stub_count; /* Number of stubs used */
3031
#ifdef CONFIG_PPC_KERNEL_PCREL
3132
unsigned int got_section; /* What section is the GOT? */
3233
unsigned int pcpu_section; /* .data..percpu section */

arch/powerpc/kernel/module_64.c

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,7 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
209209
char *secstrings,
210210
struct module *me)
211211
{
212-
/* One extra reloc so it's always 0-addr terminated */
213-
unsigned long relocs = 1;
212+
unsigned long relocs = 0;
214213
unsigned i;
215214

216215
/* Every relocated section... */
@@ -685,7 +684,7 @@ static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs,
685684

686685
/* Find this stub, or if that fails, the next avail. entry */
687686
stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr;
688-
for (i = 0; stub_func_addr(stubs[i].funcdata); i++) {
687+
for (i = 0; i < me->arch.stub_count; i++) {
689688
if (WARN_ON(i >= num_stubs))
690689
return 0;
691690

@@ -696,6 +695,7 @@ static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs,
696695
if (!create_stub(sechdrs, &stubs[i], addr, me, name))
697696
return 0;
698697

698+
me->arch.stub_count++;
699699
return (unsigned long)&stubs[i];
700700
}
701701

@@ -1098,29 +1098,19 @@ int module_trampoline_target(struct module *mod, unsigned long addr,
10981098
static int setup_ftrace_ool_stubs(const Elf64_Shdr *sechdrs, unsigned long addr, struct module *me)
10991099
{
11001100
#ifdef CONFIG_PPC_FTRACE_OUT_OF_LINE
1101-
unsigned int i, total_stubs, num_stubs;
1101+
unsigned int total_stubs, num_stubs;
11021102
struct ppc64_stub_entry *stub;
11031103

11041104
total_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stub);
11051105
num_stubs = roundup(me->arch.ool_stub_count * sizeof(struct ftrace_ool_stub),
11061106
sizeof(struct ppc64_stub_entry)) / sizeof(struct ppc64_stub_entry);
11071107

1108-
/* Find the next available entry */
1109-
stub = (void *)sechdrs[me->arch.stubs_section].sh_addr;
1110-
for (i = 0; stub_func_addr(stub[i].funcdata); i++)
1111-
if (WARN_ON(i >= total_stubs))
1112-
return -1;
1113-
1114-
if (WARN_ON(i + num_stubs > total_stubs))
1108+
if (WARN_ON(me->arch.stub_count + num_stubs > total_stubs))
11151109
return -1;
11161110

1117-
stub += i;
1118-
me->arch.ool_stubs = (struct ftrace_ool_stub *)stub;
1119-
1120-
/* reserve stubs */
1121-
for (i = 0; i < num_stubs; i++)
1122-
if (patch_u32((void *)&stub[i].funcdata, PPC_RAW_NOP()))
1123-
return -1;
1111+
stub = (void *)sechdrs[me->arch.stubs_section].sh_addr;
1112+
me->arch.ool_stubs = (struct ftrace_ool_stub *)(stub + me->arch.stub_count);
1113+
me->arch.stub_count += num_stubs;
11241114
#endif
11251115

11261116
return 0;

0 commit comments

Comments
 (0)