diff options
-rw-r--r-- | arch/x86/kernel/e820.c | 35 | ||||
-rw-r--r-- | include/asm-x86/e820.h | 2 |
2 files changed, 37 insertions, 0 deletions
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, | |||
429 | return real_updated_size; | 429 | return real_updated_size; |
430 | } | 430 | } |
431 | 431 | ||
432 | /* make e820 not cover the range */ | ||
433 | u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type, | ||
434 | int checktype) | ||
435 | { | ||
436 | int i; | ||
437 | u64 real_removed_size = 0; | ||
438 | |||
439 | for (i = 0; i < e820.nr_map; i++) { | ||
440 | struct e820entry *ei = &e820.map[i]; | ||
441 | u64 final_start, final_end; | ||
442 | |||
443 | if (checktype && ei->type != old_type) | ||
444 | continue; | ||
445 | /* totally covered? */ | ||
446 | if (ei->addr >= start && | ||
447 | (ei->addr + ei->size) <= (start + size)) { | ||
448 | real_removed_size += ei->size; | ||
449 | memset(ei, 0, sizeof(struct e820entry)); | ||
450 | continue; | ||
451 | } | ||
452 | /* partially covered */ | ||
453 | final_start = max(start, ei->addr); | ||
454 | final_end = min(start + size, ei->addr + ei->size); | ||
455 | if (final_start >= final_end) | ||
456 | continue; | ||
457 | real_removed_size += final_end - final_start; | ||
458 | |||
459 | ei->size -= final_end - final_start; | ||
460 | if (ei->addr < final_start) | ||
461 | continue; | ||
462 | ei->addr = final_end; | ||
463 | } | ||
464 | return real_removed_size; | ||
465 | } | ||
466 | |||
432 | void __init update_e820(void) | 467 | void __init update_e820(void) |
433 | { | 468 | { |
434 | int nr_map; | 469 | 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); | |||
67 | extern int copy_e820_map(struct e820entry *biosmap, int nr_map); | 67 | extern int copy_e820_map(struct e820entry *biosmap, int nr_map); |
68 | extern u64 e820_update_range(u64 start, u64 size, unsigned old_type, | 68 | extern u64 e820_update_range(u64 start, u64 size, unsigned old_type, |
69 | unsigned new_type); | 69 | unsigned new_type); |
70 | extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type, | ||
71 | int checktype); | ||
70 | extern void update_e820(void); | 72 | extern void update_e820(void); |
71 | extern void e820_setup_gap(void); | 73 | extern void e820_setup_gap(void); |
72 | struct setup_data; | 74 | struct setup_data; |