Skip to content

Commit bd05220

Browse files
jrtc27rppt
authored andcommitted
arch/ia64: Restore arch-specific pgd_offset_k implementation
IA-64 is special and treats pgd_offset_k() differently to pgd_offset(), using different formulae to calculate the indices into the kernel and user PGDs. The index into the user PGDs takes into account the region number, but the index into the kernel (init_mm) PGD always assumes a predefined kernel region number. Commit 974b9b2 ("mm: consolidate pte_index() and pte_offset_*() definitions") made IA-64 use a generic pgd_offset_k() which incorrectly used pgd_index() for kernel page tables. As a result, the index into the kernel PGD was going out of bounds and the kernel hung during early boot. Allow overrides of pgd_offset_k() and override it on IA-64 with the old implementation that will correctly index the kernel PGD. Fixes: 974b9b2 ("mm: consolidate pte_index() and pte_offset_*() definitions") Reported-by: John Paul Adrian Glaubitz <[email protected]> Signed-off-by: Jessica Clarke <[email protected]> Tested-by: John Paul Adrian Glaubitz <[email protected]> Acked-by: Tony Luck <[email protected]> Signed-off-by: Mike Rapoport <[email protected]>
1 parent 9123e3a commit bd05220

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

arch/ia64/include/asm/pgtable.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,15 @@ pgd_index (unsigned long address)
366366
}
367367
#define pgd_index pgd_index
368368

369+
/*
370+
* In the kernel's mapped region we know everything is in region number 5, so
371+
* as an optimisation its PGD already points to the area for that region.
372+
* However, this also means that we cannot use pgd_index() and we must
373+
* never add the region here.
374+
*/
375+
#define pgd_offset_k(addr) \
376+
(init_mm.pgd + (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)))
377+
369378
/* Look up a pgd entry in the gate area. On IA-64, the gate-area
370379
resides in the kernel-mapped segment, hence we use pgd_offset_k()
371380
here. */

include/linux/pgtable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ static inline pgd_t *pgd_offset_pgd(pgd_t *pgd, unsigned long address)
117117
* a shortcut which implies the use of the kernel's pgd, instead
118118
* of a process's
119119
*/
120+
#ifndef pgd_offset_k
120121
#define pgd_offset_k(address) pgd_offset(&init_mm, (address))
122+
#endif
121123

122124
/*
123125
* In many cases it is known that a virtual address is mapped at PMD or PTE

0 commit comments

Comments
 (0)