lkml.org 
[lkml]   [2013]   [Aug]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[RFC PATCH 4/4] x86: Fix EFI boot stub for large memory maps
Date
This patch adds support for EFI memory maps larger than 128 entries when
booted using the EFI boot stub.

The e820 map in struct boot_params can only hold 128 entries, but the
memory map provided by EFI may be larger. If the map contained more than
128 entries, exit_boot() would write beyond the e820_map array in
boot_params and the system would eventually halt in the BUG_ON check in
sanitize_e820_map().

In the case we come in through efi_main(), the EFI memory map is used.
Instead of populating e820_map in boot_params, create the e820 from the
EFI memory map in setup_arch() via a memory_setup hook.

The EFI memory map may also be added in efi_init() if the command line
parameter "add_efi_memmap" is specified. This is left intact to allow
the command line parameter to remain effective.

Signed-off-by: Linn Crosetto <linn@hp.com>
---
arch/x86/boot/compressed/eboot.c | 64 ++--------------------------------------
arch/x86/kernel/setup.c | 3 ++
2 files changed, 6 insertions(+), 61 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a4..66b8d3d 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -973,6 +973,9 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
if (status != EFI_SUCCESS)
goto fail2;

+ /* Use EFI memory map */
+ boot_params->e820_entries = 0;
+
return boot_params;
fail2:
if (options_size)
@@ -986,8 +989,6 @@ static efi_status_t exit_boot(struct boot_params *boot_params,
void *handle)
{
struct efi_info *efi = &boot_params->efi_info;
- struct e820entry *e820_map = &boot_params->e820_map[0];
- struct e820entry *prev = NULL;
unsigned long size, key, desc_size, _size;
efi_memory_desc_t *mem_map;
efi_status_t status;
@@ -1049,65 +1050,6 @@ get_map:
/* Historic? */
boot_params->alt_mem_k = 32 * 1024;

- /*
- * Convert the EFI memory map to E820.
- */
- nr_entries = 0;
- for (i = 0; i < size / desc_size; i++) {
- efi_memory_desc_t *d;
- unsigned int e820_type = 0;
- unsigned long m = (unsigned long)mem_map;
-
- d = (efi_memory_desc_t *)(m + (i * desc_size));
- switch (d->type) {
- case EFI_RESERVED_TYPE:
- case EFI_RUNTIME_SERVICES_CODE:
- case EFI_RUNTIME_SERVICES_DATA:
- case EFI_MEMORY_MAPPED_IO:
- case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
- case EFI_PAL_CODE:
- e820_type = E820_RESERVED;
- break;
-
- case EFI_UNUSABLE_MEMORY:
- e820_type = E820_UNUSABLE;
- break;
-
- case EFI_ACPI_RECLAIM_MEMORY:
- e820_type = E820_ACPI;
- break;
-
- case EFI_LOADER_CODE:
- case EFI_LOADER_DATA:
- case EFI_BOOT_SERVICES_CODE:
- case EFI_BOOT_SERVICES_DATA:
- case EFI_CONVENTIONAL_MEMORY:
- e820_type = E820_RAM;
- break;
-
- case EFI_ACPI_MEMORY_NVS:
- e820_type = E820_NVS;
- break;
-
- default:
- continue;
- }
-
- /* Merge adjacent mappings */
- if (prev && prev->type == e820_type &&
- (prev->addr + prev->size) == d->phys_addr)
- prev->size += d->num_pages << 12;
- else {
- e820_map->addr = d->phys_addr;
- e820_map->size = d->num_pages << 12;
- e820_map->type = e820_type;
- prev = e820_map++;
- nr_entries++;
- }
- }
-
- boot_params->e820_entries = nr_entries;
-
return EFI_SUCCESS;

free_mem_map:
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f8ec578..9682c8c 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -920,6 +920,9 @@ void __init setup_arch(char **cmdline_p)

if (efi_enabled(EFI_BOOT))
efi_memblock_x86_reserve_range();
+
+ if (efi_memmap_needed())
+ x86_init.resources.memory_setup = efi_memory_setup;
#endif

x86_init.oem.arch_setup();
--
1.7.11.3


\
 
 \ /
  Last update: 2013-08-19 22:21    [W:0.053 / U:0.924 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site