]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - mm/vmalloc.c
mm/huge_memory.c: fix modifying of page protection by insert_pfn_pmd()
[mirror_ubuntu-bionic-kernel.git] / mm / vmalloc.c
index 8a43db6284ebcb9c40dfc3532d454c783ea61412..6c906f6f16cc6f980946c94f7a608658a374371c 100644 (file)
@@ -498,7 +498,11 @@ nocache:
        }
 
 found:
-       if (addr + size > vend)
+       /*
+        * Check also calculated address against the vstart,
+        * because it can be 0 because of big align request.
+        */
+       if (addr + size > vend || addr < vstart)
                goto overflow;
 
        va->va_start = addr;
@@ -1519,7 +1523,7 @@ static void __vunmap(const void *addr, int deallocate_pages)
                        addr))
                return;
 
-       area = remove_vm_area(addr);
+       area = find_vmap_area((unsigned long)addr)->vm;
        if (unlikely(!area)) {
                WARN(1, KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n",
                                addr);
@@ -1529,6 +1533,7 @@ static void __vunmap(const void *addr, int deallocate_pages)
        debug_check_no_locks_freed(addr, get_vm_area_size(area));
        debug_check_no_obj_freed(addr, get_vm_area_size(area));
 
+       remove_vm_area(addr);
        if (deallocate_pages) {
                int i;
 
@@ -1695,11 +1700,6 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
        for (i = 0; i < area->nr_pages; i++) {
                struct page *page;
 
-               if (fatal_signal_pending(current)) {
-                       area->nr_pages = i;
-                       goto fail_no_warn;
-               }
-
                if (node == NUMA_NO_NODE)
                        page = alloc_page(alloc_mask|highmem_mask);
                else
@@ -1723,7 +1723,6 @@ fail:
        warn_alloc(gfp_mask, NULL,
                          "vmalloc: allocation failure, allocated %ld of %ld bytes",
                          (area->nr_pages*PAGE_SIZE), area->size);
-fail_no_warn:
        vfree(area->addr);
        return NULL;
 }
@@ -1949,11 +1948,15 @@ void *vmalloc_exec(unsigned long size)
 }
 
 #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
-#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL
+#define GFP_VMALLOC32 (GFP_DMA32 | GFP_KERNEL)
 #elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA)
-#define GFP_VMALLOC32 GFP_DMA | GFP_KERNEL
+#define GFP_VMALLOC32 (GFP_DMA | GFP_KERNEL)
 #else
-#define GFP_VMALLOC32 GFP_KERNEL
+/*
+ * 64b systems should always have either DMA or DMA32 zones. For others
+ * GFP_DMA32 should do the right thing and use the normal zone.
+ */
+#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL
 #endif
 
 /**
@@ -2263,7 +2266,7 @@ int remap_vmalloc_range_partial(struct vm_area_struct *vma, unsigned long uaddr,
        if (!(area->flags & VM_USERMAP))
                return -EINVAL;
 
-       if (kaddr + size > area->addr + area->size)
+       if (kaddr + size > area->addr + get_vm_area_size(area))
                return -EINVAL;
 
        do {