Messages in this thread Patch in this message | | | From | Masayoshi Mizuma <> | Subject | [PATCH v3 5/5] x86/mm/KASLR: Adjust the padding size for the direct mapping. | Date | Fri, 30 Aug 2019 17:47:07 -0400 |
| |
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
| |