Thread (6 messages) flat view 6 messages, 3 authors, 2008-06-19

Re: [RFC/PATCH] powerpc: rework 4xx PTE access and TLB miss

From: Kumar Gala <hidden>
Date: 2008-06-11 02:18:57

quoted hunk ↗ jump to hunk
Index: linux-work/include/asm-powerpc/pgtable-ppc32.h
===================================================================
--- linux-work.orig/include/asm-powerpc/pgtable-ppc32.h	2008-06-10  
18:13:47.000000000 +1000
+++ linux-work/include/asm-powerpc/pgtable-ppc32.h	2008-06-10  
18:16:49.000000000 +1000
@@ -182,6 +182,9 @@ extern int icache_44x_need_flush;
#define _PMD_SIZE_16M	0x0e0
#define PMD_PAGE_SIZE(pmdval)	(1024 << (((pmdval) & _PMD_SIZE) >> 4))

+/* Until my rework is finished, 40x still needs atomic PTE updates */
+#define PTE_ATOMIC_UPDATES	1
+
#elif defined(CONFIG_44x)
/*
 * Definitions for PPC440
@@ -253,17 +256,17 @@ extern int icache_44x_need_flush;
 */
#define _PAGE_PRESENT	0x00000001		/* S: PTE valid */
-#define	_PAGE_RW	0x00000002		/* S: Write permission */
+#define _PAGE_RW	0x00000002		/* S: Write permission */
#define _PAGE_FILE	0x00000004		/* S: nonlinear file mapping */
+#define _PAGE_HWEXEC	0x00000004		/* H: Execute permission */
I'm sure this is ok, but why can we overlay _PAGE_HWEXEC and _PAGE_FILE?
#define _PAGE_ACCESSED	0x00000008		/* S: Page referenced */
-#define _PAGE_HWWRITE	0x00000010		/* H: Dirty & RW */
-#define _PAGE_HWEXEC	0x00000020		/* H: Execute permission */
-#define	_PAGE_USER	0x00000040		/* S: User page */
-#define	_PAGE_ENDIAN	0x00000080		/* H: E bit */
-#define	_PAGE_GUARDED	0x00000100		/* H: G bit */
-#define	_PAGE_DIRTY	0x00000200		/* S: Page dirty */
-#define	_PAGE_NO_CACHE	0x00000400		/* H: I bit */
-#define	_PAGE_WRITETHRU	0x00000800		/* H: W bit */
+#define _PAGE_DIRTY	0x00000010		/* S: Page dirty */
why the gap?
quoted hunk ↗ jump to hunk
+#define _PAGE_USER	0x00000040		/* S: User page */
+#define _PAGE_ENDIAN	0x00000080		/* H: E bit */
+#define _PAGE_GUARDED	0x00000100		/* H: G bit */
+#define _PAGE_COHERENT	0x00000200		/* H: M bit */
+#define _PAGE_NO_CACHE	0x00000400		/* H: I bit */
+#define _PAGE_WRITETHRU	0x00000800		/* H: W bit */

/* TODO: Add large page lowmem mapping support */
#define _PMD_PRESENT	0
@@ -273,6 +276,7 @@ extern int icache_44x_need_flush;
/* ERPN in a PTE never gets cleared, ignore it */
#define _PTE_NONE_MASK	0xffffffff00000000ULL

+
#elif defined(CONFIG_FSL_BOOKE)
/*
   MMU Assist Register 3:
@@ -315,6 +319,9 @@ extern int icache_44x_need_flush;
#define _PMD_PRESENT_MASK (PAGE_MASK)
#define _PMD_BAD	(~PAGE_MASK)

+/* Until my rework is finished, 40x still needs atomic PTE updates */
+#define PTE_ATOMIC_UPDATES	1
fix comment
quoted hunk ↗ jump to hunk
+
#elif defined(CONFIG_8xx)
/* Definitions for 8xx embedded chips. */
#define _PAGE_PRESENT	0x0001	/* Page is valid */
@@ -345,6 +352,9 @@ extern int icache_44x_need_flush;
#define _PTE_NONE_MASK _PAGE_ACCESSED

+/* Until my rework is finished, 40x still needs atomic PTE updates */
+#define PTE_ATOMIC_UPDATES	1
+
fix comment
quoted hunk ↗ jump to hunk
#else /* CONFIG_6xx */
/* Definitions for 60x, 740/750, etc. */
#define _PAGE_PRESENT	0x001	/* software: pte contains a translation */
@@ -365,6 +375,10 @@ extern int icache_44x_need_flush;
#define _PMD_PRESENT	0
#define _PMD_PRESENT_MASK (PAGE_MASK)
#define _PMD_BAD	(~PAGE_MASK)
+
+/* Hash tbale based platforms need atomic updates of the linux PTE */
tbale?
quoted hunk ↗ jump to hunk
+#define PTE_ATOMIC_UPDATES	1
+
#endif

/*
@@ -557,9 +571,11 @@ extern void add_hash_page(unsigned conte
 * low PTE word since we expect ALL flag bits to be there
 */
#ifndef CONFIG_PTE_64BIT
-static inline unsigned long pte_update(pte_t *p, unsigned long clr,
+static inline unsigned long pte_update(pte_t *p,
+				       unsigned long clr,
				       unsigned long set)
{
+#ifdef PTE_ATOMIC_UPDATES
	unsigned long old, tmp;

	__asm__ __volatile__("\
@@ -572,16 +588,26 @@ static inline unsigned long pte_update(p
	: "=&r" (old), "=&r" (tmp), "=m" (*p)
	: "r" (p), "r" (clr), "r" (set), "m" (*p)
	: "cc" );
+#else /* PTE_ATOMIC_UPDATES */
+	unsigned long old = pte_val(*p);
+	*p = __pte((old & ~clr) | set);
+#endif /* !PTE_ATOMIC_UPDATES */
+
#ifdef CONFIG_44x
	if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
		icache_44x_need_flush = 1;
#endif
	return old;
}
-#else
-static inline unsigned long long pte_update(pte_t *p, unsigned long  
clr,
-				       unsigned long set)
+#else /* CONFIG_PTE_64BIT */
+/* TODO: Change that to only modify the low word and move  
set_pte_at()
+ * out of line
+ */
+static inline unsigned long long pte_update(pte_t *p,
+					    unsigned long clr,
+					    unsigned long set)
{
+#ifdef PTE_ATOMIC_UPDATES
	unsigned long long old;
	unsigned long tmp;
@@ -596,13 +622,18 @@ static inline unsigned long long pte_upd
	: "=&r" (old), "=&r" (tmp), "=m" (*p)
	: "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set),  
"m" (*p)
	: "cc" );
+#else /* PTE_ATOMIC_UPDATES */
+	unsigned long long old = pte_val(*p);
+	*p = __pte((old & ~clr) | set);
+#endif /* !PTE_ATOMIC_UPDATES */
+
#ifdef CONFIG_44x
	if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
		icache_44x_need_flush = 1;
#endif
	return old;
}
-#endif
+#endif /* CONFIG_PTE_64BIT */

/*
 * set_pte stores a linux PTE into the linux page table.
@@ -665,7 +696,7 @@ static inline void __ptep_set_access_fla
({									   \
	int __changed = !pte_same(*(__ptep), __entry);			   \
	if (__changed) {						   \
-		__ptep_set_access_flags(__ptep, __entry, __dirty);    	   \
+		__ptep_set_access_flags(__ptep, __entry, __dirty);         \
		flush_tlb_page_nohash(__vma, __address);		   \
	}								   \
	__changed;							   \
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help