|
Lines 210-215
int __init efi_memblock_x86_reserve_range(void)
Link Here
|
| 210 |
return 0; |
210 |
return 0; |
| 211 |
} |
211 |
} |
| 212 |
|
212 |
|
|
|
213 |
#define OVERFLOW_ADDR_SHIFT (64 - EFI_PAGE_SHIFT) |
| 214 |
#define OVERFLOW_ADDR_MASK (U64_MAX << OVERFLOW_ADDR_SHIFT) |
| 215 |
#define U64_HIGH_BIT (~(U64_MAX >> 1)) |
| 216 |
|
| 217 |
static bool __init efi_memmap_entry_valid(const efi_memory_desc_t *md, int i) |
| 218 |
{ |
| 219 |
u64 end = (md->num_pages << EFI_PAGE_SHIFT) + md->phys_addr - 1; |
| 220 |
u64 end_hi = 0; |
| 221 |
char buf[64]; |
| 222 |
|
| 223 |
if (md->num_pages == 0) { |
| 224 |
end = 0; |
| 225 |
} else if (md->num_pages > EFI_PAGES_MAX || |
| 226 |
EFI_PAGES_MAX - md->num_pages < |
| 227 |
(md->phys_addr >> EFI_PAGE_SHIFT)) { |
| 228 |
end_hi = (md->num_pages & OVERFLOW_ADDR_MASK) |
| 229 |
>> OVERFLOW_ADDR_SHIFT; |
| 230 |
|
| 231 |
if ((md->phys_addr & U64_HIGH_BIT) && !(end & U64_HIGH_BIT)) |
| 232 |
end_hi += 1; |
| 233 |
} else { |
| 234 |
return true; |
| 235 |
} |
| 236 |
|
| 237 |
pr_warn_once(FW_BUG "Invalid EFI memory map entries:\n"); |
| 238 |
|
| 239 |
if (end_hi) { |
| 240 |
pr_warn("mem%02u: %s range=[0x%016llx-0x%llx%016llx] (invalid)\n", |
| 241 |
i, efi_md_typeattr_format(buf, sizeof(buf), md), |
| 242 |
md->phys_addr, end_hi, end); |
| 243 |
} else { |
| 244 |
pr_warn("mem%02u: %s range=[0x%016llx-0x%016llx] (invalid)\n", |
| 245 |
i, efi_md_typeattr_format(buf, sizeof(buf), md), |
| 246 |
md->phys_addr, end); |
| 247 |
} |
| 248 |
return false; |
| 249 |
} |
| 250 |
|
| 251 |
static void __init efi_clean_memmap(void) |
| 252 |
{ |
| 253 |
efi_memory_desc_t *out = efi.memmap.map; |
| 254 |
const efi_memory_desc_t *in = out; |
| 255 |
const efi_memory_desc_t *end = efi.memmap.map_end; |
| 256 |
int i, n_removal; |
| 257 |
|
| 258 |
for (i = n_removal = 0; in < end; i++) { |
| 259 |
if (efi_memmap_entry_valid(in, i)) { |
| 260 |
if (out != in) |
| 261 |
memcpy(out, in, efi.memmap.desc_size); |
| 262 |
out = (void *)out + efi.memmap.desc_size; |
| 263 |
} else { |
| 264 |
n_removal++; |
| 265 |
} |
| 266 |
in = (void *)in + efi.memmap.desc_size; |
| 267 |
} |
| 268 |
|
| 269 |
if (n_removal > 0) { |
| 270 |
u64 size = efi.memmap.nr_map - n_removal; |
| 271 |
|
| 272 |
pr_warn("Removing %d invalid memory map entries.\n", n_removal); |
| 273 |
efi_memmap_install(efi.memmap.phys_map, size); |
| 274 |
} |
| 275 |
} |
| 276 |
|
| 213 |
void __init efi_print_memmap(void) |
277 |
void __init efi_print_memmap(void) |
| 214 |
{ |
278 |
{ |
| 215 |
efi_memory_desc_t *md; |
279 |
efi_memory_desc_t *md; |
|
Lines 472-477
void __init efi_init(void)
Link Here
|
| 472 |
} |
536 |
} |
| 473 |
} |
537 |
} |
| 474 |
|
538 |
|
|
|
539 |
efi_clean_memmap(); |
| 540 |
|
| 475 |
if (efi_enabled(EFI_DBG)) |
541 |
if (efi_enabled(EFI_DBG)) |
| 476 |
efi_print_memmap(); |
542 |
efi_print_memmap(); |
| 477 |
} |
543 |
} |