vserver 1.9.5.x5
[linux-2.6.git] / arch / i386 / mm / ioremap.c
index aee0bb1..9073267 100644 (file)
@@ -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();
        }