All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Clean up page tables
@ 2010-11-17 17:27 Russell King - ARM Linux
  2010-11-17 17:28 ` [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware " Russell King - ARM Linux
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Russell King - ARM Linux @ 2010-11-17 17:27 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series is preparation for LPAE, allowing a cleaner
transition from the current methodology to that required for
LPAE.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware page tables
  2010-11-17 17:27 [PATCH 0/5] Clean up page tables Russell King - ARM Linux
@ 2010-11-17 17:28 ` Russell King - ARM Linux
  2010-11-18 16:59   ` Catalin Marinas
                     ` (2 more replies)
  2010-11-17 17:28 ` [PATCH 2/5] ARM: pgtable: directly pass pgd/pmd/pte to their error functions Russell King - ARM Linux
                   ` (4 subsequent siblings)
  5 siblings, 3 replies; 16+ messages in thread
From: Russell King - ARM Linux @ 2010-11-17 17:28 UTC (permalink / raw)
  To: linux-arm-kernel

This switches the ordering of the Linux vs hardware page tables in
each page, thereby eliminating some of the arithmetic in the page
table walks.  As we now place the Linux page table at the beginning
of the page, we can deal with the offset in the pgt by simply masking
it away, along with the other control bits.

This also makes the arithmetic all be positive, rather than a mixture.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/pgalloc.h |   34 +++++++++++++++-------------------
 arch/arm/include/asm/pgtable.h |   30 +++++++++++++++---------------
 arch/arm/mm/fault.c            |    2 +-
 arch/arm/mm/mmu.c              |    2 +-
 arch/arm/mm/proc-macros.S      |   10 +++++-----
 arch/arm/mm/proc-v7.S          |    8 +++-----
 6 files changed, 40 insertions(+), 46 deletions(-)

diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index b12cc98..e2a6613 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -38,6 +38,11 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
 
 #define PGALLOC_GFP	(GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
 
+static inline void clean_pte_table(void *ptr)
+{
+	clean_dcache_area(ptr + PTE_HWTABLE_OFF, PTE_HWTABLE_SIZE);
+}
+
 /*
  * Allocate one PTE table.
  *
@@ -60,10 +65,8 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
 	pte_t *pte;
 
 	pte = (pte_t *)__get_free_page(PGALLOC_GFP);
-	if (pte) {
-		clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
-		pte += PTRS_PER_PTE;
-	}
+	if (pte)
+		clean_pte_table(pte);
 
 	return pte;
 }
@@ -79,10 +82,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
 	pte = alloc_pages(PGALLOC_GFP, 0);
 #endif
 	if (pte) {
-		if (!PageHighMem(pte)) {
-			void *page = page_address(pte);
-			clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
-		}
+		if (!PageHighMem(pte))
+			clean_pte_table(page_address(pte));
 		pgtable_page_ctor(pte);
 	}
 
@@ -94,10 +95,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
  */
 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 {
-	if (pte) {
-		pte -= PTRS_PER_PTE;
+	if (pte)
 		free_page((unsigned long)pte);
-	}
 }
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
@@ -106,8 +105,9 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 	__free_page(pte);
 }
 
