sh: Fix up legacy PTEA space attribute mapping.
authorPaul Mundt <lethal@linux-sh.org>
Tue, 11 Jan 2011 06:02:59 +0000 (15:02 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Tue, 11 Jan 2011 06:02:59 +0000 (15:02 +0900)
When p3_ioremap() was converted to ioremap_prot() there was some breakage
introduced where the 29-bit segmentation logic would trap the area range
and return an identity mapping without having allowed the area
specification to force mapping through page tables. This wires up a PCC
mask for pgprot verification to work out whether to short-circuit the
identity mapping on legacy parts, restoring the previous behaviour.

Reported-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Cc: stable@kernel.org
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
arch/sh/include/asm/io.h
arch/sh/include/asm/pgtable_32.h

index 70c1186b508893216bbae1c19ece1860e45964f8..28c5aa58bb45ec73edd45a3d878704f25eb6564b 100644 (file)
@@ -290,7 +290,15 @@ __ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot)
         * mapping must be done by the PMB or by using page tables.
         */
        if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) {
         * mapping must be done by the PMB or by using page tables.
         */
        if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) {
-               if (unlikely(pgprot_val(prot) & _PAGE_CACHABLE))
+               u64 flags = pgprot_val(prot);
+
+               /*
+                * Anything using the legacy PTEA space attributes needs
+                * to be kicked down to page table mappings.
+                */
+               if (unlikely(flags & _PAGE_PCC_MASK))
+                       return NULL;
+               if (unlikely(flags & _PAGE_CACHABLE))
                        return (void __iomem *)P1SEGADDR(offset);
 
                return (void __iomem *)P2SEGADDR(offset);
                        return (void __iomem *)P1SEGADDR(offset);
 
                return (void __iomem *)P2SEGADDR(offset);
index 3cbedd21fd83ba4cf41beff547eee954cef8f385..b799fe71114cf3fece0043a95a5eb45c505d578a 100644 (file)
 /* Wrapper for extended mode pgprot twiddling */
 #define _PAGE_EXT(x)           ((unsigned long long)(x) << 32)
 
 /* Wrapper for extended mode pgprot twiddling */
 #define _PAGE_EXT(x)           ((unsigned long long)(x) << 32)
 
+#ifdef CONFIG_X2TLB
+#define _PAGE_PCC_MASK 0x00000000      /* No legacy PTEA support */
+#else
+
 /* software: moves to PTEA.TC (Timing Control) */
 #define _PAGE_PCC_AREA5        0x00000000      /* use BSC registers for area5 */
 #define _PAGE_PCC_AREA6        0x80000000      /* use BSC registers for area6 */
 /* software: moves to PTEA.TC (Timing Control) */
 #define _PAGE_PCC_AREA5        0x00000000      /* use BSC registers for area5 */
 #define _PAGE_PCC_AREA6        0x80000000      /* use BSC registers for area6 */
@@ -89,7 +93,8 @@
 #define _PAGE_PCC_ATR8 0x60000000      /* Attribute Memory space, 8 bit bus */
 #define _PAGE_PCC_ATR16        0x60000001      /* Attribute Memory space, 6 bit bus */
 
 #define _PAGE_PCC_ATR8 0x60000000      /* Attribute Memory space, 8 bit bus */
 #define _PAGE_PCC_ATR16        0x60000001      /* Attribute Memory space, 6 bit bus */
 
-#ifndef CONFIG_X2TLB
+#define _PAGE_PCC_MASK 0xe0000001
+
 /* copy the ptea attributes */
 static inline unsigned long copy_ptea_attributes(unsigned long x)
 {
 /* copy the ptea attributes */
 static inline unsigned long copy_ptea_attributes(unsigned long x)
 {