arch_add_memory() sets up the direct map before calling add_pages(). If add_pages() fails, the range stays mapped and any page tables allocated for it are leaked. A later hot add can reuse the stale mapping. Remove the direct mapping on failure. Fixes: 45e0b78b0532 ("[PATCH] hot-add-mem x86_64: use CONFIG_MEMORY_HOTPLUG_RESERVE") Signed-off-by: Chris Down --- arch/x86/mm/init_64.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 8b6d86fb5a42..846cb34b38dd 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -989,15 +989,23 @@ int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, return ret; } +static void __meminit kernel_physical_mapping_remove(unsigned long start, + unsigned long end); + int arch_add_memory(int nid, u64 start, u64 size, struct mhp_params *params) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; + int ret; init_memory_mapping(start, start + size, params->pgprot); - return add_pages(nid, start_pfn, nr_pages, params); + ret = add_pages(nid, start_pfn, nr_pages, params); + if (ret) + kernel_physical_mapping_remove(start, start + size); + + return ret; } static void __meminit free_pagetable(struct page *page) base-commit: fa4ad798f6f681031775266044ba1b0cf3c670bd