diff options
Diffstat (limited to 'arch/i386/kernel/e820.c')
-rw-r--r-- | arch/i386/kernel/e820.c | 64 |
1 files changed, 40 insertions, 24 deletions
diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c index 70f39560846a..9645bb51f76a 100644 --- a/arch/i386/kernel/e820.c +++ b/arch/i386/kernel/e820.c | |||
@@ -161,26 +161,27 @@ static struct resource standard_io_resources[] = { { | |||
161 | 161 | ||
162 | static int __init romsignature(const unsigned char *rom) | 162 | static int __init romsignature(const unsigned char *rom) |
163 | { | 163 | { |
164 | const unsigned short * const ptr = (const unsigned short *)rom; | ||
164 | unsigned short sig; | 165 | unsigned short sig; |
165 | 166 | ||
166 | return probe_kernel_address((const unsigned short *)rom, sig) == 0 && | 167 | return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE; |
167 | sig == ROMSIGNATURE; | ||
168 | } | 168 | } |
169 | 169 | ||
170 | static int __init romchecksum(unsigned char *rom, unsigned long length) | 170 | static int __init romchecksum(const unsigned char *rom, unsigned long length) |
171 | { | 171 | { |
172 | unsigned char sum; | 172 | unsigned char sum, c; |
173 | 173 | ||
174 | for (sum = 0; length; length--) | 174 | for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--) |
175 | sum += *rom++; | 175 | sum += c; |
176 | return sum == 0; | 176 | return !length && !sum; |
177 | } | 177 | } |
178 | 178 | ||
179 | static void __init probe_roms(void) | 179 | static void __init probe_roms(void) |
180 | { | 180 | { |
181 | const unsigned char *rom; | ||
181 | unsigned long start, length, upper; | 182 | unsigned long start, length, upper; |
182 | unsigned char *rom; | 183 | unsigned char c; |
183 | int i; | 184 | int i; |
184 | 185 | ||
185 | /* video rom */ | 186 | /* video rom */ |
186 | upper = adapter_rom_resources[0].start; | 187 | upper = adapter_rom_resources[0].start; |
@@ -191,8 +192,11 @@ static void __init probe_roms(void) | |||
191 | 192 | ||
192 | video_rom_resource.start = start; | 193 | video_rom_resource.start = start; |
193 | 194 | ||
195 | if (probe_kernel_address(rom + 2, c) != 0) | ||
196 | continue; | ||
197 | |||
194 | /* 0 < length <= 0x7f * 512, historically */ | 198 | /* 0 < length <= 0x7f * 512, historically */ |
195 | length = rom[2] * 512; | 199 | length = c * 512; |
196 | 200 | ||
197 | /* if checksum okay, trust length byte */ | 201 | /* if checksum okay, trust length byte */ |
198 | if (length && romchecksum(rom, length)) | 202 | if (length && romchecksum(rom, length)) |
@@ -226,8 +230,11 @@ static void __init probe_roms(void) | |||
226 | if (!romsignature(rom)) | 230 | if (!romsignature(rom)) |
227 | continue; | 231 | continue; |
228 | 232 | ||
233 | if (probe_kernel_address(rom + 2, c) != 0) | ||
234 | continue; | ||
235 | |||
229 | /* 0 < length <= 0x7f * 512, historically */ | 236 | /* 0 < length <= 0x7f * 512, historically */ |
230 | length = rom[2] * 512; | 237 | length = c * 512; |
231 | 238 | ||
232 | /* but accept any length that fits if checksum okay */ | 239 | /* but accept any length that fits if checksum okay */ |
233 | if (!length || start + length > upper || !romchecksum(rom, length)) | 240 | if (!length || start + length > upper || !romchecksum(rom, length)) |
@@ -386,10 +393,8 @@ int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) | |||
386 | ____________________33__ | 393 | ____________________33__ |
387 | ______________________4_ | 394 | ______________________4_ |
388 | */ | 395 | */ |
389 | printk("sanitize start\n"); | ||
390 | /* if there's only one memory region, don't bother */ | 396 | /* if there's only one memory region, don't bother */ |
391 | if (*pnr_map < 2) { | 397 | if (*pnr_map < 2) { |
392 | printk("sanitize bail 0\n"); | ||
393 | return -1; | 398 | return -1; |
394 | } | 399 | } |
395 | 400 | ||
@@ -398,7 +403,6 @@ int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) | |||
398 | /* bail out if we find any unreasonable addresses in bios map */ | 403 | /* bail out if we find any unreasonable addresses in bios map */ |
399 | for (i=0; i<old_nr; i++) | 404 | for (i=0; i<old_nr; i++) |
400 | if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr) { | 405 | if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr) { |
401 | printk("sanitize bail 1\n"); | ||
402 | return -1; | 406 | return -1; |
403 | } | 407 | } |
404 | 408 | ||
@@ -494,7 +498,6 @@ int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) | |||
494 | memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry)); | 498 | memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry)); |
495 | *pnr_map = new_nr; | 499 | *pnr_map = new_nr; |
496 | 500 | ||
497 | printk("sanitize end\n"); | ||
498 | return 0; | 501 | return 0; |
499 | } | 502 | } |
500 | 503 | ||
@@ -525,7 +528,6 @@ int __init copy_e820_map(struct e820entry * biosmap, int nr_map) | |||
525 | unsigned long long size = biosmap->size; | 528 | unsigned long long size = biosmap->size; |
526 | unsigned long long end = start + size; | 529 | unsigned long long end = start + size; |
527 | unsigned long type = biosmap->type; | 530 | unsigned long type = biosmap->type; |
528 | printk("copy_e820_map() start: %016Lx size: %016Lx end: %016Lx type: %ld\n", start, size, end, type); | ||
529 | 531 | ||
530 | /* Overflow in 64 bits? Ignore the memory map. */ | 532 | /* Overflow in 64 bits? Ignore the memory map. */ |
531 | if (start > end) | 533 | if (start > end) |
@@ -536,17 +538,11 @@ int __init copy_e820_map(struct e820entry * biosmap, int nr_map) | |||
536 | * Not right. Fix it up. | 538 | * Not right. Fix it up. |
537 | */ | 539 | */ |
538 | if (type == E820_RAM) { | 540 | if (type == E820_RAM) { |
539 | printk("copy_e820_map() type is E820_RAM\n"); | ||
540 | if (start < 0x100000ULL && end > 0xA0000ULL) { | 541 | if (start < 0x100000ULL && end > 0xA0000ULL) { |
541 | printk("copy_e820_map() lies in range...\n"); | 542 | if (start < 0xA0000ULL) |
542 | if (start < 0xA0000ULL) { | ||
543 | printk("copy_e820_map() start < 0xA0000ULL\n"); | ||
544 | add_memory_region(start, 0xA0000ULL-start, type); | 543 | add_memory_region(start, 0xA0000ULL-start, type); |
545 | } | 544 | if (end <= 0x100000ULL) |
546 | if (end <= 0x100000ULL) { | ||
547 | printk("copy_e820_map() end <= 0x100000ULL\n"); | ||
548 | continue; | 545 | continue; |
549 | } | ||
550 | start = 0x100000ULL; | 546 | start = 0x100000ULL; |
551 | size = end - start; | 547 | size = end - start; |
552 | } | 548 | } |
@@ -818,6 +814,26 @@ void __init limit_regions(unsigned long long size) | |||
818 | print_memory_map("limit_regions endfunc"); | 814 | print_memory_map("limit_regions endfunc"); |
819 | } | 815 | } |
820 | 816 | ||
817 | /* | ||
818 | * This function checks if any part of the range <start,end> is mapped | ||
819 | * with type. | ||
820 | */ | ||
821 | int | ||
822 | e820_any_mapped(u64 start, u64 end, unsigned type) | ||
823 | { | ||
824 | int i; | ||
825 | for (i = 0; i < e820.nr_map; i++) { | ||
826 | const struct e820entry *ei = &e820.map[i]; | ||
827 | if (type && ei->type != type) | ||
828 | continue; | ||
829 | if (ei->addr >= end || ei->addr + ei->size <= start) | ||
830 | continue; | ||
831 | return 1; | ||
832 | } | ||
833 | return 0; | ||
834 | } | ||
835 | EXPORT_SYMBOL_GPL(e820_any_mapped); | ||
836 | |||
821 | /* | 837 | /* |
822 | * This function checks if the entire range <start,end> is mapped with type. | 838 | * This function checks if the entire range <start,end> is mapped with type. |
823 | * | 839 | * |