[PATCH v2 1/2] arm64: vmemmap: use virtual projection of linear region
David Daney
ddaney.cavm at gmail.com
Mon Mar 7 17:07:41 PST 2016
On 02/26/2016 08:57 AM, Ard Biesheuvel wrote:
> Commit dd006da21646 ("arm64: mm: increase VA range of identity map") made
> some changes to the memory mapping code to allow physical memory to reside
> at an offset that exceeds the size of the virtual mapping.
>
> However, since the size of the vmemmap area is proportional to the size of
> the VA area, but it is populated relative to the physical space, we may
> end up with the struct page array being mapped outside of the vmemmap
> region. For instance, on my Seattle A0 box, I can see the following output
> in the dmesg log.
>
> vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000 ( 8 GB maximum)
> 0xffffffbfc0000000 - 0xffffffbfd0000000 ( 256 MB actual)
>
> We can fix this by deciding that the vmemmap region is not a projection of
> the physical space, but of the virtual space above PAGE_OFFSET, i.e., the
> linear region. This way, we are guaranteed that the vmemmap region is of
> sufficient size, and we can even reduce the size by half.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
I see this commit now in Linus' kernel.org tree in v4.5-rc7.
FYI: I am seeing a crash that goes away when I revert this. My kernel
has some other modifications (our NUMA patches) so I haven't yet fully
tracked this down on an unmodified kernel, but this is what I am getting:
.
.
.
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000001400000-0x00000000fffeffff]
[ 0.000000] node 0: [mem 0x00000000ffff0000-0x00000000ffffffff]
[ 0.000000] node 0: [mem 0x0000000100000000-0x00000003f51cffff]
[ 0.000000] node 0: [mem 0x00000003f51d0000-0x00000003f51dffff]
[ 0.000000] node 0: [mem 0x00000003f51e0000-0x00000003fa9bffff]
[ 0.000000] node 0: [mem 0x00000003fa9c0000-0x00000003faa8ffff]
[ 0.000000] node 0: [mem 0x00000003faa90000-0x00000003ffa3ffff]
[ 0.000000] node 0: [mem 0x00000003ffa40000-0x00000003ffa9ffff]
[ 0.000000] node 0: [mem 0x00000003ffaa0000-0x00000003ffffffff]
[ 0.000000] Initmem setup node 0 [mem
0x0000000001400000-0x00000003ffffffff]
[ 0.000000] Unable to handle kernel paging request at virtual address
fffffdff60ff0000
[ 0.000000] pgd = fffffe0000e00000
[ 0.000000] [fffffdff60ff0000] *pgd=00000003ffd90003,
*pud=00000003ffd90003, *pmd=00000003ffd90003, *pte=0000000000000000
[ 0.000000] Internal error: Oops: 96000007 [#1] PREEMPT SMP
[ 0.000000] Modules linked in:
[ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.5.0-rc7-numa+ #123
[ 0.000000] Hardware name: Cavium ThunderX CN88XX board (DT)
[ 0.000000] task: fffffe0000b39880 ti: fffffe0000b00000 task.ti:
fffffe0000b00000
[ 0.000000] PC is at memmap_init_zone+0xe0/0x130
[ 0.000000] LR is at memmap_init_zone+0xc0/0x130
[ 0.000000] pc : [<fffffe0000a85b28>] lr : [<fffffe0000a85b08>]
pstate: 800002c5
[ 0.000000] sp : fffffe0000b03cf0
[ 0.000000] x29: fffffe0000b03cf0 x28: fffffe03febe1b80
[ 0.000000] x27: fffffe03febe2a08 x26: fffffe0000b30000
[ 0.000000] x25: 0000000000040000 x24: 0000000000000000
[ 0.000000] x23: 1000000000000000 x22: 0000000000000000
[ 0.000000] x21: 0000000000000001 x20: 00000000ffffffff
[ 0.000000] x19: 000000000003fd40 x18: fffffe0000d7c240
[ 0.000000] x17: 0000000000000009 x16: 0000000400000000
[ 0.000000] x15: 0000000000000008 x14: 0000000000000004
[ 0.000000] x13: 0000000000000000 x12: 000000000001c854
[ 0.000000] x11: 00000003fffe37a8 x10: 0000000000000004
[ 0.000000] x9 : 0000000000000000 x8 : fffffe03febc0000
[ 0.000000] x7 : 0000000000000000 x6 : fffffe0000d7c240
[ 0.000000] x5 : fffffdff60000000 x4 : 0000000000000007
[ 0.000000] x3 : fffffdff60000000 x2 : fffffe0000d7c300
[ 0.000000] x1 : 0000000000ff0000 x0 : 0000000000000001
[ 0.000000]
[ 0.000000] Process swapper (pid: 0, stack limit = 0xfffffe0000b00020)
[ 0.000000] Stack: (0xfffffe0000b03cf0 to 0xfffffe0000b04000)
[ 0.000000] 3ce0: fffffe0000b03d40
fffffe0000a85fd4
[ 0.000000] 3d00: fffffe03febe2400 fffffe0000aa3000 0000000000000000
0000000000030000
[ 0.000000] 3d20: fffffe0000b5eab4 fffffe0000b5eab8 0000000000000001
fffffe0000734d18
[ 0.000000] 3d40: fffffe0000b03df0 fffffe0000a56928 0000000000000000
fffffe0000b32e68
[ 0.000000] 3d60: 0000000000000004 fffffe0000b32e70 fffffe0000b30000
fffffe03febe1b80
[ 0.000000] 3d80: fffffe0000c40000 0000000002200000 fffffe0000081198
00000003f51eaa0c
[ 0.000000] 3da0: fffffe0000d7bc90 0000000000030000 fffffe000093f148
fffffe000093f008
[ 0.000000] 3dc0: fffffe000093efb0 fffffe000093efd8 0000000000010000
fffffe0000af6798
[ 0.000000] 3de0: 0000000000000140 0000000000040000 fffffe0000b03e90
fffffe0000a44e84
[ 0.000000] 3e00: fffffe0000b03ec8 0000000001400000 0000000000040000
fffffe0000b30000
[ 0.000000] 3e20: fffffe0000b30000 0000000001400000 fffffe0000c40000
0000000002200000
[ 0.000000] 3e40: fffffe0000081198 00000003f51eaa0c 0000000000040000
0000000000000000
[ 0.000000] 3e60: fffffe0000b30000 0000000001400000 ffffffff00c40000
00000000ffffffff
[ 0.000000] 3e80: 000000000003ffaa 0000000000040000 fffffe0000b03ee0
fffffe0000a452d4
[ 0.000000] 3ea0: fffffe03febd0000 fffffe0000b30b98 fffffe0000080000
fffffe0000a45168
[ 0.000000] 3ec0: fffffe0000b03ee0 0000000000010000 0000000000040000
0000000000000000
[ 0.000000] 3ee0: fffffe0000b03f00 fffffe0000a42f2c fffffdfffa800000
00000003ffaa0000
[ 0.000000] 3f00: fffffe0000b03fa0 fffffe0000a40680 0000000000000000
fffffe0000b30b98
[ 0.000000] 3f20: 0000000021200000 00000003f50de7c8 fffffe0000b30000
0000000001400000
[ 0.000000] 3f40: 00000000021d0000 0000000002200000 fffffe0000081198
00000000ffffffc8
[ 0.000000] 3f60: 00000003f50deb40 fffffe00007200a8 0000000000000001
0000000021200000
[ 0.000000] 3f80: ffffffffffffffff 0000000000000000 0000000080808080
fefefefefefefefe
[ 0.000000] 3fa0: 0000000000000000 fffffe00000811b4 00000003f50deb40
0000000000000e12
[ 0.000000] 3fc0: 0000000021200000 00000003f50de7c8 00000003f50de7dd
0000000001400000
[ 0.000000] 3fe0: 0000000000000000 fffffe0000a88a28 0000000000000000
0000000000000000
[ 0.000000] Call trace:
[ 0.000000] Exception stack(0xfffffe0000b03b30 to 0xfffffe0000b03c50)
[ 0.000000] 3b20: 000000000003fd40
00000000ffffffff
[ 0.000000] 3b40: fffffe0000b03cf0 fffffe0000a85b28 00000003fffba000
0000000000006000
[ 0.000000] 3b60: 0000000000000004 0000000000000000 fffffe0000b03be0
fffffe00001d253c
[ 0.000000] 3b80: 00000003fffba000 0000000000006000 fffffe0000a5abec
0000000000000080
[ 0.000000] 3ba0: 0000000000000000 0000000000000000 0000000000010000
fffffe0000b674f0
[ 0.000000] 3bc0: fffffe0000942288 00000003fffba000 0000000000000001
0000000000ff0000
[ 0.000000] 3be0: fffffe0000d7c300 fffffdff60000000 0000000000000007
fffffdff60000000
[ 0.000000] 3c00: fffffe0000d7c240 0000000000000000 fffffe03febc0000
0000000000000000
[ 0.000000] 3c20: 0000000000000004 00000003fffe37a8 000000000001c854
0000000000000000
[ 0.000000] 3c40: 0000000000000004 0000000000000008
[ 0.000000] [<fffffe0000a85b28>] memmap_init_zone+0xe0/0x130
[ 0.000000] [<fffffe0000a85fd4>] free_area_init_node+0x45c/0x4a4
[ 0.000000] [<fffffe0000a56928>] free_area_init_nodes+0x594/0x5ec
[ 0.000000] [<fffffe0000a44e84>] bootmem_init+0xc8/0xf8
[ 0.000000] [<fffffe0000a452d4>] paging_init_rest+0x1c/0xdc
[ 0.000000] [<fffffe0000a42f2c>] setup_arch+0x118/0x5a0
[ 0.000000] [<fffffe0000a40680>] start_kernel+0xa8/0x3e0
[ 0.000000] [<fffffe00000811b4>] 0xfffffe00000811b4
[ 0.000000] Code: cb414261 f2dfbfe5 d37ae421 f2ffffe5 (f8656820)
[ 0.000000] ---[ end trace cb88537fdc8fa200 ]---
[ 0.000000] Kernel panic - not syncing: Fatal exception
[ 0.000000] ---[ end Kernel panic - not syncing: Fatal exception
.
.
.
> ---
> v2: simplify the expression for vmemmap, forward compatible with the patch that
> changes the type of memstart_addr to s64
>
> arch/arm64/include/asm/pgtable.h | 7 ++++---
> arch/arm64/mm/init.c | 4 ++--
> 2 files changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 16438dd8916a..43abcbc30813 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -34,18 +34,19 @@
> /*
> * VMALLOC and SPARSEMEM_VMEMMAP ranges.
> *
> - * VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array
> + * VMEMAP_SIZE: allows the whole linear region to be covered by a struct page array
> * (rounded up to PUD_SIZE).
> * VMALLOC_START: beginning of the kernel vmalloc space
> * VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space,
> * fixed mappings and modules
> */
> -#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)
> +#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT - 1)) * sizeof(struct page), PUD_SIZE)
>
> #define VMALLOC_START (MODULES_END)
> #define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
>
> -#define vmemmap ((struct page *)(VMALLOC_END + SZ_64K))
> +#define VMEMMAP_START (VMALLOC_END + SZ_64K)
> +#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
>
> #define FIRST_USER_ADDRESS 0UL
>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index e1f425fe5a81..4ea7efc28e65 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -380,8 +380,8 @@ void __init mem_init(void)
> MLK_ROUNDUP(_text, _etext),
> MLK_ROUNDUP(_sdata, _edata),
> #ifdef CONFIG_SPARSEMEM_VMEMMAP
> - MLG((unsigned long)vmemmap,
> - (unsigned long)vmemmap + VMEMMAP_SIZE),
> + MLG(VMEMMAP_START,
> + VMEMMAP_START + VMEMMAP_SIZE),
> MLM((unsigned long)phys_to_page(memblock_start_of_DRAM()),
> (unsigned long)virt_to_page(high_memory)),
> #endif
>
More information about the linux-arm-kernel
mailing list