Skip to content

Commit 058effe

Browse files
paulburtonralfbaechle
authored andcommitted
MIPS: Fix detection of unsupported highmem with cache aliases
The paging_init() function contains code which detects that highmem is in use but unsupported due to dcache aliasing. However this code was ineffective because it was being run before the caches are probed, meaning that cpu_has_dc_aliases would always evaluate to false (unless a platform overrides it to a compile-time constant) and the detection of the unsupported case is never triggered. The kernel would then go on to attempt to use highmem & either hit coherency issues or trigger the BUG_ON in flush_kernel_dcache_page(). Fix this by running paging_init() later than cpu_cache_init(), such that the cpu_has_dc_aliases macro will evaluate correctly & the unsupported highmem case will be detected successfully. This then leads to a formerly hidden issue in that mem_init_free_highmem() will attempt to free all highmem pages, even though we're avoiding use of them & don't have valid page structs for them. This leads to an invalid pointer dereference & a TLB exception. Avoid this by skipping the loop in mem_init_free_highmem() if cpu_has_dc_aliases evaluates true. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Cc: Rabin Vincent <rabinv@axis.com> Cc: Matt Redfearn <matt.redfearn@imgtec.com> Cc: Jerome Marchand <jmarchan@redhat.com> Cc: Alexander Sverdlin <alexander.sverdlin@gmail.com> Cc: Aurelien Jarno <aurelien@aurel32.net> Cc: Jaedon Shin <jaedon.shin@gmail.com> Cc: Toshi Kani <toshi.kani@hpe.com> Cc: James Hogan <james.hogan@imgtec.com> Cc: Sergey Ryazanov <ryazanov.s.a@gmail.com> Cc: Jonas Gorski <jogo@openwrt.org> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14184/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
1 parent 305723a commit 058effe

File tree

2 files changed

+4
-1
lines changed

2 files changed

+4
-1
lines changed

arch/mips/kernel/setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,6 @@ static void __init arch_mem_init(char **cmdline_p)
764764
device_tree_init();
765765
sparse_init();
766766
plat_swiotlb_setup();
767-
paging_init();
768767

769768
dma_contiguous_reserve(PFN_PHYS(max_low_pfn));
770769
/* Tell bootmem about cma reserved memblock section */
@@ -877,6 +876,7 @@ void __init setup_arch(char **cmdline_p)
877876
prefill_possible_map();
878877

879878
cpu_cache_init();
879+
paging_init();
880880
}
881881

882882
unsigned long kernelsp[NR_CPUS];

arch/mips/mm/init.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,9 @@ static inline void mem_init_free_highmem(void)
440440
#ifdef CONFIG_HIGHMEM
441441
unsigned long tmp;
442442

443+
if (cpu_has_dc_aliases)
444+
return;
445+
443446
for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
444447
struct page *page = pfn_to_page(tmp);
445448

0 commit comments

Comments
 (0)