[3.13.y-ckt stable] Patch "ARM: 8356/1: mm: handle non-pmd-aligned end of RAM" has been added to staging queue

Kamal Mostafa kamal at canonical.com
Tue Jul 7 22:16:00 UTC 2015


This is a note to let you know that I have just added a patch titled

    ARM: 8356/1: mm: handle non-pmd-aligned end of RAM

to the linux-3.13.y-queue branch of the 3.13.y-ckt extended stable tree 
which can be found at:

    http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-3.13.y-queue

This patch is scheduled to be released in version 3.13.11-ckt23.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.13.y-ckt tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Kamal

------

>From 1efef185b0870b01164b994c49115d6cd7542063 Mon Sep 17 00:00:00 2001
From: Mark Rutland <mark.rutland at arm.com>
Date: Wed, 13 May 2015 15:07:54 +0100
Subject: ARM: 8356/1: mm: handle non-pmd-aligned end of RAM

commit 965278dcb8ab0b1f666cc47937933c4be4aea48d upstream.

At boot time we round the memblock limit down to section size in an
attempt to ensure that we will have mapped this RAM with section
mappings prior to allocating from it. When mapping RAM we iterate over
PMD-sized chunks, creating these section mappings.

Section mappings are only created when the end of a chunk is aligned to
section size. Unfortunately, with classic page tables (where PMD_SIZE is
2 * SECTION_SIZE) this means that if a chunk is between 1M and 2M in
size the first 1M will not be mapped despite having been accounted for
in the memblock limit. This has been observed to result in page tables
being allocated from unmapped memory, causing boot-time hangs.

This patch modifies the memblock limit rounding to always round down to
PMD_SIZE instead of SECTION_SIZE. For classic MMU this means that we
will round the memblock limit down to a 2M boundary, matching the limits
on section mappings, and preventing allocations from unmapped memory.
For LPAE there should be no change as PMD_SIZE == SECTION_SIZE.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reported-by: Stefan Agner <stefan at agner.ch>
Tested-by: Stefan Agner <stefan at agner.ch>
Acked-by: Laura Abbott <labbott at redhat.com>
Tested-by: Hans de Goede <hdegoede at redhat.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Steve Capper <steve.capper at linaro.org>
Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
[ kamal: backport to 3.13-stable: block_start, block_end rename ]
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
 arch/arm/mm/mmu.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index b8c90c5..7425ed6 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1077,22 +1077,22 @@ void __init sanity_check_meminfo(void)
 				arm_lowmem_limit = bank_end;

 			/*
-			 * Find the first non-section-aligned page, and point
+			 * Find the first non-pmd-aligned page, and point
 			 * memblock_limit at it. This relies on rounding the
-			 * limit down to be section-aligned, which happens at
-			 * the end of this function.
+			 * limit down to be pmd-aligned, which happens at the
+			 * end of this function.
 			 *
 			 * With this algorithm, the start or end of almost any
-			 * bank can be non-section-aligned. The only exception
-			 * is that the start of the bank 0 must be section-
+			 * bank can be non-pmd-aligned. The only exception is
+			 * that the start of the bank 0 must be section-
 			 * aligned, since otherwise memory would need to be
 			 * allocated when mapping the start of bank 0, which
 			 * occurs before any free memory is mapped.
 			 */
 			if (!memblock_limit) {
-				if (!IS_ALIGNED(bank->start, SECTION_SIZE))
+				if (!IS_ALIGNED(bank->start, PMD_SIZE))
 					memblock_limit = bank->start;
-				else if (!IS_ALIGNED(bank_end, SECTION_SIZE))
+				else if (!IS_ALIGNED(bank_end, PMD_SIZE))
 					memblock_limit = bank_end;
 			}
 		}
@@ -1122,12 +1122,12 @@ void __init sanity_check_meminfo(void)
 	high_memory = __va(arm_lowmem_limit - 1) + 1;

 	/*
-	 * Round the memblock limit down to a section size.  This
+	 * Round the memblock limit down to a pmd size.  This
 	 * helps to ensure that we will allocate memory from the
-	 * last full section, which should be mapped.
+	 * last full pmd, which should be mapped.
 	 */
 	if (memblock_limit)
-		memblock_limit = round_down(memblock_limit, SECTION_SIZE);
+		memblock_limit = round_down(memblock_limit, PMD_SIZE);
 	if (!memblock_limit)
 		memblock_limit = arm_lowmem_limit;

--
1.9.1





More information about the kernel-team mailing list