[ARM] 4568/1: fix l2x0 cache invalidate handling of unaligned addresses
authorRui Sousa <rui.p.m.sousa@gmail.com>
Fri, 14 Sep 2007 23:56:19 +0000 (00:56 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 17 Sep 2007 13:56:39 +0000 (14:56 +0100)
The l2x0_inv_range() function doesn't handle unaligned addresses
correctly. It's necessary to clean the cache lines that are at the
start and end of the invalidate range, if the addresses are not aligned,
to prevent corruption of other data sharing the same cache line.

Signed-off-by: Rui Sousa <rui.p.m.sousa@gmail.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mm/cache-l2x0.c

index b4e9b734e0bd939cddcdc392889368fe43f30846..76b800a951917d96b7aad433c344562f484743df 100644 (file)
@@ -57,7 +57,17 @@ static void l2x0_inv_range(unsigned long start, unsigned long end)
 {
        unsigned long addr;
 
-       start &= ~(CACHE_LINE_SIZE - 1);
+       if (start & (CACHE_LINE_SIZE - 1)) {
+               start &= ~(CACHE_LINE_SIZE - 1);
+               sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1);
+               start += CACHE_LINE_SIZE;
+       }
+
+       if (end & (CACHE_LINE_SIZE - 1)) {
+               end &= ~(CACHE_LINE_SIZE - 1);
+               sync_writel(end, L2X0_CLEAN_INV_LINE_PA, 1);
+       }
+
        for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
                sync_writel(addr, L2X0_INV_LINE_PA, 1);
        cache_sync();