From patchwork Sat Sep 22 08:11:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Walmsley X-Patchwork-Id: 1494271 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 7ADD7DF2D2 for ; Sat, 22 Sep 2012 08:13:17 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TFKoL-0003bI-2c; Sat, 22 Sep 2012 08:11:37 +0000 Received: from utopia.booyaka.com ([74.50.51.50]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TFKoB-0003Zc-Ge for linux-arm-kernel@lists.infradead.org; Sat, 22 Sep 2012 08:11:33 +0000 Received: (qmail 24632 invoked by uid 1019); 22 Sep 2012 08:11:25 -0000 Date: Sat, 22 Sep 2012 08:11:25 +0000 (UTC) From: Paul Walmsley To: tony@atomide.com, santosh.shilimkar@ti.com Subject: [PATCH] ARM: OMAP4+: wakeupgen: fix memory corruption Message-ID: User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Fix a memory corruption bug caused by commit 247c445c0fbd52c77e497ff5bfcf0dceb8afea8d ("ARM: OMAP5: Add the WakeupGen IP updates") and commit ec2c0825ca3183a646a24717966cc7752e8b0393 ("ARM: OMAP2+: Remove hardcoded IRQs and enable SPARSE_IRQ"). The first commit, in the OMAP4+ wakeupgen code, has an implicit dependency on !SPARSE_IRQ. It allocates a static array with NR_IRQS elements, then proceeds to iterate over 128 or 160 elements of that array, clearing them to zero. The second commit switched OMAP2+ to use sparse IRQs, but missed the NR_IRQS reference in the wakeupgen code. Before the second commit, NR_IRQS was 474 on OMAP4430; but afterwards, it became 16. This resulted in the wakeupgen code allocating a 16 element array, and then attempting to write to 128 or 160 of those elements, depending on the type of SoC. This trashed a chunk of whatever was allocated after the array. The immediate manifestation was a set of boot warnings similar to the following: WARNING: at arch/arm/mach-omap2/omap_hwmod.c:1941 _enable+0x1bc/0x204() omap_hwmod: mpu: could not enable clockdomain mpuss_clkdm: -22 ... since it blew away arch_clkdm. Ultimately the kernel crashed during boot. Fix the problem in the OMAP4+ wakeupgen code by removing the reference to NR_IRQS, allocating a larger array, and warning if the iteration is larger than the array. Signed-off-by: Paul Walmsley Cc: Tony Lindgren Cc: Santosh Shilimkar --- Applies on arm-soc omap/cleanup-sparseirq and should ideally be merged there before the 3.7 merge window. Test logs are here: http://www.pwsan.com/omap/testlogs/broken_sparseirq_fix_3.7/20120922012656/ arch/arm/mach-omap2/omap-wakeupgen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index b54427d..869f16c 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -47,7 +47,7 @@ static void __iomem *wakeupgen_base; static void __iomem *sar_base; static DEFINE_SPINLOCK(wakeupgen_lock); -static unsigned int irq_target_cpu[NR_IRQS]; +static unsigned int irq_target_cpu[MAX_IRQS]; static unsigned int irq_banks = MAX_NR_REG_BANKS; static unsigned int max_irqs = MAX_IRQS; static unsigned int omap_secure_apis; @@ -446,6 +446,12 @@ int __init omap_wakeupgen_init(void) * GIC code has necessary hooks in place. */ + /* + * If you see this warning, then the subsequent loop just + * corrupted some memory + */ + WARN_ON(max_irqs > ARRAY_SIZE(irq_target_cpu)); + /* Associate all the IRQs to boot CPU like GIC init does. */ for (i = 0; i < max_irqs; i++) irq_target_cpu[i] = boot_cpu;