[lkml]   [2018]   [Jul]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[PATCH 4.17 011/220] m68k/mm: Adjust VM area to be unmapped by gap size for __iounmap()
    4.17-stable review patch.  If anyone has any objections, please let me know.


    From: Michael Schmitz <>

    commit 3f90f9ef2dda316d64e420d5d51ba369587ccc55 upstream.

    If 020/030 support is enabled, get_io_area() leaves an IO_SIZE gap
    between mappings which is added to the vm_struct representing the
    mapping. __ioremap() uses the actual requested size (after alignment),
    while __iounmap() is passed the size from the vm_struct.

    On 020/030, early termination descriptors are used to set up mappings of
    extent 'size', which are validated on unmapping. The unmapped gap of
    size IO_SIZE defeats the sanity check of the pmd tables, causing
    __iounmap() to loop forever on 030.

    On 040/060, unmapping of page table entries does not check for a valid
    mapping, so the umapping loop always completes there.

    Adjust size to be unmapped by the gap that had been added in the
    vm_struct prior.

    This fixes the hang in atari_platform_init() reported a long time ago,
    and a similar one reported by Finn recently (addressed by removing
    ioremap() use from the SWIM driver.

    Tested on my Falcon in 030 mode - untested but should work the same on
    040/060 (the extra page tables cleared there would never have been set
    up anyway).

    Signed-off-by: Michael Schmitz <>
    [geert: Minor commit description improvements]
    [geert: This was fixed in 2.4.23, but not in 2.5.x]
    Signed-off-by: Geert Uytterhoeven <>
    Signed-off-by: Greg Kroah-Hartman <>

    arch/m68k/mm/kmap.c | 3 ++-
    1 file changed, 2 insertions(+), 1 deletion(-)

    --- a/arch/m68k/mm/kmap.c
    +++ b/arch/m68k/mm/kmap.c
    @@ -89,7 +89,8 @@ static inline void free_io_area(void *ad
    for (p = &iolist ; (tmp = *p) ; p = &tmp->next) {
    if (tmp->addr == addr) {
    *p = tmp->next;
    - __iounmap(tmp->addr, tmp->size);
    + /* remove gap added in get_io_area() */
    + __iounmap(tmp->addr, tmp->size - IO_SIZE);

     \ /
      Last update: 2018-07-01 18:37    [W:2.457 / U:0.252 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site