-static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
+static inline void __pmd_populate(pmd_t *pmdp, unsigned long pte, unsigned long prot)
 {
+	unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot;
 	pmdp[0] = __pmd(pmdval);
 	pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
 	flush_pmd_entry(pmdp);
@@ -122,20 +122,16 @@ static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
 static inline void
 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
 {
-	unsigned long pte_ptr = (unsigned long)ptep;
-
 	/*
-	 * The pmd must be loaded with the physical
-	 * address of the PTE table
+	 * The pmd must be loaded with the physical address of the PTE table
 	 */
-	pte_ptr -= PTRS_PER_PTE * sizeof(void *);
-	__pmd_populate(pmdp, __pa(pte_ptr) | _PAGE_KERNEL_TABLE);
+	__pmd_populate(pmdp, __pa(ptep), _PAGE_KERNEL_TABLE);
 }
 
 static inline void
 pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
 {
-	__pmd_populate(pmdp, page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE);
+	__pmd_populate(pmdp, page_to_pfn(ptep) << PAGE_SHIFT, _PAGE_USER_TABLE);
 }
 #define pmd_pgtable(pmd) pmd_page(pmd)
 
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index b155414..d9f1bfa 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -54,7 +54,7 @@
  * Therefore, we tweak the implementation slightly - we tell Linux that we
  * have 2048 entries in the first level, each of which is 8 bytes (iow, two
  * hardware pointers to the second level.)  The second level contains two
- * hardware PTE tables arranged contiguously, followed by Linux versions
+ * hardware PTE tables arranged contiguously, preceded by Linux versions
  * which contain the state information Linux needs.  We, therefore, end up
  * with 512 entries in the "PTE" level.
  *
@@ -62,15 +62,15 @@
  *
  *    pgd             pte
  * |        |
- * +--------+ +0
- * |        |-----> +------------+ +0
+ * +--------+
+ * |        |       +------------+ +0
+ * +- - - - +       | Linux pt 0 |
+ * |        |       +------------+ +1024
+ * +--------+ +0    | Linux pt 1 |
+ * |        |-----> +------------+ +2048
  * +- - - - + +4    |  h/w pt 0  |
- * |        |-----> +------------+ +1024
+ * |        |-----> +------------+ +3072
  * +--------+ +8    |  h/w pt 1  |
- * |        |       +------------+ +2048
- * +- - - - +       | Linux pt 0 |
- * |        |       +------------+ +3072
- * +--------+       | Linux pt 1 |
  * |        |       +------------+ +4096
  *
  * See L_PTE_xxx below for definitions of bits in the "Linux pt", and
@@ -102,6 +102,10 @@
 #define PTRS_PER_PMD		1
 #define PTRS_PER_PGD		2048
 
+#define PTE_HWTABLE_PTRS	(PTRS_PER_PTE)
+#define PTE_HWTABLE_OFF		(PTE_HWTABLE_PTRS * sizeof(pte_t))
+#define PTE_HWTABLE_SIZE	(PTRS_PER_PTE * sizeof(u32))
+
 /*
  * PMD_SHIFT determines the size of the area a second-level page table can map
  * PGDIR_SHIFT determines what a third-level page table entry can map
@@ -270,8 +274,8 @@ extern struct page *empty_zero_page;
 #define __pte_map(dir)		pmd_page_vaddr(*(dir))
 #define __pte_unmap(pte)	do { } while (0)
 #else
-#define __pte_map(dir)		((pte_t *)kmap_atomic(pmd_page(*(dir))) + PTRS_PER_PTE)
-#define __pte_unmap(pte)	kunmap_atomic((pte - PTRS_PER_PTE))
+#define __pte_map(dir)		(pte_t *)kmap_atomic(pmd_page(*(dir)))
+#define __pte_unmap(pte)	kunmap_atomic(pte)
 #endif
 
 #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
@@ -364,11 +368,7 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 
 static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 {
-	unsigned long ptr;
-
-	ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
-	ptr += PTRS_PER_PTE * sizeof(void *);
-
+	unsigned long ptr = pmd_val(pmd) & PAGE_MASK;
 	return __va(ptr);
 }
 
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 1e21e12..f10f9ba 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -108,7 +108,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
 
 		pte = pte_offset_map(pmd, addr);
 		printk(", *pte=%08lx", pte_val(*pte));
-		printk(", *ppte=%08lx", pte_val(pte[-PTRS_PER_PTE]));
+		printk(", *ppte=%08lx", pte_val(pte[PTE_HWTABLE_PTRS]));
 		pte_unmap(pte);
 	} while(0);
 
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 72ad3e1..9963189 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -535,7 +535,7 @@ static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned l
 {
 	if (pmd_none(*pmd)) {
 		pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
-		__pmd_populate(pmd, __pa(pte) | prot);
+		__pmd_populate(pmd, __pa(pte), prot);
 	}
 	BUG_ON(pmd_bad(*pmd));
 	return pte_offset_kernel(pmd, addr);
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 7d63bea..cbedf9c 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -121,7 +121,7 @@
 	.endm
 
 	.macro	armv6_set_pte_ext pfx
-	str	r1, [r0], #-2048		@ linux version
+	str	r1, [r0], #2048			@ linux version
 
 	bic	r3, r1, #0x000003fc
 	bic	r3, r3, #PTE_TYPE_MASK
@@ -170,7 +170,7 @@
  *  1111  0xff	r/w	r/w
  */
 	.macro	armv3_set_pte_ext wc_disable=1
-	str	r1, [r0], #-2048		@ linux version
+	str	r1, [r0], #2048			@ linux version
 
 	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
 
@@ -193,7 +193,7 @@
 	bicne	r2, r2, #PTE_BUFFERABLE
 #endif
 	.endif
-	str	r2, [r0]			@ hardware version
+	str	r2, [r0]		@ hardware version
 	.endm
 
 
@@ -213,7 +213,7 @@
  *  1111  11	r/w	r/w
  */
 	.macro	xscale_set_pte_ext_prologue
-	str	r1, [r0], #-2048		@ linux version
+	str	r1, [r0]			@ linux version
 
 	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
 
@@ -232,7 +232,7 @@
 	tst	r3, #L_PTE_PRESENT | L_PTE_YOUNG	@ present and young?
 	movne	r2, #0				@ no -> fault
 
-	str	r2, [r0]			@ hardware version
+	str	r2, [r0, #2048]!		@ hardware version
 	mov	ip, #0
 	mcr	p15, 0, r0, c7, c10, 1		@ clean L1 D line
 	mcr	p15, 0, ip, c7, c10, 4		@ data write barrier
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 53cbe22..89c31a6 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -124,15 +124,13 @@ ENDPROC(cpu_v7_switch_mm)
  *	Set a level 2 translation table entry.
  *
  *	- ptep  - pointer to level 2 translation table entry
- *		  (hardware version is stored at -1024 bytes)
+ *		  (hardware version is stored at +2048 bytes)
  *	- pte   - PTE value to store
  *	- ext	- value for extended PTE bits
  */
 ENTRY(cpu_v7_set_pte_ext)
 #ifdef CONFIG_MMU
- ARM(	str	r1, [r0], #-2048	)	@ linux version
- THUMB(	str	r1, [r0]		)	@ linux version
- THUMB(	sub	r0, r0, #2048		)
+	str	r1, [r0]			@ linux version
 
 	bic	r3, r1, #0x000003f0
 	bic	r3, r3, #PTE_TYPE_MASK
@@ -158,7 +156,7 @@ ENTRY(cpu_v7_set_pte_ext)
 	tstne	r1, #L_PTE_PRESENT
 	moveq	r3, #0
 
-	str	r3, [r0]
+	str	r3, [r0, #2048]!
 	mcr	p15, 0, r0, c7, c10, 1		@ flush_pte
 #endif
 	mov	pc, lr
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/5] ARM: pgtable: directly pass pgd/pmd/pte to their error functions
  2010-11-17 17:27 [PATCH 0/5] Clean up page tables Russell King - ARM Linux
  2010-11-17 17:28 ` [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware " Russell King - ARM Linux
@ 2010-11-17 17:28 ` Russell King - ARM Linux
  2010-11-17 17:29 ` [PATCH 3/5] ARM: pgtable: introduce pteval_t to represent a pte value Russell King - ARM Linux
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Russell King - ARM Linux @ 2010-11-17 17:28 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than passing the pte value to __pte_error, pass the raw pte_t
cookie instead.  Do the same for pmd and pgd functions.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/pgtable.h |   12 ++++++------
 arch/arm/kernel/traps.c        |   12 ++++++------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index d9f1bfa..f54d2fe 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -116,13 +116,13 @@
 #define LIBRARY_TEXT_START	0x0c000000
 
 #ifndef __ASSEMBLY__
-extern void __pte_error(const char *file, int line, unsigned long val);
-extern void __pmd_error(const char *file, int line, unsigned long val);
-extern void __pgd_error(const char *file, int line, unsigned long val);
+extern void __pte_error(const char *file, int line, pte_t);
+extern void __pmd_error(const char *file, int line, pmd_t);
+extern void __pgd_error(const char *file, int line, pgd_t);
 
-#define pte_ERROR(pte)		__pte_error(__FILE__, __LINE__, pte_val(pte))
-#define pmd_ERROR(pmd)		__pmd_error(__FILE__, __LINE__, pmd_val(pmd))
-#define pgd_ERROR(pgd)		__pgd_error(__FILE__, __LINE__, pgd_val(pgd))
+#define pte_ERROR(pte)		__pte_error(__FILE__, __LINE__, pte)
+#define pmd_ERROR(pmd)		__pmd_error(__FILE__, __LINE__, pmd)
+#define pgd_ERROR(pgd)		__pgd_error(__FILE__, __LINE__, pgd)
 #endif /* !__ASSEMBLY__ */
 
 #define PMD_SIZE		(1UL << PMD_SHIFT)
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 446aee9..354cd4c 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -708,19 +708,19 @@ void __readwrite_bug(const char *fn)
 }
 EXPORT_SYMBOL(__readwrite_bug);
 
-void __pte_error(const char *file, int line, unsigned long val)
+void __pte_error(const char *file, int line, pte_t pte)
 {
-	printk("%s:%d: bad pte %08lx.\n", file, line, val);
+	printk("%s:%d: bad pte %08lx.\n", file, line, pte_val(pte));
 }
 
-void __pmd_error(const char *file, int line, unsigned long val)
+void __pmd_error(const char *file, int line, pmd_t pmd)
 {
-	printk("%s:%d: bad pmd %08lx.\n", file, line, val);
+	printk("%s:%d: bad pmd %08lx.\n", file, line, pmd_val(pmd));
 }
 
-void __pgd_error(const char *file, int line, unsigned long val)
+void __pgd_error(const char *file, int line, pgd_t pgd)
 {
-	printk("%s:%d: bad pgd %08lx.\n", file, line, val);
+	printk("%s:%d: bad pgd %08lx.\n", file, line, pgd_val(pgd));
 }
 
 asmlinkage void __div0(void)
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/5] ARM: pgtable: introduce pteval_t to represent a pte value
  2010-11-17 17:27 [PATCH 0/5] Clean up page tables Russell King - ARM Linux
  2010-11-17 17:28 ` [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware " Russell King - ARM Linux
  2010-11-17 17:28 ` [PATCH 2/5] ARM: pgtable: directly pass pgd/pmd/pte to their error functions Russell King - ARM Linux
@ 2010-11-17 17:29 ` Russell King - ARM Linux
  2010-11-18 10:59   ` Catalin Marinas
  2010-11-19 14:23   ` Catalin Marinas
  2010-11-17 17:29 ` [PATCH 4/5] ARM: pgtable: invert L_PTE_EXEC to L_PTE_XN Russell King - ARM Linux
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 16+ messages in thread
From: Russell King - ARM Linux @ 2010-11-17 17:29 UTC (permalink / raw)
  To: linux-arm-kernel

This makes everywhere dealing with pte values use the same type.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/page.h    |    6 ++++--
 arch/arm/include/asm/pgtable.h |   39 ++++++++++++++++++++-------------------
 arch/arm/mm/fault-armv.c       |    2 +-
 3 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index a485ac3..f51a695 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -151,13 +151,15 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
 #define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, const void *from);
 
+typedef unsigned long pteval_t;
+
 #undef STRICT_MM_TYPECHECKS
 
 #ifdef STRICT_MM_TYPECHECKS
 /*
  * These are used to make use of C type-checking..
  */
-typedef struct { unsigned long pte; } pte_t;
+typedef struct { pteval_t pte; } pte_t;
 typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd[2]; } pgd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
@@ -175,7 +177,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 /*
  * .. while these make it easier on the compiler
  */
-typedef unsigned long pte_t;
+typedef pteval_t pte_t;
 typedef unsigned long pmd_t;
 typedef unsigned long pgd_t[2];
 typedef unsigned long pgprot_t;
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index f54d2fe..59e0ea2 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -10,6 +10,7 @@
 #ifndef _ASMARM_PGTABLE_H
 #define _ASMARM_PGTABLE_H
 
+#include <linux/const.h>
 #include <asm-generic/4level-fixup.h>
 #include <asm/proc-fns.h>
 
@@ -165,30 +166,30 @@ extern void __pgd_error(const char *file, int line, pgd_t);
  * The PTE table pointer refers to the hardware entries; the "Linux"
  * entries are stored 1024 bytes below.
  */
-#define L_PTE_PRESENT		(1 << 0)
-#define L_PTE_YOUNG		(1 << 1)
-#define L_PTE_FILE		(1 << 2)	/* only when !PRESENT */
-#define L_PTE_DIRTY		(1 << 6)
-#define L_PTE_WRITE		(1 << 7)
-#define L_PTE_USER		(1 << 8)
-#define L_PTE_EXEC		(1 << 9)
-#define L_PTE_SHARED		(1 << 10)	/* shared(v6), coherent(xsc3) */
+#define L_PTE_PRESENT		(_AT(pteval_t, 1) << 0)
+#define L_PTE_YOUNG		(_AT(pteval_t, 1) << 1)
+#define L_PTE_FILE		(_AT(pteval_t, 1) << 2)	/* only when !PRESENT */
+#define L_PTE_DIRTY		(_AT(pteval_t, 1) << 6)
+#define L_PTE_WRITE		(_AT(pteval_t, 1) << 7)
+#define L_PTE_USER		(_AT(pteval_t, 1) << 8)
+#define L_PTE_EXEC		(_AT(pteval_t, 1) << 9)
+#define L_PTE_SHARED		(_AT(pteval_t, 1) << 10)	/* shared(v6), coherent(xsc3) */
 
 /*
  * These are the memory types, defined to be compatible with
  * pre-ARMv6 CPUs cacheable and bufferable bits:   XXCB
  */
-#define L_PTE_MT_UNCACHED	(0x00 << 2)	/* 0000 */
-#define L_PTE_MT_BUFFERABLE	(0x01 << 2)	/* 0001 */
-#define L_PTE_MT_WRITETHROUGH	(0x02 << 2)	/* 0010 */
-#define L_PTE_MT_WRITEBACK	(0x03 << 2)	/* 0011 */
-#define L_PTE_MT_MINICACHE	(0x06 << 2)	/* 0110 (sa1100, xscale) */
-#define L_PTE_MT_WRITEALLOC	(0x07 << 2)	/* 0111 */
-#define L_PTE_MT_DEV_SHARED	(0x04 << 2)	/* 0100 */
-#define L_PTE_MT_DEV_NONSHARED	(0x0c << 2)	/* 1100 */
-#define L_PTE_MT_DEV_WC		(0x09 << 2)	/* 1001 */
-#define L_PTE_MT_DEV_CACHED	(0x0b << 2)	/* 1011 */
-#define L_PTE_MT_MASK		(0x0f << 2)
+#define L_PTE_MT_UNCACHED	(_AT(pteval_t, 0x00) << 2)	/* 0000 */
+#define L_PTE_MT_BUFFERABLE	(_AT(pteval_t, 0x01) << 2)	/* 0001 */
+#define L_PTE_MT_WRITETHROUGH	(_AT(pteval_t, 0x02) << 2)	/* 0010 */
+#define L_PTE_MT_WRITEBACK	(_AT(pteval_t, 0x03) << 2)	/* 0011 */
+#define L_PTE_MT_MINICACHE	(_AT(pteval_t, 0x06) << 2)	/* 0110 (sa1100, xscale) */
+#define L_PTE_MT_WRITEALLOC	(_AT(pteval_t, 0x07) << 2)	/* 0111 */
+#define L_PTE_MT_DEV_SHARED	(_AT(pteval_t, 0x04) << 2)	/* 0100 */
+#define L_PTE_MT_DEV_NONSHARED	(_AT(pteval_t, 0x0c) << 2)	/* 1100 */
+#define L_PTE_MT_DEV_WC		(_AT(pteval_t, 0x09) << 2)	/* 1001 */
+#define L_PTE_MT_DEV_CACHED	(_AT(pteval_t, 0x0b) << 2)	/* 1011 */
+#define L_PTE_MT_MASK		(_AT(pteval_t, 0x0f) << 2)
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 83e59f8..01210db 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -26,7 +26,7 @@
 
 #include "mm.h"
 
-static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE;
+static pteval_t shared_pte_mask = L_PTE_MT_BUFFERABLE;
 
 #if __LINUX_ARM_ARCH__ < 6
 /*
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/5] ARM: pgtable: invert L_PTE_EXEC to L_PTE_XN
  2010-11-17 17:27 [PATCH 0/5] Clean up page tables Russell King - ARM Linux
                   ` (2 preceding siblings ...)
  2010-11-17 17:29 ` [PATCH 3/5] ARM: pgtable: introduce pteval_t to represent a pte value Russell King - ARM Linux
@ 2010-11-17 17:29 ` Russell King - ARM Linux
  2010-11-17 17:29 ` [PATCH 5/5] ARM: pgtable: provide RDONLY page table bit rather than WRITE bit Russell King - ARM Linux
  2010-11-19 12:00 ` [PATCH 0/5] Clean up page tables Catalin Marinas
  5 siblings, 0 replies; 16+ messages in thread
From: Russell King - ARM Linux @ 2010-11-17 17:29 UTC (permalink / raw)
  To: linux-arm-kernel

The hardware page tables use an XN bit 'execute never'.  Historically,
we've had a Linux 'execute allow' bit, in the positive sense.  Get rid
of this artifact as future hardware will continue to have the XN sense.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/pgtable.h |   44 ++++++++++++++++++++--------------------
 arch/arm/mm/mmu.c              |   15 ++++++-------
 arch/arm/mm/proc-macros.S      |    6 ++--
 arch/arm/mm/proc-v7.S          |    4 +-
 4 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 59e0ea2..a4eda5f 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -172,7 +172,7 @@ extern void __pgd_error(const char *file, int line, pgd_t);
 #define L_PTE_DIRTY		(_AT(pteval_t, 1) << 6)
 #define L_PTE_WRITE		(_AT(pteval_t, 1) << 7)
 #define L_PTE_USER		(_AT(pteval_t, 1) << 8)
-#define L_PTE_EXEC		(_AT(pteval_t, 1) << 9)
+#define L_PTE_XN		(_AT(pteval_t, 1) << 9)
 #define L_PTE_SHARED		(_AT(pteval_t, 1) << 10)	/* shared(v6), coherent(xsc3) */
 
 /*
@@ -206,23 +206,23 @@ extern pgprot_t		pgprot_kernel;
 
 #define _MOD_PROT(p, b)	__pgprot(pgprot_val(p) | (b))
 
-#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)
+#define PAGE_NONE		_MOD_PROT(pgprot_user, L_PTE_XN)
+#define PAGE_SHARED		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE | L_PTE_XN)
+#define PAGE_SHARED_EXEC	_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE)
+#define PAGE_COPY		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
+#define PAGE_COPY_EXEC		_MOD_PROT(pgprot_user, L_PTE_USER)
+#define PAGE_READONLY		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
+#define PAGE_READONLY_EXEC	_MOD_PROT(pgprot_user, L_PTE_USER)
+#define PAGE_KERNEL		_MOD_PROT(pgprot_kernel, L_PTE_XN)
+#define PAGE_KERNEL_EXEC	pgprot_kernel
+
+#define __PAGE_NONE		__pgprot(_L_PTE_DEFAULT | L_PTE_XN)
+#define __PAGE_SHARED		__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE | L_PTE_XN)
+#define __PAGE_SHARED_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE)
+#define __PAGE_COPY		__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
+#define __PAGE_COPY_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER)
+#define __PAGE_READONLY		__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
+#define __PAGE_READONLY_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER)
 
 #endif /* __ASSEMBLY__ */
 
@@ -308,7 +308,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 #define pte_write(pte)		(pte_val(pte) & L_PTE_WRITE)
 #define pte_dirty(pte)		(pte_val(pte) & L_PTE_DIRTY)
 #define pte_young(pte)		(pte_val(pte) & L_PTE_YOUNG)
-#define pte_exec(pte)		(pte_val(pte) & L_PTE_EXEC)
+#define pte_exec(pte)		(!(pte_val(pte) & L_PTE_XN))
 #define pte_special(pte)	(0)
 
 #define pte_present_user(pte) \
@@ -339,14 +339,14 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
 	__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
 #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
 #define pgprot_dmacoherent(prot) \
-	__pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
+	__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE|L_PTE_XN)
 #define __HAVE_PHYS_MEM_ACCESS_PROT
 struct file;
 extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 				     unsigned long size, pgprot_t vma_prot);
 #else
 #define pgprot_dmacoherent(prot) \
-	__pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED)
+	__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED|L_PTE_XN)
 #endif
 
 #define pmd_none(pmd)		(!pmd_val(pmd))
@@ -408,7 +408,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
-	const unsigned long mask = L_PTE_EXEC | L_PTE_WRITE | L_PTE_USER;
+	const unsigned long mask = L_PTE_XN | L_PTE_WRITE | L_PTE_USER;
 	pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
 	return pte;
 }
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 9963189..a7f56fc 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -190,7 +190,7 @@ void adjust_cr(unsigned long mask, unsigned long set)
 }
 #endif
 
