* [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.