Skip to content

Commit f0d1eab

Browse files
rpptjcmvbkbc
authored andcommitted
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: Mike Rapoport <[email protected]> Message-Id: <[email protected]> Signed-off-by: Max Filippov <[email protected]>
1 parent 8951eb1 commit f0d1eab

File tree

5 files changed

+19
-9
lines changed

5 files changed

+19
-9
lines changed

arch/xtensa/include/asm/pgtable.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,6 @@ ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
371371

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

374-
/* Find an entry in the second-level page table.. */
375-
#define pmd_offset(dir,address) ((pmd_t*)(dir))
376-
377374
/* Find an entry in the third-level page table.. */
378375
#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
379376
#define pte_offset_kernel(dir,addr) \

arch/xtensa/mm/fault.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ void do_page_fault(struct pt_regs *regs)
197197
struct mm_struct *act_mm = current->active_mm;
198198
int index = pgd_index(address);
199199
pgd_t *pgd, *pgd_k;
200+
pud_t *pud, *pud_k;
200201
pmd_t *pmd, *pmd_k;
201202
pte_t *pte_k;
202203

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

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

214-
pmd = pmd_offset(pgd, address);
215-
pmd_k = pmd_offset(pgd_k, address);
215+
pud = pud_offset(pgd, address);
216+
pud_k = pud_offset(pgd_k, address);
217+
if (!pud_present(*pud) || !pud_present(*pud_k))
218+
goto bad_page_fault;
219+
220+
pmd = pmd_offset(pud, address);
221+
pmd_k = pmd_offset(pud_k, address);
216222
if (!pmd_present(*pmd) || !pmd_present(*pmd_k))
217223
goto bad_page_fault;
218224

arch/xtensa/mm/kasan_init.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ void __init kasan_early_init(void)
2020
{
2121
unsigned long vaddr = KASAN_SHADOW_START;
2222
pgd_t *pgd = pgd_offset_k(vaddr);
23-
pmd_t *pmd = pmd_offset(pgd, vaddr);
23+
pud_t *pud = pud_offset(pgd, vaddr);
24+
pmd_t *pmd = pmd_offset(pud, vaddr);
2425
int i;
2526

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

4850
if (!pte)

arch/xtensa/mm/mmu.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
static void * __init init_pmd(unsigned long vaddr, unsigned long n_pages)
2323
{
2424
pgd_t *pgd = pgd_offset_k(vaddr);
25-
pmd_t *pmd = pmd_offset(pgd, vaddr);
25+
pud_t *pud = pud_offset(pgd, vaddr);
26+
pmd_t *pmd = pmd_offset(pud, vaddr);
2627
pte_t *pte;
2728
unsigned long i;
2829

arch/xtensa/mm/tlb.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ static unsigned get_pte_for_vaddr(unsigned vaddr)
169169
struct task_struct *task = get_current();
170170
struct mm_struct *mm = task->mm;
171171
pgd_t *pgd;
172+
pud_t *pud;
172173
pmd_t *pmd;
173174
pte_t *pte;
174175

@@ -177,7 +178,10 @@ static unsigned get_pte_for_vaddr(unsigned vaddr)
177178
pgd = pgd_offset(mm, vaddr);
178179
if (pgd_none_or_clear_bad(pgd))
179180
return 0;
180-
pmd = pmd_offset(pgd, vaddr);
181+
pud = pud_offset(pgd, vaddr);
182+
if (pud_none_or_clear_bad(pud))
183+
return 0;
184+
pmd = pmd_offset(pud, vaddr);
181185
if (pmd_none_or_clear_bad(pmd))
182186
return 0;
183187
pte = pte_offset_map(pmd, vaddr);

0 commit comments

Comments
 (0)