From 716a3dc20084da9b3ab17bd125005a5345e23e3b Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 13 Jan 2012 15:00:51 +0000 Subject: 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 --- arch/arm/mm/init.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'arch/arm/mm/init.c') diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index e34ea8a..6ec1226 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -307,6 +308,21 @@ static void arm_memory_present(void) } #endif +static bool arm_memblock_steal_permitted = true; + +phys_addr_t arm_memblock_steal(phys_addr_t size, phys_addr_t align) +{ + phys_addr_t phys; + + BUG_ON(!arm_memblock_steal_permitted); + + phys = memblock_alloc(size, align); + memblock_free(phys, size); + memblock_remove(phys, size); + + return phys; +} + void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) { int i; @@ -349,6 +365,7 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) if (mdesc->reserve) mdesc->reserve(); + arm_memblock_steal_permitted = false; memblock_allow_resize(); memblock_dump_all(); } -- cgit v1.1