Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-x86setup

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-x86setup:
[x86 setup] Handle case of improperly terminated E820 chain

+23 -7
+23 -7
arch/i386/boot/memory.c
··· 20 20 21 21 static int detect_memory_e820(void) 22 22 { 23 + int count = 0; 23 24 u32 next = 0; 24 25 u32 size, id; 25 26 u8 err; ··· 34 33 "=m" (*desc) 35 34 : "D" (desc), "a" (0xe820)); 36 35 37 - if (err || id != SMAP) 36 + /* Some BIOSes stop returning SMAP in the middle of 37 + the search loop. We don't know exactly how the BIOS 38 + screwed up the map at that point, we might have a 39 + partial map, the full map, or complete garbage, so 40 + just return failure. */ 41 + if (id != SMAP) { 42 + count = 0; 43 + break; 44 + } 45 + 46 + if (err) 38 47 break; 39 48 40 - boot_params.e820_entries++; 49 + count++; 41 50 desc++; 42 - } while (next && boot_params.e820_entries < E820MAX); 51 + } while (next && count < E820MAX); 43 52 44 - return boot_params.e820_entries; 53 + return boot_params.e820_entries = count; 45 54 } 46 55 47 56 static int detect_memory_e801(void) ··· 100 89 101 90 int detect_memory(void) 102 91 { 92 + int err = -1; 93 + 103 94 if (detect_memory_e820() > 0) 104 - return 0; 95 + err = 0; 105 96 106 97 if (!detect_memory_e801()) 107 - return 0; 98 + err = 0; 108 99 109 - return detect_memory_88(); 100 + if (!detect_memory_88()) 101 + err = 0; 102 + 103 + return err; 110 104 }