-#define PROT_PTE_DEVICE		L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_WRITE
+#define PROT_PTE_DEVICE		L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_WRITE|L_PTE_XN
 #define PROT_SECT_DEVICE	PMD_TYPE_SECT|PMD_SECT_AP_WRITE
 
 static struct mem_type mem_types[] = {
@@ -234,20 +234,19 @@ static struct mem_type mem_types[] = {
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_LOW_VECTORS] = {
-		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-				L_PTE_EXEC,
+		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.domain    = DOMAIN_USER,
 	},
 	[MT_HIGH_VECTORS] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-				L_PTE_USER | L_PTE_EXEC,
+				L_PTE_USER,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.domain    = DOMAIN_USER,
 	},
 	[MT_MEMORY] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-				L_PTE_WRITE | L_PTE_EXEC,
+				L_PTE_WRITE,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
 		.domain    = DOMAIN_KERNEL,
@@ -258,21 +257,21 @@ static struct mem_type mem_types[] = {
 	},
 	[MT_MEMORY_NONCACHED] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-				L_PTE_WRITE | L_PTE_EXEC | L_PTE_MT_BUFFERABLE,
+				L_PTE_WRITE| L_PTE_MT_BUFFERABLE,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_MEMORY_DTCM] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-				L_PTE_WRITE,
+				L_PTE_WRITE | L_PTE_XN,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_MEMORY_ITCM] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-				L_PTE_WRITE | L_PTE_EXEC,
+				L_PTE_WRITE,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.domain    = DOMAIN_KERNEL,
 	},
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index cbedf9c..4a7a9e1 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -81,7 +81,7 @@
 #if L_PTE_SHARED != PTE_EXT_SHARED
 #error PTE shared bit mismatch
 #endif
