]> 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 673942094328a710b059b2b50e149ce7eb3d5f11..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;
 
@@ -1943,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
 
 /**
@@ -2257,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 {