<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: Paul Mackerras &lt;paulus@samba.org&gt;

When I tried -mm4 on a ppc32 box, it hit a BUG because I hadn't excluded
_PAGE_FILE from the bits used for swap entries.  While looking at that I
realised that the pte_to_pgoff and pgoff_prot_to_pte macros were wrong for
4xx and 8xx (embedded) PPC chips, since they use


---

 25-akpm/include/asm-ppc/pgtable.h |   48 ++++++++++++++++++++++++++++++--------
 1 files changed, 39 insertions(+), 9 deletions(-)

diff -puN include/asm-ppc/pgtable.h~ppc32-pgtable-fixes include/asm-ppc/pgtable.h
--- 25/include/asm-ppc/pgtable.h~ppc32-pgtable-fixes	2004-03-28 14:39:28.212872352 -0800
+++ 25-akpm/include/asm-ppc/pgtable.h	2004-03-28 14:39:28.215871896 -0800
@@ -202,6 +202,7 @@ extern unsigned long ioremap_bot, iorema
  */
 #define _PAGE_PRESENT	0x00000001		/* S: PTE valid */
 #define	_PAGE_RW	0x00000002		/* S: Write permission */
+#define _PAGE_FILE	0x00000004		/* S: nonlinear file mapping */
 #define	_PAGE_DIRTY	0x00000004		/* S: Page dirty */
 #define _PAGE_ACCESSED	0x00000008		/* S: Page referenced */
 #define _PAGE_HWWRITE	0x00000010		/* H: Dirty &amp; RW */
@@ -210,7 +211,6 @@ extern unsigned long ioremap_bot, iorema
 #define	_PAGE_ENDIAN	0x00000080		/* H: E bit */
 #define	_PAGE_GUARDED	0x00000100		/* H: G bit */
 #define	_PAGE_COHERENT	0x00000200		/* H: M bit */
-#define _PAGE_FILE	0x00000400		/* S: nonlinear file mapping */
 #define	_PAGE_NO_CACHE	0x00000400		/* H: I bit */
 #define	_PAGE_WRITETHRU	0x00000800		/* H: W bit */
 
@@ -624,20 +624,50 @@ extern void add_hash_page(unsigned conte
 #define __swp_type(entry)		((entry).val &amp; 0x1f)
 #define __swp_offset(entry)		((entry).val &gt;&gt; 5)
 #define __swp_entry(type, offset)	((swp_entry_t) { (type) | ((offset) &lt;&lt; 5) })
+
+#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
+/* _PAGE_FILE and _PAGE_PRESENT are in the bottom 3 bits on all these chips. */
 #define __pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) &gt;&gt; 3 })
 #define __swp_entry_to_pte(x)		((pte_t) { (x).val &lt;&lt; 3 })
+#else	/* Classic PPC */
+#define __pte_to_swp_entry(pte)		\
+    ((swp_entry_t) { ((pte_val(pte) &gt;&gt; 3) &amp; ~1) | ((pte_val(pte) &gt;&gt; 2) &amp; 1) })
+#define __swp_entry_to_pte(x)		\
+    ((pte_t) { (((x).val &amp; ~1) &lt;&lt; 3) | (((x).val &amp; 1) &lt;&lt; 2) })
+#endif
 
 /* Encode and decode a nonlinear file mapping entry */
-#define PTE_FILE_MAX_BITS	27
-#define pte_to_pgoff(pte)	(((pte_val(pte) &amp; ~0x7ff) &gt;&gt; 5)		\
-				 | ((pte_val(pte) &amp; 0x3f0) &gt;&gt; 4))
-#define pte_to_pgprot(pte)	\
-__pgprot((pte_val(pte) &amp; (_PAGE_USER|_PAGE_RW|_PAGE_PRESENT)) | _PAGE_ACCESSED)
+/* We can't use any the _PAGE_PRESENT, _PAGE_FILE, _PAGE_USER, _PAGE_RW,
+   or _PAGE_HASHPTE bits for storing a page offset. */
+#if defined(CONFIG_40x)
+/* 40x, avoid the 0x53 bits - to simplify things, avoid 0x73 */ */
+#define __pgoff_split(x)	((((x) &lt;&lt; 5) &amp; ~0x7f) | (((x) &lt;&lt; 2) &amp; 0xc))
+#define __pgoff_glue(x)		((((x) &amp; ~0x7f) &gt;&gt; 5) | (((x) &amp; 0xc) &gt;&gt; 2))
+#elif defined(CONFIG_44x)
+/* 44x, avoid the 0x47 bits */
+#define __pgoff_split(x)	((((x) &lt;&lt; 4) &amp; ~0x7f) | (((x) &lt;&lt; 3) &amp; 0x38))
+#define __pgoff_glue(x)		((((x) &amp; ~0x7f) &gt;&gt; 4) | (((x) &amp; 0x38) &gt;&gt; 3))
+#elif defined(CONFIG_8xx)
+/* 8xx, avoid the 0x843 bits */
+#define __pgoff_split(x)	((((x) &lt;&lt; 4) &amp; ~0xfff) | (((x) &lt;&lt; 3) &amp; 0x780) \
+				 | (((x) &lt;&lt; 2) &amp; 0x3c))
+#define __pgoff_glue(x)		((((x) &amp; ~0xfff) &gt;&gt; 4) | (((x) &amp; 0x780) &gt;&gt; 3))\
+				 | (((x) &amp; 0x3c) &gt;&gt; 2))
+#else
+/* classic PPC, avoid the 0x40f bits */
+#define __pgoff_split(x)	((((x) &lt;&lt; 5) &amp; ~0x7ff) | (((x) &lt;&lt; 4) &amp; 0x3f0))
+#define __pgoff_glue(x)		((((x) &amp; ~0x7ff) &gt;&gt; 5) | (((x) &amp; 0x3f0) &gt;&gt; 4))
+#endif
 
+#define PTE_FILE_MAX_BITS	27
+#define pte_to_pgoff(pte)	__pgoff_glue(pte_val(pte))
 #define pgoff_prot_to_pte(off, prot)					\
-	((pte_t) { (((off) &lt;&lt; 5) &amp; ~0x7ff) | (((off) &lt;&lt; 4) &amp; 0x3f0)	\
-		   | (pgprot_val(prot) &amp; (_PAGE_USER|_PAGE_RW))		\
-		   | _PAGE_FILE })
+	((pte_t) { __pgoff_split(off) | _PAGE_FILE |			\
+		   (pgprot_val(prot) &amp; (_PAGE_USER|_PAGE_RW)) })
+
+#define pte_to_pgprot(pte)						\
+	__pgprot((pte_val(pte) &amp; (_PAGE_USER|_PAGE_RW|_PAGE_PRESENT))	\
+		 | _PAGE_ACCESSED)
 
 /* CONFIG_APUS */
 /* For virtual address to physical address conversion */

_
</pre></body></html>