-#if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\
+#if (L_PTE_XN+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\
      L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
 #error Invalid Linux PTE bit settings
 #endif
@@ -141,8 +141,8 @@
 	tstne	r3, #PTE_EXT_APX
 	bicne	r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
 
-	tst	r1, #L_PTE_EXEC
-	orreq	r3, r3, #PTE_EXT_XN
+	tst	r1, #L_PTE_XN
+	orrne	r3, r3, #PTE_EXT_XN
 
 	orr	r3, r3, r2
 
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 89c31a6..4f5a594 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -149,8 +149,8 @@ ENTRY(cpu_v7_set_pte_ext)
 	tstne	r3, #PTE_EXT_APX
 	bicne	r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
 
-	tst	r1, #L_PTE_EXEC
-	orreq	r3, r3, #PTE_EXT_XN
+	tst	r1, #L_PTE_XN
+	orrne	r3, r3, #PTE_EXT_XN
 
 	tst	r1, #L_PTE_YOUNG
 	tstne	r1, #L_PTE_PRESENT
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/5] ARM: pgtable: provide RDONLY page table bit rather than WRITE bit
  2010-11-17 17:27 [PATCH 0/5] Clean up page tables Russell King - ARM Linux
                   ` (3 preceding siblings ...)
  2010-11-17 17:29 ` [PATCH 4/5] ARM: pgtable: invert L_PTE_EXEC to L_PTE_XN Russell King - ARM Linux
@ 2010-11-17 17:29 ` Russell King - ARM Linux
  2010-11-19 12:00 ` [PATCH 0/5] Clean up page tables Catalin Marinas
  5 siblings, 0 replies; 16+ messages in thread
From: Russell King - ARM Linux @ 2010-11-17 17:29 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/include/asm/pgtable.h |   38 +++++++++++++++++++-------------------
 arch/arm/mm/mmu.c              |   19 +++++++++----------
 arch/arm/mm/proc-macros.S      |   16 ++++++++--------
 arch/arm/mm/proc-v7.S          |    6 +++---
 arch/arm/mm/proc-xscale.S      |    4 ++--
 5 files changed, 41 insertions(+), 42 deletions(-)

diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index a4eda5f..77b6634 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -170,7 +170,7 @@ extern void __pgd_error(const char *file, int line, pgd_t);
 #define L_PTE_YOUNG		(_AT(pteval_t, 1) << 1)
 #define L_PTE_FILE		(_AT(pteval_t, 1) << 2)	/* only when !PRESENT */
 #define L_PTE_DIRTY		(_AT(pteval_t, 1) << 6)
-#define L_PTE_WRITE		(_AT(pteval_t, 1) << 7)
+#define L_PTE_RDONLY		(_AT(pteval_t, 1) << 7)
 #define L_PTE_USER		(_AT(pteval_t, 1) << 8)
 #define L_PTE_XN		(_AT(pteval_t, 1) << 9)
 #define L_PTE_SHARED		(_AT(pteval_t, 1) << 10)	/* shared(v6), coherent(xsc3) */
@@ -206,23 +206,23 @@ extern pgprot_t		pgprot_kernel;
 
 #define _MOD_PROT(p, b)	__pgprot(pgprot_val(p) | (b))
 
-#define PAGE_NONE		_MOD_PROT(pgprot_user, L_PTE_XN)
-#define PAGE_SHARED		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE | L_PTE_XN)
-#define PAGE_SHARED_EXEC	_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE)
-#define PAGE_COPY		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
-#define PAGE_COPY_EXEC		_MOD_PROT(pgprot_user, L_PTE_USER)
-#define PAGE_READONLY		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
-#define PAGE_READONLY_EXEC	_MOD_PROT(pgprot_user, L_PTE_USER)
+#define PAGE_NONE		_MOD_PROT(pgprot_user, L_PTE_XN | L_PTE_RDONLY)
+#define PAGE_SHARED		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
+#define PAGE_SHARED_EXEC	_MOD_PROT(pgprot_user, L_PTE_USER)
+#define PAGE_COPY		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define PAGE_COPY_EXEC		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
+#define PAGE_READONLY		_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define PAGE_READONLY_EXEC	_MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
 #define PAGE_KERNEL		_MOD_PROT(pgprot_kernel, L_PTE_XN)
 #define PAGE_KERNEL_EXEC	pgprot_kernel
 
-#define __PAGE_NONE		__pgprot(_L_PTE_DEFAULT | L_PTE_XN)
-#define __PAGE_SHARED		__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE | L_PTE_XN)
-#define __PAGE_SHARED_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE)
-#define __PAGE_COPY		__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
-#define __PAGE_COPY_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER)
-#define __PAGE_READONLY		__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
-#define __PAGE_READONLY_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER)
+#define __PAGE_NONE		__pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN)
+#define __PAGE_SHARED		__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
+#define __PAGE_SHARED_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER)
+#define __PAGE_COPY		__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define __PAGE_COPY_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
+#define __PAGE_READONLY		__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define __PAGE_READONLY_EXEC	__pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
 
 #endif /* __ASSEMBLY__ */
 
@@ -305,7 +305,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
  * Undefined behaviour if not..
  */
 #define pte_present(pte)	(pte_val(pte) & L_PTE_PRESENT)
-#define pte_write(pte)		(pte_val(pte) & L_PTE_WRITE)
+#define pte_write(pte)		(!(pte_val(pte) & L_PTE_RDONLY))
 #define pte_dirty(pte)		(pte_val(pte) & L_PTE_DIRTY)
 #define pte_young(pte)		(pte_val(pte) & L_PTE_YOUNG)
 #define pte_exec(pte)		(!(pte_val(pte) & L_PTE_XN))
@@ -318,8 +318,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 #define PTE_BIT_FUNC(fn,op) \
 static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
 
-PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE);
-PTE_BIT_FUNC(mkwrite,   |= L_PTE_WRITE);
+PTE_BIT_FUNC(wrprotect, |= L_PTE_RDONLY);
+PTE_BIT_FUNC(mkwrite,   &= ~L_PTE_RDONLY);
 PTE_BIT_FUNC(mkclean,   &= ~L_PTE_DIRTY);
 PTE_BIT_FUNC(mkdirty,   |= L_PTE_DIRTY);
 PTE_BIT_FUNC(mkold,     &= ~L_PTE_YOUNG);
@@ -408,7 +408,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
-	const unsigned long mask = L_PTE_XN | L_PTE_WRITE | L_PTE_USER;
+	const unsigned long mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER;
 	pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
 	return pte;
 }
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index a7f56fc..3447c1b 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -190,7 +190,7 @@ void adjust_cr(unsigned long mask, unsigned long set)
 }
 #endif
 
-#define PROT_PTE_DEVICE		L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_WRITE|L_PTE_XN
+#define PROT_PTE_DEVICE		L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
 #define PROT_SECT_DEVICE	PMD_TYPE_SECT|PMD_SECT_AP_WRITE
 
 static struct mem_type mem_types[] = {
@@ -234,19 +234,19 @@ static struct mem_type mem_types[] = {
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_LOW_VECTORS] = {
-		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
+		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+				L_PTE_RDONLY,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.domain    = DOMAIN_USER,
 	},
 	[MT_HIGH_VECTORS] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-				L_PTE_USER,
+				L_PTE_USER | L_PTE_RDONLY,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.domain    = DOMAIN_USER,
 	},
 	[MT_MEMORY] = {
-		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-				L_PTE_WRITE,
+		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
 		.domain    = DOMAIN_KERNEL,
@@ -257,21 +257,20 @@ static struct mem_type mem_types[] = {
 	},
 	[MT_MEMORY_NONCACHED] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-				L_PTE_WRITE| L_PTE_MT_BUFFERABLE,
+				L_PTE_MT_BUFFERABLE,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_MEMORY_DTCM] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-				L_PTE_WRITE | L_PTE_XN,
+				L_PTE_XN,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_MEMORY_ITCM] = {
-		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-				L_PTE_WRITE,
+		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
 		.prot_l1   = PMD_TYPE_TABLE,
 		.domain    = DOMAIN_KERNEL,
 	},
@@ -478,7 +477,7 @@ static void __init build_mem_type_table(void)
 
 	pgprot_user   = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
 	pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
-				 L_PTE_DIRTY | L_PTE_WRITE | kern_pgprot);
+				 L_PTE_DIRTY | kern_pgprot);
 
 	mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
 	mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 4a7a9e1..f5ca6aa 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -81,7 +81,7 @@
 #if L_PTE_SHARED != PTE_EXT_SHARED
 #error PTE shared bit mismatch
 #endif
-#if (L_PTE_XN+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\
+#if (L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\
      L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
 #error Invalid Linux PTE bit settings
 #endif
@@ -132,9 +132,9 @@
 	and	r2, r1, #L_PTE_MT_MASK
 	ldr	r2, [ip, r2]
 
