mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
			
			
This commit is contained in:
		
							parent
							
								
									4de3a8e101
								
							
						
					
					
						commit
						716a3dc200
					
				
					 9 changed files with 34 additions and 32 deletions
				
			
		| 
						 | 
				
			
			@ -6,4 +6,6 @@ struct machine_desc;
 | 
			
		|||
 | 
			
		||||
extern void arm_memblock_init(struct meminfo *, struct machine_desc *);
 | 
			
		||||
 | 
			
		||||
phys_addr_t arm_memblock_steal(phys_addr_t size, phys_addr_t align);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,6 +36,7 @@
 | 
			
		|||
#include <asm/mach/time.h>
 | 
			
		||||
#include <asm/memory.h>
 | 
			
		||||
#include <asm/mach/map.h>
 | 
			
		||||
#include <asm/memblock.h>
 | 
			
		||||
#include <mach/common.h>
 | 
			
		||||
#include <mach/iomux-mx3.h>
 | 
			
		||||
#include <mach/3ds_debugboard.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -754,10 +755,8 @@ static struct sys_timer mx31_3ds_timer = {
 | 
			
		|||
static void __init mx31_3ds_reserve(void)
 | 
			
		||||
{
 | 
			
		||||
	/* reserve MX31_3DS_CAMERA_BUF_SIZE bytes for mx3-camera */
 | 
			
		||||
	mx3_camera_base = memblock_alloc(MX31_3DS_CAMERA_BUF_SIZE,
 | 
			
		||||
	mx3_camera_base = arm_memblock_steal(MX31_3DS_CAMERA_BUF_SIZE,
 | 
			
		||||
					 MX31_3DS_CAMERA_BUF_SIZE);
 | 
			
		||||
	memblock_free(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE);
 | 
			
		||||
	memblock_remove(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,6 +41,7 @@
 | 
			
		|||
#include <asm/mach/arch.h>
 | 
			
		||||
#include <asm/mach/time.h>
 | 
			
		||||
#include <asm/mach/map.h>
 | 
			
		||||
#include <asm/memblock.h>
 | 
			
		||||
#include <mach/board-mx31moboard.h>
 | 
			
		||||
#include <mach/common.h>
 | 
			
		||||
#include <mach/hardware.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -584,10 +585,8 @@ struct sys_timer mx31moboard_timer = {
 | 
			
		|||
static void __init mx31moboard_reserve(void)
 | 
			
		||||
{
 | 
			
		||||
	/* reserve 4 MiB for mx3-camera */
 | 
			
		||||
	mx3_camera_base = memblock_alloc(MX3_CAMERA_BUF_SIZE,
 | 
			
		||||
	mx3_camera_base = arm_memblock_steal(MX3_CAMERA_BUF_SIZE,
 | 
			
		||||
			MX3_CAMERA_BUF_SIZE);
 | 
			
		||||
	memblock_free(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
 | 
			
		||||
	memblock_remove(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,7 @@
 | 
			
		|||
#include <asm/mach/arch.h>
 | 
			
		||||
#include <asm/mach/time.h>
 | 
			
		||||
#include <asm/mach/map.h>
 | 
			
		||||
#include <asm/memblock.h>
 | 
			
		||||
#include <mach/common.h>
 | 
			
		||||
#include <mach/hardware.h>
 | 
			
		||||
#include <mach/iomux-mx3.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -680,10 +681,8 @@ struct sys_timer pcm037_timer = {
 | 
			
		|||
static void __init pcm037_reserve(void)
 | 
			
		||||
{
 | 
			
		||||
	/* reserve 4 MiB for mx3-camera */
 | 
			
		||||
	mx3_camera_base = memblock_alloc(MX3_CAMERA_BUF_SIZE,
 | 
			
		||||
	mx3_camera_base = arm_memblock_steal(MX3_CAMERA_BUF_SIZE,
 | 
			
		||||
			MX3_CAMERA_BUF_SIZE);
 | 
			
		||||
	memblock_free(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
 | 
			
		||||
	memblock_remove(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MACHINE_START(PCM037, "Phytec Phycore pcm037")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -366,8 +366,8 @@ config OMAP3_SDRC_AC_TIMING
 | 
			
		|||
	  going on could result in system crashes;
 | 
			
		||||
 | 
			
		||||
config OMAP4_ERRATA_I688
 | 
			
		||||
	bool "OMAP4 errata: Async Bridge Corruption"
 | 
			
		||||
	depends on ARCH_OMAP4
 | 
			
		||||
	bool "OMAP4 errata: Async Bridge Corruption (BROKEN)"
 | 
			
		||||
	depends on ARCH_OMAP4 && BROKEN
 | 
			
		||||
	select ARCH_HAS_BARRIERS
 | 
			
		||||
	help
 | 
			
		||||
	  If a data is stalled inside asynchronous bridge because of back
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@
 | 
			
		|||
#include <linux/memblock.h>
 | 
			
		||||
 | 
			
		||||
#include <asm/cacheflush.h>
 | 
			
		||||
#include <asm/memblock.h>
 | 
			
		||||
 | 
			
		||||
#include <mach/omap-secure.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -57,20 +58,10 @@ u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2,
 | 
			
		|||
/* Allocate the memory to save secure ram */
 | 
			
		||||
int __init omap_secure_ram_reserve_memblock(void)
 | 
			
		||||
{
 | 
			
		||||
	phys_addr_t paddr;
 | 
			
		||||
	u32 size = OMAP_SECURE_RAM_STORAGE;
 | 
			
		||||
 | 
			
		||||
	size = ALIGN(size, SZ_1M);
 | 
			
		||||
	paddr = memblock_alloc(size, SZ_1M);
 | 
			
		||||
	if (!paddr) {
 | 
			
		||||
		pr_err("%s: failed to reserve %x bytes\n",
 | 
			
		||||
				__func__, size);
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
	}
 | 
			
		||||
	memblock_free(paddr, size);
 | 
			
		||||
	memblock_remove(paddr, size);
 | 
			
		||||
 | 
			
		||||
	omap_secure_memblock_base = paddr;
 | 
			
		||||
	omap_secure_memblock_base = arm_memblock_steal(size, SZ_1M);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@
 | 
			
		|||
#include <asm/hardware/gic.h>
 | 
			
		||||
#include <asm/hardware/cache-l2x0.h>
 | 
			
		||||
#include <asm/mach/map.h>
 | 
			
		||||
#include <asm/memblock.h>
 | 
			
		||||
 | 
			
		||||
#include <plat/irqs.h>
 | 
			
		||||
#include <plat/sram.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -61,13 +62,8 @@ static int __init omap_barriers_init(void)
 | 
			
		|||
		return -ENODEV;
 | 
			
		||||
 | 
			
		||||
	size = ALIGN(PAGE_SIZE, SZ_1M);
 | 
			
		||||
	paddr = memblock_alloc(size, SZ_1M);
 | 
			
		||||
	if (!paddr) {
 | 
			
		||||
		pr_err("%s: failed to reserve 4 Kbytes\n", __func__);
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
	}
 | 
			
		||||
	memblock_free(paddr, size);
 | 
			
		||||
	memblock_remove(paddr, size);
 | 
			
		||||
	paddr = arm_memblock_steal(size, SZ_1M);
 | 
			
		||||
 | 
			
		||||
	dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
 | 
			
		||||
	dram_io_desc[0].pfn = __phys_to_pfn(paddr);
 | 
			
		||||
	dram_io_desc[0].length = size;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@
 | 
			
		|||
#include <linux/memblock.h>
 | 
			
		||||
 | 
			
		||||
#include <asm/mach-types.h>
 | 
			
		||||
#include <asm/memblock.h>
 | 
			
		||||
#include <asm/prom.h>
 | 
			
		||||
#include <asm/sections.h>
 | 
			
		||||
#include <asm/setup.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@
 | 
			
		|||
#include <mach/hardware.h>
 | 
			
		||||
#include <asm/mach-types.h>
 | 
			
		||||
#include <asm/mach/map.h>
 | 
			
		||||
#include <asm/memblock.h>
 | 
			
		||||
 | 
			
		||||
#include <plat/tc.h>
 | 
			
		||||
#include <plat/board.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -164,14 +165,12 @@ void __init omap_dsp_reserve_sdram_memblock(void)
 | 
			
		|||
	if (!size)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	paddr = memblock_alloc(size, SZ_1M);
 | 
			
		||||
	paddr = arm_memblock_steal(size, SZ_1M);
 | 
			
		||||
	if (!paddr) {
 | 
			
		||||
		pr_err("%s: failed to reserve %x bytes\n",
 | 
			
		||||
				__func__, size);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	memblock_free(paddr, size);
 | 
			
		||||
	memblock_remove(paddr, size);
 | 
			
		||||
 | 
			
		||||
	omap_dsp_phys_mempool_base = paddr;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue