Skip to content
  • Paul Burton's avatar
    MIPS: Fix ioremap() RAM check · bc20ab94
    Paul Burton authored
    commit 523402fa9101090c91d2033b7ebdfdcf65880488 upstream.
    
    We currently attempt to check whether a physical address range provided
    to __ioremap() may be in use by the page allocator by examining the
    value of PageReserved for each page in the region - lowmem pages not
    marked reserved are presumed to be in use by the page allocator, and
    requests to ioremap them fail.
    
    The way we check this has been broken since commit 92923ca3 ("mm:
    meminit: only set page reserved in the memblock region"), because
    memblock will typically not have any knowledge of non-RAM pages and
    therefore those pages will not have the PageReserved flag set. Thus when
    we attempt to ioremap a region outside of RAM we incorrectly fail
    believing that the region is RAM that may be in use.
    
    In most cases ioremap() on MIPS will take a fast-path to use the
    unmapped kseg1 or xkphys virtual address spaces and never hit this path,
    so the only way to hit it is for a MIPS32 system to attempt to ioremap()
    an address range in lowmem with flags other than _CACHE_UNCACHED.
    Perhaps the most straightforward way to do this is using
    ioremap_uncached_accelerated(), which is how the problem was discovered.
    
    Fix this by making use of walk_system_ram_range() to test the address
    range provided to __ioremap() against only RAM pages, rather than all
    lowmem pages. This means that if we have a lowmem I/O region, which is
    very common for MIPS systems, we're free to ioremap() address ranges
    within it. A nice bonus is that the test is no longer limited to lowmem.
    
    The approach here matches the way x86 performed the same test after
    commit c81c8a1e ("x86, ioremap: Speed up check for RAM pages") until
    x86 moved towards a slightly more complicated check using walk_mem_res()
    for unrelated reasons with commit 0e4c12b4
    
     ("x86/mm, resource: Use
    PAGE_KERNEL protection for ioremap of memory pages").
    
    Signed-off-by: default avatarPaul Burton <paul.burton@mips.com>
    Reported-by: default avatarSerge Semin <fancer.lancer@gmail.com>
    Tested-by: default avatarSerge Semin <fancer.lancer@gmail.com>
    Fixes: 92923ca3 ("mm: meminit: only set page reserved in the memblock region")
    Cc: James Hogan <jhogan@kernel.org>
    Cc: Ralf Baechle <ralf@linux-mips.org>
    Cc: linux-mips@linux-mips.org
    Cc: stable@vger.kernel.org # v4.2+
    Patchwork: https://patchwork.linux-mips.org/patch/19786/
    
    
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    bc20ab94