lkml.org 
[lkml]   [2019]   [Aug]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 5/5] x86/mm/KASLR: Adjust the padding size for the direct mapping.
    Date
    From: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>

    The system sometimes crashes while memory hot-adding on KASLR
    enabled system. The crash happens because the regions pointed by
    kaslr_regions[].base are overwritten by the hot-added memory.

    It happens because of the padding size for kaslr_regions[].base isn't
    enough for the system whose physical memory layout has huge space for
    memory hotplug. kaslr_regions[].base points "actual installed
    memory size + padding" or higher address. So, if the "actual + padding"
    is lower address than the maximum memory address, which means the memory
    address reachable by memory hot-add, kaslr_regions[].base is destroyed by
    the overwritten.

    address
    ^
    |------- maximum memory address (Hotplug)
    | ^
    |------- kaslr_regions[0].base | Hotadd-able region
    | ^ |
    | | padding |
    | V V
    |------- actual memory address (Installed on boot)
    |

    Fix it by getting the maximum memory address from SRAT and store
    the value in boot_param, then set the padding size while KASLR
    initializing if the default padding size isn't enough.

    Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
    ---
    arch/x86/mm/kaslr.c | 31 +++++++++++++++++++++++++++++--
    1 file changed, 29 insertions(+), 2 deletions(-)

    diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c
    index 8e5f3642e..a78844c57 100644
    --- a/arch/x86/mm/kaslr.c
    +++ b/arch/x86/mm/kaslr.c
    @@ -70,6 +70,34 @@ static inline bool kaslr_memory_enabled(void)
    return kaslr_enabled() && !IS_ENABLED(CONFIG_KASAN);
    }

    +static inline unsigned long phys_memmap_size(void)
    +{
    + unsigned long padding = CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING;
    +#ifdef CONFIG_MEMORY_HOTPLUG
    + unsigned long actual, maximum, base;
    +
    + if (!boot_params.max_addr)
    + goto out;
    +
    + /*
    + * The padding size should set to get for kaslr_regions[].base
    + * bigger address than the maximum memory address the system can
    + * have. kaslr_regions[].base points "actual size + padding" or
    + * higher address. If "actual size + padding" points the lower
    + * address than the maximum memory size, fix the padding size.
    + */
    + actual = roundup(PFN_PHYS(max_pfn), 1UL << TB_SHIFT);
    + maximum = roundup(boot_params.max_addr, 1UL << TB_SHIFT);
    + base = actual + (padding << TB_SHIFT);
    +
    + if (maximum > base)
    + padding = (maximum - actual) >> TB_SHIFT;
    +out:
    +#endif
    + return DIV_ROUND_UP(max_pfn << PAGE_SHIFT, 1UL << TB_SHIFT) +
    + padding;
    +}
    +
    /*
    * Even though a huge virtual address space is reserved for the direct
    * mapping of physical memory, e.g in 4-level paging mode, it's 64TB,
    @@ -87,8 +115,7 @@ static inline unsigned long calc_direct_mapping_size(void)
    * Update Physical memory mapping to available and
    * add padding if needed (especially for memory hotplug support).
    */
    - memory_tb = DIV_ROUND_UP(max_pfn << PAGE_SHIFT, 1UL << TB_SHIFT) +
    - CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING;
    + memory_tb = phys_memmap_size();

    size_tb = 1 << (MAX_PHYSMEM_BITS - TB_SHIFT);

    --
    2.18.1
    \
     
     \ /
      Last update: 2019-08-30 23:48    [W:3.193 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site