[PATCH] powerpc/e500: Always use 64 bits PTE

Christophe Leroy (CS GROUP) chleroy at kernel.org
Wed Jan 7 04:40:19 AEDT 2026


From: Christophe Leroy <christophe.leroy at csgroup.eu>

Today there are two PTE formats for e500:
- The 64 bits format, used
 - On 64 bits kernel
 - On 32 bits kernel with 64 bits physical addresses
 - On 32 bits kernel with support of huge pages
- The 32 bits format, used in other cases

Maintaining two PTE formats means unnecessary maintenance burden
because every change needs to be implemented and tested for both
formats.

Remove the 32 bits PTE format. The memory usage increase due to
larger PTEs is minimal (approx. 0,1% of memory).

This also means that from now on huge pages are supported also
with 32 bits physical addresses.

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
---
 arch/powerpc/include/asm/nohash/32/pgtable.h  |  4 +-
 arch/powerpc/include/asm/nohash/32/pte-85xx.h | 59 -------------------
 arch/powerpc/include/asm/pgtable-types.h      |  2 +-
 arch/powerpc/kernel/head_85xx.S               | 46 +--------------
 arch/powerpc/platforms/Kconfig.cputype        |  4 +-
 5 files changed, 5 insertions(+), 110 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/nohash/32/pte-85xx.h

diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 2d71e4b7cd09c..496ecc65ac255 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -120,10 +120,8 @@
 
 #if defined(CONFIG_44x)
 #include <asm/nohash/32/pte-44x.h>
-#elif defined(CONFIG_PPC_85xx) && defined(CONFIG_PTE_64BIT)
-#include <asm/nohash/pte-e500.h>
 #elif defined(CONFIG_PPC_85xx)
-#include <asm/nohash/32/pte-85xx.h>
+#include <asm/nohash/pte-e500.h>
 #elif defined(CONFIG_PPC_8xx)
 #include <asm/nohash/32/pte-8xx.h>
 #endif
diff --git a/arch/powerpc/include/asm/nohash/32/pte-85xx.h b/arch/powerpc/include/asm/nohash/32/pte-85xx.h
deleted file mode 100644
index 14d64b4f3f14a..0000000000000
--- a/arch/powerpc/include/asm/nohash/32/pte-85xx.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_POWERPC_NOHASH_32_PTE_85xx_H
-#define _ASM_POWERPC_NOHASH_32_PTE_85xx_H
-#ifdef __KERNEL__
-
-/* PTE bit definitions for Freescale BookE SW loaded TLB MMU based
- * processors
- *
-   MMU Assist Register 3:
-
-   32 33 34 35 36  ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63
-   RPN......................  0  0 U0 U1 U2 U3 UX SX UW SW UR SR
-
-   - PRESENT *must* be in the bottom two bits because swap PTEs use
-     the top 30 bits.
-
-*/
-
-/* Definitions for FSL Book-E Cores */
-#define _PAGE_READ	0x00001	/* H: Read permission (SR) */
-#define _PAGE_PRESENT	0x00002	/* S: PTE contains a translation */
-#define _PAGE_WRITE	0x00004	/* S: Write permission (SW) */
-#define _PAGE_DIRTY	0x00008	/* S: Page dirty */
-#define _PAGE_EXEC	0x00010	/* H: SX permission */
-#define _PAGE_ACCESSED	0x00020	/* S: Page referenced */
-
-#define _PAGE_ENDIAN	0x00040	/* H: E bit */
-#define _PAGE_GUARDED	0x00080	/* H: G bit */
-#define _PAGE_COHERENT	0x00100	/* H: M bit */
-#define _PAGE_NO_CACHE	0x00200	/* H: I bit */
-#define _PAGE_WRITETHRU	0x00400	/* H: W bit */
-#define _PAGE_SPECIAL	0x00800 /* S: Special page */
-
-#define _PMD_PRESENT	0
-#define _PMD_PRESENT_MASK (PAGE_MASK)
-#define _PMD_BAD	(~PAGE_MASK)
-#define _PMD_USER	0
-
-#define _PTE_NONE_MASK	0
-
-#define PTE_WIMGE_SHIFT (6)
-
-/*
- * We define 2 sets of base prot bits, one for basic pages (ie,
- * cacheable kernel and user pages) and one for non cacheable
- * pages. We always set _PAGE_COHERENT when SMP is enabled or
- * the processor might need it for DMA coherency.
- */
-#define _PAGE_BASE_NC	(_PAGE_PRESENT | _PAGE_ACCESSED)
-#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)
-#define _PAGE_BASE	(_PAGE_BASE_NC | _PAGE_COHERENT)
-#else
-#define _PAGE_BASE	(_PAGE_BASE_NC)
-#endif
-
-#include <asm/pgtable-masks.h>
-
-#endif /* __KERNEL__ */
-#endif /*  _ASM_POWERPC_NOHASH_32_PTE_FSL_85xx_H */
diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h
index f3086e39e7d2c..e8dec885b6e47 100644
--- a/arch/powerpc/include/asm/pgtable-types.h
+++ b/arch/powerpc/include/asm/pgtable-types.h
@@ -49,7 +49,7 @@ static inline unsigned long pud_val(pud_t x)
 #endif /* CONFIG_PPC64 */
 
 /* PGD level */
