Hi Nick, I love your patch! Perhaps something to improve: [auto build test WARNING on next-20220923] [cannot apply to arm/for-next rostedt-trace/for-next linus/master v6.0-rc7 v6.0-rc6 v6.0-rc5 v6.0-rc7] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Nick-Desaulniers/ARM-kprobes-move-__kretprobe_trampoline-to-out-of-line-assembler/20220927-094627 base: aaa11ce2ffc84166d11c4d2ac88c3fcf75425fbd config: arm-allyesconfig compiler: arm-linux-gnueabi-gcc (GCC) 12.1.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/4dd7f6ce622448f06b7fd5edd8620235c76152aa git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Nick-Desaulniers/ARM-kprobes-move-__kretprobe_trampoline-to-out-of-line-assembler/20220927-094627 git checkout 4dd7f6ce622448f06b7fd5edd8620235c76152aa # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash arch/arm/probes/kprobes/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot Note: functions only called from assembly code should be annotated with the asmlinkage attribute All warnings (new ones prefixed by >>): arch/arm/probes/kprobes/core.c:246:16: warning: no previous prototype for 'kprobe_handler' [-Wmissing-prototypes] 246 | void __kprobes kprobe_handler(struct pt_regs *regs) | ^~~~~~~~~~~~~~ >> arch/arm/probes/kprobes/core.c:381:17: warning: no previous prototype for 'trampoline_handler' [-Wmissing-prototypes] 381 | __kprobes void *trampoline_handler(struct pt_regs *regs) | ^~~~~~~~~~~~~~~~~~ vim +/trampoline_handler +381 arch/arm/probes/kprobes/core.c 238 239 /* 240 * Called with IRQs disabled. IRQs must remain disabled from that point 241 * all the way until processing this kprobe is complete. The current 242 * kprobes implementation cannot process more than one nested level of 243 * kprobe, and that level is reserved for user kprobe handlers, so we can't 244 * risk encountering a new kprobe in an interrupt handler. 245 */ > 246 void __kprobes kprobe_handler(struct pt_regs *regs) 247 { 248 struct kprobe *p, *cur; 249 struct kprobe_ctlblk *kcb; 250 251 kcb = get_kprobe_ctlblk(); 252 cur = kprobe_running(); 253 254 #ifdef CONFIG_THUMB2_KERNEL 255 /* 256 * First look for a probe which was registered using an address with 257 * bit 0 set, this is the usual situation for pointers to Thumb code. 258 * If not found, fallback to looking for one with bit 0 clear. 259 */ 260 p = get_kprobe((kprobe_opcode_t *)(regs->ARM_pc | 1)); 261 if (!p) 262 p = get_kprobe((kprobe_opcode_t *)regs->ARM_pc); 263 264 #else /* ! CONFIG_THUMB2_KERNEL */ 265 p = get_kprobe((kprobe_opcode_t *)regs->ARM_pc); 266 #endif 267 268 if (p) { 269 if (!p->ainsn.insn_check_cc(regs->ARM_cpsr)) { 270 /* 271 * Probe hit but conditional execution check failed, 272 * so just skip the instruction and continue as if 273 * nothing had happened. 274 * In this case, we can skip recursing check too. 275 */ 276 singlestep_skip(p, regs); 277 } else if (cur) { 278 /* Kprobe is pending, so we're recursing. */ 279 switch (kcb->kprobe_status) { 280 case KPROBE_HIT_ACTIVE: 281 case KPROBE_HIT_SSDONE: 282 case KPROBE_HIT_SS: 283 /* A pre- or post-handler probe got us here. */ 284 kprobes_inc_nmissed_count(p); 285 save_previous_kprobe(kcb); 286 set_current_kprobe(p); 287 kcb->kprobe_status = KPROBE_REENTER; 288 singlestep(p, regs, kcb); 289 restore_previous_kprobe(kcb); 290 break; 291 case KPROBE_REENTER: 292 /* A nested probe was hit in FIQ, it is a BUG */ 293 pr_warn("Failed to recover from reentered kprobes.\n"); 294 dump_kprobe(p); 295 fallthrough; 296 default: 297 /* impossible cases */ 298 BUG(); 299 } 300 } else { 301 /* Probe hit and conditional execution check ok. */ 302 set_current_kprobe(p); 303 kcb->kprobe_status = KPROBE_HIT_ACTIVE; 304 305 /* 306 * If we have no pre-handler or it returned 0, we 307 * continue with normal processing. If we have a 308 * pre-handler and it returned non-zero, it will 309 * modify the execution path and no need to single 310 * stepping. Let's just reset current kprobe and exit. 311 */ 312 if (!p->pre_handler || !p->pre_handler(p, regs)) { 313 kcb->kprobe_status = KPROBE_HIT_SS; 314 singlestep(p, regs, kcb); 315 if (p->post_handler) { 316 kcb->kprobe_status = KPROBE_HIT_SSDONE; 317 p->post_handler(p, regs, 0); 318 } 319 } 320 reset_current_kprobe(); 321 } 322 } else { 323 /* 324 * The probe was removed and a race is in progress. 325 * There is nothing we can do about it. Let's restart 326 * the instruction. By the time we can restart, the 327 * real instruction will be there. 328 */ 329 } 330 } 331 332 static int __kprobes kprobe_trap_handler(struct pt_regs *regs, unsigned int instr) 333 { 334 unsigned long flags; 335 local_irq_save(flags); 336 kprobe_handler(regs); 337 local_irq_restore(flags); 338 return 0; 339 } 340 341 int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr) 342 { 343 struct kprobe *cur = kprobe_running(); 344 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 345 346 switch (kcb->kprobe_status) { 347 case KPROBE_HIT_SS: 348 case KPROBE_REENTER: 349 /* 350 * We are here because the instruction being single 351 * stepped caused a page fault. We reset the current 352 * kprobe and the PC to point back to the probe address 353 * and allow the page fault handler to continue as a 354 * normal page fault. 355 */ 356 regs->ARM_pc = (long)cur->addr; 357 if (kcb->kprobe_status == KPROBE_REENTER) { 358 restore_previous_kprobe(kcb); 359 } else { 360 reset_current_kprobe(); 361 } 362 break; 363 } 364 365 return 0; 366 } 367 368 int __kprobes kprobe_exceptions_notify(struct notifier_block *self, 369 unsigned long val, void *data) 370 { 371 /* 372 * notify_die() is currently never called on ARM, 373 * so this callback is currently empty. 374 */ 375 return NOTIFY_DONE; 376 } 377 378 /*void __kretprobe_trampoline(void);*/ 379 380 /* Called from __kretprobe_trampoline */ > 381 __kprobes void *trampoline_handler(struct pt_regs *regs) 382 { 383 return (void *)kretprobe_trampoline_handler(regs, (void *)regs->TRAMP_FP); 384 } 385 -- 0-DAY CI Kernel Test Service https://01.org/lkp