From patchwork Sun Jan 27 17:03:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Mats_K=C3=A4rrman?= X-Patchwork-Id: 216022 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 5673E2C0092 for ; Mon, 28 Jan 2013 04:10:13 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 77C644A09D; Sun, 27 Jan 2013 18:04:11 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jAlAF5Z9E-Ld; Sun, 27 Jan 2013 18:04:11 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id F22164A094; Sun, 27 Jan 2013 18:04:09 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7FE7F4A094 for ; Sun, 27 Jan 2013 18:03:58 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id GuyPsgnGCQVV for ; Sun, 27 Jan 2013 18:03:57 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from tritech.se (tritech.se [46.59.120.190]) by theia.denx.de (Postfix) with ESMTP id AAC9A4A092 for ; Sun, 27 Jan 2013 18:03:55 +0100 (CET) Received: from post.tritech.se (post.tritech.se [10.75.60.100]) by tritech.se (8.14.3/8.14.3) with ESMTP id r0RH3jYY021500; Sun, 27 Jan 2013 18:03:50 +0100 Received: from POST.tritech.se ([fe80::b4fc:968e:bbef:54cb]) by post.tritech.se ([fe80::b4fc:968e:bbef:54cb%10]) with mapi id 14.02.0318.001; Sun, 27 Jan 2013 18:03:45 +0100 From: =?iso-8859-1?Q?Mats_K=E4rrman?= To: "u-boot@lists.denx.de" Thread-Topic: [PATCH] powerpc/lib: fix unsafe register handling in wait_ticks Thread-Index: Ac38r4fGZEEQ687oT+OreJDExp+OfA== Date: Sun, 27 Jan 2013 17:03:44 +0000 Message-ID: Accept-Language: en-US, sv-SE Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [195.84.96.196] MIME-Version: 1.0 Subject: [U-Boot] [PATCH] powerpc/lib: fix unsafe register handling in wait_ticks X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de If watchdog is enabled, the arch/powerpc/lib/ticks.S::wait_ticks() function calls the function specified by the WATCHDOG_RESET macro. The wait_ticks function depends on the registers r0, r6 and r7 being preserved however that is not guaranteed, e.g. if the reset function is a C function this will probably overwrite r0 and cause an endless loop. The following patch changes to using r14+r15 instead of r6+r7 (to resemble what would have been generated by a C compiler) and saves all necessary registers on the stack. The patch has been tested on a custom MPC5125 based machine using the 512x powerpc architecture. Signed-off-by: Mats Karrman Cc: Wolfgang Denk Acked-by: Joakim Tjernlund Tested-by: Stefan Roese --- arch/powerpc/lib/ticks.S | 17 +++++++++++------ 1 files changed, 11 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/lib/ticks.S b/arch/powerpc/lib/ticks.S index 1781039..63114bb 100644 --- a/arch/powerpc/lib/ticks.S +++ b/arch/powerpc/lib/ticks.S @@ -50,19 +50,24 @@ wait_ticks: stwu r1, -16(r1) mflr r0 /* save link register */ stw r0, 20(r1) /* Use r0 or GDB will be unhappy */ - mr r7, r3 /* save tick count */ + stw r14, 12(r1) /* save used registers */ + stw r15, 8(r1) + mr r14, r3 /* save tick count */ bl get_ticks /* Get start time */ /* Calculate end time */ - addc r7, r4, r7 /* Compute end time lower */ - addze r6, r3 /* and end time upper */ + addc r14, r4, r14 /* Compute end time lower */ + addze r15, r3 /* and end time upper */ WATCHDOG_RESET /* Trigger watchdog, if needed */ 1: bl get_ticks /* Get current time */ - subfc r4, r4, r7 /* Subtract current time from end time */ - subfe. r3, r3, r6 + subfc r4, r4, r14 /* Subtract current time from end time */ + subfe. r3, r3, r15 bge 1b /* Loop until time expired */ - mtlr r0 /* restore link register */ + lwz r15, 8(r1) /* restore saved registers */ + lwz r14, 12(r1) + lwz r0, 20(r1) addi r1,r1,16 + mtlr r0 blr