-#if defined(CONFIG_PPC_85xx) && defined(CONFIG_PTE_64BIT)
+#if defined(CONFIG_PPC_85xx)
 typedef struct { unsigned long long pgd; } pgd_t;
 
 static inline unsigned long long pgd_val(pgd_t x)
diff --git a/arch/powerpc/kernel/head_85xx.S b/arch/powerpc/kernel/head_85xx.S
index f9a73fae64641..8867596d35adc 100644
--- a/arch/powerpc/kernel/head_85xx.S
+++ b/arch/powerpc/kernel/head_85xx.S
@@ -305,7 +305,6 @@ set_ivor:
  *   r12 is pointer to the pte
  *   r10 is the pshift from the PGD, if we're a hugepage
  */
-#ifdef CONFIG_PTE_64BIT
 #ifdef CONFIG_HUGETLB_PAGE
 #define FIND_PTE	\
 	rlwinm	r12, r13, 14, 18, 28;	/* Compute pgdir/pmd offset */	\
@@ -329,15 +328,6 @@ set_ivor:
 	rlwimi	r12, r13, 23, 20, 28;	/* Compute pte address */	\
 	lwz	r11, 4(r12);		/* Get pte entry */
 #endif /* HUGEPAGE */
-#else /* !PTE_64BIT */
-#define FIND_PTE	\
-	rlwimi	r11, r13, 12, 20, 29;	/* Create L1 (pgdir/pmd) address */	\
-	lwz	r11, 0(r11);		/* Get L1 entry */			\
-	rlwinm.	r12, r11, 0, 0, 19;	/* Extract L2 (pte) base address */	\
-	beq	2f;			/* Bail if no table */			\
-	rlwimi	r12, r13, 22, 20, 29;	/* Compute PTE address */		\
-	lwz	r11, 0(r12);		/* Get Linux PTE */
-#endif
 
 /*
  * Interrupt vector entry code
@@ -473,21 +463,15 @@ END_BTB_FLUSH_SECTION
 4:
 	FIND_PTE
 
-#ifdef CONFIG_PTE_64BIT
 	li	r13,_PAGE_PRESENT|_PAGE_BAP_SR
 	oris	r13,r13,_PAGE_ACCESSED at h
-#else
-	li	r13,_PAGE_PRESENT|_PAGE_READ|_PAGE_ACCESSED
-#endif
 	andc.	r13,r13,r11		/* Check permission */
 
-#ifdef CONFIG_PTE_64BIT
 #ifdef CONFIG_SMP
 	subf	r13,r11,r12		/* create false data dep */
 	lwzx	r13,r11,r13		/* Get upper pte bits */
 #else
 	lwz	r13,0(r12)		/* Get upper pte bits */
-#endif
 #endif
 
 	bne	2f			/* Bail if permission/valid mismatch */
@@ -552,12 +536,8 @@ END_BTB_FLUSH_SECTION
 
 	FIND_PTE
 	/* Make up the required permissions for kernel code */
-#ifdef CONFIG_PTE_64BIT
 	li	r13,_PAGE_PRESENT | _PAGE_BAP_SX
 	oris	r13,r13,_PAGE_ACCESSED at h
