Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arch/tile: bug fix: exec'ed task thought it was still single-stepping

To handle single-step, tile mmap's a page of memory in the process
space for each thread and uses it to construct a version of the
instruction that we want to single step. If the process exec's,
though, we lose that mapping, and the kernel needs to be aware that
it will need to recreate it if the exec'ed process than tries to
single-step as well.

Also correct some int32_t to s32 for better kernel style.

Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>

+26 -2
+3
arch/tile/include/asm/ptrace.h
··· 141 141 /* Single-step the instruction at regs->pc */ 142 142 extern void single_step_once(struct pt_regs *regs); 143 143 144 + /* Clean up after execve(). */ 145 + extern void single_step_execve(void); 146 + 144 147 struct task_struct; 145 148 146 149 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
+4
arch/tile/kernel/process.c
··· 574 574 goto out; 575 575 error = do_execve(filename, argv, envp, regs); 576 576 putname(filename); 577 + if (error == 0) 578 + single_step_execve(); 577 579 out: 578 580 return error; 579 581 } ··· 595 593 goto out; 596 594 error = compat_do_execve(filename, argv, envp, regs); 597 595 putname(filename); 596 + if (error == 0) 597 + single_step_execve(); 598 598 out: 599 599 return error; 600 600 }
+19 -2
arch/tile/kernel/single_step.c
··· 56 56 MEMOP_STORE_POSTINCR 57 57 }; 58 58 59 - static inline tile_bundle_bits set_BrOff_X1(tile_bundle_bits n, int32_t offset) 59 + static inline tile_bundle_bits set_BrOff_X1(tile_bundle_bits n, s32 offset) 60 60 { 61 61 tile_bundle_bits result; 62 62 ··· 254 254 return bundle; 255 255 } 256 256 257 + /* 258 + * Called after execve() has started the new image. This allows us 259 + * to reset the info state. Note that the the mmap'ed memory, if there 260 + * was any, has already been unmapped by the exec. 261 + */ 262 + void single_step_execve(void) 263 + { 264 + struct thread_info *ti = current_thread_info(); 265 + kfree(ti->step_state); 266 + ti->step_state = NULL; 267 + } 268 + 257 269 /** 258 270 * single_step_once() - entry point when single stepping has been triggered. 259 271 * @regs: The machine register state ··· 385 373 /* branches */ 386 374 case BRANCH_OPCODE_X1: 387 375 { 388 - int32_t offset = signExtend17(get_BrOff_X1(bundle)); 376 + s32 offset = signExtend17(get_BrOff_X1(bundle)); 389 377 390 378 /* 391 379 * For branches, we use a rewriting trick to let the ··· 741 729 control |= SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK; 742 730 __insn_mtspr(SPR_SINGLE_STEP_CONTROL_K, control); 743 731 __insn_mtspr(SPR_SINGLE_STEP_EN_K_K, 1 << USER_PL); 732 + } 733 + 734 + void single_step_execve(void) 735 + { 736 + /* Nothing */ 744 737 } 745 738 746 739 #endif /* !__tilegx__ */