OSDN Git Service

cifs: fail i/o on soft mounts if sessionsetup errors out
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / mm / vmalloc.c
index 8e3c9c5..d118e59 100644 (file)
@@ -446,7 +446,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;
@@ -1460,7 +1464,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);
@@ -1470,6 +1474,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;
 
@@ -1673,6 +1678,12 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
                return NULL;
 
        /*
+        * First make sure the mappings are removed from all page-tables
+        * before they are freed.
+        */
+       vmalloc_sync_all();
+
+       /*
         * In this function, newly allocated vm_struct has VM_UNINITIALIZED
         * flag. It means that vm_struct is not fully initialized.
         * Now, it is fully initialized, so remove this flag here.
@@ -2161,7 +2172,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 {
@@ -2209,6 +2220,9 @@ EXPORT_SYMBOL(remap_vmalloc_range);
 /*
  * Implement a stub for vmalloc_sync_all() if the architecture chose not to
  * have one.
+ *
+ * The purpose of this function is to make sure the vmalloc area
+ * mappings are identical in all page-tables in the system.
  */
 void __weak vmalloc_sync_all(void)
 {