Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de0f9387 authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman
Browse files

powerpc/8xx: Remove _PAGE_USER and handle user access at PMD level



As Linux kernel separates KERNEL and USER address spaces, there is
therefore no need to flag USER access at page level.

Today, the 8xx TLB handlers already handle user access in the L1 entry
through Access Protection Groups, it is then natural to move the user
access handling at PMD level once _PAGE_NA allows to handle PAGE_NONE
protection without _PAGE_USER

In the mean time, as we free up one bit in the PTE, we can use it to
include SPS (page size flag) in the PTE and avoid handling it at every
TLB miss hence removing special handling based on compiled page size.

For _PAGE_EXEC, we rework it to use PP PTE bits, avoiding the copy
of _PAGE_EXEC bit into the L1 entry. Unfortunatly we are not
able to put it at the correct location as it conflicts with
NA/RO/RW bits for data entries.

Upper bits of APG in L1 entry overlap with PMD base address. In
order to avoid having to filter that out, we set up all groups so that
upper bits can have any value.

Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 35175033
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -47,8 +47,7 @@ static inline pte_t *hugepd_page(hugepd_t hpd)
{
	BUG_ON(!hugepd_ok(hpd));
#ifdef CONFIG_PPC_8xx
	return (pte_t *)__va(hpd_val(hpd) &
			     ~(_PMD_PAGE_MASK | _PMD_PRESENT_MASK));
	return (pte_t *)__va(hpd_val(hpd) & ~HUGEPD_SHIFT_MASK);
#else
	return (pte_t *)((hpd_val(hpd) &
			  ~HUGEPD_SHIFT_MASK) | PD_HUGE);
+17 −17
Original line number Diff line number Diff line
@@ -29,17 +29,17 @@
#define MI_Kp		0x40000000	/* Should always be set */

/*
 * All pages' PP exec bits are set to 000, which means Execute for Supervisor
 * and no Execute for User.
 * Then we use the APG to say whether accesses are according to Page rules,
 * "all Supervisor" rules (Exec for all) and "all User" rules (Exec for noone)
 * Therefore, we define 4 APG groups. msb is _PAGE_EXEC, lsb is _PAGE_USER
 * 0 (00) => Not User, no exec => 11 (all accesses performed as user)
 * 1 (01) => User but no exec => 11 (all accesses performed as user)
 * 2 (10) => Not User, exec => 01 (rights according to page definition)
 * 3 (11) => User, exec => 00 (all accesses performed as supervisor)
 */
#define MI_APG_INIT	0xf4ffffff
 * All pages' PP data bits are set to either 001 or 011 by copying _PAGE_EXEC
 * into bit 21 in the ITLBmiss handler (bit 21 is the middle bit), which means
 * respectively NA for All or X for Supervisor and no access for User.
 * Then we use the APG to say whether accesses are according to Page rules or
 * "all Supervisor" rules (Access to all)
 * Therefore, we define 2 APG groups. lsb is _PMD_USER
 * 0 => No user => 01 (all accesses performed according to page definition)
 * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
 * We define all 16 groups so that all other bits of APG can take any value
 */
#define MI_APG_INIT	0x44444444

/* The effective page number register.  When read, contains the information
 * about the last instruction TLB miss.  When MI_RPN is written, bits in
@@ -102,17 +102,17 @@
#define MD_Kp		0x40000000	/* Should always be set */

/*
 * All pages' PP data bits are set to either 000 or 011, which means
 * All pages' PP data bits are set to either 000 or 011 or 001, which means
 * respectively RW for Supervisor and no access for User, or RO for
 * Supervisor and no access for user.
 * Supervisor and no access for user and NA for ALL.
 * Then we use the APG to say whether accesses are according to Page rules or
 * "all Supervisor" rules (Access to all)
 * Therefore, we define 2 APG groups. lsb is _PAGE_USER
 * Therefore, we define 2 APG groups. lsb is _PMD_USER
 * 0 => No user => 01 (all accesses performed according to page definition)
 * 1 => User => 00 (all accesses performed as supervisor
 *                                 according to page definition)
 * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
 * We define all 16 groups so that all other bits of APG can take any value
 */
#define MD_APG_INIT	0x4fffffff
#define MD_APG_INIT	0x44444444

/* The effective page number register.  When read, contains the information
 * about the last instruction TLB miss.  When MD_RPN is written, bits in
+2 −1
Original line number Diff line number Diff line
@@ -61,7 +61,8 @@ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp,
				pgtable_t pte_page)
{
	*pmdp = __pmd((page_to_pfn(pte_page) << PAGE_SHIFT) | _PMD_PRESENT);
	*pmdp = __pmd((page_to_pfn(pte_page) << PAGE_SHIFT) | _PMD_USER |
		      _PMD_PRESENT);
}

#define pmd_pgtable(pmd) pmd_page(pmd)
+10 −4
Original line number Diff line number Diff line
@@ -32,27 +32,33 @@
#define _PAGE_PRESENT	0x0001	/* Page is valid */
#define _PAGE_NO_CACHE	0x0002	/* I: cache inhibit */
#define _PAGE_PRIVILEGED	0x0004	/* No ASID (context) compare */
#define _PAGE_SPECIAL	0x0008	/* SW entry, forced to 0 by the TLB miss */
#define _PAGE_HUGE	0x0008	/* SPS: Small Page Size (1 if 16k, 512k or 8M)*/
#define _PAGE_DIRTY	0x0100	/* C: page changed */

/* These 4 software bits must be masked out when the L2 entry is loaded
 * into the TLB.
 */
#define _PAGE_GUARDED	0x0010	/* Copied to L1 G entry in DTLB */
#define _PAGE_USER	0x0020	/* Copied to L1 APG lsb */
#define _PAGE_EXEC	0x0040	/* Copied to L1 APG */
#define _PAGE_SPECIAL	0x0020	/* SW entry */
#define _PAGE_EXEC	0x0040	/* Copied to PP (bit 21) in ITLB */
#define _PAGE_ACCESSED	0x0080	/* software: page referenced */

#define _PAGE_NA	0x0200	/* Supervisor NA, User no access */
#define _PAGE_RO	0x0600	/* Supervisor RO, User no access */

#define _PMD_PRESENT	0x0001
#define _PMD_BAD	0x0ff0
#define _PMD_BAD	0x0fd0
#define _PMD_PAGE_MASK	0x000c
#define _PMD_PAGE_8M	0x000c
#define _PMD_PAGE_512K	0x0004
#define _PMD_USER	0x0020	/* APG 1 */

/* Until my rework is finished, 8xx still needs atomic PTE updates */
#define PTE_ATOMIC_UPDATES	1

#ifdef CONFIG_PPC_16K_PAGES
#define _PAGE_PSIZE	_PAGE_HUGE
#endif

#endif /* __KERNEL__ */
#endif /*  _ASM_POWERPC_NOHASH_32_PTE_8xx_H */
+1 −1
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ static inline pte_t pte_mkspecial(pte_t pte)

static inline pte_t pte_mkhuge(pte_t pte)
{
	return pte;
	return __pte(pte_val(pte) | _PAGE_HUGE);
}

static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
Loading