diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/platform/efi/efi.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 7daae27e975e..a46a73ecc5f3 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -498,13 +498,41 @@ static void __init runtime_code_page_mkexec(void) | |||
498 | */ | 498 | */ |
499 | void __init efi_enter_virtual_mode(void) | 499 | void __init efi_enter_virtual_mode(void) |
500 | { | 500 | { |
501 | efi_memory_desc_t *md; | 501 | efi_memory_desc_t *md, *prev_md = NULL; |
502 | efi_status_t status; | 502 | efi_status_t status; |
503 | unsigned long size; | 503 | unsigned long size; |
504 | u64 end, systab, addr, npages, end_pfn; | 504 | u64 end, systab, addr, npages, end_pfn; |
505 | void *p, *va; | 505 | void *p, *va; |
506 | 506 | ||
507 | efi.systab = NULL; | 507 | efi.systab = NULL; |
508 | |||
509 | /* Merge contiguous regions of the same type and attribute */ | ||
510 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
511 | u64 prev_size; | ||
512 | md = p; | ||
513 | |||
514 | if (!prev_md) { | ||
515 | prev_md = md; | ||
516 | continue; | ||
517 | } | ||
518 | |||
519 | if (prev_md->type != md->type || | ||
520 | prev_md->attribute != md->attribute) { | ||
521 | prev_md = md; | ||
522 | continue; | ||
523 | } | ||
524 | |||
525 | prev_size = prev_md->num_pages << EFI_PAGE_SHIFT; | ||
526 | |||
527 | if (md->phys_addr == (prev_md->phys_addr + prev_size)) { | ||
528 | prev_md->num_pages += md->num_pages; | ||
529 | md->type = EFI_RESERVED_TYPE; | ||
530 | md->attribute = 0; | ||
531 | continue; | ||
532 | } | ||
533 | prev_md = md; | ||
534 | } | ||
535 | |||
508 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 536 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
509 | md = p; | 537 | md = p; |
510 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) | 538 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) |