* [PATCH] ARM: mm: restrict early_alloc_aligned to legal area
@ 2013-07-08 22:44 Stephen Warren
2013-07-09 16:03 ` Stephen Warren
0 siblings, 1 reply; 2+ messages in thread
From: Stephen Warren @ 2013-07-08 22:44 UTC (permalink / raw)
To: linux-arm-kernel
From: Stephen Warren <swarren@nvidia.com>
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 <swarren@nvidia.com>
---
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;
}
--
1.8.1.5
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH] ARM: mm: restrict early_alloc_aligned to legal area
2013-07-08 22:44 [PATCH] ARM: mm: restrict early_alloc_aligned to legal area Stephen Warren
@ 2013-07-09 16:03 ` Stephen Warren
0 siblings, 0 replies; 2+ messages in thread
From: Stephen Warren @ 2013-07-09 16:03 UTC (permalink / raw)
To: linux-arm-kernel
On 07/08/2013 04:44 PM, Stephen Warren wrote:
> From: Stephen Warren <swarren@nvidia.com>
>
> 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.
Scratch this; it causes problems on systems with highmem.
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> 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;
Perhaps that needs to be min(memblock 0 end, end of lowmem). I'll try
that...
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2013-07-09 16:03 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-08 22:44 [PATCH] ARM: mm: restrict early_alloc_aligned to legal area Stephen Warren
2013-07-09 16:03 ` Stephen Warren
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.