]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - mm/vmalloc.c
HID: fix a potential bug in pointer casting
[linux-2.6-omap-h63xx.git] / mm / vmalloc.c
index 8e05a11155c9208e6daf17644168929105e433da..af77e171e339a357933d7eb6ba4b001efae5e390 100644 (file)
@@ -164,6 +164,7 @@ int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
        flush_cache_vmap((unsigned long) area->addr, end);
        return err;
 }
+EXPORT_SYMBOL_GPL(map_vm_area);
 
 static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
                                            unsigned long start, unsigned long end,
@@ -189,7 +190,8 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long fl
        if (unlikely(!size))
                return NULL;
 
-       area = kmalloc_node(sizeof(*area), gfp_mask & GFP_LEVEL_MASK, node);
+       area = kmalloc_node(sizeof(*area), gfp_mask & GFP_RECLAIM_MASK, node);
+
        if (unlikely(!area))
                return NULL;
 
@@ -242,9 +244,10 @@ struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
 {
        return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL);
 }
+EXPORT_SYMBOL_GPL(__get_vm_area);
 
 /**
- *     get_vm_area  -  reserve a contingous kernel virtual area
+ *     get_vm_area  -  reserve a contiguous kernel virtual area
  *     @size:          size of the area
  *     @flags:         %VM_IOREMAP for I/O mappings or VM_ALLOC
  *
@@ -300,7 +303,7 @@ found:
 }
 
 /**
- *     remove_vm_area  -  find and remove a contingous kernel virtual area
+ *     remove_vm_area  -  find and remove a continuous kernel virtual area
  *     @addr:          base address
  *
  *     Search for the kernel VM area starting at @addr, and remove it.
@@ -361,7 +364,7 @@ static void __vunmap(void *addr, int deallocate_pages)
  *     vfree  -  release memory allocated by vmalloc()
  *     @addr:          memory base address
  *
- *     Free the virtually contiguous memory area starting at @addr, as
+ *     Free the virtually continuous memory area starting at @addr, as
  *     obtained from vmalloc(), vmalloc_32() or __vmalloc(). If @addr is
  *     NULL, no operation is performed.
  *
@@ -437,7 +440,7 @@ void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
                area->flags |= VM_VPAGES;
        } else {
                pages = kmalloc_node(array_size,
-                               (gfp_mask & GFP_LEVEL_MASK) | __GFP_ZERO,
+                               (gfp_mask & GFP_RECLAIM_MASK) | __GFP_ZERO,
                                node);
        }
        area->pages = pages;
@@ -583,9 +586,9 @@ void *vmalloc_exec(unsigned long size)
 }
 
 #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
-#define GFP_VMALLOC32 GFP_DMA32
+#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL
 #elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA)
-#define GFP_VMALLOC32 GFP_DMA
+#define GFP_VMALLOC32 GFP_DMA | GFP_KERNEL
 #else
 #define GFP_VMALLOC32 GFP_KERNEL
 #endif
@@ -767,3 +770,56 @@ EXPORT_SYMBOL(remap_vmalloc_range);
 void  __attribute__((weak)) vmalloc_sync_all(void)
 {
 }
+
+
+static int f(pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
+{
+       /* apply_to_page_range() does all the hard work. */
+       return 0;
+}
+
+/**
+ *     alloc_vm_area - allocate a range of kernel address space
+ *     @size:          size of the area
+ *     @returns:       NULL on failure, vm_struct on success
+ *
+ *     This function reserves a range of kernel address space, and
+ *     allocates pagetables to map that range.  No actual mappings
+ *     are created.  If the kernel address space is not shared
+ *     between processes, it syncs the pagetable across all
+ *     processes.
+ */
+struct vm_struct *alloc_vm_area(size_t size)
+{
+       struct vm_struct *area;
+
+       area = get_vm_area(size, VM_IOREMAP);
+       if (area == NULL)
+               return NULL;
+
+       /*
+        * This ensures that page tables are constructed for this region
+        * of kernel virtual address space and mapped into init_mm.
+        */
+       if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
+                               area->size, f, NULL)) {
+               free_vm_area(area);
+               return NULL;
+       }
+
+       /* Make sure the pagetables are constructed in process kernel
+          mappings */
+       vmalloc_sync_all();
+
+       return area;
+}
+EXPORT_SYMBOL_GPL(alloc_vm_area);
+
+void free_vm_area(struct vm_struct *area)
+{
+       struct vm_struct *ret;
+       ret = remove_vm_area(area->addr);
+       BUG_ON(ret != area);
+       kfree(area);
+}
+EXPORT_SYMBOL_GPL(free_vm_area);