CC: kbuild-all(a)lists.01.org CC: linux-kernel(a)vger.kernel.org TO: "Peter, Zijlstra," CC: Ingo Molnar CC: Miroslav Benes CC: Alexandre Chartre tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: f359287765c04711ff54fbd11645271d8e5ff763 commit: 0298739b7983cf9bf4fcfb4bfb815c539bdb87ca x86,ftrace: Fix ftrace_regs_caller() unwind date: 6 weeks ago :::::: branch date: 4 hours ago :::::: commit date: 6 weeks ago config: x86_64-randconfig-s021-20200602 (attached as .config) compiler: gcc-9 (Debian 9.3.0-13) 9.3.0 reproduce: # apt-get install sparse # sparse version: v0.6.1-243-gc100a7ab-dirty git checkout 0298739b7983cf9bf4fcfb4bfb815c539bdb87ca # save the attached .config to linux build tree make W=1 C=1 ARCH=x86_64 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' If you fix the issue, kindly add following tag as appropriate Reported-by: kbuild test robot sparse warnings: (new ones prefixed by >>) >> arch/x86/kernel/ftrace.c:371:59: sparse: sparse: subtraction of functions? Share your drugs arch/x86/kernel/ftrace.c:40:5: sparse: sparse: context imbalance in 'ftrace_arch_code_modify_prepare' - wrong count at exit arch/x86/kernel/ftrace.c:53:5: sparse: sparse: context imbalance in 'ftrace_arch_code_modify_post_process' - wrong count at exit # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0298739b7983cf9bf4fcfb4bfb815c539bdb87ca git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git git remote update linus git checkout 0298739b7983cf9bf4fcfb4bfb815c539bdb87ca vim +371 arch/x86/kernel/ftrace.c d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 311) aec0be2d6e9f02 Steven Rostedt (Red Hat 2014-11-18 312) static unsigned long aec0be2d6e9f02 Steven Rostedt (Red Hat 2014-11-18 313) create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 314) { f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 315) unsigned long start_offset; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 316) unsigned long end_offset; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 317) unsigned long op_offset; 768ae4406a5cab Peter Zijlstra 2019-08-26 318 unsigned long call_offset; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 319) unsigned long offset; 3c0dab44e22782 Nadav Amit 2019-04-25 320 unsigned long npages; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 321) unsigned long size; d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 322) unsigned long retq; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 323) unsigned long *ptr; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 324) void *trampoline; d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 325) void *ip; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 326) /* 48 8b 15 is movq (%rip), %rdx */ f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 327) unsigned const char op_ref[] = { 0x48, 0x8b, 0x15 }; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 328) union ftrace_op_code_union op_ptr; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 329) int ret; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 330) f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 331) if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) { f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 332) start_offset = (unsigned long)ftrace_regs_caller; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 333) end_offset = (unsigned long)ftrace_regs_caller_end; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 334) op_offset = (unsigned long)ftrace_regs_caller_op_ptr; 768ae4406a5cab Peter Zijlstra 2019-08-26 335 call_offset = (unsigned long)ftrace_regs_call; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 336) } else { f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 337) start_offset = (unsigned long)ftrace_caller; 0298739b7983cf Peter Zijlstra 2020-04-01 338 end_offset = (unsigned long)ftrace_caller_end; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 339) op_offset = (unsigned long)ftrace_caller_op_ptr; 768ae4406a5cab Peter Zijlstra 2019-08-26 340 call_offset = (unsigned long)ftrace_call; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 341) } f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 342) f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 343) size = end_offset - start_offset; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 344) f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 345) /* f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 346) * Allocate enough size to store the ftrace_caller code, d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 347) * the iret , as well as the address of the ftrace_ops this d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 348) * trampoline is used for. f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 349) */ d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 350) trampoline = alloc_tramp(size + RET_SIZE + sizeof(void *)); f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 351) if (!trampoline) f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 352) return 0; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 353) d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 354) *tramp_size = size + RET_SIZE + sizeof(void *); 3c0dab44e22782 Nadav Amit 2019-04-25 355 npages = DIV_ROUND_UP(*tramp_size, PAGE_SIZE); aec0be2d6e9f02 Steven Rostedt (Red Hat 2014-11-18 356) f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 357) /* Copy ftrace_caller onto the trampoline memory */ f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 358) ret = probe_kernel_read(trampoline, (void *)start_offset, size); d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 359) if (WARN_ON(ret < 0)) d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 360) goto fail; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 361) d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 362) ip = trampoline + size; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 363) d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 364) /* The trampoline ends with ret(q) */ d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 365) retq = (unsigned long)ftrace_stub; d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 366) ret = probe_kernel_read(ip, (void *)retq, RET_SIZE); d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 367) if (WARN_ON(ret < 0)) d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 368) goto fail; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 369) 0298739b7983cf Peter Zijlstra 2020-04-01 370 if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) { 0298739b7983cf Peter Zijlstra 2020-04-01 @371 ip = trampoline + (ftrace_regs_caller_ret - ftrace_regs_caller); 0298739b7983cf Peter Zijlstra 2020-04-01 372 ret = probe_kernel_read(ip, (void *)retq, RET_SIZE); 0298739b7983cf Peter Zijlstra 2020-04-01 373 if (WARN_ON(ret < 0)) 0298739b7983cf Peter Zijlstra 2020-04-01 374 goto fail; 0298739b7983cf Peter Zijlstra 2020-04-01 375 } 0298739b7983cf Peter Zijlstra 2020-04-01 376 f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 377) /* f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 378) * The address of the ftrace_ops that is used for this trampoline f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 379) * is stored at the end of the trampoline. This will be used to f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 380) * load the third parameter for the callback. Basically, that f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 381) * location@the end of the trampoline takes the place of f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 382) * the global function_trace_op variable. f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 383) */ f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 384) d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 385) ptr = (unsigned long *)(trampoline + size + RET_SIZE); f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 386) *ptr = (unsigned long)ops; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 387) f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 388) op_offset -= start_offset; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 389) memcpy(&op_ptr, trampoline + op_offset, OP_REF_SIZE); f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 390) f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 391) /* Are we pointing to the reference? */ d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 392) if (WARN_ON(memcmp(op_ptr.op, op_ref, 3) != 0)) d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 393) goto fail; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 394) f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 395) /* Load the contents of ptr into the callback parameter */ f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 396) offset = (unsigned long)ptr; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 397) offset -= (unsigned long)trampoline + op_offset + OP_REF_SIZE; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 398) f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 399) op_ptr.offset = offset; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 400) f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 401) /* put in the new offset to the ftrace_ops */ f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 402) memcpy(trampoline + op_offset, &op_ptr, OP_REF_SIZE); f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 403) 768ae4406a5cab Peter Zijlstra 2019-08-26 404 /* put in the call to the function */ 768ae4406a5cab Peter Zijlstra 2019-08-26 405 mutex_lock(&text_mutex); 768ae4406a5cab Peter Zijlstra 2019-08-26 406 call_offset -= start_offset; 768ae4406a5cab Peter Zijlstra 2019-08-26 407 memcpy(trampoline + call_offset, 768ae4406a5cab Peter Zijlstra 2019-08-26 408 text_gen_insn(CALL_INSN_OPCODE, 768ae4406a5cab Peter Zijlstra 2019-08-26 409 trampoline + call_offset, 768ae4406a5cab Peter Zijlstra 2019-08-26 410 ftrace_ops_get_func(ops)), CALL_INSN_SIZE); 768ae4406a5cab Peter Zijlstra 2019-08-26 411 mutex_unlock(&text_mutex); 768ae4406a5cab Peter Zijlstra 2019-08-26 412 f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 413) /* ALLOC_TRAMP flags lets us know we created it */ f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 414) ops->flags |= FTRACE_OPS_FL_ALLOC_TRAMP; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 415) 7fdfe1e40b225b Rick Edgecombe 2019-04-25 416 set_vm_flush_reset_perms(trampoline); 7fdfe1e40b225b Rick Edgecombe 2019-04-25 417 768ae4406a5cab Peter Zijlstra 2019-08-26 418 set_memory_ro((unsigned long)trampoline, npages); 3c0dab44e22782 Nadav Amit 2019-04-25 419 set_memory_x((unsigned long)trampoline, npages); f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 420) return (unsigned long)trampoline; d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 421) fail: 7fdfe1e40b225b Rick Edgecombe 2019-04-25 422 tramp_free(trampoline); d2a68c4effd821 Steven Rostedt (VMware 2018-12-08 423) return 0; f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 424) } f3bea49115b21e Steven Rostedt (Red Hat 2014-07-02 425) --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org