#endif /* CONFIG_PPC_MM_SLICES */
 
 /*
- * No separate kernel read-only, user access blocked by key
+ * user access blocked by key
  */
 #define _PAGE_KERNEL_RW                (_PAGE_PRIVILEGED | _PAGE_RW | _PAGE_DIRTY)
-#define _PAGE_KERNEL_RO                 _PAGE_KERNEL_RW
+#define _PAGE_KERNEL_RO                 (_PAGE_PRIVILEGED | _PAGE_READ)
 #define _PAGE_KERNEL_RWX       (_PAGE_PRIVILEGED | _PAGE_DIRTY | \
                                 _PAGE_RW | _PAGE_EXEC)
 
 
        if ((pteflags & _PAGE_EXEC) == 0)
                rflags |= HPTE_R_N;
        /*
-        * PP bits:
+        * PPP bits:
         * Linux uses slb key 0 for kernel and 1 for user.
-        * kernel areas are mapped with PP=00
-        * and there is no kernel RO (_PAGE_KERNEL_RO).
-        * User area is mapped with PP=0x2 for read/write
-        * or PP=0x3 for read-only (including writeable but clean pages).
+        * kernel RW areas are mapped with PPP=0b000
+        * User area is mapped with PPP=0b010 for read/write
+        * or PPP=0b011 for read-only (including writeable but clean pages).
         */
-       if (!(pteflags & _PAGE_PRIVILEGED)) {
+       if (pteflags & _PAGE_PRIVILEGED) {
+               /*
+                * Kernel read only mapped with ppp bits 0b110
+                */
+               if (!(pteflags & _PAGE_WRITE))
+                       rflags |= (HPTE_R_PP0 | 0x2);
+       } else {
                if (pteflags & _PAGE_RWX)
                        rflags |= 0x2;
                if (!((pteflags & _PAGE_WRITE) && (pteflags & _PAGE_DIRTY)))
 
 static int __init setup_areas(struct spu *spu)
 {
        struct table {char* name; unsigned long addr; unsigned long size;};
-       static const unsigned long shadow_flags = _PAGE_NO_CACHE | 3;
+       unsigned long shadow_flags = pgprot_val(pgprot_noncached_wc(PAGE_KERNEL_RO));
 
        spu_pdata(spu)->shadow = __ioremap(spu_pdata(spu)->shadow_addr,
                                           sizeof(struct spe_shadow),