diff mbox

arm: Make sure memory starting at physical address 0 is reserved.

Message ID 1404409205-7368-1-git-send-email-alcooperx@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Alan Cooper July 3, 2014, 5:40 p.m. UTC
Some older hardware, like USB OHCI, cannot DMA to physical address
zero. This change makes sure that the first PAGESIZE block of memory
starting at zero is reserved so it can't end up in any free
memory pool.

Signed-off-by: Al Cooper <alcooperx@gmail.com>
---
 arch/arm/mm/init.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Russell King - ARM Linux July 3, 2014, 5:52 p.m. UTC | #1
On Thu, Jul 03, 2014 at 01:40:05PM -0400, Al Cooper wrote:
> Some older hardware, like USB OHCI, cannot DMA to physical address
> zero. This change makes sure that the first PAGESIZE block of memory
> starting at zero is reserved so it can't end up in any free
> memory pool.

I really don't like this approach.  The assumption here is that DMA
address zero on a peripheral is the same as physical address zero.
That isn't always the case.

What if DMA address zero corresponds with the first byte of RAM, but
the first byte of RAM is at 0x80000000?

I believe there's even some cases where the first byte of RAM is not
what the kernel sees as the first byte of RAM (because people want
to hide the first half of RAM from the kernel for a DSP or similar.)

What I'm saying is I don't think there's a nice simple solution to
this.  We probably need the DT reserved memory support to handle
this.
diff mbox

Patch

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 659c75d..17aaa4d 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -324,6 +324,15 @@  void __init arm_memblock_init(const struct machine_desc *mdesc)
 	 */
 	dma_contiguous_reserve(min(arm_dma_limit, arm_lowmem_limit));
 
+	/*
+	 * Some older hardware, like USB OHCI, cannot DMA
+	 * to physical address zero. This makes sure that the
+	 * first PAGESIZE block of memory starting at zero is
+	 * reserved so it can't end up in any free memory pool.
+	 */
+	if (memblock_is_region_memory(0, PAGE_SIZE))
+		memblock_reserve(0, PAGE_SIZE);
+
 	arm_memblock_steal_permitted = false;
 	memblock_dump_all();
 }