Index: linux-2.6/mm/vmalloc.c =================================================================== --- linux-2.6.orig/mm/vmalloc.c +++ linux-2.6/mm/vmalloc.c @@ -31,6 +31,61 @@ /*** Page table manipulation functions ***/ +static void check_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end) +{ + pte_t *pte; + + pte = pte_offset_kernel(pmd, addr); + do { + WARN_ON_ONCE(!pte_none(*pte)); + } while (pte++, addr += PAGE_SIZE, addr != end); +} + +static void check_pmd_range(pud_t *pud, unsigned long addr, unsigned long end) +{ + pmd_t *pmd; + unsigned long next; + + pmd = pmd_offset(pud, addr); + do { + next = pmd_addr_end(addr, end); + if (pmd_none_or_clear_bad(pmd)) + continue; + check_pte_range(pmd, addr, next); + } while (pmd++, addr = next, addr != end); +} + +static void check_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end) +{ + pud_t *pud; + unsigned long next; + + pud = pud_offset(pgd, addr); + do { + next = pud_addr_end(addr, end); + if (pud_none_or_clear_bad(pud)) + continue; + check_pmd_range(pud, addr, next); + } while (pud++, addr = next, addr != end); +} + +static void check_page_range(unsigned long addr, unsigned long end) +{ + pgd_t *pgd; + unsigned long next; + + BUG_ON(addr >= end); + pgd = pgd_offset_k(addr); + flush_cache_vunmap(addr, end); + do { + next = pgd_addr_end(addr, end); + if (pgd_none_or_clear_bad(pgd)) + continue; + check_pud_range(pgd, addr, next); + } while (pgd++, addr = next, addr != end); +} + + static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end) { pte_t *pte; @@ -75,6 +130,8 @@ static void vunmap_page_range(unsigned l pgd_t *pgd; unsigned long next; + printk("vunmap_page_range (%lx-%lx size=%lx)\n", addr, end, end-addr); + BUG_ON(addr >= end); pgd = pgd_offset_k(addr); flush_cache_vunmap(addr, end); @@ -160,6 +217,8 @@ static int vmap_page_range(unsigned long int err = 0; int nr = 0; + printk("vmap_page_range (%lx-%lx size=%lx)\n", addr, end, end-addr); + BUG_ON(addr >= end); pgd = pgd_offset_k(addr); do { @@ -371,6 +430,10 @@ found: va->va_end = addr + size; va->flags = 0; __insert_vmap_area(va); + + printk("alloc_vmap_area within(%lx-%lx) size=%lx returns=(%lx-%lx)\n", vstart, vend, size, addr, addr+size); + check_page_range(va->va_start, va->va_end); + spin_unlock(&vmap_area_lock); return va; @@ -385,6 +448,9 @@ static void rcu_free_va(struct rcu_head static void __free_vmap_area(struct vmap_area *va) { + printk("free_vmap_area (%lx-%lx size=%lx)\n", va->va_start, va->va_end, va->va_end - va->va_start); + check_page_range(va->va_start, va->va_end); + BUG_ON(RB_EMPTY_NODE(&va->rb_node)); rb_erase(&va->rb_node, &vmap_area_root); RB_CLEAR_NODE(&va->rb_node);