aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/kernel/single_step.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/tile/kernel/single_step.c')
-rw-r--r--arch/tile/kernel/single_step.c106
1 files changed, 103 insertions, 3 deletions
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 5ec4b9c651f2..4032ca8e51b6 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -15,7 +15,7 @@
15 * Derived from iLib's single-stepping code. 15 * Derived from iLib's single-stepping code.
16 */ 16 */
17 17
18#ifndef __tilegx__ /* No support for single-step yet. */ 18#ifndef __tilegx__ /* Hardware support for single step unavailable. */
19 19
20/* These functions are only used on the TILE platform */ 20/* These functions are only used on the TILE platform */
21#include <linux/slab.h> 21#include <linux/slab.h>
@@ -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
@@ -186,6 +186,8 @@ static tile_bundle_bits rewrite_load_store_unaligned(
186 .si_code = SEGV_MAPERR, 186 .si_code = SEGV_MAPERR,
187 .si_addr = addr 187 .si_addr = addr
188 }; 188 };
189 trace_unhandled_signal("segfault", regs,
190 (unsigned long)addr, SIGSEGV);
189 force_sig_info(info.si_signo, &info, current); 191 force_sig_info(info.si_signo, &info, current);
190 return (tile_bundle_bits) 0; 192 return (tile_bundle_bits) 0;
191 } 193 }
@@ -196,6 +198,8 @@ static tile_bundle_bits rewrite_load_store_unaligned(
196 .si_code = BUS_ADRALN, 198 .si_code = BUS_ADRALN,
197 .si_addr = addr 199 .si_addr = addr
198 }; 200 };
201 trace_unhandled_signal("unaligned trap", regs,
202 (unsigned long)addr, SIGBUS);
199 force_sig_info(info.si_signo, &info, current); 203 force_sig_info(info.si_signo, &info, current);
200 return (tile_bundle_bits) 0; 204 return (tile_bundle_bits) 0;
201 } 205 }
@@ -254,6 +258,18 @@ P("\n");
254 return bundle; 258 return bundle;
255} 259}
256 260
261/*
262 * Called after execve() has started the new image. This allows us
263 * to reset the info state. Note that the the mmap'ed memory, if there
264 * was any, has already been unmapped by the exec.
265 */
266void single_step_execve(void)
267{
268 struct thread_info *ti = current_thread_info();
269 kfree(ti->step_state);
270 ti->step_state = NULL;
271}
272
257/** 273/**
258 * single_step_once() - entry point when single stepping has been triggered. 274 * single_step_once() - entry point when single stepping has been triggered.
259 * @regs: The machine register state 275 * @regs: The machine register state
@@ -306,6 +322,14 @@ void single_step_once(struct pt_regs *regs)
306" .popsection\n" 322" .popsection\n"
307 ); 323 );
308 324
325 /*
326 * Enable interrupts here to allow touching userspace and the like.
327 * The callers expect this: do_trap() already has interrupts
328 * enabled, and do_work_pending() handles functions that enable
329 * interrupts internally.
330 */
331 local_irq_enable();
332
309 if (state == NULL) { 333 if (state == NULL) {
310 /* allocate a page of writable, executable memory */ 334 /* allocate a page of writable, executable memory */
311 state = kmalloc(sizeof(struct single_step_state), GFP_KERNEL); 335 state = kmalloc(sizeof(struct single_step_state), GFP_KERNEL);
@@ -373,7 +397,7 @@ void single_step_once(struct pt_regs *regs)
373 /* branches */ 397 /* branches */
374 case BRANCH_OPCODE_X1: 398 case BRANCH_OPCODE_X1:
375 { 399 {
376 int32_t offset = signExtend17(get_BrOff_X1(bundle)); 400 s32 offset = signExtend17(get_BrOff_X1(bundle));
377 401
378 /* 402 /*
379 * For branches, we use a rewriting trick to let the 403 * For branches, we use a rewriting trick to let the
@@ -660,4 +684,80 @@ void single_step_once(struct pt_regs *regs)
660 regs->pc += 8; 684 regs->pc += 8;
661} 685}
662 686
687#else
688#include <linux/smp.h>
689#include <linux/ptrace.h>
690#include <arch/spr_def.h>
691
692static DEFINE_PER_CPU(unsigned long, ss_saved_pc);
693
694
695/*
696 * Called directly on the occasion of an interrupt.
697 *
698 * If the process doesn't have single step set, then we use this as an
699 * opportunity to turn single step off.
700 *
701 * It has been mentioned that we could conditionally turn off single stepping
702 * on each entry into the kernel and rely on single_step_once to turn it
703 * on for the processes that matter (as we already do), but this
704 * implementation is somewhat more efficient in that we muck with registers
705 * once on a bum interrupt rather than on every entry into the kernel.
706 *
707 * If SINGLE_STEP_CONTROL_K has CANCELED set, then an interrupt occurred,
708 * so we have to run through this process again before we can say that an
709 * instruction has executed.
710 *
711 * swint will set CANCELED, but it's a legitimate instruction. Fortunately
712 * it changes the PC. If it hasn't changed, then we know that the interrupt
713 * wasn't generated by swint and we'll need to run this process again before
714 * we can say an instruction has executed.
715 *
716 * If either CANCELED == 0 or the PC's changed, we send out SIGTRAPs and get
717 * on with our lives.
718 */
719
720void gx_singlestep_handle(struct pt_regs *regs, int fault_num)
721{
722 unsigned long *ss_pc = &__get_cpu_var(ss_saved_pc);
723 struct thread_info *info = (void *)current_thread_info();
724 int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP);
725 unsigned long control = __insn_mfspr(SPR_SINGLE_STEP_CONTROL_K);
726
727 if (is_single_step == 0) {
728 __insn_mtspr(SPR_SINGLE_STEP_EN_K_K, 0);
729
730 } else if ((*ss_pc != regs->pc) ||
731 (!(control & SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK))) {
732
733 ptrace_notify(SIGTRAP);
734 control |= SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK;
735 control |= SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK;
736 __insn_mtspr(SPR_SINGLE_STEP_CONTROL_K, control);
737 }
738}
739
740
741/*
742 * Called from need_singlestep. Set up the control registers and the enable
743 * register, then return back.
744 */
745
746void single_step_once(struct pt_regs *regs)
747{
748 unsigned long *ss_pc = &__get_cpu_var(ss_saved_pc);
749 unsigned long control = __insn_mfspr(SPR_SINGLE_STEP_CONTROL_K);
750
751 *ss_pc = regs->pc;
752 control |= SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK;
753 control |= SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK;
754 __insn_mtspr(SPR_SINGLE_STEP_CONTROL_K, control);
755 __insn_mtspr(SPR_SINGLE_STEP_EN_K_K, 1 << USER_PL);
756}
757
758void single_step_execve(void)
759{
760 /* Nothing */
761}
762
663#endif /* !__tilegx__ */ 763#endif /* !__tilegx__ */