Hi,
I made a patch for kmod/core/core.c using the upstream commit that fixes
the problem. When I apply this to core.c, kpatch 0.3.2 builds on kernel
4.9:
45a46
> #include <linux/stacktrace.h>
71,75d71
< struct kpatch_backtrace_args {
< struct kpatch_module *kpmod;
< int ret;
< };
<
135a132,138
> #define MAX_STACK_TRACE_DEPTH 64
> static unsigned long stack_entries[MAX_STACK_TRACE_DEPTH];
> struct stack_trace trace = {
> .max_entries = ARRAY_SIZE(stack_entries),
> .entries = &stack_entries[0],
> };
>
197,198c200,201
< static void kpatch_backtrace_address_verify(void *data, unsigned long address,
< int reliable)
---
> static int kpatch_backtrace_address_verify(struct kpatch_module *kpmod,
> unsigned long address)
200,201d202
< struct kpatch_backtrace_args *args = data;
< struct kpatch_module *kpmod = args->kpmod;
205,206c206
< if (args->ret)
< return;
---
> int ret;
230,233c230,233
< args->ret = kpatch_compare_addresses(address, func_addr,
< func_size, func_name);
< if (args->ret)
< return;
---
> ret = kpatch_compare_addresses(address, func_addr,
> func_size, func_name);
> if (ret)
> return ret;
239,244c239,244
< args->ret = kpatch_compare_addresses(address,
< func->new_addr,
< func->new_size,
< func->name);
< if (args->ret)
< return;
---
> ret = kpatch_compare_addresses(address,
> func->new_addr,
> func->new_size,
> func->name);
> if (ret)
> return ret;
247,258d246
< }
<
< static int kpatch_backtrace_stack(void *data, char *name)
< {
< return 0;
< }
<
< static const struct stacktrace_ops kpatch_backtrace_ops = {
< .address = kpatch_backtrace_address_verify,
< .stack = kpatch_backtrace_stack,
< .walk_stack = print_context_stack_bp,
< };
260,263c248
< static int kpatch_print_trace_stack(void *data, char *name)
< {
< pr_cont(" <%s> ", name);
< return 0;
---
> return ret;
266,278d250
< static void kpatch_print_trace_address(void *data, unsigned long addr,
< int reliable)
< {
< if (reliable)
< pr_info("[<%p>] %pB\n", (void *)addr, (void *)addr);
< }
<
< static const struct stacktrace_ops kpatch_print_trace_ops = {
< .stack = kpatch_print_trace_stack,
< .address = kpatch_print_trace_address,
< .walk_stack = print_context_stack,
< };
<
287a260
> int i;
290,294d262
< struct kpatch_backtrace_args args = {
< .kpmod = kpmod,
< .ret = 0
< };
<
297,302c265,271
< dump_trace(t, NULL, NULL, 0, &kpatch_backtrace_ops, &args);
< if (args.ret) {
< ret = args.ret;
< pr_info("PID: %d Comm: %.20s\n", t->pid, t->comm);
< dump_trace(t, NULL, (unsigned long *)t->thread.sp,
< 0, &kpatch_print_trace_ops, NULL);
---
>
> trace.nr_entries = 0;
> save_stack_trace_tsk(t, &trace);
> if (trace.nr_entries >= trace.max_entries) {
> ret = -EBUSY;
> pr_err("more than %u trace entries!\n",
> trace.max_entries);
304a274,283
>
> for (i = 0; i < trace.nr_entries; i++) {
> if (trace.entries[i] == ULONG_MAX)
> break;
> ret = kpatch_backtrace_address_verify(kpmod,
>
> trace.entries[i]);
> if (ret)
> goto out;
> }
>
307a287,297
> if (ret) {
> pr_err("PID: %d Comm: %.20s\n", t->pid, t->comm);
> for (i = 0; i < trace.nr_entries; i++) {
> if (trace.entries[i] == ULONG_MAX)
> break;
> pr_err(" [<%pK>] %pB\n",
> (void *)trace.entries[i],
> (void *)trace.entries[i]);
> }
> }
>