From 3ae54d6d9b447b3aae4cdfc1b64b59c791cc2102 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 16 Dec 2010 10:38:56 -0700 Subject: [PATCH] --- yaml --- r: 223417 b: refs/heads/master c: 4dc2287c1805e7fe8a7cb90bbcd44abee8cdb914 h: refs/heads/master i: 223415: 67c96ed15d2f89c76c0d4f0f6da83c1e779d6eeb v: v3 --- [refs] | 2 +- trunk/arch/x86/kernel/resource.c | 38 +++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 0425e93662fc..d75fa2655f46 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 30919b0bf356a8ee0ef4f7d38ca8ad99b96820b2 +refs/heads/master: 4dc2287c1805e7fe8a7cb90bbcd44abee8cdb914 diff --git a/trunk/arch/x86/kernel/resource.c b/trunk/arch/x86/kernel/resource.c index 407a900da9df..89638af2ff19 100644 --- a/trunk/arch/x86/kernel/resource.c +++ b/trunk/arch/x86/kernel/resource.c @@ -1,11 +1,47 @@ #include #include +static void resource_clip(struct resource *res, resource_size_t start, + resource_size_t end) +{ + resource_size_t low = 0, high = 0; + + if (res->end < start || res->start > end) + return; /* no conflict */ + + if (res->start < start) + low = start - res->start; + + if (res->end > end) + high = res->end - end; + + /* Keep the area above or below the conflict, whichever is larger */ + if (low > high) + res->end = start - 1; + else + res->start = end + 1; +} + +static void remove_e820_regions(struct resource *avail) +{ + int i; + struct e820entry *entry; + + for (i = 0; i < e820.nr_map; i++) { + entry = &e820.map[i]; + + resource_clip(avail, entry->addr, + entry->addr + entry->size - 1); + } +} + void arch_remove_reservations(struct resource *avail) { - /* Trim out BIOS area (low 1MB) */ + /* Trim out BIOS area (low 1MB) and E820 regions */ if (avail->flags & IORESOURCE_MEM) { if (avail->start < BIOS_END) avail->start = BIOS_END; + + remove_e820_regions(avail); } }