Skip to content

Commit 25ba8b4

Browse files
author
CKI KWF Bot
committed
Merge: powerpc fixes for out-of-line ftrace stubs and livepatching
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1561 JIRA: https://issues.redhat.com/browse/RHEL-113085 This patch series fixes a couple of bugs in the powerpc64 out-of-line (OOL) ftrace support for modules, and follows up with a patch to simplify the module .stubs allocation code. The first two patches fix bugs introduced by commit eec3796 ("powerpc64/ftrace: Move ftrace sequence out of line"). The first, suggested by Naveen, ensures that a NOP'd ftrace call site has its ftrace_ops record updated correctly. The second patch corrects a loop in setup_ftrace_ool_stubs() to ensure all required stubs are reserved, not just the first. Together, these bugs lead to potential corruption of the OOL ftrace stubs area for livepatch modules. Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> Approved-by: Steve Best <sbest@redhat.com> Approved-by: Luis Claudio R. Goncalves <lgoncalv@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Approved-by: Waiman Long <longman@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents a4f05a6 + 2d65f41 commit 25ba8b4

File tree

3 files changed

+17
-20
lines changed

3 files changed

+17
-20
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->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;

arch/powerpc/kernel/trace/ftrace.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,10 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
490490
return ret;
491491

492492
/* Set up out-of-line stub */
493-
if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE))
494-
return ftrace_init_ool_stub(mod, rec);
493+
if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) {
494+
ret = ftrace_init_ool_stub(mod, rec);
495+
goto out;
496+
}
495497

496498
/* Nop-out the ftrace location */
497499
new = ppc_inst(PPC_RAW_NOP());
@@ -522,6 +524,10 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
522524
return -EINVAL;
523525
}
524526

527+
out:
528+
if (!ret)
529+
ret = ftrace_rec_set_nop_ops(rec);
530+
525531
return ret;
526532
}
527533

0 commit comments

Comments
 (0)