From 7a1fd9866cbb59a00006f1e0fd5726951b167c97 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 21 Jun 2008 14:48:05 -0700 Subject: [PATCH] x86: add e820_remove_range ... so could add real hole in e820 agp check is using request_mem_region, and could fail if e820 is reserved... Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/e820.c | 35 +++++++++++++++++++++++++++++++++++ include/asm-x86/e820.h | 2 ++ 2 files changed, 37 insertions(+) diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 7b613d2efb04..e285ea38c8e5 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -429,6 +429,41 @@ u64 __init e820_update_range(u64 start, u64 size, unsigned old_type, return real_updated_size; } +/* make e820 not cover the range */ +u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type, + int checktype) +{ + int i; + u64 real_removed_size = 0; + + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + u64 final_start, final_end; + + if (checktype && ei->type != old_type) + continue; + /* totally covered? */ + if (ei->addr >= start && + (ei->addr + ei->size) <= (start + size)) { + real_removed_size += ei->size; + memset(ei, 0, sizeof(struct e820entry)); + continue; + } + /* partially covered */ + final_start = max(start, ei->addr); + final_end = min(start + size, ei->addr + ei->size); + if (final_start >= final_end) + continue; + real_removed_size += final_end - final_start; + + ei->size -= final_end - final_start; + if (ei->addr < final_start) + continue; + ei->addr = final_end; + } + return real_removed_size; +} + void __init update_e820(void) { int nr_map; diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h index 0e92b6a2ea00..7c32df07bae4 100644 --- a/include/asm-x86/e820.h +++ b/include/asm-x86/e820.h @@ -67,6 +67,8 @@ sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, int *pnr_map); extern int copy_e820_map(struct e820entry *biosmap, int nr_map); extern u64 e820_update_range(u64 start, u64 size, unsigned old_type, unsigned new_type); +extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type, + int checktype); extern void update_e820(void); extern void e820_setup_gap(void); struct setup_data; -- 2.20.1