On Sat, Sep 28, 2019 at 7:14 AM Albert Ou <a...@eecs.berkeley.edu> wrote: > > This fixes an error with how the FDT blob is reserved in memblock. > An incorrect physical address calculation exposed the FDT header to > unintended corruption, which typically manifested with of_fdt_raw_init() > faulting during late boot after fdt_totalsize() returned a wrong value. > Systems with smaller physical memory sizes more frequently trigger this > issue, as the kernel is more likely to allocate from the DMA32 zone > where bbl places the DTB after the kernel image. > > Commit 671f9a3e2e24 ("RISC-V: Setup initial page tables in two stages") > changed the mapping of the DTB to reside in the fixmap area. > Consequently, early_init_fdt_reserve_self() cannot be used anymore in > setup_bootmem() since it relies on __pa() to derive a physical address, > which does not work with dtb_early_va that is no longer a valid kernel > logical address. > > The reserved[0x1] region shows the effect of the pointer underflow > resulting from the __pa(initial_boot_params) offset subtraction: > > [ 0.000000] MEMBLOCK configuration: > [ 0.000000] memory size = 0x000000001fe00000 reserved size = > 0x0000000000a2e514 > [ 0.000000] memory.cnt = 0x1 > [ 0.000000] memory[0x0] [0x0000000080200000-0x000000009fffffff], > 0x000000001fe00000 bytes flags: 0x0 > [ 0.000000] reserved.cnt = 0x2 > [ 0.000000] reserved[0x0] [0x0000000080200000-0x0000000080c2dfeb], > 0x0000000000a2dfec bytes flags: 0x0 > [ 0.000000] reserved[0x1] [0xfffffff080100000-0xfffffff080100527], > 0x0000000000000528 bytes flags: 0x0 > > With the fix applied: > > [ 0.000000] MEMBLOCK configuration: > [ 0.000000] memory size = 0x000000001fe00000 reserved size = > 0x0000000000a2e514 > [ 0.000000] memory.cnt = 0x1 > [ 0.000000] memory[0x0] [0x0000000080200000-0x000000009fffffff], > 0x000000001fe00000 bytes flags: 0x0 > [ 0.000000] reserved.cnt = 0x2 > [ 0.000000] reserved[0x0] [0x0000000080200000-0x0000000080c2dfeb], > 0x0000000000a2dfec bytes flags: 0x0 > [ 0.000000] reserved[0x1] [0x0000000080e00000-0x0000000080e00527], > 0x0000000000000528 bytes flags: 0x0 > > Fixes: 671f9a3e2e24 ("RISC-V: Setup initial page tables in two stages")
I also found that with commit 671f9a3e2e24 ("RISC-V: Setup initial page tables in two stages"), when booting the kernel from U-Boot via: => bootm $kernel_addr_t - $fdtcontroladdr ($kernel_addr_t = 0x84000000 and $fdtcontroladdr = 0xff741c60) kernel does not boot. I looked at people's instructions of booting Linux kernel, and they seem to have such: => cp.l ${fdtcontroladdr} ${fdt_addr_r} 0x10000 => bootm ${kernel_addr_r} - ${fdt_addr_r} where ${fdt_addr_r} is 0x88000000, and "bootm 84000000 - 88000000" can make the kernel boot. Thanks for the patch. Now "bootm $kernel_addr_t - $fdtcontroladdr" works again! Tested-by: Bin Meng <bmeng...@gmail.com> > Signed-off-by: Albert Ou <a...@eecs.berkeley.edu> > --- > > Changes in v2: > * Changed variable identifier to dtb_early_pa per reviewer feedback. > * Removed whitespace change. > > arch/riscv/mm/init.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > Regards, Bin