From patchwork Fri Jul 5 22:11:05 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Yang X-Patchwork-Id: 257206 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [IPv6:::1]) by ozlabs.org (Postfix) with ESMTP id 8853D2C036F for ; Sat, 6 Jul 2013 08:12:16 +1000 (EST) Received: from db8outboundpool.messaging.microsoft.com (mail-db8lp0185.outbound.messaging.microsoft.com [213.199.154.185]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (Client CN "mail.global.frontbridge.com", Issuer "MSIT Machine Auth CA 2" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 10C5E2C009A for ; Sat, 6 Jul 2013 08:11:20 +1000 (EST) Received: from mail212-db8-R.bigfish.com (10.174.8.243) by DB8EHSOBE002.bigfish.com (10.174.4.65) with Microsoft SMTP Server id 14.1.225.22; Fri, 5 Jul 2013 22:11:15 +0000 Received: from mail212-db8 (localhost [127.0.0.1]) by mail212-db8-R.bigfish.com (Postfix) with ESMTP id 247E536009F; Fri, 5 Jul 2013 22:11:15 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1f42h1ee6h1de0h1fdah2073h1202h1e76h1d1ah1d2ah1fc6hzz8275bhz2dh2a8h668h839he5bhf0ah1239h1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1b5bh1d0ch1d2eh1d3fh1dfeh1dffh1e1dh1e23h1155h) Received: from mail212-db8 (localhost.localdomain [127.0.0.1]) by mail212-db8 (MessageSwitch) id 1373062271998171_14018; Fri, 5 Jul 2013 22:11:11 +0000 (UTC) Received: from DB8EHSMHS020.bigfish.com (unknown [10.174.8.225]) by mail212-db8.bigfish.com (Postfix) with ESMTP id EE7DB4C0045; Fri, 5 Jul 2013 22:11:11 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by DB8EHSMHS020.bigfish.com (10.174.4.30) with Microsoft SMTP Server (TLS) id 14.16.227.3; Fri, 5 Jul 2013 22:11:11 +0000 Received: from tx30smr01.am.freescale.net (10.81.153.31) by 039-SN1MMR1-003.039d.mgd.msft.net (10.84.1.16) with Microsoft SMTP Server (TLS) id 14.2.328.11; Fri, 5 Jul 2013 22:11:10 +0000 Received: from perf2farm5.perfsim (perf2farm5.am.freescale.net [10.82.177.65]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id r65MB9E8008247; Fri, 5 Jul 2013 15:11:09 -0700 Received: from ra8135 by perf2farm5.perfsim with local (Exim 4.71) (envelope-from ) id 1UvEDd-000188-0C; Fri, 05 Jul 2013 17:11:09 -0500 From: James Yang To: , Subject: [RFC][PATCH 2/2] powerpc/booke: revert PTRACE_SINGLEBLOCK to BookE behavior Date: Fri, 5 Jul 2013 17:11:05 -0500 Message-ID: <1373062265-4267-3-git-send-email-James.Yang@freescale.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1373062265-4267-1-git-send-email-James.Yang@freescale.com> References: <1373062265-4267-1-git-send-email-James.Yang@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.net X-FOPE-CONNECTOR: Id%0$Dn%*$RO%0$TLS%0$FQDN%$TlsDn% Cc: James Yang , linuxppc-dev@lists.ozlabs.org X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" A BookE branch taken debug exception followed by a single step does not accurately simulate Server's branch execute debug exception. BookE's branch taken debug exception stops before the branch is to be executed and only happens if the branch will actually be taken. Server's branch execute trace exception stops on the instruction after the branch executes, regardless of whether or not the branch redirected the program counter. The existing PTRACE_SINGLEBLOCK support for BookE hardcodes a single step after the branch taken exception is taken in order to simulate Server's behavior, but this misses fall-through branch instructions (i.e., branches that are NOT taken). Also, the si_code became masked as TRAP_TRACE instead of TRAP_BRANCH. This patch provides native support for the BookE branch taken debug exception's behavior: PTRACE_SINGLEBLOCK stops with a SIGTRAP before a branch-that-would-be-taken would execute. Userspace software will be able to examine the process state upon catching the SIGTRAP, and it will need to issue a PTRACE_SINGLESTEP or PTRACE_CONT to resume program execution past the branch. Signed-off-by: James Yang --- arch/powerpc/kernel/traps.c | 40 +++++++++++++++++++++++++++------------- 1 files changed, 27 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index c3ceaa2..5837d7f 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1518,12 +1518,21 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status) { current->thread.dbsr = debug_status; - /* 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 + /* BookE's Branch Taken Debug Exception stops on the branch iff the + * branch is resolved to be taken. No exception occurs if the branch + * is not taken (no exception if the branch does not redirect the PC). + * This is unlike Classic/Server's behavior where the exception occurs + * after the branch executes, regardless of whether or not the branch + * redirected the PC. + * + * The past behavior of this function was to simulate Classic/Server's + * behavior by performing a single-step upon a branch taken exception. + * However, the simulation is not accurate because fall-through non- + * taken branches would not result in a SIGTRAP. Also, that SIGTRAP's + * si_code would be reported as a TRAP_TRACE instead of a TRAP_BRANCH. */ - if (debug_status & DBSR_BT) { + + if (debug_status & DBSR_BT) { /* Branch Taken */ regs->msr &= ~MSR_DE; /* Disable BT */ @@ -1531,20 +1540,25 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status) /* 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; + + if (user_mode(regs)) { + current->thread.dbcr0 &= ~DBCR0_BT; + if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0, + current->thread.dbcr1)) + regs->msr |= MSR_DE; + else + /* Make sure the IDM bit is off */ + current->thread.dbcr0 &= ~DBCR0_IDM; + } + + _exception(SIGTRAP, regs, TRAP_BRANCH, regs->nip); } else if (debug_status & DBSR_IC) { /* Instruction complete */ regs->msr &= ~MSR_DE;