Thomas Gleixner wrote: > iounmap() on x86 occasionally fails to unmap because the provided valid > ioremap address is not below high_memory. It turned out that this > happens due to KASLR. > > KASLR uses the full address space between PAGE_OFFSET and vaddr_end to > randomize the starting points of the direct map, vmalloc and vmemmap > regions. It thereby limits the size of the direct map by using the > installed memory size plus an extra configurable margin for hot-plug > memory. This limitation is done to gain more randomization space > because otherwise only the holes between the direct map, vmalloc, > vmemmap and vaddr_end would be usable for randomizing. > > The limited direct map size is not exposed to the rest of the kernel, so > the memory hot-plug and resource management related code paths still > operate under the assumption that the available address space can be > determined with MAX_PHYSMEM_BITS. > > request_free_mem_region() allocates from (1 << MAX_PHYSMEM_BITS) - 1 > downwards. That means the first allocation happens past the end of the > direct map and if unlucky this address is in the vmalloc space, which > causes high_memory to become greater than VMALLOC_START and consequently > causes iounmap() to fail for valid ioremap addresses. > > MAX_PHYSMEM_BITS cannot be changed for that because the randomization > does not align with address bit boundaries and there are other places > which actually require to know the maximum number of address bits. All > remaining usage sites of MAX_PHYSMEM_BITS have been analyzed and found > to be correct. > > Cure this by exposing the end of the direct map via PHYSMEM_END and use > that for the memory hot-plug and resource management related places > instead of relying on MAX_PHYSMEM_BITS. In the KASLR case PHYSMEM_END > maps to a variable which is initialized by the KASLR initialization and > otherwise it is based on MAX_PHYSMEM_BITS as before. > > To prevent future hickups add a check into add_pages() to catch callers > trying to add memory above PHYSMEM_END. > > Fixes: 0483e1fa6e09 ("x86/mm: Implement ASLR for kernel memory regions") > Reported-by: Max Ramanouski <max8rr8@xxxxxxxxx> > Reported-by: Alistair Popple <apopple@xxxxxxxxxx> > Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> [..] > --- a/arch/x86/mm/kaslr.c > +++ b/arch/x86/mm/kaslr.c [..] > @@ -134,6 +147,8 @@ void __init kernel_randomize_memory(void > */ > vaddr += get_padding(&kaslr_regions[i]); > vaddr = round_up(vaddr + 1, PUD_SIZE); > + if (kaslr_regions[i].end) > + *kaslr_regions[i].end = __pa(vaddr) - 1; In the context of the patch it is clear that this is physmem_end, when someone comes to read this later maybe a comment like: /* * KASLR trims the maximum possible size of the direct-map record that * physmem_end boundary here */ With or without that the patch looks good to me: Reviewed-by: Dan Williams <dan.j.williams@xxxxxxxxx>