From patchwork Mon Jul 8 22:44:55 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Warren X-Patchwork-Id: 2825004 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D78F9C0AB2 for ; Mon, 8 Jul 2013 22:45:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 014DA2013D for ; Mon, 8 Jul 2013 22:45:36 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C90CF2011B for ; Mon, 8 Jul 2013 22:45:34 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UwKBW-0001eZ-Us; Mon, 08 Jul 2013 22:45:31 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UwKBU-0001oR-Fi; Mon, 08 Jul 2013 22:45:28 +0000 Received: from avon.wwwdotorg.org ([2001:470:1f0f:bd7::2]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UwKBR-0001nv-K0 for linux-arm-kernel@lists.infradead.org; Mon, 08 Jul 2013 22:45:26 +0000 Received: from severn.wwwdotorg.org (unknown [192.168.65.5]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by avon.wwwdotorg.org (Postfix) with ESMTPS id D026563C3; Mon, 8 Jul 2013 16:56:26 -0600 (MDT) Received: from swarren-lx1.nvidia.com (localhost [127.0.0.1]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by severn.wwwdotorg.org (Postfix) with ESMTPSA id 05813E461B; Mon, 8 Jul 2013 16:45:00 -0600 (MDT) From: Stephen Warren To: Russell King Subject: [PATCH] ARM: mm: restrict early_alloc_aligned to legal area Date: Mon, 8 Jul 2013 16:44:55 -0600 Message-Id: <1373323495-10087-1-git-send-email-swarren@wwwdotorg.org> X-Mailer: git-send-email 1.8.1.5 X-NVConfidentiality: public X-Virus-Scanned: clamav-milter 0.97.7 at avon.wwwdotorg.org X-Virus-Status: Clean X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130708_184525_749792_7397F14F X-CRM114-Status: GOOD ( 13.55 ) X-Spam-Score: -2.2 (--) Cc: Stephen Warren , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stephen Warren When early_alloc_aligned() is called, it appears that only memory in the first memory bank is mapped for CPU access. However, memblock_alloc() is called to allocate the RAM, and that can return RAM that is part of any valid memory bank, which hence could be inaccessible to the CPU. If this happens, the subsequent memset() will hang or crash. Solve this by calling memblock_alloc_base() instead of memblock_alloc(). This function takes an explicit max address. Use the end of the first memory bank as the address. As an example, this issue can be triggered as follows: * Total of 512MB system RAM, so it is all lowmem not highmem. Without this, subsequent banks may be ignored by map_lowmem() due to being highmem. * RAM is split into multiple banks, due to some RAM somewhere in the middle having been allocated for purposes other than Linux, e.g. an LCD frame-buffer of for a co-processor. * Some bank is not section-aligned, so that alloc_init_pte() is called rather than __map_init_section(). Signed-off-by: Stephen Warren --- arch/arm/mm/mmu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index d7229d2..0849741 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -585,7 +585,10 @@ EXPORT_SYMBOL(phys_mem_access_prot); static void __init *early_alloc_aligned(unsigned long sz, unsigned long align) { - void *ptr = __va(memblock_alloc(sz, align)); + phys_addr_t max_pa = memblock.memory.regions[0].base + + memblock.memory.regions[0].size; + phys_addr_t pa = memblock_alloc_base(sz, align, max_pa); + void *ptr = __va(pa); memset(ptr, 0, sz); return ptr; }