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]); > } > } >