[ARM] Improve non-executable support

Add support for detecting non-executable stack binaries, and adjust
permissions to prevent execution from data and stack areas.  Also,
ensure that READ_IMPLIES_EXEC is enabled for older CPUs where that
is true, and for any executable-stack binary.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index e5054b0..b02be6c 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -197,22 +197,29 @@
  * shared mapping bits.
  */
 #define _L_PTE_DEFAULT	L_PTE_PRESENT | L_PTE_YOUNG
-#define _L_PTE_READ	L_PTE_USER | L_PTE_EXEC
 
 extern pgprot_t		pgprot_user;
 extern pgprot_t		pgprot_kernel;
 
-#define PAGE_NONE	pgprot_user
-#define PAGE_COPY	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
-#define PAGE_SHARED	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ | \
-				 L_PTE_WRITE)
-#define PAGE_READONLY	__pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
-#define PAGE_KERNEL	pgprot_kernel
+#define _MOD_PROT(p, b)	__pgprot(pgprot_val(p) | (b))
 
-#define __PAGE_NONE	__pgprot(_L_PTE_DEFAULT)
-#define __PAGE_COPY	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
-#define __PAGE_SHARED	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
-#define __PAGE_READONLY	__pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define PAGE_NONE		pgprot_user
+#define PAGE_SHARED		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE)
+#define PAGE_SHARED_EXEC	_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC)
+#define PAGE_COPY		_MOD_PROT(pgprot_user, L_PTE_USER)
+#define PAGE_COPY_EXEC		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC)
+#define PAGE_READONLY		_MOD_PROT(pgprot_user, L_PTE_USER)
+#define PAGE_READONLY_EXEC	_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC)
+#define PAGE_KERNEL		pgprot_kernel
+#define PAGE_KERNEL_EXEC	_MOD_PROT(pgprot_kernel, L_PTE_EXEC)
+
+#define __PAGE_NONE		__pgprot(_L_PTE_DEFAULT)
+#define __PAGE_SHARED		__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE)
+#define __PAGE_SHARED_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC)
+#define __PAGE_COPY		__pgprot(_L_PTE_DEFAULT | L_PTE_USER)
+#define __PAGE_COPY_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC)
+#define __PAGE_READONLY		__pgprot(_L_PTE_DEFAULT | L_PTE_USER)
+#define __PAGE_READONLY_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC)
 
 #endif /* __ASSEMBLY__ */
 
@@ -228,19 +235,19 @@
 #define __P001  __PAGE_READONLY
 #define __P010  __PAGE_COPY
 #define __P011  __PAGE_COPY
-#define __P100  __PAGE_READONLY
-#define __P101  __PAGE_READONLY
-#define __P110  __PAGE_COPY
-#define __P111  __PAGE_COPY
+#define __P100  __PAGE_READONLY_EXEC
+#define __P101  __PAGE_READONLY_EXEC
+#define __P110  __PAGE_COPY_EXEC
+#define __P111  __PAGE_COPY_EXEC
 
 #define __S000  __PAGE_NONE
 #define __S001  __PAGE_READONLY
 #define __S010  __PAGE_SHARED
 #define __S011  __PAGE_SHARED
-#define __S100  __PAGE_READONLY
-#define __S101  __PAGE_READONLY
-#define __S110  __PAGE_SHARED
-#define __S111  __PAGE_SHARED
+#define __S100  __PAGE_READONLY_EXEC
+#define __S101  __PAGE_READONLY_EXEC
+#define __S110  __PAGE_SHARED_EXEC
+#define __S111  __PAGE_SHARED_EXEC
 
 #ifndef __ASSEMBLY__
 /*