X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fi386%2Fmm%2Fioremap.c;h=907326772fff520df0759580484fb7fb6aded1ed;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=aee0bb1f495d6380ba4a1b498c34aa01882a0686;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index aee0bb1f4..907326772 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c @@ -80,9 +80,14 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr, BUG(); spin_lock(&init_mm.page_table_lock); do { + pud_t *pud; pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + error = -ENOMEM; + pud = pud_alloc(&init_mm, dir, address); + if (!pud) + break; + pmd = pmd_alloc(&init_mm, pud, address); if (!pmd) break; if (remap_area_pmd(pmd, address, end - address, @@ -130,7 +135,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l /* * Don't allow anybody to remap normal RAM that we're using.. */ - if (phys_addr < virt_to_phys(high_memory)) { + if (phys_addr <= virt_to_phys(high_memory - 1)) { char *t_addr, *t_end; struct page *page; @@ -152,7 +157,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l /* * Ok, go for it.. */ - area = get_vm_area(size, VM_IOREMAP); + area = get_vm_area(size, VM_IOREMAP | (flags << 20)); if (!area) return NULL; area->phys_addr = phys_addr; @@ -197,7 +202,7 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size) /* Guaranteed to be > phys_addr, as per __ioremap() */ last_addr = phys_addr + size - 1; - if (last_addr < virt_to_phys(high_memory)) { + if (last_addr < virt_to_phys(high_memory) - 1) { struct page *ppage = virt_to_page(__va(phys_addr)); unsigned long npages; @@ -230,11 +235,12 @@ void iounmap(volatile void __iomem *addr) if (!p) { printk("__iounmap: bad address %p\n", addr); return; - } + } - if (p->flags && p->phys_addr < virt_to_phys(high_memory)) { + if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) { + /* p->size includes the guard page, but cpa doesn't like that */ change_page_attr(virt_to_page(__va(p->phys_addr)), - p->size >> PAGE_SHIFT, + (p->size - PAGE_SIZE) >> PAGE_SHIFT, PAGE_KERNEL); global_flush_tlb(); }