*/
 
 /* Remove W bit on private pages for COW support */
-#define __P000 MKP(0, 0, 0)
-#define __P001 MKP(0, 0, 1)
-#define __P010 MKP(0, 0, 0)    /* COW */
-#define __P011 MKP(0, 0, 1)    /* COW */
-#define __P100 MKP(1, 0, 0)
-#define __P101 MKP(1, 0, 1)
-#define __P110 MKP(1, 0, 0)    /* COW */
-#define __P111 MKP(1, 0, 1)    /* COW */
 
 /* Shared pages can have exact HW mapping */
-#define __S000 MKP(0, 0, 0)
-#define __S001 MKP(0, 0, 1)
-#define __S010 MKP(0, 1, 0)
-#define __S011 MKP(0, 1, 1)
-#define __S100 MKP(1, 0, 0)
-#define __S101 MKP(1, 0, 1)
-#define __S110 MKP(1, 1, 0)
-#define __S111 MKP(1, 1, 1)
 
 /* Used all over the kernel */
 #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_CACHED | _PAGE_READ | \
 
 {
        return (vma->vm_start == KUSER_BASE) ? "[kuser]" : NULL;
 }
+
+static const pgprot_t protection_map[16] = {
+       [VM_NONE]                                       = MKP(0, 0, 0),
+       [VM_READ]                                       = MKP(0, 0, 1),
+       [VM_WRITE]                                      = MKP(0, 0, 0),
+       [VM_WRITE | VM_READ]                            = MKP(0, 0, 1),
+       [VM_EXEC]                                       = MKP(1, 0, 0),
+       [VM_EXEC | VM_READ]                             = MKP(1, 0, 1),
+       [VM_EXEC | VM_WRITE]                            = MKP(1, 0, 0),
+       [VM_EXEC | VM_WRITE | VM_READ]                  = MKP(1, 0, 1),
+       [VM_SHARED]                                     = MKP(0, 0, 0),
+       [VM_SHARED | VM_READ]                           = MKP(0, 0, 1),
+       [VM_SHARED | VM_WRITE]                          = MKP(0, 1, 0),
+       [VM_SHARED | VM_WRITE | VM_READ]                = MKP(0, 1, 1),
+       [VM_SHARED | VM_EXEC]                           = MKP(1, 0, 0),
+       [VM_SHARED | VM_EXEC | VM_READ]                 = MKP(1, 0, 1),
+       [VM_SHARED | VM_EXEC | VM_WRITE]                = MKP(1, 1, 0),
+       [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ]      = MKP(1, 1, 1)
+};
+DECLARE_VM_GET_PAGE_PROT