userns: Convert audit to work with user namespaces enabled
[firefly-linux-kernel-4.4.55.git] / kernel / resource.c
index e1d2b8ee76d5bcd22d552c21cdf2102eaf6c7627..34d45886ee8429acc7197c8ceaca18ef215fb2ae 100644 (file)
@@ -7,6 +7,8 @@
  * Arbitrary resource management.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/export.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
@@ -722,14 +724,12 @@ int adjust_resource(struct resource *res, resource_size_t start, resource_size_t
 
        write_lock(&resource_lock);
 
+       if (!parent)
+               goto skip;
+
        if ((start < parent->start) || (end > parent->end))
                goto out;
 
-       for (tmp = res->child; tmp; tmp = tmp->sibling) {
-               if ((tmp->start < start) || (tmp->end > end))
-                       goto out;
-       }
-
        if (res->sibling && (res->sibling->start <= end))
                goto out;
 
@@ -741,6 +741,11 @@ int adjust_resource(struct resource *res, resource_size_t start, resource_size_t
                        goto out;
        }
 
+skip:
+       for (tmp = res->child; tmp; tmp = tmp->sibling)
+               if ((tmp->start < start) || (tmp->end > end))
+                       goto out;
+
        res->start = start;
        res->end = end;
        result = 0;
@@ -788,8 +793,28 @@ void __init reserve_region_with_split(struct resource *root,
                resource_size_t start, resource_size_t end,
                const char *name)
 {
+       int abort = 0;
+
        write_lock(&resource_lock);
-       __reserve_region_with_split(root, start, end, name);
+       if (root->start > start || root->end < end) {
+               pr_err("requested range [0x%llx-0x%llx] not in root %pr\n",
+                      (unsigned long long)start, (unsigned long long)end,
+                      root);
+               if (start > root->end || end < root->start)
+                       abort = 1;
+               else {
+                       if (end > root->end)
+                               end = root->end;
+                       if (start < root->start)
+                               start = root->start;
+                       pr_err("fixing request to [0x%llx-0x%llx]\n",
+                              (unsigned long long)start,
+                              (unsigned long long)end);
+               }
+               dump_stack();
+       }
+       if (!abort)
+               __reserve_region_with_split(root, start, end, name);
        write_unlock(&resource_lock);
 }