powerpc: Add PTRACE_SINGLEBLOCK support
Reworked by: Benjamin Herrenschmidt <benh@kernel.crashing.org> This adds block-step support on powerpc, including a PTRACE_SINGLEBLOCK request for ptrace. The BookE implementation is tweaked to fire a single step after a block step in order to mimmic the server behaviour. Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:

committed by
Benjamin Herrenschmidt

parent
dac4ccfb64
commit
ec097c84df
@@ -1041,7 +1041,34 @@ void SoftwareEmulation(struct pt_regs *regs)
|
||||
|
||||
void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
|
||||
{
|
||||
if (debug_status & DBSR_IC) { /* instruction completion */
|
||||
/* Hack alert: On BookE, Branch Taken stops on the branch itself, while
|
||||
* on server, it stops on the target of the branch. In order to simulate
|
||||
* the server behaviour, we thus restart right away with a single step
|
||||
* instead of stopping here when hitting a BT
|
||||
*/
|
||||
if (debug_status & DBSR_BT) {
|
||||
regs->msr &= ~MSR_DE;
|
||||
|
||||
/* Disable BT */
|
||||
mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_BT);
|
||||
/* Clear the BT event */
|
||||
mtspr(SPRN_DBSR, DBSR_BT);
|
||||
|
||||
/* Do the single step trick only when coming from userspace */
|
||||
if (user_mode(regs)) {
|
||||
current->thread.dbcr0 &= ~DBCR0_BT;
|
||||
current->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
|
||||
regs->msr |= MSR_DE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (notify_die(DIE_SSTEP, "block_step", regs, 5,
|
||||
5, SIGTRAP) == NOTIFY_STOP) {
|
||||
return;
|
||||
}
|
||||
if (debugger_sstep(regs))
|
||||
return;
|
||||
} else if (debug_status & DBSR_IC) { /* Instruction complete */
|
||||
regs->msr &= ~MSR_DE;
|
||||
|
||||
/* Disable instruction completion */
|
||||
@@ -1057,9 +1084,8 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
|
||||
if (debugger_sstep(regs))
|
||||
return;
|
||||
|
||||
if (user_mode(regs)) {
|
||||
current->thread.dbcr0 &= ~DBCR0_IC;
|
||||
}
|
||||
if (user_mode(regs))
|
||||
current->thread.dbcr0 &= ~(DBCR0_IC);
|
||||
|
||||
_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
|
||||
} else if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
|
||||
|
Reference in New Issue
Block a user