• Andres Salomon's avatar
    x86: ioremap ram check fix · cb8ab687
    Andres Salomon authored
    bdd3cee2 (x86: ioremap(), extend check
    to all RAM pages) breaks OLPC's ioremap call.  The ioremap that OLPC uses is:
    
            romsig = ioremap(0xffffffc0, 16);
    
    The commit that breaks it is basically:
    
    -       for (pfn = phys_addr >> PAGE_SHIFT; pfn < max_pfn_mapped &&
    -            (pfn << PAGE_SHIFT) < last_addr; pfn++) {
    +       for (pfn = phys_addr >> PAGE_SHIFT;
    +                               (pfn << PAGE_SHIFT) < last_addr; pfn++) {
    +
    
    Previously, the 'pfn < max_pfn_mapped' check would've caused us to not
    enter the loop.  Removing that check means we loop infinitely.  The
    reason for that is because pfn is 0xfffff, and last_addr is 0xffffffcf.
    The remaining check that is used to exit the loop is not sufficient;
    when pfn<<PAGE_SHIFT is 0xfffff000, that is less than 0xffffffcf; when
    we increment pfn and it overflows (pfn == 0x100000), pfn<<PAGE_SHIFT
    ends up being 0.  That, of course, is less than last_addr.  In effect,
    pfn<<PAGE_SHIFT is never lower than last_addr.
    
    The simple fix for this is to limit the last_addr check to the PAGE_MASK;
    a patch is below.
    Signed-off-by: default avatarAndres Salomon <dilinger@debian.org>
    Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    cb8ab687
ioremap.c 14.8 KB