It seems we have an issue with 4.8 toolchain. Recent Linux kernels (v3.15, v3.16) fails to boot on TI Keystone 2 SoC with LPAE enabled if built by gcc 4.8, while they boots fine if built by 4.6, 4.7 or 4.9.
Linux kernel versions used for testing: - 3.15, 3.16 - git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
4.8 toolchain binaries: http://releases.linaro.org/14.04/components/toolchain/binaries/gcc-linaro-ar...
4.9 toolchain binaries: http://releases.linaro.org/14.05/components/toolchain/binaries/gcc-linaro-ar...
Our current investigation results: 1) The issue happened somewhere inside function arch/arm/mm/mmu.c -> paging_init().
2) At the moment when paging_init() -> kmap_init() function is called the value of static structure "init_mm" become corrupted and (&init_mm)->pgd has changed its value from 0xc0003000 to 0xe2411001.
2.1) "init_mm" is initialized statically in mm/init-mm.c and not modified by code
struct mm_struct init_mm = { .mm_rb = RB_ROOT, .pgd = swapper_pg_dir, .mm_users = ATOMIC_INIT(2), .mm_count = ATOMIC_INIT(1), .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem), .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock), .mmlist = LIST_HEAD_INIT(init_mm.mmlist), INIT_MM_CONTEXT(init_mm) };
2.2) The below debugging code produces following log output: [ 0.000000] cma: CMA: reserved 16 MiB at 2e800000 [ 0.000000] Memory policy: Data cache writealloc [ 0.000000] ==== map_lowmem c06ecc08 c0003000 [ 0.000000] ==== dma_contiguous_remap c06ecc08 c0003000 [ 0.000000] ==== devicemaps_init c06ecc08 c0003000 [ 0.000000] ==== kmap_init c06ecc08 e2411001 [ 0.000000] Unhandled fault: alignment fault (0x221) at 0xe2411011
Debugging code: void __init paging_init(const struct machine_desc *mdesc) { void *zero_page;
build_mem_type_table(); prepare_page_table(); pr_err("==== map_lowmem %p %p\n", &init_mm, (&init_mm)->pgd); map_lowmem(); pr_err("==== dma_contiguous_remap %p %p\n", &init_mm, (&init_mm)->pgd);
dma_contiguous_remap(); pr_err("==== devicemaps_init %p %p\n", &init_mm, (&init_mm)->pgd);
devicemaps_init(mdesc); pr_err("==== kmap_init %p %p\n", &init_mm, (&init_mm)->pgd);
kmap_init(); pr_err("==== tcm_init\n");
2.3) Most of functions called by paging_init() are static and get inlined. If 'static' modifier is removed from devicemaps_init() (so it will not be inlined by compiler), the issue disappears and kernel boots fine.
2.4) The same kernel binary boot fine if LPAE is disable.
Does it make sense to file a toolchain bug?
=== Log === Starting kernel ...
Uncompressing Linux... done, booting the kernel. [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 3.15.0-rc8-next-20140605-dirty (x0174654@uglx0174654) (gcc version 4.8.3 20140401 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2014.04 - Linaro GCC 4.8-2014.04) ) #93 SMP PREEMPT Fri Jun 6 15:31:19 EEST 2014 [ 0.000000] CPU: ARMv7 Processor [412fc0f4] revision 4 (ARMv7), cr=30c7387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache [ 0.000000] Machine model: Texas Instruments Keystone 2 Kepler/Hawking EVM [ 0.000000] bootconsole [earlycon0] enabled [ 0.000000] Switching to high address space at 0x800000000 [ 0.000000] cma: CMA: reserved 16 MiB at 2e800000 [ 0.000000] Memory policy: Data cache writealloc [ 0.000000] Unhandled fault: alignment fault (0x221) at 0xe2411011 [ 0.000000] Internal error: : 221 [#1] PREEMPT SMP ARM [ 0.000000] Modules linked in: [ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 3.15.0-rc8-next-20140605-dirty #93 [ 0.000000] task: c06e3be0 ti: c06d6000 task.ti: c06d6000 [ 0.000000] PC is at paging_init+0xa00/0xaf0 [ 0.000000] LR is at paging_init+0x9e8/0xaf0 [ 0.000000] pc : [<c0693b2c>] lr : [<c0693b14>] psr: 600001d3 [ 0.000000] sp : c06d7ea0 ip : c06e5ce4 fp : 00000000 [ 0.000000] r10: 00000000 r9 : 00001000 r8 : fffff000 [ 0.000000] r7 : 00002530 r6 : fffff000 r5 : feb30000 r4 : c0692cd8 [ 0.000000] r3 : e2411001 r2 : 00000003 r1 : bfe00000 r0 : 00000000 [ 0.000000] Flags: nZCv IRQs off FIQs off Mode SVC_32 ISA ARM Segment kernel [ 0.000000] Control: 30c5387d Table: 00003000 DAC: fffffffd [ 0.000000] Process swapper (pid: 0, stack limit = 0xc06d6240) [ 0.000000] Stack: (0xc06d7ea0 to 0xc06d8000) [ 0.000000] 7ea0: 2e800000 c06b194c 0000071f 00800000 00000401 00000000 00000000 00000000 [ 0.000000] 7ec0: 00000000 00000000 c0000000 00000000 c001cd40 00000000 00000800 00c00000 [ 0.000000] 7ee0: c06df834 00000000 c0800000 00c00000 c06ecc08 c06c4070 ffff1000 0082e7f5 [ 0.000000] 7f00: 00001000 00000007 c06cade4 c07184e0 c0008000 c06c4070 c06d7fd4 c06ca3e8 [ 0.000000] 7f20: c06ca3d8 c001cd40 c06cade4 c0690054 00000000 30c7387d 00000000 00000000 [ 0.000000] 7f40: 00000000 00000000 c071ac0e 000000dd 00000000 00000000 c071a318 00000000 [ 0.000000] 7f60: 00000000 00000000 00000000 00000000 00000000 00000001 c06e4d68 c06df800 [ 0.000000] 7f80: 00000000 00000000 00000000 c04a94ac c05d6e38 00000000 00000000 00000001 [ 0.000000] 7fa0: ffffffff c06df800 00000000 00000000 00000000 c068d898 00000000 00000000 [ 0.000000] 7fc0: 00000000 00000000 00000000 00000000 00000000 c06ca3e8 30c7387d c06df84c [ 0.000000] 7fe0: c06ca3e4 c06e4d68 80007000 412fc0f4 00000000 80008084 00000000 00000000 [ 0.000000] [<c0693b2c>] (paging_init) from [<c0690054>] (setup_arch+0x4b4/0x9ac) [ 0.000000] [<c0690054>] (setup_arch) from [<c068d898>] (start_kernel+0x80/0x39c) [ 0.000000] [<c068d898>] (start_kernel) from [<80008084>] (0x80008084) [ 0.000000] Code: e34f6fff e3a01000 e3a02003 e34b1fe0 (e1c381d0) [ 0.000000] ---[ end trace 3406ff24bd97382e ]--- [ 0.000000] Kernel panic - not syncing: Attempted to kill the idle task! [ 0.000000] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ====================================================================================================================