aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/e820_64.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c
index 9be697126013..a8694a35352b 100644
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -95,7 +95,8 @@ void __init early_res_to_bootmem(void)
95} 95}
96 96
97/* Check for already reserved areas */ 97/* Check for already reserved areas */
98static inline int bad_addr(unsigned long *addrp, unsigned long size) 98static inline int
99bad_addr(unsigned long *addrp, unsigned long size, unsigned long align)
99{ 100{
100 int i; 101 int i;
101 unsigned long addr = *addrp, last; 102 unsigned long addr = *addrp, last;
@@ -105,7 +106,7 @@ again:
105 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) { 106 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
106 struct early_res *r = &early_res[i]; 107 struct early_res *r = &early_res[i];
107 if (last >= r->start && addr < r->end) { 108 if (last >= r->start && addr < r->end) {
108 *addrp = addr = r->end; 109 *addrp = addr = round_up(r->end, align);
109 changed = 1; 110 changed = 1;
110 goto again; 111 goto again;
111 } 112 }
@@ -174,26 +175,27 @@ int __init e820_all_mapped(unsigned long start, unsigned long end,
174 * Find a free area with specified alignment in a specific range. 175 * Find a free area with specified alignment in a specific range.
175 */ 176 */
176unsigned long __init find_e820_area(unsigned long start, unsigned long end, 177unsigned long __init find_e820_area(unsigned long start, unsigned long end,
177 unsigned size, unsigned long align) 178 unsigned long size, unsigned long align)
178{ 179{
179 int i; 180 int i;
180 unsigned long mask = ~(align - 1);
181 181
182 for (i = 0; i < e820.nr_map; i++) { 182 for (i = 0; i < e820.nr_map; i++) {
183 struct e820entry *ei = &e820.map[i]; 183 struct e820entry *ei = &e820.map[i];
184 unsigned long addr = ei->addr, last; 184 unsigned long addr, last;
185 unsigned long ei_last;
185 186
186 if (ei->type != E820_RAM) 187 if (ei->type != E820_RAM)
187 continue; 188 continue;
189 addr = round_up(ei->addr, align);
190 ei_last = ei->addr + ei->size;
188 if (addr < start) 191 if (addr < start)
189 addr = start; 192 addr = round_up(start, align);
190 if (addr > ei->addr + ei->size) 193 if (addr > ei_last)
191 continue; 194 continue;
192 while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size) 195 while (bad_addr(&addr, size, align) && addr+size <= ei_last)
193 ; 196 ;
194 addr = (addr + align - 1) & mask;
195 last = addr + size; 197 last = addr + size;
196 if (last > ei->addr + ei->size) 198 if (last > ei_last)
197 continue; 199 continue;
198 if (last > end) 200 if (last > end)
199 continue; 201 continue;