diff options
author | Yinghai Lu <yhlu.kernel.send@gmail.com> | 2008-03-18 19:44:19 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-03-21 12:06:15 -0400 |
commit | 5dca6a1bb014875a17289fdaae8c31e0a3641c99 (patch) | |
tree | c6cb1eab44e92cedbfcee707de6ed2ad960e20e6 /arch/x86/kernel/e820_32.c | |
parent | fc1c8925c8210009c1fc5d909d189252d8fb4fb2 (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_32.c')
-rw-r--r-- | arch/x86/kernel/e820_32.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c index 4e16ef4a2659..80444c5c9b14 100644 --- a/arch/x86/kernel/e820_32.c +++ b/arch/x86/kernel/e820_32.c | |||
@@ -749,6 +749,32 @@ static int __init parse_memmap(char *arg) | |||
749 | return 0; | 749 | return 0; |
750 | } | 750 | } |
751 | early_param("memmap", parse_memmap); | 751 | early_param("memmap", parse_memmap); |
752 | void __init update_memory_range(u64 start, u64 size, unsigned old_type, | ||
753 | unsigned new_type) | ||
754 | { | ||
755 | int i; | ||
756 | |||
757 | BUG_ON(old_type == new_type); | ||
758 | |||
759 | for (i = 0; i < e820.nr_map; i++) { | ||
760 | struct e820entry *ei = &e820.map[i]; | ||
761 | u64 final_start, final_end; | ||
762 | if (ei->type != old_type) | ||
763 | continue; | ||
764 | /* totally covered? */ | ||
765 | if (ei->addr >= start && ei->size <= size) { | ||
766 | ei->type = new_type; | ||
767 | continue; | ||
768 | } | ||
769 | /* partially covered */ | ||
770 | final_start = max(start, ei->addr); | ||
771 | final_end = min(start + size, ei->addr + ei->size); | ||
772 | if (final_start >= final_end) | ||
773 | continue; | ||
774 | add_memory_region(final_start, final_end - final_start, | ||
775 | new_type); | ||
776 | } | ||
777 | } | ||
752 | void __init update_e820(void) | 778 | void __init update_e820(void) |
753 | { | 779 | { |
754 | u8 nr_map; | 780 | u8 nr_map; |