• Vasily Gorbik's avatar
    s390/boot: rework decompressor reserved tracking · f913a660
    Vasily Gorbik authored
    Currently several approaches for finding unused memory in decompressor
    are utilized. While "safe_addr" grows towards higher addresses, vmem
    code allocates paging structures top down. The former requires careful
    ordering. In addition to that ipl report handling code verifies potential
    intersections with secure boot certificates on its own. Neither of two
    approaches are memory holes aware and consistent with each other in low
    memory conditions.
    
    To solve that, existing approaches are generalized and combined
    together, as well as online memory ranges are now taken into
    consideration.
    
    physmem_info has been extended to contain reserved memory ranges. New
    set of functions allow to handle reserves and find unused memory.
    All reserves and memory allocations are "typed". In case of out of
    memory condition decompressor fails with detailed info on current
    reserved ranges and usable online memory.
    
    Linux version 6.2.0 ...
    Kernel command line: ... mem=100M
    Our of memory allocating 100000 bytes 100000 aligned in range 0:5800000
    Reserved memory ranges:
    0000000000000000 0000000003e33000 DECOMPRESSOR
    0000000003f00000 00000000057648a3 INITRD
    00000000063e0000 00000000063e8000 VMEM
    00000000063eb000 00000000063f4000 VMEM
    00000000063f7800 0000000006400000 VMEM
    0000000005800000 0000000006300000 KASAN
    Usable online memory ranges (info source: sclp read info [3]):
    0000000000000000 0000000006400000
    Usable online memory total: 6400000 Reserved: 61b10a3 Free: 24ef5d
    Call Trace:
    (sp:000000000002bd58 [<0000000000012a70>] physmem_alloc_top_down+0x60/0x14c)
     sp:000000000002bdc8 [<0000000000013756>] _pa+0x56/0x6a
     sp:000000000002bdf0 [<0000000000013bcc>] pgtable_populate+0x45c/0x65e
     sp:000000000002be90 [<00000000000140aa>] setup_vmem+0x2da/0x424
     sp:000000000002bec8 [<0000000000011c20>] startup_kernel+0x428/0x8b4
     sp:000000000002bf60 [<00000000000100f4>] startup_normal+0xd4/0xd4
    
    physmem_alloc_range allows to find free memory in specified range. It
    should be used for one time allocations only like finding position for
    amode31 and vmlinux.
    physmem_alloc_top_down can be used just like physmem_alloc_range, but
    it also allows multiple allocations per type and tries to merge sequential
    allocations together. Which is useful for paging structures allocations.
    If sequential allocations cannot be merged together they are "chained",
    allowing easy per type reserved ranges enumeration and migration to
    memblock later. Extra "struct reserved_range" allocated for chaining are
    not tracked or reserved but rely on the fact that both
    physmem_alloc_range and physmem_alloc_top_down search for free memory
    only below current top down allocator position. All reserved ranges
    should be transferred to memblock before memblock allocations are
    enabled.
    
    The startup code has been reordered to delay any memory allocations until
    online memory ranges are detected and occupied memory ranges are marked as
    reserved to be excluded from follow-up allocations.
    Ipl report certificates are a special case, ipl report certificates list
    is checked together with other memory reserves until certificates are
    saved elsewhere.
    KASAN required memory for shadow memory allocation and mapping is reserved
    as 1 large chunk which is later passed to KASAN early initialization code.
    Acked-by: default avatarHeiko Carstens <hca@linux.ibm.com>
    Reviewed-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
    Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
    Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
    f913a660
vmem.c 5.77 KB