-	tst	r1, #L_PTE_WRITE
-	tstne	r1, #L_PTE_DIRTY
-	orreq	r3, r3, #PTE_EXT_APX
+	eor	r1, r1, #L_PTE_DIRTY
+	tst	r1, #L_PTE_DIRTY|L_PTE_RDONLY
+	orrne	r3, r3, #PTE_EXT_APX
 
 	tst	r1, #L_PTE_USER
 	orrne	r3, r3, #PTE_EXT_AP1
@@ -172,7 +172,7 @@
 	.macro	armv3_set_pte_ext wc_disable=1
 	str	r1, [r0], #2048			@ linux version
 
-	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY
 
 	bic	r2, r1, #PTE_SMALL_AP_MASK	@ keep C, B bits
 	bic	r2, r2, #PTE_TYPE_MASK
@@ -181,7 +181,7 @@
 	tst	r3, #L_PTE_USER			@ user?
 	orrne	r2, r2, #PTE_SMALL_AP_URO_SRW
 
-	tst	r3, #L_PTE_WRITE | L_PTE_DIRTY	@ write and dirty?
+	tst	r3, #L_PTE_RDONLY | L_PTE_DIRTY	@ write and dirty?
 	orreq	r2, r2, #PTE_SMALL_AP_UNO_SRW
 
 	tst	r3, #L_PTE_PRESENT | L_PTE_YOUNG	@ present and young?
@@ -215,7 +215,7 @@
 	.macro	xscale_set_pte_ext_prologue
 	str	r1, [r0]			@ linux version
 
-	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY
 
 	bic	r2, r1, #PTE_SMALL_AP_MASK	@ keep C, B bits
 	orr	r2, r2, #PTE_TYPE_EXT		@ extended page
@@ -223,7 +223,7 @@
 	tst	r3, #L_PTE_USER			@ user?
 	orrne	r2, r2, #PTE_EXT_AP_URO_SRW	@ yes -> user r/o, system r/w
 
-	tst	r3, #L_PTE_WRITE | L_PTE_DIRTY	@ write and dirty?
+	tst	r3, #L_PTE_RDONLY | L_PTE_DIRTY	@ write and dirty?
 	orreq	r2, r2, #PTE_EXT_AP_UNO_SRW	@ yes -> user n/a, system r/w
 						@ combined with user -> user r/w
 	.endm
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 4f5a594..210d051 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -140,9 +140,9 @@ ENTRY(cpu_v7_set_pte_ext)
 	tst	r1, #1 << 4
 	orrne	r3, r3, #PTE_EXT_TEX(1)
 
-	tst	r1, #L_PTE_WRITE
-	tstne	r1, #L_PTE_DIRTY
-	orreq	r3, r3, #PTE_EXT_APX
+	eor	r1, r1, #L_PTE_DIRTY
+	tst	r1, #L_PTE_RDONLY | L_PTE_DIRTY
+	orrne	r3, r3, #PTE_EXT_APX
 
 	tst	r1, #L_PTE_USER
 	orrne	r3, r3, #PTE_EXT_AP1
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 523408c..5a37c5e 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -500,8 +500,8 @@ ENTRY(cpu_xscale_set_pte_ext)
 	@
 	@ Erratum 40: must set memory to write-through for user read-only pages
 	@
