--- include/linux/mm.h | 17 ++++++++++++++++- mm/page_alloc.c | 2 +- mm/vmalloc.c | 9 +++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) Index: linux-2.6/include/linux/mm.h =================================================================== --- linux-2.6.orig/include/linux/mm.h 2007-09-24 18:39:09.000000000 -0700 +++ linux-2.6/include/linux/mm.h 2007-09-24 18:40:08.000000000 -0700 @@ -307,6 +307,14 @@ static inline int is_vmalloc_addr(const return addr >= VMALLOC_START && addr < VMALLOC_END; } +static inline struct page *addr_to_page(const void *x) +{ + + if (unlikely(is_vmalloc_addr(x))) + return vmalloc_to_page(x); + return virt_to_page(x); +} + static inline struct page *compound_head(struct page *page) { if (unlikely(PageTail(page))) @@ -328,7 +336,7 @@ static inline void get_page(struct page static inline struct page *virt_to_head_page(const void *x) { - struct page *page = virt_to_page(x); + struct page *page = addr_to_page(x); return compound_head(page); } @@ -632,6 +640,13 @@ void page_address_init(void); #define page_address_init() do { } while(0) #endif +static inline void *page_to_addr(struct page *page) +{ + if (unlikely(PageVcompound(page))) + return vmalloc_address(page); + return page_address(page); +} + /* * On an anonymous page mapped into a user virtual memory area, * page->mapping points to its anon_vma, not to a struct address_space; Index: linux-2.6/mm/page_alloc.c =================================================================== --- linux-2.6.orig/mm/page_alloc.c 2007-09-24 18:39:09.000000000 -0700 +++ linux-2.6/mm/page_alloc.c 2007-09-24 18:40:08.000000000 -0700 @@ -1523,7 +1523,7 @@ fastcall unsigned long get_zeroed_page(g page = alloc_pages(gfp_mask | __GFP_ZERO, 0); if (page) - return (unsigned long) page_address(page); + return (unsigned long) page_to_addr(page); return 0; } Index: linux-2.6/mm/vmalloc.c =================================================================== --- linux-2.6.orig/mm/vmalloc.c 2007-09-24 18:39:09.000000000 -0700 +++ linux-2.6/mm/vmalloc.c 2007-09-24 18:40:08.000000000 -0700 @@ -666,6 +666,15 @@ struct page *vmalloc_nth_page(struct pag return vmalloc_to_page(vmalloc_address(page) + n * PAGE_SIZE); } +/* + * Given a pointer to the first page struct: + * Determine a pointer to the nth page. + */ +struct page *vmalloc_nth_page(struct page *page, int n) +{ + return vmalloc_to_page(vmalloc_address(page) + n * PAGE_SIZE); +} + /** * vmalloc_user - allocate zeroed virtually contiguous memory for userspace * @size: allocation size