-#else
-	li	r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
-#endif
 	b	4f
 
 	/* Get the PGD for the current thread */
@@ -573,23 +553,17 @@ END_BTB_FLUSH_SECTION
 
 	FIND_PTE
 	/* Make up the required permissions for user code */
-#ifdef CONFIG_PTE_64BIT
 	li	r13,_PAGE_PRESENT | _PAGE_BAP_UX
 	oris	r13,r13,_PAGE_ACCESSED at h
-#else
-	li	r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
-#endif
 
 4:
 	andc.	r13,r13,r11		/* Check permission */
 
-#ifdef CONFIG_PTE_64BIT
 #ifdef CONFIG_SMP
 	subf	r13,r11,r12		/* create false data dep */
 	lwzx	r13,r11,r13		/* Get upper pte bits */
 #else
 	lwz	r13,0(r12)		/* Get upper pte bits */
-#endif
 #endif
 
 	bne	2f			/* Bail if permission mismatch */
@@ -683,7 +657,7 @@ interrupt_end:
  *	r10 - tsize encoding (if HUGETLB_PAGE) or available to use
  *	r11 - TLB (info from Linux PTE)
  *	r12 - available to use
- *	r13 - upper bits of PTE (if PTE_64BIT) or available to use
+ *	r13 - upper bits of PTE
  *	CR5 - results of addr >= PAGE_OFFSET
  *	MAS0, MAS1 - loaded with proper value when we get here
  *	MAS2, MAS3 - will need additional info from Linux PTE
@@ -751,7 +725,6 @@ finish_tlb_load:
 	 * here we (properly should) assume have the appropriate value.
 	 */
 finish_tlb_load_cont:
-#ifdef CONFIG_PTE_64BIT
 	rlwinm	r12, r11, 32-2, 26, 31	/* Move in perm bits */
 	andi.	r10, r11, _PAGE_DIRTY
 	bne	1f
@@ -764,26 +737,9 @@ BEGIN_MMU_FTR_SECTION
 	srwi	r10, r13, 12		/* grab RPN[12:31] */
 	mtspr	SPRN_MAS7, r10
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
-#else
-	li	r10, (_PAGE_EXEC | _PAGE_READ)
-	mr	r13, r11
-	rlwimi	r10, r11, 31, 29, 29	/* extract _PAGE_DIRTY into SW */
-	and	r12, r11, r10
-	mcrf	cr0, cr5		/* Test for user page */
-	slwi	r10, r12, 1
-	or	r10, r10, r12
-	rlwinm	r10, r10, 0, ~_PAGE_EXEC	/* Clear SX on user pages */
-	isellt	r12, r10, r12
-	rlwimi	r13, r12, 0, 20, 31	/* Get RPN from PTE, merge w/ perms */
-	mtspr	SPRN_MAS3, r13
-#endif
 
 	mfspr	r12, SPRN_MAS2
-#ifdef CONFIG_PTE_64BIT
 	rlwimi	r12, r11, 32-19, 27, 31	/* extract WIMGE from pte */
-#else
-	rlwimi	r12, r11, 26, 27, 31	/* extract WIMGE from pte */
-#endif
 #ifdef CONFIG_HUGETLB_PAGE
 	beq	6, 3f			/* don't mask if page isn't huge */
 	li	r13, 1
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 4c321a8ea8965..2d9b10b2ce8a2 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -275,7 +275,7 @@ config PPC_BOOK3S
 config PPC_E500
 	select FSL_EMB_PERFMON
 	bool
-	select ARCH_SUPPORTS_HUGETLBFS if PHYS_64BIT || PPC64
+	select ARCH_SUPPORTS_HUGETLBFS
 	select PPC_SMP_MUXED_IPI
 	select PPC_DOORBELL
 	select PPC_KUEP
@@ -336,7 +336,7 @@ config BOOKE
 config PTE_64BIT
 	bool
 	depends on 44x || PPC_E500 || PPC_86xx
-	default y if PHYS_64BIT
+	default y if PPC_E500 || PHYS_64BIT
 
 config PHYS_64BIT
 	bool 'Large physical address support' if PPC_E500 || PPC_86xx
-- 
2.49.0



More information about the Linuxppc-dev mailing list