-	and	ip, r1, #(L_PTE_MT_MASK | L_PTE_USER | L_PTE_WRITE) & ~(4 << 2)
-	teq	ip, #L_PTE_MT_WRITEBACK | L_PTE_USER
+	and	ip, r1, #(L_PTE_MT_MASK | L_PTE_USER | L_PTE_RDONLY) & ~(4 << 2)
+	teq	ip, #L_PTE_MT_WRITEBACK | L_PTE_USER | L_PTE_RDONLY
 
 	moveq	r1, #L_PTE_MT_WRITETHROUGH
 	and	r1, r1, #L_PTE_MT_MASK
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/5] ARM: pgtable: introduce pteval_t to represent a pte value
  2010-11-17 17:29 ` [PATCH 3/5] ARM: pgtable: introduce pteval_t to represent a pte value Russell King - ARM Linux
@ 2010-11-18 10:59   ` Catalin Marinas
  2010-11-19 14:23   ` Catalin Marinas
  1 sibling, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2010-11-18 10:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 17 November 2010 17:29, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> This makes everywhere dealing with pte values use the same type.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
> ?arch/arm/include/asm/page.h ? ?| ? ?6 ++++--
> ?arch/arm/include/asm/pgtable.h | ? 39 ++++++++++++++++++++-------------------

Do we need to adjust the type of the mask in pte_modify?

-- 
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware page tables
  2010-11-17 17:28 ` [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware " Russell King - ARM Linux
@ 2010-11-18 16:59   ` Catalin Marinas
  2010-11-18 17:38     ` Catalin Marinas
  2010-11-18 17:18   ` Catalin Marinas
  2010-11-19 11:48   ` Catalin Marinas
  2 siblings, 1 reply; 16+ messages in thread
From: Catalin Marinas @ 2010-11-18 16:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 17 November 2010 17:28, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> This switches the ordering of the Linux vs hardware page tables in
> each page, thereby eliminating some of the arithmetic in the page
> table walks. ?As we now place the Linux page table at the beginning
> of the page, we can deal with the offset in the pgt by simply masking
> it away, along with the other control bits.
[...]
> -static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
> +static inline void __pmd_populate(pmd_t *pmdp, unsigned long pte, unsigned long prot)
> ?{
> + ? ? ? unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot;

Since I'm introducing pmdval_t with LPAE patches, would it make sense
in your patch to pass pteval_t or I should just keep it in my patches?

-static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
+static inline void __pmd_populate(pmd_t *pmdp, pteval_t pte, unsigned
long prot)

-- 
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware page tables
  2010-11-17 17:28 ` [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware " Russell King - ARM Linux
  2010-11-18 16:59   ` Catalin Marinas
@ 2010-11-18 17:18   ` Catalin Marinas
  2010-11-19 11:48   ` Catalin Marinas
  2 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2010-11-18 17:18 UTC (permalink / raw)
  To: linux-arm-kernel

On 17 November 2010 17:28, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> This switches the ordering of the Linux vs hardware page tables in
> each page, thereby eliminating some of the arithmetic in the page
> table walks. ?As we now place the Linux page table at the beginning
> of the page, we can deal with the offset in the pgt by simply masking
> it away, along with the other control bits.
[...]
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -535,7 +535,7 @@ static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned l
> ?{
> ? ? ? ?if (pmd_none(*pmd)) {
> ? ? ? ? ? ? ? ?pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
> - ? ? ? ? ? ? ? __pmd_populate(pmd, __pa(pte) | prot);
> + ? ? ? ? ? ? ? __pmd_populate(pmd, __pa(pte), prot);

While you are here, can you change the early_alloc size to
PTE_HWTABLE_OFF+PTE_HWTABLE_SIZE? This way I don't need to patch this
in LPAE.

-- 
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware page tables
  2010-11-18 16:59   ` Catalin Marinas
@ 2010-11-18 17:38     ` Catalin Marinas
  0 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2010-11-18 17:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 18 November 2010 16:59, Catalin Marinas <catalin.marinas@arm.com> wrote:
> On 17 November 2010 17:28, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
>> This switches the ordering of the Linux vs hardware page tables in
>> each page, thereby eliminating some of the arithmetic in the page
>> table walks. ?As we now place the Linux page table at the beginning
>> of the page, we can deal with the offset in the pgt by simply masking
>> it away, along with the other control bits.
> [...]
>> -static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
>> +static inline void __pmd_populate(pmd_t *pmdp, unsigned long pte, unsigned long prot)
>> ?{
>> + ? ? ? unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot;
>
> Since I'm introducing pmdval_t with LPAE patches, would it make sense
> in your patch to pass pteval_t or I should just keep it in my patches?
>
> -static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
> +static inline void __pmd_populate(pmd_t *pmdp, pteval_t pte, unsigned long prot)

I think your initial version is correct since the pte above is
actually a physical address. We'll change it to phys_addr_t.

-- 
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware page tables
  2010-11-17 17:28 ` [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware " Russell King - ARM Linux
  2010-11-18 16:59   ` Catalin Marinas
  2010-11-18 17:18   ` Catalin Marinas
@ 2010-11-19 11:48   ` Catalin Marinas
  2010-11-26 11:38     ` Russell King - ARM Linux
  2 siblings, 1 reply; 16+ messages in thread
From: Catalin Marinas @ 2010-11-19 11:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 17 November 2010 17:28, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -158,7 +156,7 @@ ENTRY(cpu_v7_set_pte_ext)
> ? ? ? ?tstne ? r1, #L_PTE_PRESENT
> ? ? ? ?moveq ? r3, #0
>
> - ? ? ? str ? ? r3, [r0]
> + ? ? ? str ? ? r3, [r0, #2048]!

Thumb-2 build gives "offset out of range".  We need to do a separate
ADD for this case.

diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 688deda..9aba33c 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -186,7 +186,9 @@ ENTRY(cpu_v7_set_pte_ext)
 	tstne	r1, #L_PTE_PRESENT
 	moveq	r3, #0

-	str	r3, [r0, #2048]!
+ ARM(	str	r3, [r0, #2048]!	)
+ THUMB(	str	r3, [r0, #2048]		)
+ THUMB(	add	r0, r0, #2048		)
 #endif	/* CONFIG_ARM_LPAE */
 	mcr	p15, 0, r0, c7, c10, 1		@ flush_pte
 #endif


-- 
Catalin

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 0/5] Clean up page tables
  2010-11-17 17:27 [PATCH 0/5] Clean up page tables Russell King - ARM Linux
                   ` (4 preceding siblings ...)
  2010-11-17 17:29 ` [PATCH 5/5] ARM: pgtable: provide RDONLY page table bit rather than WRITE bit Russell King - ARM Linux
@ 2010-11-19 12:00 ` Catalin Marinas
  5 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2010-11-19 12:00 UTC (permalink / raw)
  To: linux-arm-kernel

On 17 November 2010 17:27, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> This patch series is preparation for LPAE, allowing a cleaner
> transition from the current methodology to that required for
> LPAE.

Apart from a few things I raised (after which you can even add my ack
for all of them), the LPAE patches work fine on top of your series.

What are your plans for upstream? It looks like stuff for 2.6.38 but
it would be good if in the meantime you make them available on some
branch (just these patches) so that I can rebase my LPAE work on top
without carrying your patches.

Thanks.

-- 
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 3/5] ARM: pgtable: introduce pteval_t to represent a pte value
  2010-11-17 17:29 ` [PATCH 3/5] ARM: pgtable: introduce pteval_t to represent a pte value Russell King - ARM Linux
  2010-11-18 10:59   ` Catalin Marinas
@ 2010-11-19 14:23   ` Catalin Marinas
  2010-11-19 14:27     ` Catalin Marinas
  1 sibling, 1 reply; 16+ messages in thread
From: Catalin Marinas @ 2010-11-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

On 17 November 2010 17:29, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> --- a/arch/arm/include/asm/pgtable.h
> +++ b/arch/arm/include/asm/pgtable.h
> @@ -10,6 +10,7 @@
> ?#ifndef _ASMARM_PGTABLE_H
> ?#define _ASMARM_PGTABLE_H
>
> +#include <linux/const.h>
> ?#include <asm-generic/4level-fixup.h>
> ?#include <asm/proc-fns.h>
>
> @@ -165,30 +166,30 @@ extern void __pgd_error(const char *file, int line, pgd_t);
> ?* The PTE table pointer refers to the hardware entries; the "Linux"
> ?* entries are stored 1024 bytes below.
> ?*/
> -#define L_PTE_PRESENT ? ? ? ? ?(1 << 0)
> -#define L_PTE_YOUNG ? ? ? ? ? ?(1 << 1)
> -#define L_PTE_FILE ? ? ? ? ? ? (1 << 2) ? ? ? ?/* only when !PRESENT */
> -#define L_PTE_DIRTY ? ? ? ? ? ?(1 << 6)
> -#define L_PTE_WRITE ? ? ? ? ? ?(1 << 7)
> -#define L_PTE_USER ? ? ? ? ? ? (1 << 8)
> -#define L_PTE_EXEC ? ? ? ? ? ? (1 << 9)
> -#define L_PTE_SHARED ? ? ? ? ? (1 << 10) ? ? ? /* shared(v6), coherent(xsc3) */
> +#define L_PTE_PRESENT ? ? ? ? ?(_AT(pteval_t, 1) << 0)
> +#define L_PTE_YOUNG ? ? ? ? ? ?(_AT(pteval_t, 1) << 1)
> +#define L_PTE_FILE ? ? ? ? ? ? (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
> +#define L_PTE_DIRTY ? ? ? ? ? ?(_AT(pteval_t, 1) << 6)
> +#define L_PTE_WRITE ? ? ? ? ? ?(_AT(pteval_t, 1) << 7)
> +#define L_PTE_USER ? ? ? ? ? ? (_AT(pteval_t, 1) << 8)
> +#define L_PTE_EXEC ? ? ? ? ? ? (_AT(pteval_t, 1) << 9)
> +#define L_PTE_SHARED ? ? ? ? ? (_AT(pteval_t, 1) << 10) ? ? ? ?/* shared(v6), coherent(xsc3) */

One of my patches which adds pmdval_t etc. also defines the PMD_SECT_*
macros with _AT(pmdval_t...). For consistency in the same file, I
defined the PTE_* as _AT(pteval_t), though the latter are only used in
.S files. Note that 64-bit values aren't handled by .S anyway.

Should your patch use _AT() for PTE_* macros as well or we just leave
them as they are?

-- 
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 3/5] ARM: pgtable: introduce pteval_t to represent a pte value
  2010-11-19 14:23   ` Catalin Marinas
@ 2010-11-19 14:27     ` Catalin Marinas
  0 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2010-11-19 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 19 November 2010 14:23, Catalin Marinas <catalin.marinas@arm.com> wrote:
> On 17 November 2010 17:29, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
>> --- a/arch/arm/include/asm/pgtable.h
>> +++ b/arch/arm/include/asm/pgtable.h
>> @@ -10,6 +10,7 @@
>> ?#ifndef _ASMARM_PGTABLE_H
>> ?#define _ASMARM_PGTABLE_H
>>
>> +#include <linux/const.h>
>> ?#include <asm-generic/4level-fixup.h>
>> ?#include <asm/proc-fns.h>
>>
>> @@ -165,30 +166,30 @@ extern void __pgd_error(const char *file, int line, pgd_t);
>> ?* The PTE table pointer refers to the hardware entries; the "Linux"
>> ?* entries are stored 1024 bytes below.
>> ?*/
>> -#define L_PTE_PRESENT ? ? ? ? ?(1 << 0)
>> -#define L_PTE_YOUNG ? ? ? ? ? ?(1 << 1)
>> -#define L_PTE_FILE ? ? ? ? ? ? (1 << 2) ? ? ? ?/* only when !PRESENT */
>> -#define L_PTE_DIRTY ? ? ? ? ? ?(1 << 6)
>> -#define L_PTE_WRITE ? ? ? ? ? ?(1 << 7)
>> -#define L_PTE_USER ? ? ? ? ? ? (1 << 8)
>> -#define L_PTE_EXEC ? ? ? ? ? ? (1 << 9)
>> -#define L_PTE_SHARED ? ? ? ? ? (1 << 10) ? ? ? /* shared(v6), coherent(xsc3) */
>> +#define L_PTE_PRESENT ? ? ? ? ?(_AT(pteval_t, 1) << 0)
>> +#define L_PTE_YOUNG ? ? ? ? ? ?(_AT(pteval_t, 1) << 1)
>> +#define L_PTE_FILE ? ? ? ? ? ? (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
>> +#define L_PTE_DIRTY ? ? ? ? ? ?(_AT(pteval_t, 1) << 6)
>> +#define L_PTE_WRITE ? ? ? ? ? ?(_AT(pteval_t, 1) << 7)
>> +#define L_PTE_USER ? ? ? ? ? ? (_AT(pteval_t, 1) << 8)
>> +#define L_PTE_EXEC ? ? ? ? ? ? (_AT(pteval_t, 1) << 9)
>> +#define L_PTE_SHARED ? ? ? ? ? (_AT(pteval_t, 1) << 10) ? ? ? ?/* shared(v6), coherent(xsc3) */
>
> One of my patches which adds pmdval_t etc. also defines the PMD_SECT_*
> macros with _AT(pmdval_t...). For consistency in the same file, I
> defined the PTE_* as _AT(pteval_t), though the latter are only used in
> .S files.

Ah, there is PTE_EXT_NG. Fortunately, that's bit 11 and it fits in
32-bit. So my proposal is to add _AT(pteval_t) to the PTE_*
definitions as well, unless you want to add a corresponding
L_PTE_EXT_NG.

-- 
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware page tables
  2010-11-19 11:48   ` Catalin Marinas
@ 2010-11-26 11:38     ` Russell King - ARM Linux
  2010-11-26 14:41       ` Catalin Marinas
  0 siblings, 1 reply; 16+ messages in thread
From: Russell King - ARM Linux @ 2010-11-26 11:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 19, 2010 at 11:48:31AM +0000, Catalin Marinas wrote:
> On 17 November 2010 17:28, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > --- a/arch/arm/mm/proc-v7.S
> > +++ b/arch/arm/mm/proc-v7.S
> > @@ -158,7 +156,7 @@ ENTRY(cpu_v7_set_pte_ext)
> > ? ? ? ?tstne ? r1, #L_PTE_PRESENT
> > ? ? ? ?moveq ? r3, #0
> >
> > - ? ? ? str ? ? r3, [r0]
> > + ? ? ? str ? ? r3, [r0, #2048]!
> 
> Thumb-2 build gives "offset out of range".  We need to do a separate
> ADD for this case.

Do we have any clues about the typical timing of:

	str	r3, [r0, #2048]!
	mcr	p15, 0, r0, c7, c10, 1

vs:
	add	r0, r0, #2048
	str	r3, [r0]
	mcr	p15, 0, r0, c7, c10, 1

or
	str	r3, [r0, #2048]
	add	r0, r0, #2048
	mcr	p15, 0, r0, c7, c10, 1

on ARMv7?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware page tables
  2010-11-26 11:38     ` Russell King - ARM Linux
@ 2010-11-26 14:41       ` Catalin Marinas
  0 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2010-11-26 14:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2010-11-26 at 11:38 +0000, Russell King - ARM Linux wrote:
> On Fri, Nov 19, 2010 at 11:48:31AM +0000, Catalin Marinas wrote:
> > On 17 November 2010 17:28, Russell King - ARM Linux
> > <linux@arm.linux.org.uk> wrote:
> > > --- a/arch/arm/mm/proc-v7.S
> > > +++ b/arch/arm/mm/proc-v7.S
> > > @@ -158,7 +156,7 @@ ENTRY(cpu_v7_set_pte_ext)
> > >        tstne   r1, #L_PTE_PRESENT
> > >        moveq   r3, #0
> > >
> > > -       str     r3, [r0]
> > > +       str     r3, [r0, #2048]!
> >
> > Thumb-2 build gives "offset out of range".  We need to do a separate
> > ADD for this case.
> 
> Do we have any clues about the typical timing of:
> 
>         str     r3, [r0, #2048]!
>         mcr     p15, 0, r0, c7, c10, 1
> 
> vs:
>         add     r0, r0, #2048
>         str     r3, [r0]
>         mcr     p15, 0, r0, c7, c10, 1
> 
> or
>         str     r3, [r0, #2048]
>         add     r0, r0, #2048
>         mcr     p15, 0, r0, c7, c10, 1
> 
> on ARMv7?

Since there is an address (r0) dependency in the last mcr, all three may
take the same number of cycles.

For T2, the last one could be better, generally, since the str has a bit
more time available before the cache flushing.

For ARM, the advantage of the first one (writeback) is that we don't use
another instruction and have more room in the prefetch buffer, though
not sure this would be noticeable. You could use some ARM/THUMB macros.

-- 
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2010-11-26 14:41 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-17 17:27 [PATCH 0/5] Clean up page tables Russell King - ARM Linux
2010-11-17 17:28 ` [PATCH 1/5] ARM: pgtable: switch order of Linux vs hardware " Russell King - ARM Linux
2010-11-18 16:59   ` Catalin Marinas
2010-11-18 17:38     ` Catalin Marinas
2010-11-18 17:18   ` Catalin Marinas
2010-11-19 11:48   ` Catalin Marinas
2010-11-26 11:38     ` Russell King - ARM Linux
2010-11-26 14:41       ` Catalin Marinas
2010-11-17 17:28 ` [PATCH 2/5] ARM: pgtable: directly pass pgd/pmd/pte to their error functions Russell King - ARM Linux
2010-11-17 17:29 ` [PATCH 3/5] ARM: pgtable: introduce pteval_t to represent a pte value Russell King - ARM Linux
2010-11-18 10:59   ` Catalin Marinas
2010-11-19 14:23   ` Catalin Marinas
2010-11-19 14:27     ` Catalin Marinas
2010-11-17 17:29 ` [PATCH 4/5] ARM: pgtable: invert L_PTE_EXEC to L_PTE_XN Russell King - ARM Linux
2010-11-17 17:29 ` [PATCH 5/5] ARM: pgtable: provide RDONLY page table bit rather than WRITE bit Russell King - ARM Linux
2010-11-19 12:00 ` [PATCH 0/5] Clean up page tables Catalin Marinas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.