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

Reply via email to