aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2011-02-28 13:08:32 -0500
committerChris Metcalf <cmetcalf@tilera.com>2011-03-01 16:19:58 -0500
commit04f7a3f12e10032ee3d44df1a509dbf5b2001fce (patch)
tree2e9281f10f1dffc9fc6b470e823b02bb720ecc4c /arch
parent2cb82400719e085a3c226cf7cce8950208f09a06 (diff)
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/tile/include/asm/ptrace.h3
-rw-r--r--arch/tile/kernel/process.c4
-rw-r--r--arch/tile/kernel/single_step.c21
3 files changed, 26 insertions, 2 deletions
diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h
index ac6d343129d3..6be2246e015c 100644
--- a/arch/tile/include/asm/ptrace.h
+++ b/arch/tile/include/asm/ptrace.h
@@ -141,6 +141,9 @@ struct single_step_state {
141/* Single-step the instruction at regs->pc */ 141/* Single-step the instruction at regs->pc */
142extern void single_step_once(struct pt_regs *regs); 142extern void single_step_once(struct pt_regs *regs);
143 143
144/* Clean up after execve(). */
145extern void single_step_execve(void);
146
144struct task_struct; 147struct task_struct;
145 148
146extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, 149extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index e90eb53173b0..5db8b5b63cea 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -574,6 +574,8 @@ SYSCALL_DEFINE4(execve, const char __user *, path,
574 goto out; 574 goto out;
575 error = do_execve(filename, argv, envp, regs); 575 error = do_execve(filename, argv, envp, regs);
576 putname(filename); 576 putname(filename);
577 if (error == 0)
578 single_step_execve();
577out: 579out:
578 return error; 580 return error;
579} 581}
@@ -593,6 +595,8 @@ long compat_sys_execve(const char __user *path,
593 goto out; 595 goto out;
594 error = compat_do_execve(filename, argv, envp, regs); 596 error = compat_do_execve(filename, argv, envp, regs);
595 putname(filename); 597 putname(filename);
598 if (error == 0)
599 single_step_execve();
596out: 600out:
597 return error; 601 return error;
598} 602}
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 1eb3b39e36c7..84a729e06ec4 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -56,7 +56,7 @@ enum mem_op {
56 MEMOP_STORE_POSTINCR 56 MEMOP_STORE_POSTINCR
57}; 57};
58 58
59static inline tile_bundle_bits set_BrOff_X1(tile_bundle_bits n, int32_t offset) 59static inline tile_bundle_bits set_BrOff_X1(tile_bundle_bits n, s32 offset)
60{ 60{
61 tile_bundle_bits result; 61 tile_bundle_bits result;
62 62
@@ -254,6 +254,18 @@ P("\n");
254 return bundle; 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 */
262void 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 * single_step_once() - entry point when single stepping has been triggered. 270 * single_step_once() - entry point when single stepping has been triggered.
259 * @regs: The machine register state 271 * @regs: The machine register state
@@ -373,7 +385,7 @@ void single_step_once(struct pt_regs *regs)
373 /* branches */ 385 /* branches */
374 case BRANCH_OPCODE_X1: 386 case BRANCH_OPCODE_X1:
375 { 387 {
376 int32_t offset = signExtend17(get_BrOff_X1(bundle)); 388 s32 offset = signExtend17(get_BrOff_X1(bundle));
377 389
378 /* 390 /*
379 * For branches, we use a rewriting trick to let the 391 * For branches, we use a rewriting trick to let the
@@ -731,4 +743,9 @@ void single_step_once(struct pt_regs *regs)
731 __insn_mtspr(SPR_SINGLE_STEP_EN_K_K, 1 << USER_PL); 743 __insn_mtspr(SPR_SINGLE_STEP_EN_K_K, 1 << USER_PL);
732} 744}
733 745
746void single_step_execve(void)
747{
748 /* Nothing */
749}
750
734#endif /* !__tilegx__ */ 751#endif /* !__tilegx__ */