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

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

powerpc/mm: use pte helpers in generic code



Get rid of platform specific _PAGE_XXXX in powerpc common code and
use helpers instead.

mm/dump_linuxpagetables.c will be handled separately

Reviewed-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 34eb138e
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -331,17 +331,14 @@ static inline bool pte_ci(pte_t pte)
#define pte_access_permitted pte_access_permitted
static inline bool pte_access_permitted(pte_t pte, bool write)
{
	unsigned long pteval = pte_val(pte);
	/*
	 * A read-only access is controlled by _PAGE_USER bit.
	 * We have _PAGE_READ set for WRITE and EXECUTE
	 */
	unsigned long need_pte_bits = _PAGE_PRESENT | _PAGE_USER;

	if (write)
		need_pte_bits |= _PAGE_WRITE;
	if (!pte_present(pte) || !pte_user(pte) || !pte_read(pte))
		return false;

	if ((pteval & need_pte_bits) != need_pte_bits)
	if (write && !pte_write(pte))
		return false;

	return true;
+8 −4
Original line number Diff line number Diff line
@@ -277,7 +277,10 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
				      pte_t *ptep)
{
	pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), _PAGE_RO);
	unsigned long clr = ~pte_val(pte_wrprotect(__pte(~0)));
	unsigned long set = pte_val(pte_wrprotect(__pte(0)));

	pte_update(ptep, clr, set);
}
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
					   unsigned long addr, pte_t *ptep)
@@ -291,9 +294,10 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma,
					   unsigned long address,
					   int psize)
{
	unsigned long set = pte_val(entry) &
		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
	unsigned long clr = ~pte_val(entry) & (_PAGE_RO | _PAGE_NA);
	pte_t pte_set = pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(0)))));
	pte_t pte_clr = pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(~0)))));
	unsigned long set = pte_val(entry) & pte_val(pte_set);
	unsigned long clr = ~pte_val(entry) & ~pte_val(pte_clr);

	pte_update(ptep, clr, set);

+1 −2
Original line number Diff line number Diff line
@@ -32,8 +32,7 @@ static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PA
 */
static inline int pte_protnone(pte_t pte)
{
	return (pte_val(pte) &
		(_PAGE_PRESENT | _PAGE_USER)) == _PAGE_PRESENT;
	return pte_present(pte) && !pte_user(pte);
}

static inline int pmd_protnone(pmd_t pmd)
+7 −14
Original line number Diff line number Diff line
@@ -44,20 +44,13 @@ static inline int is_exec_fault(void)
static inline int pte_looks_normal(pte_t pte)
{

#if defined(CONFIG_PPC_BOOK3S_64)
	if ((pte_val(pte) & (_PAGE_PRESENT | _PAGE_SPECIAL)) == _PAGE_PRESENT) {
	if (pte_present(pte) && !pte_special(pte)) {
		if (pte_ci(pte))
			return 0;
		if (pte_user(pte))
			return 1;
	}
	return 0;
#else
	return (pte_val(pte) &
		(_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE | _PAGE_USER |
		 _PAGE_PRIVILEGED)) ==
		(_PAGE_PRESENT | _PAGE_USER);
#endif
}

static struct page *maybe_pte_to_page(pte_t pte)
@@ -117,7 +110,7 @@ static pte_t set_pte_filter(pte_t pte)
	struct page *pg;

	/* No exec permission in the first place, move on */
	if (!(pte_val(pte) & _PAGE_EXEC) || !pte_looks_normal(pte))
	if (!pte_exec(pte) || !pte_looks_normal(pte))
		return pte;

	/* If you set _PAGE_EXEC on weird pages you're on your own */
@@ -137,7 +130,7 @@ static pte_t set_pte_filter(pte_t pte)
	}

	/* Else, we filter out _PAGE_EXEC */
	return __pte(pte_val(pte) & ~_PAGE_EXEC);
	return pte_exprotect(pte);
}

static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
@@ -150,7 +143,7 @@ static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
	 * if necessary. Also if _PAGE_EXEC is already set, same deal,
	 * we just bail out
	 */
	if (dirty || (pte_val(pte) & _PAGE_EXEC) || !is_exec_fault())
	if (dirty || pte_exec(pte) || !is_exec_fault())
		return pte;

#ifdef CONFIG_DEBUG_VM
@@ -176,7 +169,7 @@ static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
	set_bit(PG_arch_1, &pg->flags);

 bail:
	return __pte(pte_val(pte) | _PAGE_EXEC);
	return pte_mkexec(pte);
}

#endif /* CONFIG_PPC_BOOK3S */
@@ -191,10 +184,10 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
	 * Make sure hardware valid bit is not set. We don't do
	 * tlb flush for this update.
	 */
	VM_WARN_ON(pte_val(*ptep) & _PAGE_PRESENT);
	VM_WARN_ON(pte_hw_valid(*ptep));

	/* Add the pte bit when trying to set a pte */
	pte = __pte(pte_val(pte) | _PAGE_PTE);
	pte = pte_mkpte(pte);

	/* Note: mm->context.id might not yet have been assigned as
	 * this context might not have been activated yet when this
+8 −7
Original line number Diff line number Diff line
@@ -112,15 +112,17 @@ EXPORT_SYMBOL(ioremap_coherent);
void __iomem *
ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags)
{
	pte_t pte = __pte(flags);

	/* writeable implies dirty for kernel addresses */
	if ((flags & (_PAGE_RW | _PAGE_RO)) != _PAGE_RO)
		flags |= _PAGE_DIRTY | _PAGE_HWWRITE;
	if (pte_write(pte))
		pte = pte_mkdirty(pte);

	/* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
	flags &= ~(_PAGE_USER | _PAGE_EXEC);
	flags |= _PAGE_PRIVILEGED;
	pte = pte_exprotect(pte);
	pte = pte_mkprivileged(pte);

	return __ioremap_caller(addr, size, __pgprot(flags), __builtin_return_address(0));
	return __ioremap_caller(addr, size, pte_pgprot(pte), __builtin_return_address(0));
}
EXPORT_SYMBOL(ioremap_prot);

@@ -235,8 +237,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot)
		/* The PTE should never be already set nor present in the
		 * hash table
		 */
		BUG_ON((pte_val(*pg) & (_PAGE_PRESENT | _PAGE_HASHPTE)) &&
		       pgprot_val(prot));
		BUG_ON((pte_present(*pg) | pte_hashpte(*pg)) && pgprot_val(prot));
		set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, prot));
	}
	smp_wmb();
Loading