resource: Set type of "reserve=" user-specified resources

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>
This commit is contained in:
Bjorn Helgaas 2017-12-01 11:50:33 -06:00
parent 6a9d42ed0d
commit ffd2e8df8d
2 changed files with 23 additions and 7 deletions

View File

@ -3675,7 +3675,11 @@
[KNL, SMP] Set scheduler's default relax_domain_level. [KNL, SMP] Set scheduler's default relax_domain_level.
See Documentation/cgroup-v1/cpusets.txt. 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] reservetop= [X86-32]
Format: nn[KMG] Format: nn[KMG]

View File

@ -1478,7 +1478,7 @@ void __devm_release_region(struct device *dev, struct resource *parent,
EXPORT_SYMBOL(__devm_release_region); 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 #define MAXRESERVE 4
static int __init reserve_setup(char *str) static int __init reserve_setup(char *str)
@ -1489,26 +1489,38 @@ static int __init reserve_setup(char *str)
for (;;) { for (;;) {
unsigned int io_start, io_num; unsigned int io_start, io_num;
int x = reserved; int x = reserved;
struct resource *parent;
if (get_option (&str, &io_start) != 2) if (get_option(&str, &io_start) != 2)
break; break;
if (get_option (&str, &io_num) == 0) if (get_option(&str, &io_num) == 0)
break; break;
if (x < MAXRESERVE) { if (x < MAXRESERVE) {
struct resource *res = reserve + x; 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->name = "reserved";
res->start = io_start; res->start = io_start;
res->end = io_start + io_num - 1; res->end = io_start + io_num - 1;
res->flags = IORESOURCE_BUSY; res->flags |= IORESOURCE_BUSY;
res->desc = IORES_DESC_NONE; res->desc = IORES_DESC_NONE;
res->child = NULL; res->child = NULL;
if (request_resource(res->start >= 0x10000 ? &iomem_resource : &ioport_resource, res) == 0) if (request_resource(parent, res) == 0)
reserved = x+1; reserved = x+1;
} }
} }
return 1; return 1;
} }
__setup("reserve=", reserve_setup); __setup("reserve=", reserve_setup);
/* /*