Commit b9e7e3ea authored by Christophe Leroy's avatar Christophe Leroy Committed by Madhavan Srinivasan
Browse files

powerpc/e500: Always use 64 bits PTE



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: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: default avatarMadhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/04a658209ea78dcc0f3dbde6b2c29cf1939adfe9.1767721208.git.chleroy@kernel.org
parent 11439c46
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -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
+0 −59
Original line number Diff line number Diff line
/* 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 */
+1 −1
Original line number Diff line number Diff line
@@ -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)
+1 −45
Original line number Diff line number Diff line
@@ -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@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@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@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
+2 −2
Original line number Diff line number Diff line
@@ -276,7 +276,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
@@ -337,7 +337,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