Commit f0d1eab8 authored by Mike Rapoport's avatar Mike Rapoport Committed by Max Filippov
Browse files

xtensa: mm: fix PMD folding implementation



There was a definition of pmd_offset() in arch/xtensa/include/asm/pgtable.h
that shadowed the generic implementation defined in
include/asm-generic/pgtable-nopmd.h.

As the result, xtensa had shortcuts in page table traversal in several
places instead of doing level unfolding.

Remove local override for pmd_offset() and add page table unfolding where
necessary.

Signed-off-by: default avatarMike Rapoport <rppt@linux.ibm.com>
Message-Id: <1572964400-16542-2-git-send-email-rppt@kernel.org>
Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
parent 8951eb15
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -371,9 +371,6 @@ ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)

#define pgd_index(address)	((address) >> PGDIR_SHIFT)

/* Find an entry in the second-level page table.. */
#define pmd_offset(dir,address) ((pmd_t*)(dir))

/* Find an entry in the third-level page table.. */
#define pte_index(address)	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#define pte_offset_kernel(dir,addr) 					\
+8 −2
Original line number Diff line number Diff line
@@ -197,6 +197,7 @@ void do_page_fault(struct pt_regs *regs)
		struct mm_struct *act_mm = current->active_mm;
		int index = pgd_index(address);
		pgd_t *pgd, *pgd_k;
		pud_t *pud, *pud_k;
		pmd_t *pmd, *pmd_k;
		pte_t *pte_k;

@@ -211,8 +212,13 @@ void do_page_fault(struct pt_regs *regs)

		pgd_val(*pgd) = pgd_val(*pgd_k);

		pmd = pmd_offset(pgd, address);
		pmd_k = pmd_offset(pgd_k, address);
		pud = pud_offset(pgd, address);
		pud_k = pud_offset(pgd_k, address);
		if (!pud_present(*pud) || !pud_present(*pud_k))
			goto bad_page_fault;

		pmd = pmd_offset(pud, address);
		pmd_k = pmd_offset(pud_k, address);
		if (!pmd_present(*pmd) || !pmd_present(*pmd_k))
			goto bad_page_fault;

+4 −2
Original line number Diff line number Diff line
@@ -20,7 +20,8 @@ void __init kasan_early_init(void)
{
	unsigned long vaddr = KASAN_SHADOW_START;
	pgd_t *pgd = pgd_offset_k(vaddr);
	pmd_t *pmd = pmd_offset(pgd, vaddr);
	pud_t *pud = pud_offset(pgd, vaddr);
	pmd_t *pmd = pmd_offset(pud, vaddr);
	int i;

	for (i = 0; i < PTRS_PER_PTE; ++i)
@@ -42,7 +43,8 @@ static void __init populate(void *start, void *end)
	unsigned long i, j;
	unsigned long vaddr = (unsigned long)start;
	pgd_t *pgd = pgd_offset_k(vaddr);
	pmd_t *pmd = pmd_offset(pgd, vaddr);
	pud_t *pud = pud_offset(pgd, vaddr);
	pmd_t *pmd = pmd_offset(pud, vaddr);
	pte_t *pte = memblock_alloc(n_pages * sizeof(pte_t), PAGE_SIZE);

	if (!pte)
+2 −1
Original line number Diff line number Diff line
@@ -22,7 +22,8 @@
static void * __init init_pmd(unsigned long vaddr, unsigned long n_pages)
{
	pgd_t *pgd = pgd_offset_k(vaddr);
	pmd_t *pmd = pmd_offset(pgd, vaddr);
	pud_t *pud = pud_offset(pgd, vaddr);
	pmd_t *pmd = pmd_offset(pud, vaddr);
	pte_t *pte;
	unsigned long i;

+5 −1
Original line number Diff line number Diff line
@@ -169,6 +169,7 @@ static unsigned get_pte_for_vaddr(unsigned vaddr)
	struct task_struct *task = get_current();
	struct mm_struct *mm = task->mm;
	pgd_t *pgd;
	pud_t *pud;
	pmd_t *pmd;
	pte_t *pte;

@@ -177,7 +178,10 @@ static unsigned get_pte_for_vaddr(unsigned vaddr)
	pgd = pgd_offset(mm, vaddr);
	if (pgd_none_or_clear_bad(pgd))
		return 0;
	pmd = pmd_offset(pgd, vaddr);
	pud = pud_offset(pgd, vaddr);
	if (pud_none_or_clear_bad(pud))
		return 0;
	pmd = pmd_offset(pud, vaddr);
	if (pmd_none_or_clear_bad(pmd))
		return 0;
	pte = pte_offset_map(pmd, vaddr);