aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/kernel/e820_64.c
diff options
context:
space:
mode:
authorYinghai Lu2008-03-18 16:44:19 -0700
committerIngo Molnar2008-03-21 17:06:15 +0100
commit5dca6a1bb014875a17289fdaae8c31e0a3641c99 (patch)
treec6cb1eab44e92cedbfcee707de6ed2ad960e20e6 /arch/x86/kernel/e820_64.c
parentfc1c8925c8210009c1fc5d909d189252d8fb4fb2 (diff)
x86: trim mtrr don't close gap for resource allocation.
fix the bug reported here: http://bugzilla.kernel.org/show_bug.cgi?id=10232 use update_memory_range() instead of add_memory_range() directly to avoid closing the gap. ( the new code only affects and runs on systems where the MTRR workaround triggers. ) Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/e820_64.c')
-rw-r--r--arch/x86/kernel/e820_64.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c
index 9f65b4cc323c..9be697126013 100644
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -744,6 +744,33 @@ void __init finish_e820_parsing(void)
}
}
+void __init update_memory_range(u64 start, u64 size, unsigned old_type,
+ unsigned new_type)
+{
+ int i;
+
+ BUG_ON(old_type == new_type);
+
+ for (i = 0; i < e820.nr_map; i++) {
+ struct e820entry *ei = &e820.map[i];
+ u64 final_start, final_end;
+ if (ei->type != old_type)
+ continue;
+ /* totally covered? */
+ if (ei->addr >= start && ei->size <= size) {
+ ei->type = new_type;
+ continue;
+ }
+ /* partially covered */
+ final_start = max(start, ei->addr);
+ final_end = min(start + size, ei->addr + ei->size);
+ if (final_start >= final_end)
+ continue;
+ add_memory_region(final_start, final_end - final_start,
+ new_type);
+ }
+}
+
void __init update_e820(void)
{
u8 nr_map;