Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86, mm: Ensure correct alignment of the fixmap

The early_ioremap code requires that its buffers not span a PMD
boundary. The logic for ensuring that only works if the fixmap is
aligned, so assert that it's aligned correctly.

To make this work reliably, reserve_top_address needs to be
adjusted.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>
Link: http://lkml.kernel.org/r/e59a5f4362661f75dd4841fa74e1f2448045e245.1399317206.git.luto@amacapital.net
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>

authored by

Andy Lutomirski and committed by
H. Peter Anvin
73159fdc 89ca3b88

+9 -3
+6
arch/x86/mm/ioremap.c
··· 355 355 { 356 356 pmd_t *pmd; 357 357 358 + #ifdef CONFIG_X86_64 359 + BUILD_BUG_ON((fix_to_virt(0) + PAGE_SIZE) & ((1 << PMD_SHIFT) - 1)); 360 + #else 361 + WARN_ON((fix_to_virt(0) + PAGE_SIZE) & ((1 << PMD_SHIFT) - 1)); 362 + #endif 363 + 358 364 early_ioremap_setup(); 359 365 360 366 pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
+3 -3
arch/x86/mm/pgtable.c
··· 449 449 { 450 450 #ifdef CONFIG_X86_32 451 451 BUG_ON(fixmaps_set > 0); 452 - printk(KERN_INFO "Reserving virtual address space above 0x%08x\n", 453 - (int)-reserve); 454 - __FIXADDR_TOP = -reserve - PAGE_SIZE; 452 + __FIXADDR_TOP = round_down(-reserve, 1 << PMD_SHIFT) - PAGE_SIZE; 453 + printk(KERN_INFO "Reserving virtual address space above 0x%08lx (rounded to 0x%08lx)\n", 454 + -reserve, __FIXADDR_TOP + PAGE_SIZE); 455 455 #endif 456 456 } 457 457