aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-01-13 10:00:51 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-01-13 10:02:35 -0500
commit716a3dc20084da9b3ab17bd125005a5345e23e3b (patch)
treef7ba487050d33fc2913fdee81b384f5578ccb105 /arch/arm/mm
parent4de3a8e101150feaefa1139611a50ff37467f33e (diff)
ARM: Add arm_memblock_steal() to allocate memory away from the kernel
Several platforms are now using the memblock_alloc+memblock_free+ memblock_remove trick to obtain memory which won't be mapped in the kernel's page tables. Most platforms do this (correctly) in the ->reserve callback. However, OMAP has started to call these functions outside of this callback, and this is extremely unsafe - memory will not be unmapped, and could well be given out after memblock is no longer responsible for its management. So, provide arm_memblock_steal() to perform this function, and ensure that it panic()s if it is used inappropriately. Convert everyone over, including OMAP. As a result, OMAP with OMAP4_ERRATA_I688 enabled will panic on boot with this change. Mark this option as BROKEN and make it depend on BROKEN. OMAP needs to be fixed, or 137d105d50 (ARM: OMAP4: Fix errata i688 with MPU interconnect barriers.) reverted until such time it can be fixed correctly. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/init.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index e34ea8adc1f9..6ec1226fc62d 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -22,6 +22,7 @@
22#include <linux/memblock.h> 22#include <linux/memblock.h>
23 23
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25#include <asm/memblock.h>
25#include <asm/prom.h> 26#include <asm/prom.h>
26#include <asm/sections.h> 27#include <asm/sections.h>
27#include <asm/setup.h> 28#include <asm/setup.h>
@@ -307,6 +308,21 @@ static void arm_memory_present(void)
307} 308}
308#endif 309#endif
309 310
311static bool arm_memblock_steal_permitted = true;
312
313phys_addr_t arm_memblock_steal(phys_addr_t size, phys_addr_t align)
314{
315 phys_addr_t phys;
316
317 BUG_ON(!arm_memblock_steal_permitted);
318
319 phys = memblock_alloc(size, align);
320 memblock_free(phys, size);
321 memblock_remove(phys, size);
322
323 return phys;
324}
325
310void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) 326void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
311{ 327{
312 int i; 328 int i;
@@ -349,6 +365,7 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
349 if (mdesc->reserve) 365 if (mdesc->reserve)
350 mdesc->reserve(); 366 mdesc->reserve();
351 367
368 arm_memblock_steal_permitted = false;
352 memblock_allow_resize(); 369 memblock_allow_resize();
353 memblock_dump_all(); 370 memblock_dump_all();
354} 371}