aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/platform/efi/efi.c30
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 */
499void __init efi_enter_virtual_mode(void) 499void __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))