resource: Set type of "reserve=" user-specified resources
authorBjorn Helgaas <bhelgaas@google.com>
Fri, 1 Dec 2017 17:50:33 +0000 (11:50 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 19 Dec 2017 05:07:46 +0000 (23:07 -0600)
When we reserve regions because the user specified a "reserve=" parameter,
set the resource type to either IORESOURCE_IO (for regions below 0x10000)
or IORESOURCE_MEM.  The test for 0x10000 is just a heuristic; obviously
there can be memory below 0x10000 as well.

Improve documentation of the "reserve=" parameter.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Documentation/admin-guide/kernel-parameters.txt
kernel/resource.c

index 6571fbf..78cdf6a 100644 (file)
                        [KNL, SMP] Set scheduler's default relax_domain_level.
                        See Documentation/cgroup-v1/cpusets.txt.
 
-       reserve=        [KNL,BUGS] Force the kernel to ignore some iomem area
+       reserve=        [KNL,BUGS] Force kernel to ignore I/O ports or memory
+                       Format: <base1>,<size1>[,<base2>,<size2>,...]
+                       Reserve I/O ports or memory so the kernel won't use
+                       them.  If <base> is less than 0x10000, the region
+                       is assumed to be I/O ports; otherwise it is memory.
 
        reservetop=     [X86-32]
                        Format: nn[KMG]
index 54ba6de..ba3252f 100644 (file)
@@ -1478,7 +1478,7 @@ void __devm_release_region(struct device *dev, struct resource *parent,
 EXPORT_SYMBOL(__devm_release_region);
 
 /*
- * Called from init/main.c to reserve IO ports.
+ * Reserve I/O ports or memory based on "reserve=" kernel parameter.
  */
 #define MAXRESERVE 4
 static int __init reserve_setup(char *str)
@@ -1489,26 +1489,38 @@ static int __init reserve_setup(char *str)
        for (;;) {
                unsigned int io_start, io_num;
                int x = reserved;
+               struct resource *parent;
 
-               if (get_option (&str, &io_start) != 2)
+               if (get_option(&str, &io_start) != 2)
                        break;
-               if (get_option (&str, &io_num)   == 0)
+               if (get_option(&str, &io_num) == 0)
                        break;
                if (x < MAXRESERVE) {
                        struct resource *res = reserve + x;
+
+                       /*
+                        * If the region starts below 0x10000, we assume it's
+                        * I/O port space; otherwise assume it's memory.
+                        */
+                       if (io_start < 0x10000) {
+                               res->flags = IORESOURCE_IO;
+                               parent = &ioport_resource;
+                       } else {
+                               res->flags = IORESOURCE_MEM;
+                               parent = &iomem_resource;
+                       }
                        res->name = "reserved";
                        res->start = io_start;
                        res->end = io_start + io_num - 1;
-                       res->flags = IORESOURCE_BUSY;
+                       res->flags |= IORESOURCE_BUSY;
                        res->desc = IORES_DESC_NONE;
                        res->child = NULL;
-                       if (request_resource(res->start >= 0x10000 ? &iomem_resource : &ioport_resource, res) == 0)
+                       if (request_resource(parent, res) == 0)
                                reserved = x+1;
                }
        }
        return 1;
 }
-
 __setup("reserve=", reserve_setup);
 
 /*