Revert "ARM: 7304/1: ioremap: fix boundary check when reusing static mapping"
authorRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 29 Jan 2012 14:55:21 +0000 (14:55 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 2 Feb 2012 17:37:41 +0000 (17:37 +0000)
This reverts commit 3c424f359898aff48c3d5bed608ac706f8a528c3.

Joachim Eastwood reports:
| "ARM: 7304/1: ioremap: fix boundary check when reusing static mapping"
| Commit: 3c424f359898aff48c3d5bed608ac706f8a528c3 in Linus master
|
| Breaks booting on my custom AT91RM9200 board.
| There isn't any error messages or anything that indicates what goes
| wrong it just stops after; Uncompressing Linux... done, booting the
| kernel.
|
| Reverting it makes my board boot again.

and further debugging reveals:

ioremap: pfn=fffff phys=fffff000 offset=400 size=1000
ioremap: area c3ffdfc0: phys_addr=200000 pfn=200 size=4000
ioremap: found: addr fef74000 => fed73000 => fed73400

Clearly, an area for pfn 0x200, 16K can't ever satisfy a request for pfn
0xfffff.  This happens because the changed if statement becomes:

                if (0x00200 > 0xfffff ||
                    0xfffff000 + 0x400 + 0x1000-1 > 0x00200000 + 0x4000-1)
and therefore:
                if (0x00200 > 0xfffff ||
                    0x000003ff > 0x00203fff)

The if condition fails, and so we _believe_ that the SRAM mapping fits
our request.  Clearly that's totally bogus.

Moreover, the original premise of the 'fix' patch was wrong:
|    The condition checking boundaries of the requested and existing
|    mappings didn't take in-page offset into consideration though,
|    which lead to obscure and hard to debug problems when requested
|    mapping crossed end of the static one.

as the code immediately above this loop does:

        size = PAGE_ALIGN(offset + size);

so 'size' already contains the requested offset into the page.

So, revert the broken 'fix'.

Acked-by: Nicolas Pitre <nico@linaro.org>
arch/arm/mm/ioremap.c

index ba159370fa5f710633d6b00a078c23bc40ad6f6a..80632e8d7538f33d5a6539df5a72a90fff52e7ec 100644 (file)
@@ -225,8 +225,7 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
                if ((area->flags & VM_ARM_MTYPE_MASK) != VM_ARM_MTYPE(mtype))
                        continue;
                if (__phys_to_pfn(area->phys_addr) > pfn ||
-                   __pfn_to_phys(pfn) + offset + size-1 >
-                   area->phys_addr + area->size-1)
+                   __pfn_to_phys(pfn) + size-1 > area->phys_addr + area->size-1)
                        continue;
                /* we can drop the lock here as we know *area is static */
                read_unlock(&vmlist_lock);