Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

resources: add arch hook for preventing allocation in reserved areas

This adds arch_remove_reservations(), which an arch can implement if it
needs to protect part of the address space from allocation.

Sometimes that can be done by just putting a region in the resource tree,
but there are cases where that doesn't work well. For example, x86 BIOS
E820 reservations are not related to devices, so they may overlap part of,
all of, or more than a device resource, so they may not end up at the
correct spot in the resource tree.

Acked-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>

authored by

Bjorn Helgaas and committed by
Jesse Barnes
fcb11918 c0f5ac54

+7
+1
include/linux/ioport.h
··· 123 123 extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new); 124 124 extern int insert_resource(struct resource *parent, struct resource *new); 125 125 extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); 126 + extern void arch_remove_reservations(struct resource *avail); 126 127 extern int allocate_resource(struct resource *root, struct resource *new, 127 128 resource_size_t size, resource_size_t min, 128 129 resource_size_t max, resource_size_t align,
+6
kernel/resource.c
··· 357 357 return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1; 358 358 } 359 359 360 + void __weak arch_remove_reservations(struct resource *avail) 361 + { 362 + } 363 + 360 364 static resource_size_t simple_align_resource(void *data, 361 365 const struct resource *avail, 362 366 resource_size_t size, ··· 398 394 struct resource *this = root->child; 399 395 struct resource tmp = *new, avail, alloc; 400 396 397 + tmp.flags = new->flags; 401 398 tmp.start = root->start; 402 399 /* 403 400 * Skip past an allocated resource that starts at 0, since the assignment ··· 415 410 tmp.end = root->end; 416 411 417 412 resource_clip(&tmp, min, max); 413 + arch_remove_reservations(&tmp); 418 414 419 415 /* Check for overflow after ALIGN() */ 420 416 avail = *new;