The patch titled x86_64 memory hot-add: fix kernel mapping code has been added to the -mm tree. Its filename is x86_64-memory-hot-add-fix-kernel-mapping-code.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: x86_64 memory hot-add: fix kernel mapping code From: keith mannthey <kmannth@xxxxxxxxxx> phys_pud_init is broken when using it at runtime with some offsets. It currently only maps one pud entry worth of pages while trampling any mappings that may have existed on the pmd_page :( This patch makes it safe to map addresses that are not pmd_page aligned and generally more robust. This is a critical patch for hot-add and x86_64. Thanks to Dave Hansen for input on look and feel of this patch and it's constructs. Signed-off-by: Keith Mannthey <kmannth@xxxxxxxxxx> Cc: Andi Kleen <ak@xxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- arch/x86_64/mm/init.c | 48 +++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff -puN arch/x86_64/mm/init.c~x86_64-memory-hot-add-fix-kernel-mapping-code arch/x86_64/mm/init.c --- a/arch/x86_64/mm/init.c~x86_64-memory-hot-add-fix-kernel-mapping-code +++ a/arch/x86_64/mm/init.c @@ -252,9 +252,11 @@ __init void early_iounmap(void *addr, un static void __meminit phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end) { - int i; + int i = pmd_index(address); - for (i = 0; i < PTRS_PER_PMD; pmd++, i++, address += PMD_SIZE) { + pmd = pmd + i; + + for (; i < PTRS_PER_PMD; pmd++, i++, address += PMD_SIZE) { unsigned long entry; if (address >= end) { @@ -263,6 +265,11 @@ phys_pmd_init(pmd_t *pmd, unsigned long set_pmd(pmd, __pmd(0)); break; } + + if (pmd_val(*pmd)) { + printk (KERN_ERR "%s trying to trample pte entry \ + %08lx@%08lx\n",__func__,pmd_val(*pmd),address); + } entry = _PAGE_NX|_PAGE_PSE|_KERNPG_TABLE|_PAGE_GLOBAL|address; entry &= __supported_pte_mask; set_pmd(pmd, __pmd(entry)); @@ -272,45 +279,42 @@ phys_pmd_init(pmd_t *pmd, unsigned long static void __meminit phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end) { - pmd_t *pmd = pmd_offset(pud, (unsigned long)__va(address)); - - if (pmd_none(*pmd)) { - spin_lock(&init_mm.page_table_lock); - phys_pmd_init(pmd, address, end); - spin_unlock(&init_mm.page_table_lock); - __flush_tlb_all(); - } + pmd_t *pmd = pmd_offset(pud,0); + spin_lock(&init_mm.page_table_lock); + phys_pmd_init(pmd, address, end); + spin_unlock(&init_mm.page_table_lock); + __flush_tlb_all(); } static void __meminit phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) { - long i = pud_index(address); + int i = pud_index(address); pud = pud + i; - if (after_bootmem && pud_val(*pud)) { - phys_pmd_update(pud, address, end); - return; - } - - for (; i < PTRS_PER_PUD; pud++, i++) { + for (; i < PTRS_PER_PUD; pud++, i++, \ + address = (address & PUD_MASK) + PUD_SIZE ) { int map; - unsigned long paddr, pmd_phys; + unsigned long pmd_phys; pmd_t *pmd; - paddr = (address & PGDIR_MASK) + i*PUD_SIZE; - if (paddr >= end) + if (address >= end) break; - if (!after_bootmem && !e820_any_mapped(paddr, paddr+PUD_SIZE, 0)) { + if (!after_bootmem && !e820_any_mapped(address, address+PUD_SIZE, 0)) { set_pud(pud, __pud(0)); continue; } + if (pud_val(*pud)) { + phys_pmd_update(pud, address, end); + continue; + } + pmd = alloc_low_page(&map, &pmd_phys); spin_lock(&init_mm.page_table_lock); set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); - phys_pmd_init(pmd, paddr, end); + phys_pmd_init(pmd, address, end); spin_unlock(&init_mm.page_table_lock); unmap_low_page(map); } _ Patches currently in -mm which might be from kmannth@xxxxxxxxxx are x86_64-memory-hot-add-nodes_add-cleanup.patch x86_64-memory-hot-add-create-arch_find_node.patch x86_64-memory-hot-add-arch_find_node-x86_64.patch x86_64-memory-hot-add-fix-kernel-mapping-code.patch x86_64-memory-hot-add-fix-acpi-motherboardc.patch convert-i386-numa-kva-space-to-bootmem.patch convert-i386-numa-kva-space-to-bootmem-tidy.patch convert-i386-summit-subarch-to-use-srat-info-for-apicid_to_node-calls.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html