Memory-Hotplug: Fix the bug on interface /dev/mem for 64-bit kernel The new added memory can not be access by interface /dev/mem, because we do not update the variables high_memory, max_pfn and max_low_pfn. Add a function update_end_of_memory_vars to update these variables for 64-bit kernel. CC: Andi Kleen CC: Li Haicheng Reviewed-by: Wu Fengguang Reviewed-by: KAMEZAWA Hiroyuki Signed-off-by: Shaohui Zheng diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 5a4398a..acfc01a 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -49,6 +49,7 @@ #include #include #include +#include static unsigned long dma_reserve __initdata; @@ -614,6 +615,21 @@ void __init paging_init(void) * Memory hotplug specific functions */ #ifdef CONFIG_MEMORY_HOTPLUG +/** + * After memory hotplug, the variable max_pfn, max_low_pfn and high_memory will + * be affected, it will be updated in this function. + */ +static inline void __meminit update_end_of_memory_vars(u64 start, + u64 size) +{ + unsigned long end_pfn = PFN_UP(start + size); + + if (end_pfn > max_pfn) { + max_low_pfn = max_pfn = end_pfn; + high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1; + } +} + /* * Memory is added always to NORMAL zone. This means you will never get * additional DMA/DMA32 memory. @@ -633,6 +649,9 @@ int arch_add_memory(int nid, u64 start, u64 size) ret = __add_pages(nid, zone, start_pfn, nr_pages); WARN_ON_ONCE(ret); + /* update max_pfn, max_low_pfn and high_memory */ + update_end_of_memory_vars(start, size); + return ret; } EXPORT_SYMBOL_GPL(arch_add_memory);