aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/e820.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/e820.c')
-rw-r--r--arch/x86/kernel/e820.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 508bec1cee27..3cf6681ac80d 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -421,7 +421,7 @@ static u64 __init e820_update_range_map(struct e820map *e820x, u64 start,
421 u64 size, unsigned old_type, 421 u64 size, unsigned old_type,
422 unsigned new_type) 422 unsigned new_type)
423{ 423{
424 int i; 424 unsigned int i, x;
425 u64 real_updated_size = 0; 425 u64 real_updated_size = 0;
426 426
427 BUG_ON(old_type == new_type); 427 BUG_ON(old_type == new_type);
@@ -429,7 +429,7 @@ static u64 __init e820_update_range_map(struct e820map *e820x, u64 start,
429 if (size > (ULLONG_MAX - start)) 429 if (size > (ULLONG_MAX - start))
430 size = ULLONG_MAX - start; 430 size = ULLONG_MAX - start;
431 431
432 for (i = 0; i < e820.nr_map; i++) { 432 for (i = 0; i < e820x->nr_map; i++) {
433 struct e820entry *ei = &e820x->map[i]; 433 struct e820entry *ei = &e820x->map[i];
434 u64 final_start, final_end; 434 u64 final_start, final_end;
435 if (ei->type != old_type) 435 if (ei->type != old_type)
@@ -446,14 +446,23 @@ static u64 __init e820_update_range_map(struct e820map *e820x, u64 start,
446 final_end = min(start + size, ei->addr + ei->size); 446 final_end = min(start + size, ei->addr + ei->size);
447 if (final_start >= final_end) 447 if (final_start >= final_end)
448 continue; 448 continue;
449 e820_add_region(final_start, final_end - final_start, 449
450 new_type); 450 x = e820x->nr_map;
451 if (x == ARRAY_SIZE(e820x->map)) {
452 printk(KERN_ERR "Too many memory map entries!\n");
453 break;
454 }
455 e820x->map[x].addr = final_start;
456 e820x->map[x].size = final_end - final_start;
457 e820x->map[x].type = new_type;
458 e820x->nr_map++;
459
451 real_updated_size += final_end - final_start; 460 real_updated_size += final_end - final_start;
452 461
453 ei->size -= final_end - final_start;
454 if (ei->addr < final_start) 462 if (ei->addr < final_start)
455 continue; 463 continue;
456 ei->addr = final_end; 464 ei->addr = final_end;
465 ei->size -= final_end - final_start;
457 } 466 }
458 return real_updated_size; 467 return real_updated_size;
459} 468}
@@ -1020,8 +1029,8 @@ u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align)
1020 continue; 1029 continue;
1021 return addr; 1030 return addr;
1022 } 1031 }
1023 return -1UL;
1024 1032
1033 return -1ULL;
1025} 1034}
1026 1035
1027/* 1036/*
@@ -1034,13 +1043,22 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
1034 u64 start; 1043 u64 start;
1035 1044
1036 start = startt; 1045 start = startt;
1037 while (size < sizet) 1046 while (size < sizet && (start + 1))
1038 start = find_e820_area_size(start, &size, align); 1047 start = find_e820_area_size(start, &size, align);
1039 1048
1040 if (size < sizet) 1049 if (size < sizet)
1041 return 0; 1050 return 0;
1042 1051
1052#ifdef CONFIG_X86_32
1053 if (start >= MAXMEM)
1054 return 0;
1055 if (start + size > MAXMEM)
1056 size = MAXMEM - start;
1057#endif
1058
1043 addr = round_down(start + size - sizet, align); 1059 addr = round_down(start + size - sizet, align);
1060 if (addr < start)
1061 return 0;
1044 e820_update_range(addr, sizet, E820_RAM, E820_RESERVED); 1062 e820_update_range(addr, sizet, E820_RAM, E820_RESERVED);
1045 e820_update_range_saved(addr, sizet, E820_RAM, E820_RESERVED); 1063 e820_update_range_saved(addr, sizet, E820_RAM, E820_RESERVED);
1046 printk(KERN_INFO "update e820 for early_reserve_e820\n"); 1064 printk(KERN_INFO "update e820 for early_reserve_e820\n");