#ifdef CONFIG_MMU
 void *module_alloc(unsigned long size)
 {
-       struct vm_struct *area;
-
-       size = PAGE_ALIGN(size);
-       if (!size)
-               return NULL;
-
-       area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
-       if (!area)
-               return NULL;
-
-       return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
+       return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+                               GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
+                               __builtin_return_address(0));
 }
 #else /* CONFIG_MMU */
 void *module_alloc(unsigned long size)
 
 
 static void *module_map(unsigned long size)
 {
-       struct vm_struct *area;
-
-       size = PAGE_ALIGN(size);
-       if (!size || size > MODULES_LEN)
-               return NULL;
-
-       area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
-       if (!area)
+       if (PAGE_ALIGN(size) > MODULES_LEN)
                return NULL;
-
-       return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL);
+       return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+                               GFP_KERNEL, PAGE_KERNEL, -1,
+                               __builtin_return_address(0));
 }
 
 static char *dot2underscore(char *name)
 
 
 void *module_alloc(unsigned long size)
 {
-       struct vm_struct *area;
-
-       if (!size)
-               return NULL;
-       size = PAGE_ALIGN(size);
-       if (size > MODULES_LEN)
+       if (PAGE_ALIGN(size) > MODULES_LEN)
                return NULL;
-
-       area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
-       if (!area)
-               return NULL;
-
-       return __vmalloc_area(area, GFP_KERNEL | __GFP_HIGHMEM,
-                                       PAGE_KERNEL_EXEC);
+       return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+                               GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
+                               -1, __builtin_return_address(0));
 }
 
 /* Free memory returned from module_alloc */
 
 extern void *vmalloc_32(unsigned long size);
 extern void *vmalloc_32_user(unsigned long size);
 extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot);
-extern void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask,
-                               pgprot_t prot);
+extern void *__vmalloc_node_range(unsigned long size, unsigned long align,
+                       unsigned long start, unsigned long end, gfp_t gfp_mask,
+                       pgprot_t prot, int node, void *caller);
 extern void vfree(const void *addr);
 
 extern void *vmap(struct page **pages, unsigned int count,
 
        return NULL;
 }
 
-void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
-{
-       void *addr = __vmalloc_area_node(area, gfp_mask, prot, -1,
-                                        __builtin_return_address(0));
-
-       /*
-        * A ref_count = 3 is needed because the vm_struct and vmap_area
-        * structures allocated in the __get_vm_area_node() function contain
-        * references to the virtual address of the vmalloc'ed block.
-        */
-       kmemleak_alloc(addr, area->size - PAGE_SIZE, 3, gfp_mask);
-
-       return addr;
-}
-
 /**
- *     __vmalloc_node  -  allocate virtually contiguous memory
+ *     __vmalloc_node_range  -  allocate virtually contiguous memory
  *     @size:          allocation size
  *     @align:         desired alignment
+ *     @start:         vm area range start
+ *     @end:           vm area range end
  *     @gfp_mask:      flags for the page level allocator
  *     @prot:          protection mask for the allocated pages
  *     @node:          node to use for allocation or -1
  *     allocator with @gfp_mask flags.  Map them into contiguous
  *     kernel virtual space, using a pagetable protection of @prot.
  */
-static void *__vmalloc_node(unsigned long size, unsigned long align,
-                           gfp_t gfp_mask, pgprot_t prot,
-                           int node, void *caller)
+void *__vmalloc_node_range(unsigned long size, unsigned long align,
+                       unsigned long start, unsigned long end, gfp_t gfp_mask,
+                       pgprot_t prot, int node, void *caller)
 {
        struct vm_struct *area;
        void *addr;
        if (!size || (size >> PAGE_SHIFT) > totalram_pages)
                return NULL;
 
-       area = __get_vm_area_node(size, align, VM_ALLOC, VMALLOC_START,
-                                 VMALLOC_END, node, gfp_mask, caller);
+       area = __get_vm_area_node(size, align, VM_ALLOC, start, end, node,
+                                 gfp_mask, caller);
 
        if (!area)
                return NULL;
        return addr;
 }
 
+/**
+ *     __vmalloc_node  -  allocate virtually contiguous memory
+ *     @size:          allocation size
+ *     @align:         desired alignment
+ *     @gfp_mask:      flags for the page level allocator
+ *     @prot:          protection mask for the allocated pages
+ *     @node:          node to use for allocation or -1
+ *     @caller:        caller's return address
+ *
+ *     Allocate enough pages to cover @size from the page level
+ *     allocator with @gfp_mask flags.  Map them into contiguous
+ *     kernel virtual space, using a pagetable protection of @prot.
+ */
+static void *__vmalloc_node(unsigned long size, unsigned long align,
+                           gfp_t gfp_mask, pgprot_t prot,
+                           int node, void *caller)
+{
+       return __vmalloc_node_range(size, align, VMALLOC_START, VMALLOC_END,
+                               gfp_mask, prot, node, caller);
+}
+
 void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
 {
        return __vmalloc_node(size, 1, gfp_mask, prot, -1,